2
0
Эх сурвалжийг харах

Implement two phase specialization to support inline specialization of generic functions in non-Delphi modes.

pexpr.pas, factor.factor_read_id:
  * instead of using generate_specialization() use generate_specialization_phase1() and (for non-procdefs) generate_specialization_phase2
  * pass generated specialization context for procdef on to the generated call nodes which do the second part of the specialization then

git-svn-id: trunk@32384 -
svenbarth 9 жил өмнө
parent
commit
ae8316b1b4
1 өөрчлөгдсөн 43 нэмэгдсэн , 6 устгасан
  1. 43 6
      compiler/pexpr.pas

+ 43 - 6
compiler/pexpr.pas

@@ -2709,7 +2709,9 @@ implementation
            allowspecialize,
            isspecialize,
            unit_found : boolean;
+           dummypos,
            tokenpos: tfileposinfo;
+           spezcontext : tspecializationcontext;
          begin
            { allow post fix operators }
            again:=true;
@@ -2717,6 +2719,7 @@ implementation
            { preinitalize tokenpos }
            tokenpos:=current_filepos;
            p1:=nil;
+           spezcontext:=nil;
 
            allowspecialize:=not (m_delphi in current_settings.modeswitches) and
                             not (ef_had_specialize in flags) and
@@ -2781,17 +2784,44 @@ implementation
                      end
                    else
                      begin
-                       hdef:=ttypesym(srsym).typedef;
-                       generate_specialization(hdef,false,'');
+                       {$push}
+                       {$warn 5036 off}
+                       hdef:=generate_specialization_phase1(spezcontext,nil,nil,orgstoredpattern,dummypos);
+                       {$pop}
                        if hdef=generrordef then
                          begin
+                           spezcontext.free;
+                           spezcontext:=nil;
                            srsym:=generrorsym;
                            srsymtable:=nil;
                          end
                        else
                          begin
-                           srsym:=hdef.typesym;
-                           srsymtable:=srsym.owner;
+                           if hdef.typ in [objectdef,recorddef,procvardef,arraydef] then
+                             begin
+                               hdef:=generate_specialization_phase2(spezcontext,tstoreddef(hdef),false,'');
+                               spezcontext.free;
+                               spezcontext:=nil;
+                               srsym:=hdef.typesym;
+                               srsymtable:=srsym.owner;
+                             end
+                           else
+                             if hdef.typ=procdef then
+                               begin
+                                 if block_type<>bt_body then
+                                   begin
+                                     message(parser_e_illegal_expression);
+                                     srsym:=generrorsym;
+                                     srsymtable:=nil;
+                                   end
+                                 else
+                                   begin
+                                     srsym:=tprocdef(hdef).procsym;
+                                     srsymtable:=srsym.owner;
+                                   end;
+                               end
+                             else
+                               internalerror(2015061204);
                          end;
                      end;
                  end;
@@ -2995,7 +3025,10 @@ implementation
                         { not srsymtable.symtabletype since that can be }
                         { withsymtable as well                          }
                         if (srsym.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
-                          do_member_read(tabstractrecorddef(hdef),getaddr,srsym,p1,again,[],nil)
+                          begin
+                            do_member_read(tabstractrecorddef(hdef),getaddr,srsym,p1,again,[],spezcontext);
+                            spezcontext:=nil;
+                          end
                         else
                           { no procsyms in records (yet) }
                           internalerror(2007012006);
@@ -3009,7 +3042,8 @@ implementation
                           callflags:=[cnf_unit_specified];
                         do_proc_call(srsym,srsymtable,nil,
                                      (getaddr and not(token in [_CARET,_POINT,_LECKKLAMMER])),
-                                     again,p1,callflags,nil);
+                                     again,p1,callflags,spezcontext);
+                        spezcontext:=nil;
                       end;
                   end;
 
@@ -3096,6 +3130,9 @@ implementation
                   end;
               end; { end case }
 
+              if assigned(spezcontext) then
+                internalerror(2015061207);
+
               if assigned(p1) and (p1.nodetype<>errorn) then
                 p1.fileinfo:=tokenpos;
             end;