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
              { Convert tp procvars, this is needs to be done
                here to make the change permanent. in the overload
                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
                 not(parasym.vardef.typ in [procvardef,formaldef]) then
                begin
                begin
                  if maybe_call_procvar(left,true) then
                  if maybe_call_procvar(left,true) then
@@ -3045,24 +3052,6 @@ implementation
                 else
                 else
                  if vo_is_syscall_lib in para.parasym.varoptions then
                  if vo_is_syscall_lib in para.parasym.varoptions then
                    gen_syscall_para(para)
                    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
                 else
                  if vo_is_range_check in para.parasym.varoptions then
                  if vo_is_range_check in para.parasym.varoptions then
                    begin
                    begin
@@ -3260,7 +3249,15 @@ implementation
                { Here we handle only the parameters that depend on
                { Here we handle only the parameters that depend on
                  the types of the previous parameter. The typeconversion
                  the types of the previous parameter. The typeconversion
                  can change the type in the next step. For example passing
                  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
                if vo_is_high_para in currpara.varoptions then
                 begin
                 begin
                   if not assigned(pt) or (i=0) then
                   if not assigned(pt) or (i=0) then
@@ -3289,6 +3286,26 @@ implementation
                       crttinode.create(Tstoreddef(pt.resultdef),fullrtti,rdt_normal)
                       crttinode.create(Tstoreddef(pt.resultdef),fullrtti,rdt_normal)
                     );
                     );
                   end
                   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
               else
                 hiddentree:=cnothingnode.create;
                 hiddentree:=cnothingnode.create;
               pt:=ccallparanode.create(hiddentree,oldppt^);
               pt:=ccallparanode.create(hiddentree,oldppt^);