Browse Source

ncal.pas:
* extend tcallnode with the ability to pass a tspecializationcontext so that tcallcandidates can do a final specialization
* the final procdef is registered at the end of tcallnode.pass_typecheck

git-svn-id: trunk@31763 -

svenbarth 10 years ago
parent
commit
529677cc79

+ 2 - 2
compiler/htypechk.pas

@@ -779,7 +779,7 @@ implementation
 
         { the nil as symtable signs firstcalln that this is
           an overloaded operator }
-        t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
+        t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
 
         { we already know the procdef to use, so it can
           skip the overload choosing in callnode.pass_typecheck }
@@ -958,7 +958,7 @@ implementation
 
         { the nil as symtable signs firstcalln that this is
           an overloaded operator }
-        ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
+        ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
 
         { we already know the procdef to use, so it can
           skip the overload choosing in callnode.pass_typecheck }

+ 1 - 1
compiler/i386/n386flw.pas

@@ -241,7 +241,7 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
       begin
         finalizepi.code:=right;
         foreachnodestatic(right,@copy_parasize,finalizepi);
-        right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[]);
+        right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
         firstpass(right);
         { For implicit frames, no actual code is available at this time,
           it is added later in assembler form. So store the nested procinfo

+ 1 - 1
compiler/jvm/njvmcal.pas

@@ -591,7 +591,7 @@ implementation
                   in theory do that, because the parameter nodes have already
                   been bound to the current procdef's parasyms }
                 remove_hidden_paras;
-                result:=ccallnode.create(left,tprocsym(sym),symtableproc,methodpointer,callnodeflags);
+                result:=ccallnode.create(left,tprocsym(sym),symtableproc,methodpointer,callnodeflags,nil);
                 result.flags:=flags;
                 left:=nil;
                 methodpointer:=nil;

+ 5 - 5
compiler/jvm/njvmcnv.pas

@@ -524,7 +524,7 @@ implementation
           with a single #0 }
         result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
           ps.owner,
-          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
+          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[],nil);
         include(result.flags,nf_isproperty);
         result:=ctypeconvnode.create_explicit(result,resultdef);
         { reused }
@@ -863,7 +863,7 @@ implementation
           { call the (static class) method to get the raw bits }
           result:=ccallnode.create(ccallparanode.create(left,nil),
             tprocsym(psym),psym.owner,
-            cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[]);
+            cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[],nil);
           { convert the result to the result type of this type conversion node }
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
@@ -882,7 +882,7 @@ implementation
             internalerror(2011062601);
           result:=ccallnode.create(ccallparanode.create(left,nil),
             tprocsym(psym),psym.owner,
-            cloadvmtaddrnode.create(ctypenode.create(todef.classdef)),[]);
+            cloadvmtaddrnode.create(ctypenode.create(todef.classdef)),[],nil);
           { convert the result to the result type of this type conversion node }
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
@@ -899,7 +899,7 @@ implementation
           if not assigned(psym) or
              (psym.typ<>procsym) then
             internalerror(2011062602);
-          result:=ccallnode.create(nil,tprocsym(psym),psym.owner,left,[]);
+          result:=ccallnode.create(nil,tprocsym(psym),psym.owner,left,[],nil);
           { convert the result to the result type of this type conversion node }
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
@@ -1506,7 +1506,7 @@ implementation
               if not assigned(ps) or
                  (ps.typ<>procsym) then
                 internalerror(2011041910);
-              call:=ccallnode.create(ccallparanode.create(node.left,nil),tprocsym(ps),ps.owner,ctypeconvnode.create_explicit(node.right,jlclass),[]);
+              call:=ccallnode.create(ccallparanode.create(node.left,nil),tprocsym(ps),ps.owner,ctypeconvnode.create_explicit(node.right,jlclass),[],nil);
               node.left:=nil;
               node.right:=nil;
               firstpass(call);

+ 2 - 2
compiler/jvm/njvminl.pas

