Browse Source

* moved the generation of th ehidden self parameter from pass_1 to
typecheckpass, because if it's for a nested routine on a platform
that uses ncgnstmm/ncgnstld, all parentfpstructs (which are
generated by the typecheckpass of the loadparentfpnode) must be
generated before pass_1 starts

git-svn-id: trunk@32559 -

Jonas Maebe 9 years ago
parent
commit
6fda08705b
1 changed files with 38 additions and 21 deletions
  1. 38 21
      compiler/ncal.pas

+ 38 - 21
compiler/ncal.pas

@@ -1086,8 +1086,15 @@ implementation
 
              { Convert tp procvars, this is needs to be done
                here to make the change permanent. in the overload
-               choosing the changes are only made temporarily }
-             if (left.resultdef.typ=procvardef) and
+               choosing the changes are only made temporarily
+
+               Don't do this for parentfp parameters, as for calls to nested
+               procvars they are a copy of right, which is the procvar itself
+               and hence turning that into a call would result into endless
+               recursion. For regular nested calls, the parentfp node can
+               never be a procvar (it's a loadparentfpnode). }
+             if not(vo_is_parentfp in parasym.varoptions) and
+                (left.resultdef.typ=procvardef) and
                 not(parasym.vardef.typ in [procvardef,formaldef]) then
                begin
                  if maybe_call_procvar(left,true) then
@@ -3045,24 +3052,6 @@ implementation
                 else
                  if vo_is_syscall_lib in para.parasym.varoptions then
                    gen_syscall_para(para)
-                else
-                 if vo_is_parentfp in para.parasym.varoptions then
-                   begin
-                     if not assigned(right) then
-                       begin
-                         if assigned(procdefinition.owner.defowner) then
-                           para.left:=cloadparentfpnode.create(tprocdef(procdefinition.owner.defowner),lpf_forpara)
-                         { exceptfilters called from main level are not owned }
-                         else if procdefinition.proctypeoption=potype_exceptfilter then
-                           para.left:=cloadparentfpnode.create(current_procinfo.procdef,lpf_forpara)
-                         else
-                           internalerror(200309287);
-                       end
-                     else if not(po_is_block in procdefinition.procoptions) then
-                       para.left:=gen_procvar_context_tree_parentfp
-                     else
-                       para.left:=gen_block_context
-                   end
                 else
                  if vo_is_range_check in para.parasym.varoptions then
                    begin
@@ -3260,7 +3249,15 @@ implementation
                { Here we handle only the parameters that depend on
                  the types of the previous parameter. The typeconversion
                  can change the type in the next step. For example passing
-                 an array can be change to a pointer and a deref }
+                 an array can be change to a pointer and a deref.
+
+                 We also handle the generation of parentfp parameters, as they
+                 must all be created before pass_1 on targets that use explicit
+                 parentfp structs (rather than the frame pointer). The reason
+                 is that the necessary initialisation code for the these
+                 structures is attached to the procedure's nodetree after
+                 the resulttype pass.
+               }
                if vo_is_high_para in currpara.varoptions then
                 begin
                   if not assigned(pt) or (i=0) then
@@ -3289,6 +3286,26 @@ implementation
                       crttinode.create(Tstoreddef(pt.resultdef),fullrtti,rdt_normal)
                     );
                   end
+              else if vo_is_parentfp in currpara.varoptions then
+                begin
+                  if assigned(right) and (right.resultdef.typ=procvardef) and
+                     not tabstractprocdef(right.resultdef).is_addressonly then
+                    maybe_load_in_temp(right);
+                  if not assigned(right) then
+                    begin
+                      if assigned(procdefinition.owner.defowner) then
+                        hiddentree:=cloadparentfpnode.create(tprocdef(procdefinition.owner.defowner),lpf_forpara)
+                      { exceptfilters called from main level are not owned }
+                      else if procdefinition.proctypeoption=potype_exceptfilter then
+                        hiddentree:=cloadparentfpnode.create(current_procinfo.procdef,lpf_forpara)
+                      else
+                        internalerror(200309287);
+                    end
+                  else if not(po_is_block in procdefinition.procoptions) then
+                    hiddentree:=gen_procvar_context_tree_parentfp
+                  else
+                    hiddentree:=gen_block_context
+                end
               else
                 hiddentree:=cnothingnode.create;
               pt:=ccallparanode.create(hiddentree,oldppt^);