pexpr.pas:

* extend handle_specialize_inline_specialization() with the ability to handle generic functions
  * have handle_factor_typenode() and postfixoperators() make use of this extension

git-svn-id: trunk@31856 -
This commit is contained in:
svenbarth 2015-09-27 18:53:16 +00:00
parent 88e1e963a3
commit 9dcfec8c63

View File

@ -1377,27 +1377,64 @@ implementation
end; end;
function handle_specialize_inline_specialization(var srsym:tsym;out srsymtable:tsymtable):boolean; function handle_specialize_inline_specialization(var srsym:tsym;out srsymtable:tsymtable;out spezcontext:tspecializationcontext):boolean;
var var
spezdef : tdef; spezdef : tdef;
begin begin
result:=false; result:=false;
spezcontext:=nil;
srsymtable:=nil;
if not assigned(srsym) then if not assigned(srsym) then
message1(sym_e_id_no_member,orgpattern) message1(sym_e_id_no_member,orgpattern)
else else
if srsym.typ<>typesym then if not (srsym.typ in [typesym,procsym]) then
message(type_e_type_id_expected) message(type_e_type_id_expected)
else else
begin begin
spezdef:=ttypesym(srsym).typedef; if srsym.typ=typesym then
generate_specialization(spezdef,false,''); spezdef:=ttypesym(srsym).typedef
if spezdef<>generrordef then else
begin spezdef:=tdef(tprocsym(srsym).procdeflist[0]);
srsym:=spezdef.typesym; spezdef:=generate_specialization_phase1(spezcontext,spezdef);
srsymtable:=srsym.owner; case spezdef.typ of
check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg); errordef:
result:=true; begin
end spezcontext.free;
spezcontext:=nil;
srsym:=generrorsym;
end;
procdef:
begin
if block_type<>bt_body then
begin
message(parser_e_illegal_expression);
spezcontext.free;
spezcontext:=nil;
srsym:=generrorsym;
end
else
begin
srsym:=tprocdef(spezdef).procsym;
srsymtable:=srsym.owner;
result:=true;
end;
end;
objectdef,
recorddef,
arraydef,
procvardef:
begin
spezdef:=generate_specialization_phase2(spezcontext,tstoreddef(spezdef),false,'');
spezcontext.free;
spezcontext:=nil;
srsym:=spezdef.typesym;
srsymtable:=srsym.owner;
check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
result:=true;
end;
else
internalerror(2015070302);
end;
end; end;
end; end;
@ -1407,7 +1444,9 @@ implementation
srsym : tsym; srsym : tsym;
srsymtable : tsymtable; srsymtable : tsymtable;
isspecialize : boolean; isspecialize : boolean;
spezcontext : tspecializationcontext;
begin begin
spezcontext:=nil;
if sym=nil then if sym=nil then
sym:=hdef.typesym; sym:=hdef.typesym;
{ allow Ordinal(Value) for type declarations since it { allow Ordinal(Value) for type declarations since it
@ -1455,7 +1494,7 @@ implementation
if isspecialize then if isspecialize then
begin begin
consume(_ID); consume(_ID);
if not handle_specialize_inline_specialization(srsym,srsymtable) then if not handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
begin begin
result.free; result.free;
result:=cerrornode.create; result:=cerrornode.create;
@ -1468,7 +1507,9 @@ implementation
consume(_ID); consume(_ID);
end; end;
if result.nodetype<>errorn then if result.nodetype<>errorn then
do_member_read(tabstractrecorddef(hdef),false,srsym,result,again,[],nil); do_member_read(tabstractrecorddef(hdef),false,srsym,result,again,[],spezcontext)
else
spezcontext.free;
end end
else else
begin begin
@ -1495,7 +1536,7 @@ implementation
if isspecialize then if isspecialize then
begin begin
consume(_ID); consume(_ID);
if not handle_specialize_inline_specialization(srsym,srsymtable) then if not handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
begin begin
result.free; result.free;
result:=cerrornode.create; result:=cerrornode.create;
@ -1512,7 +1553,9 @@ implementation
Message1(sym_e_id_no_member,orgpattern); Message1(sym_e_id_no_member,orgpattern);
end; end;
if (result.nodetype<>errorn) and assigned(srsym) then if (result.nodetype<>errorn) and assigned(srsym) then
do_member_read(tabstractrecorddef(hdef),getaddr,srsym,result,again,[],nil); do_member_read(tabstractrecorddef(hdef),getaddr,srsym,result,again,[],spezcontext)
else
spezcontext.free;
end; end;
end end
else else
@ -1860,6 +1903,8 @@ implementation
intval : qword; intval : qword;
code : integer; code : integer;
strdef : tdef; strdef : tdef;
spezcontext : tspecializationcontext;
old_current_filepos : tfileposinfo;
label label
skipreckklammercheck, skipreckklammercheck,
skippointdefcheck; skippointdefcheck;
@ -1868,6 +1913,7 @@ implementation
again:=true; again:=true;
while again do while again do
begin begin
spezcontext:=nil;
{ we need the resultdef } { we need the resultdef }
do_typecheckpass_changed(p1,nodechanged); do_typecheckpass_changed(p1,nodechanged);
result:=result or nodechanged; result:=result or nodechanged;
@ -2222,7 +2268,7 @@ implementation
begin begin
searchsym_in_record(structh,pattern,srsym,srsymtable); searchsym_in_record(structh,pattern,srsym,srsymtable);
consume(_ID); consume(_ID);
if handle_specialize_inline_specialization(srsym,srsymtable) then if handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
erroroutp1:=false; erroroutp1:=false;
end; end;
end end
@ -2248,7 +2294,7 @@ implementation
p1:=cerrornode.create; p1:=cerrornode.create;
end end
else else
do_member_read(structh,getaddr,srsym,p1,again,[],nil); do_member_read(structh,getaddr,srsym,p1,again,[],spezcontext);
end end
else else
consume(_ID); consume(_ID);
@ -2359,21 +2405,43 @@ implementation
if token=_ID then if token=_ID then
begin begin
structh:=tobjectdef(tclassrefdef(p1.resultdef).pointeddef); structh:=tobjectdef(tclassrefdef(p1.resultdef).pointeddef);
searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]); if isspecialize then
if assigned(srsym) then
begin begin
check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg); { consume the specialize }
consume(_ID); consume(_ID);
do_member_read(structh,getaddr,srsym,p1,again,[],nil); if token<>_ID then
consume(_ID)
else
begin
searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
consume(_ID);
if handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
erroroutp1:=false;
end;
end end
else else
begin begin
Message1(sym_e_id_no_member,orgpattern); searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
p1.destroy; if assigned(srsym) then
p1:=cerrornode.create; begin
{ try to clean up } check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
consume(_ID); consume(_ID);
erroroutp1:=false;
end
else
begin
Message1(sym_e_id_no_member,orgpattern);
{ try to clean up }
consume(_ID);
end;
end; end;
if erroroutp1 then
begin
p1.free;
p1:=cerrornode.create;
end
else
do_member_read(structh,getaddr,srsym,p1,again,[],spezcontext);
end end
else { Error } else { Error }
Consume(_ID); Consume(_ID);
@ -2395,7 +2463,7 @@ implementation
begin begin
searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]); searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,[ssf_search_helper]);
consume(_ID); consume(_ID);
if handle_specialize_inline_specialization(srsym,srsymtable) then if handle_specialize_inline_specialization(srsym,srsymtable,spezcontext) then
erroroutp1:=false; erroroutp1:=false;
end; end;
end end
@ -2421,7 +2489,7 @@ implementation
p1:=cerrornode.create; p1:=cerrornode.create;
end end
else else
do_member_read(structh,getaddr,srsym,p1,again,[],nil); do_member_read(structh,getaddr,srsym,p1,again,[],spezcontext);
end end
else { Error } else { Error }
Consume(_ID); Consume(_ID);