@@ -595,7 +595,7 @@ implementation
               internalerror(2011031403);
             stringnonnull:=cassignmentnode.create(
               ctemprefnode.create(lentemp),
-              ccallnode.create(nil,tprocsym(psym),psym.owner,stringtemp,[]));
+              ccallnode.create(nil,tprocsym(psym),psym.owner,stringtemp,[],nil));
             { else-path: length is 0 }
             stringnull:=cassignmentnode.create(
               ctemprefnode.create(lentemp),
@@ -618,7 +618,7 @@ implementation
               internalerror(2011052402);
             result:=
               ccallnode.create(nil,tprocsym(psym),psym.owner,
-                ctypeconvnode.create_explicit(caddrnode.create_internal(left),java_shortstring),[]);
+                ctypeconvnode.create_explicit(caddrnode.create_internal(left),java_shortstring),[],nil);
             { reused }
             left:=nil;
           end

+ 1 - 1
compiler/jvm/njvmld.pas

@@ -142,7 +142,7 @@ function tjvmassignmentnode.pass_1: tnode;
           ccallnode.create(
             ccallparanode.create(right,
               ccallparanode.create(tvecnode(target).right,nil)),
-            tprocsym(psym),psym.owner,tvecnode(target).left,[]);
+            tprocsym(psym),psym.owner,tvecnode(target).left,[],nil);
         right:=nil;
         tvecnode(target).left:=nil;
         tvecnode(target).right:=nil;

+ 2 - 2
compiler/jvm/njvmmem.pas

@@ -332,7 +332,7 @@ implementation
             if not assigned(vs) or
                (tsym(vs).typ<>procsym) then
               internalerror(2011041901);
-            result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[]);
+            result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[],nil);
             inserttypeconv_explicit(result,resultdef);
             { reused }
             left:=nil;
@@ -385,7 +385,7 @@ implementation
             { Pascal strings are 1-based, Java strings 0-based }
             result:=ccallnode.create(ccallparanode.create(
               caddnode.create(subn,right,genintconstnode(1)),nil),tprocsym(psym),
-              psym.owner,ctypeconvnode.create_explicit(left,stringclass),[]);
+              psym.owner,ctypeconvnode.create_explicit(left,stringclass),[],nil);
             left:=nil;
             right:=nil;
             exit;

+ 16 - 8
compiler/ncal.pas

@@ -35,7 +35,8 @@ interface
        {$ifdef state_tracking}
        nstate,
        {$endif state_tracking}
-       symbase,symtype,symsym,symdef,symtable;
+       symbase,symtype,symsym,symdef,symtable,
+       pgentype;
 
     type
        tcallnodeflag = (
@@ -153,9 +154,11 @@ interface
           typedef: tdef;
           callnodeflags : tcallnodeflags;
 
+          spezcontext : tspecializationcontext;
+
           { only the processor specific nodes need to override this }
           { constructor                                             }
-          constructor create(l:tnode; v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags);virtual;
+          constructor create(l:tnode; v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags;sc:tspecializationcontext);virtual;
           constructor create_procvar(l,r:tnode);
           constructor createintern(const name: string; params: tnode);
           constructor createinternfromunit(const fromunit, procname: string; params: tnode);
@@ -1412,9 +1415,10 @@ implementation
                                  TCALLNODE
  ****************************************************************************}
 
-    constructor tcallnode.create(l:tnode;v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags);
+    constructor tcallnode.create(l:tnode;v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags;sc:tspecializationcontext);
       begin
          inherited create(calln,l,nil);
+         spezcontext:=sc;
          symtableprocentry:=v;
          symtableproc:=st;
          callnodeflags:=callflags+[cnf_return_value_used];
@@ -1440,7 +1444,7 @@ implementation
 
     constructor tcallnode.create_procvar(l,r:tnode);
       begin
