Forráskód Böngészése

* passing a var parameter to var parameter is now also allowed
for register locations (=regvars)

peter 21 éve
szülő
commit
0573c742e4
2 módosított fájl, 60 hozzáadás és 45 törlés
  1. 35 20
      compiler/ncgcal.pas
  2. 25 25
      compiler/ncgld.pas

+ 35 - 20
compiler/ncgcal.pas

@@ -428,20 +428,33 @@ implementation
                      paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
                      paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
                          aktcallnode.procdefinition.proccalloption)) then
                          aktcallnode.procdefinition.proccalloption)) then
                    begin
                    begin
-                      { Check for passing a constant to var,out parameter }
-                      if (paraitem.paratyp in [vs_var,vs_out]) and
-                         (left.location.loc<>LOC_REFERENCE) then
-                       begin
-                         { passing self to a var parameter is allowed in
-                           TP and delphi }
-                         if not((left.location.loc=LOC_CREFERENCE) and
-                                is_self_node(left)) then
-                          internalerror(200106041);
-                       end;
-                      { Force to be in memory }
-                      if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
-                        location_force_mem(exprasmlist,left.location);
-                      push_addr_para;
+                      { Passing a var parameter to a var parameter, we can
+                        just push the address transparently }
+                      if (left.nodetype=loadn) and
+                         (tloadnode(left).is_addr_param_load) then
+                        begin
+                          if (left.location.reference.index<>NR_NO) or
+                             (left.location.reference.offset<>0) then
+                            internalerror(200410107);
+                          cg.a_param_reg(exprasmlist,OS_ADDR,left.location.reference.base,tempcgpara)
+                        end
+                      else
+                        begin
+                          { Check for passing a constant to var,out parameter }
+                          if (paraitem.paratyp in [vs_var,vs_out]) and
+                             (left.location.loc<>LOC_REFERENCE) then
+                           begin
+                             { passing self to a var parameter is allowed in
+                               TP and delphi }
+                             if not((left.location.loc=LOC_CREFERENCE) and
+                                    is_self_node(left)) then
+                              internalerror(200106041);
+                           end;
+                          { Force to be in memory }
+                          if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+                            location_force_mem(exprasmlist,left.location);
+                          push_addr_para;
+                        end;
                    end
                    end
                  else
                  else
                    push_value_para;
                    push_value_para;
@@ -1049,8 +1062,7 @@ implementation
          { Allocate parameters and locals }
          { Allocate parameters and locals }
          gen_alloc_inline_parast(exprasmlist,tprocdef(procdefinition));
          gen_alloc_inline_parast(exprasmlist,tprocdef(procdefinition));
          gen_alloc_inline_funcret(exprasmlist,tprocdef(procdefinition));
          gen_alloc_inline_funcret(exprasmlist,tprocdef(procdefinition));
-         if tprocdef(procdefinition).localst.symtabletype=localsymtable then
-           gen_alloc_localst(exprasmlist,tlocalsymtable(tprocdef(procdefinition).localst));
+         gen_alloc_symtable(exprasmlist,tlocalsymtable(tprocdef(procdefinition).localst));
 
 
          { if we allocate the temp. location for ansi- or widestrings }
          { if we allocate the temp. location for ansi- or widestrings }
          { already here, we avoid later a push/pop                    }
          { already here, we avoid later a push/pop                    }
@@ -1183,9 +1195,8 @@ implementation
            end;
            end;
 
 
          { Release parameters and locals }
          { Release parameters and locals }
-         gen_free_parast(exprasmlist,tparasymtable(current_procinfo.procdef.parast));
-         if current_procinfo.procdef.localst.symtabletype=localsymtable then
-           gen_free_localst(exprasmlist,tlocalsymtable(current_procinfo.procdef.localst));
+         gen_free_symtable(exprasmlist,tparasymtable(current_procinfo.procdef.parast));
+         gen_free_symtable(exprasmlist,tlocalsymtable(current_procinfo.procdef.localst));
 
 
 {$ifdef GDB}
 {$ifdef GDB}
          if (cs_debuginfo in aktmoduleswitches) and
          if (cs_debuginfo in aktmoduleswitches) and
@@ -1232,7 +1243,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.176  2004-09-27 15:15:20  peter
+  Revision 1.177  2004-10-10 20:21:18  peter
+    * passing a var parameter to var parameter is now also allowed
+      for register locations (=regvars)
+
+  Revision 1.176  2004/09/27 15:15:20  peter
     * dealloc function result registers, register allocation is now
     * dealloc function result registers, register allocation is now
       back at pre-paraloc level
       back at pre-paraloc level
 
 

+ 25 - 25
compiler/ncgld.pas

@@ -119,13 +119,8 @@ implementation
                begin
                begin
                   symtabletype:=symtable.symtabletype;
                   symtabletype:=symtable.symtabletype;
                   hregister:=NR_NO;
                   hregister:=NR_NO;