-         create(l,nil,nil,nil,[]);
+         create(l,nil,nil,nil,[],nil);
          right:=r;
       end;
 
@@ -1460,7 +1464,7 @@ implementation
          if not assigned(srsym) or
             (srsym.typ<>procsym) then
            Message1(cg_f_unknown_compilerproc,name);
-         create(params,tprocsym(srsym),srsym.owner,nil,[]);
+         create(params,tprocsym(srsym),srsym.owner,nil,[],nil);
        end;
 
 
@@ -1473,7 +1477,7 @@ implementation
          if not searchsym_in_named_module(fromunit,procname,srsym,srsymtable) or
             (srsym.typ<>procsym) then
            Message1(cg_f_unknown_compilerproc,fromunit+'.'+procname);
-         create(params,tprocsym(srsym),srsymtable,nil,[]);
+         create(params,tprocsym(srsym),srsymtable,nil,[],nil);
        end;
 
 
@@ -1530,7 +1534,7 @@ implementation
         if not assigned(ps) or
            (ps.typ<>procsym) then
           internalerror(2011062806);
-        create(params,tprocsym(ps),ps.owner,mp,[]);
+        create(params,tprocsym(ps),ps.owner,mp,[],nil);
       end;
 
 
@@ -3442,7 +3446,7 @@ implementation
                                       ((m_delphi in current_settings.modeswitches) and (cnf_anon_inherited in callnodeflags));
                     candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility,
                       not(nf_isproperty in flags),cnf_objc_id_call in callnodeflags,cnf_unit_specified in callnodeflags,
-                      callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags,nil);
+                      callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags,spezcontext);
 
                      { no procedures found? then there is something wrong
                        with the parameter size or the procedures are
@@ -3543,6 +3547,10 @@ implementation
                         exit;
                       end;
 
+                     { if the final procedure definition is not yet owned,
+                       ensure that it is }
+                     procdefinition.register_def;
+
                      candidates.free;
                  end; { end of procedure to call determination }
              end;

+ 2 - 2
compiler/ncnv.pas

@@ -2227,7 +2227,7 @@ implementation
                 begin
                   include(current_procinfo.flags,pi_do_call);
                   addsymref(aprocdef.procsym);
-                  hp:=ccallnode.create(ccallparanode.create(left,nil),Tprocsym(aprocdef.procsym),nil,nil,[]);
+                  hp:=ccallnode.create(ccallparanode.create(left,nil),Tprocsym(aprocdef.procsym),nil,nil,[],nil);
                   { tell explicitly which def we must use !! (PM) }
                   tcallnode(hp).procdefinition:=aprocdef;
                   left:=nil;
@@ -3355,7 +3355,7 @@ implementation
                          { constructor create(l:tnode; v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags); }
                          result:=ccallnode.create(nil,tprocsym(tpropertysym(implintf.implementsgetter).propaccesslist[palt_read].firstsym^.sym),
                            tprocsym(tpropertysym(implintf.implementsgetter).propaccesslist[palt_read].firstsym^.sym).owner,
-                           left,[]);
+                           left,[],nil);
                          addsymref(tpropertysym(implintf.implementsgetter).propaccesslist[palt_read].firstsym^.sym);
                          { if it is a class, process it further in a similar way }
                          if not is_interface(result.resultdef) then

+ 7 - 7
compiler/nflw.pas

@@ -402,7 +402,7 @@ implementation
          if not assigned(sym) or
             (sym.typ<>procsym) then
            internalerror(2010061901);
-         hp:=ccallnode.create(hp,tprocsym(sym),sym.owner,ctemprefnode.create(expressiontemp),[]);
+         hp:=ccallnode.create(hp,tprocsym(sym),sym.owner,ctemprefnode.create(expressiontemp),[],nil);
          addstatement(outerloopbodystatement,cassignmentnode.create(
            ctemprefnode.create(currentamount),hp));
          { if currentamount = 0, bail out (use copy of hloopvar, because we
@@ -750,12 +750,12 @@ implementation
         if enumerator_get.proctypeoption=potype_operator then
           begin
             enum_get_params:=ccallparanode.create(expr.getcopy,nil);
-            enum_get:=ccallnode.create(enum_get_params, tprocsym(enumerator_get.procsym), nil, nil, []);
+            enum_get:=ccallnode.create(enum_get_params, tprocsym(enumerator_get.procsym), nil, nil, [],nil);
             tcallnode(enum_get).procdefinition:=enumerator_get;
             addsymref(enumerator_get.procsym);
           end
         else
-          enum_get:=ccallnode.create(nil, tprocsym(enumerator_get.procsym), enumerator_get.owner, expr.getcopy, []);
+          enum_get:=ccallnode.create(nil, tprocsym(enumerator_get.procsym), enumerator_get.owner, expr.getcopy, [],nil);
 
         addstatement(loopstatement,
           cassignmentnode.create(
@@ -778,7 +778,7 @@ implementation
                procsym :
                  begin
                    { generate the method call }
-                   enum_current:=ccallnode.create(nil,tprocsym(propaccesslist.firstsym^.sym),enumerator_current.owner,ctemprefnode.create(enumvar),[]);
+                   enum_current:=ccallnode.create(nil,tprocsym(propaccesslist.firstsym^.sym),enumerator_current.owner,ctemprefnode.create(enumvar),[],nil);
                    include(enum_current.flags,nf_isproperty);
                  end
                else
@@ -797,7 +797,7 @@ implementation
         { add the actual statement to the loop }
         addstatement(loopbodystatement,hloopbody);
 
-        enum_move:=ccallnode.create(nil, tprocsym(enumerator_move.procsym), enumerator_move.owner, ctemprefnode.create(enumvar), []);
+        enum_move:=ccallnode.create(nil, tprocsym(enumerator_move.procsym), enumerator_move.owner, ctemprefnode.create(enumvar), [],nil);
         whileloopnode:=cwhilerepeatnode.create(enum_move,loopbody,true,false);
 
         if enumerator_is_class then
@@ -809,7 +809,7 @@ implementation
                 whileloopnode:=ctryfinallynode.create(
                   whileloopnode, // try node
                   ccallnode.create(nil,tprocsym(enumerator_destructor.procsym), // finally node
-                    enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[]));
+                    enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[],nil));
               end;
             { if getenumerator <> nil then do the loop }
             whileloopnode:=cifnode.create(
@@ -828,7 +828,7 @@ implementation
               begin
                 addstatement(loopstatement,
                   ccallnode.create(nil,tprocsym(enumerator_destructor.procsym),
-                    enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[]));
+                    enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[],nil));
               end;
           end;
 

+ 2 - 2
compiler/ngenutil.pas

@@ -146,7 +146,7 @@ implementation
                       caddnode.create(unequaln,
                           load_vmt_pointer_node,
                           cnilnode.create)),
-                  ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                  ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
                   nil));
             end
           else
@@ -353,7 +353,7 @@ implementation
                        (tprocsym(psym).procdeflist.count<>1) then
                       internalerror(2011040301);
                     addstatement(stat,ccallnode.create(nil,tprocsym(psym),
-                      pd.struct.symtable,nil,[]));
+                      pd.struct.symtable,nil,[],nil));
                   end;
                 addstatement(stat,result);
                 result:=block

+ 1 - 1
compiler/nmem.pas