-                  { C variable }
-                  if (vo_is_C_var in tvarsym(symtableentry).varoptions) then
-                    begin
-                       location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
-                    end
                   { DLL variable }
                   { DLL variable }
-                  else if (vo_is_dll_var in tvarsym(symtableentry).varoptions) then
+                  if (vo_is_dll_var in tvarsym(symtableentry).varoptions) then
                     begin
                     begin
                       if target_info.system=system_powerpc_darwin then
                       if target_info.system=system_powerpc_darwin then
                         begin
                         begin
@@ -141,12 +136,7 @@ implementation
                           reference_reset_base(location.reference,hregister,0);
                           reference_reset_base(location.reference,hregister,0);
                         end;
                         end;
                     end
                     end
-                  { external variable }
-                  else if (vo_is_external in tvarsym(symtableentry).varoptions) then
-                    begin
-                      location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
-                    end
-                  { thread variable }
+                  { Thread variable }
                   else if (vo_is_thread_var in tvarsym(symtableentry).varoptions) then
                   else if (vo_is_thread_var in tvarsym(symtableentry).varoptions) then
                     begin
                     begin
                        {
                        {
@@ -192,7 +182,7 @@ implementation
                        cg.a_label(exprasmlist,endrelocatelab);
                        cg.a_label(exprasmlist,endrelocatelab);
                        location.reference.base:=hregister;
                        location.reference.base:=hregister;
                     end
                     end
-                  { nested variable }
+                  { Nested variable }
                   else if assigned(left) then
                   else if assigned(left) then
                     begin
                     begin
                       if not(symtabletype in [localsymtable,parasymtable]) then
                       if not(symtabletype in [localsymtable,parasymtable]) then
@@ -205,7 +195,7 @@ implementation
                       hregister:=left.location.register;
                       hregister:=left.location.register;
                       reference_reset_base(location.reference,hregister,tvarsym(symtableentry).localloc.reference.offset);
                       reference_reset_base(location.reference,hregister,tvarsym(symtableentry).localloc.reference.offset);
                     end
                     end
-                  { normal variable }
+                  { Normal (or external) variable }
                   else
                   else
                     begin
                     begin
 {$ifdef OLDREGVARS}
 {$ifdef OLDREGVARS}
@@ -246,7 +236,12 @@ implementation
                                         internalerror(200403023);
                                         internalerror(200403023);
                                     end
                                     end
                                   else
                                   else
-                                    location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
+                                    begin
+                                      if tvarsym(symtableentry).localloc.loc=LOC_INVALID then
+                                        reference_reset_symbol(location.reference,objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA),0)
+                                      else
+                                        location:=tvarsym(symtableentry).localloc;
+                                    end;
                                 end;
                                 end;
                               else
                               else
                                 internalerror(200305102);
                                 internalerror(200305102);
@@ -257,16 +252,17 @@ implementation
                   { handle call by reference variables when they are not
                   { handle call by reference variables when they are not
                     alreayd copied to local copies. Also ignore the reference
                     alreayd copied to local copies. Also ignore the reference
                     when we need to load the self pointer for objects }
                     when we need to load the self pointer for objects }
-                  if (symtabletype=parasymtable) and
-                     not(vo_has_local_copy in tvarsym(symtableentry).varoptions) and
-                     not(nf_load_self_pointer in flags) and
-                     paramanager.push_addr_param(tvarsym(symtableentry).varspez,tvarsym(symtableentry).vartype.def,tprocdef(symtable.defowner).proccalloption) then
+                  if is_addr_param_load then
                     begin
                     begin
-                      if hregister=NR_NO then
-                        hregister:=cg.getaddressregister(exprasmlist);
-                      { we need to load only an address }
-                      location.size:=OS_ADDR;
-                      cg.a_load_loc_reg(exprasmlist,location.size,location,hregister);
+                      if (location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
+                        hregister:=location.register
+                      else
+                        begin
+                          hregister:=cg.getaddressregister(exprasmlist);
+                          { we need to load only an address }
+                          location.size:=OS_ADDR;
+                          cg.a_load_loc_reg(exprasmlist,location.size,location,hregister);
+                        end;
                       location_reset(location,LOC_REFERENCE,newsize);
                       location_reset(location,LOC_REFERENCE,newsize);
                       location.reference.base:=hregister;
                       location.reference.base:=hregister;
                     end;
                     end;
@@ -927,7 +923,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.126  2004-09-26 17:45:30  peter
+  Revision 1.127  2004-10-10 20:21:18  peter
+    * passing a var parameter to var parameter is now also allowed
+      for register locations (=regvars)
+
+  Revision 1.126  2004/09/26 17:45:30  peter
     * simple regvar support, not yet finished
     * simple regvar support, not yet finished
 
 
   Revision 1.125  2004/09/25 14:23:54  peter
   Revision 1.125  2004/09/25 14:23:54  peter