@@ -293,7 +293,7 @@ implementation
                 (vs.typ<>procsym) then
                internalerror(2011080601);
              { can't reuse "self", because it will be freed when we return }
-             result:=ccallnode.create(nil,tprocsym(vs),vs.owner,self.getcopy,[]);
+             result:=ccallnode.create(nil,tprocsym(vs),vs.owner,self.getcopy,[],nil);
            end;
       end;
 

+ 4 - 4
compiler/pexpr.pas

@@ -1056,10 +1056,10 @@ implementation
                begin
                  if not (st.symtabletype in [ObjectSymtable,recordsymtable]) then
                    internalerror(200310031);
-                 p1:=ccallnode.create(para,tprocsym(sym),obj.symtable,p1,callflags);
+                 p1:=ccallnode.create(para,tprocsym(sym),obj.symtable,p1,callflags,nil);
                end
              else
-               p1:=ccallnode.create(para,tprocsym(sym),st,p1,callflags);
+               p1:=ccallnode.create(para,tprocsym(sym),st,p1,callflags,nil);
            end;
          afterassignment:=prevafterassn;
       end;
@@ -1146,7 +1146,7 @@ implementation
                          membercall:=maybe_load_methodpointer(st,p1);
                          if membercall then
                            include(callflags,cnf_member_call);
-                         p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags);
+                         p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags,nil);
                          addsymref(sym);
                          paras:=nil;
                          consume(_ASSIGNMENT);
@@ -1207,7 +1207,7 @@ implementation
                           membercall:=maybe_load_methodpointer(st,p1);
                           if membercall then
                             include(callflags,cnf_member_call);
-                          p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags);
+                          p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags,nil);
                           paras:=nil;
                           include(p1.flags,nf_isproperty);
                           include(p1.flags,nf_no_lvalue);

+ 1 - 1
compiler/pinline.pas

@@ -245,7 +245,7 @@ implementation
                       do_member_read(classh,false,sym,p2,again,[callflag])
                     else
                       begin
-                        p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2,[callflag]);
+                        p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2,[callflag],nil);
                         { support dispose(p,done()); }
                         if try_to_consume(_LKLAMMER) then
                           begin

+ 6 - 6
compiler/psub.pas

@@ -480,7 +480,7 @@ implementation
                                     voidpointertype),
                                 ccallnode.create(nil,tprocsym(srsym),srsym.owner,
                                   ctypeconvnode.create_internal(load_self_pointer_node,cclassrefdef.create(current_structdef)),
-                                  [])),
+                                  [],nil)),
                             nil));
                       end
                     else
@@ -527,7 +527,7 @@ implementation
                          if assigned(srsym) and
                             (srsym.typ=procsym) then
                            begin
-                             call:=ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[cnf_inherited]);
+                             call:=ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[cnf_inherited],nil);
                              exclude(tcallnode(call).callnodeflags,cnf_return_value_used);
                              addstatement(newstatement,call);
                            end
@@ -569,7 +569,7 @@ implementation
                               load_vmt_pointer_node,ptrsinttype),
                             ctypeconvnode.create_internal(
                               cnilnode.create,ptrsinttype)),
-                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
                         nil));
                   end
                 else
@@ -620,7 +620,7 @@ implementation
                                         load_vmt_pointer_node,
                                         voidpointertype),
                                     cpointerconstnode.create(0,voidpointertype))),
-                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
                             nil));
                       end
                     else
@@ -766,7 +766,7 @@ implementation
                         caddnode.create(unequaln,
                           load_vmt_pointer_node,
                           cnilnode.create)),
-                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
                         nil));
                     tocode:=afterconstructionblock;
                   end
@@ -794,7 +794,7 @@ implementation
                             load_vmt_pointer_node,
                             cnilnode.create),
                           { cnf_create_failed -> don't call BeforeDestruction }
-                          ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node,[cnf_create_failed]),
+                          ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node,[cnf_create_failed],nil),
                           nil))
                     else
                       { object without destructor, call 'fail' helper }

+ 1 - 1
compiler/x86_64/nx64flw.pas

@@ -211,7 +211,7 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
       begin
         finalizepi.code:=right;
         foreachnodestatic(right,@copy_parasize,finalizepi);
-        right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[]);
+        right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
         firstpass(right);
         { For implicit frames, no actual code is available at this time,
           it is added later in assembler form. So store the nested procinfo