Procházet zdrojové kódy

* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not

peter před 23 roky
rodič
revize
a28f75ed03

+ 12 - 2
compiler/browcol.pas

@@ -1461,7 +1461,7 @@ end;
                  end
                else
                  MemInfo.Size:=getsize;
-               MemInfo.PushSize:=getpushsize;
+               MemInfo.PushSize:=getpushsize(false);
                Symbol^.SetMemInfo(MemInfo);
              end;
           constsym :
@@ -2125,7 +2125,17 @@ begin
 end.
 {
   $Log$
-  Revision 1.26  2002-07-02 06:09:08  michael
+  Revision 1.27  2002-08-25 19:25:18  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.26  2002/07/02 06:09:08  michael
   + Patch from peter to fix snapshots
 
   Revision 1.25  2002/05/18 13:34:05  peter

+ 13 - 4
compiler/i386/n386cal.pas

@@ -114,7 +114,7 @@ implementation
          { handle varargs first, because defcoll is not valid }
          if (nf_varargs_para in flags) then
            begin
-             if paramanager.push_addr_param(left.resulttype.def) then
+             if paramanager.push_addr_param(left.resulttype.def,is_cdecl) then
                begin
                  inc(pushedparasize,4);
                  cg.a_paramaddr_ref(exprasmlist,left.location.reference,paralocdummy);
@@ -214,8 +214,7 @@ implementation
                    is_array_of_const(defcoll.paratype.def))
                  ) or
                  (
-                  paramanager.push_addr_param(resulttype.def) and
-                  not is_cdecl
+                  paramanager.push_addr_param(resulttype.def,is_cdecl)
                  ) then
                 begin
                    if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
@@ -1315,7 +1314,17 @@ begin
 end.
 {
   $Log$
-  Revision 1.66  2002-08-23 16:14:49  peter
+  Revision 1.67  2002-08-25 19:25:21  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.66  2002/08/23 16:14:49  peter
     * tempgen cleanup
     * tt_noreuse temp type added that will be used in genentrycode
 

+ 13 - 4
compiler/ncgcal.pas

@@ -116,7 +116,7 @@ implementation
          { handle varargs first, because defcoll is not valid }
          if (nf_varargs_para in flags) then
            begin
-             if paramanager.push_addr_param(left.resulttype.def) then
+             if paramanager.push_addr_param(left.resulttype.def,is_cdecl) then
                begin
                  inc(pushedparasize,4);
                  cg.a_paramaddr_ref(exprasmlist,left.location.reference,defcoll.paraloc);
@@ -216,8 +216,7 @@ implementation
                    is_array_of_const(defcoll.paratype.def))
                  ) or
                  (
-                  paramanager.push_addr_param(resulttype.def) and
-                  not is_cdecl
+                  paramanager.push_addr_param(resulttype.def,is_cdecl)
                  ) then
                 begin
                    if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
@@ -1476,7 +1475,17 @@ begin
 end.
 {
   $Log$
-  Revision 1.15  2002-08-23 16:14:48  peter
+  Revision 1.16  2002-08-25 19:25:18  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.15  2002/08/23 16:14:48  peter
     * tempgen cleanup
     * tt_noreuse temp type added that will be used in genentrycode
 

+ 17 - 3
compiler/ncgld.pas

@@ -52,7 +52,7 @@ implementation
 
     uses
       systems,
-      verbose,globals,
+      verbose,globtype,globals,
       symconst,symtype,symdef,symsym,symtable,defbase,paramgr,
       ncnv,ncon,nmem,
       aasmbase,aasmtai,aasmcpu,regvars,
@@ -68,6 +68,7 @@ implementation
       var
         intreg,
         hregister : tregister;
+        is_cdecl,
         freereg   : boolean;
         symtabletype : tsymtabletype;
         i : longint;
@@ -248,13 +249,16 @@ implementation
                                    end;
                               end;
                          end;
+                       { cdecl procedure }
+                       is_cdecl:=(symtabletype=parasymtable) and
+                                 (tprocdef(symtable.defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
                        { in case call by reference, then calculate. Open array
                          is always an reference! }
                        if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
                           is_open_array(tvarsym(symtableentry).vartype.def) or
                           is_array_of_const(tvarsym(symtableentry).vartype.def) or
                           ((tvarsym(symtableentry).varspez=vs_const) and
-                           paramanager.push_addr_param(tvarsym(symtableentry).vartype.def)) then
+                           paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,is_cdecl)) then
                          begin
                             if hregister=R_NO then
                               hregister:=rg.getaddressregister(exprasmlist);
@@ -940,7 +944,17 @@ begin
 end.
 {
   $Log$
-  Revision 1.25  2002-08-23 16:14:48  peter
+  Revision 1.26  2002-08-25 19:25:18  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.25  2002/08/23 16:14:48  peter
     * tempgen cleanup
     * tt_noreuse temp type added that will be used in genentrycode
 

+ 13 - 3
compiler/ncgutil.pas

@@ -737,7 +737,7 @@ implementation
          begin
            { call by value open array ? }
            if is_cdecl and
-              paramanager.push_addr_param(p.resulttype.def) then
+              paramanager.push_addr_param(p.resulttype.def,false) then
             begin
               if not (p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
                 internalerror(200204241);
@@ -839,7 +839,7 @@ implementation
         list:=taasmoutput(arg);
         if (tsym(p).typ=varsym) and
            (tvarsym(p).varspez=vs_value) and
-           (paramanager.push_addr_param(tvarsym(p).vartype.def)) then
+           (paramanager.push_addr_param(tvarsym(p).vartype.def,false)) then
          begin
            reference_reset_base(href1,procinfo.framepointer,tvarsym(p).address+procinfo.para_offset);
            if is_open_array(tvarsym(p).vartype.def) or
@@ -1732,7 +1732,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.42  2002-08-24 18:38:26  peter
+  Revision 1.43  2002-08-25 19:25:18  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.42  2002/08/24 18:38:26  peter
     * really use tt_noreuse for exception frame buffers
 
   Revision 1.41  2002/08/23 16:14:49  peter

+ 12 - 2
compiler/nld.pas

@@ -396,7 +396,7 @@ implementation
                    { we need a register for call by reference parameters }
                    if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
                       ((tvarsym(symtableentry).varspez=vs_const) and
-                      paramanager.push_addr_param(tvarsym(symtableentry).vartype.def)) or
+                      paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,false)) or
                       { call by value open arrays are also indirect addressed }
                       is_open_array(tvarsym(symtableentry).vartype.def) then
                      registers32:=1;
@@ -1120,7 +1120,17 @@ begin
 end.
 {
   $Log$
-  Revision 1.53  2002-08-19 19:36:43  peter
+  Revision 1.54  2002-08-25 19:25:19  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.53  2002/08/19 19:36:43  peter
     * More fixes for cross unit inlining, all tnodes are now implemented
     * Moved pocall_internconst to po_internconst because it is not a
       calling type at all and it conflicted when inlining of these small

+ 21 - 7
compiler/paramgr.pas

@@ -56,7 +56,7 @@ unit paramgr;
           {# Returns true if a parameter is too large to copy and only
             the address is pushed
           }
-          function push_addr_param(def : tdef) : boolean;virtual;
+          function push_addr_param(def : tdef;is_cdecl:boolean) : boolean;virtual;
           {# Returns a structure giving the information on
              the storage of the parameter (which must be
              an integer parameter)
@@ -138,7 +138,7 @@ unit paramgr;
 
 
     { true if a parameter is too large to copy and only the address is pushed }
-    function tparamanager.push_addr_param(def : tdef) : boolean;
+    function tparamanager.push_addr_param(def : tdef;is_cdecl:boolean) : boolean;
       begin
         push_addr_param:=false;
         if never_copy_const_param then
@@ -150,9 +150,13 @@ unit paramgr;
              formaldef :
                push_addr_param:=true;
              recorddef :
-               push_addr_param:=(def.size>pointer_size);
+               push_addr_param:=(not is_cdecl) and (def.size>pointer_size);
              arraydef :
-               push_addr_param:=((tarraydef(def).highrange>=tarraydef(def).lowrange) and (def.size>pointer_size)) or
+               push_addr_param:=(
+                                 (tarraydef(def).highrange>=tarraydef(def).lowrange) and
+                                 (def.size>pointer_size) and
+                                 (not is_cdecl)
+                                ) or
                                 is_open_array(def) or
                                 is_array_of_const(def) or
                                 is_array_constructor(def);
@@ -161,9 +165,9 @@ unit paramgr;
              stringdef :
                push_addr_param:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
              procvardef :
-               push_addr_param:=(po_methodpointer in tprocvardef(def).procoptions);
+               push_addr_param:=(not is_cdecl) and (po_methodpointer in tprocvardef(def).procoptions);
              setdef :
-               push_addr_param:=(tsetdef(def).settype<>smallset);
+               push_addr_param:=(not is_cdecl) and (tsetdef(def).settype<>smallset);
            end;
          end;
       end;
@@ -302,7 +306,17 @@ end.
 
 {
    $Log$
-   Revision 1.14  2002-08-17 22:09:47  florian
+   Revision 1.15  2002-08-25 19:25:19  peter
+     * sym.insert_in_data removed
+     * symtable.insertvardata/insertconstdata added
+     * removed insert_in_data call from symtable.insert, it needs to be
+       called separatly. This allows to deref the address calculation
+     * procedures now calculate the parast addresses after the procedure
+       directives are parsed. This fixes the cdecl parast problem
+     * push_addr_param has an extra argument that specifies if cdecl is used
+       or not
+
+   Revision 1.14  2002/08/17 22:09:47  florian
      * result type handling in tcgcal.pass_2 overhauled
      * better tnode.dowrite
      * some ppc stuff fixed

+ 12 - 1
compiler/pdecl.pas

@@ -195,6 +195,7 @@ implementation
                    sym:=ttypedconstsym.createtype(orgname,tt,(cs_typed_const_writable in aktlocalswitches));
                    akttokenpos:=storetokenpos;
                    symtablestack.insert(sym);
+                   symtablestack.insertconstdata(sym);
                    { procvar can have proc directives }
                    if (tt.def.deftype=procvardef) then
                     begin
@@ -616,7 +617,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.52  2002-08-12 15:08:40  carl
+  Revision 1.53  2002-08-25 19:25:19  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.52  2002/08/12 15:08:40  carl
     + stab register indexes for powerpc (moved from gdb to cpubase)
     + tprocessor enumeration moved to cpuinfo
     + linker in target_info is now a class

+ 86 - 60
compiler/pdecsub.pas

@@ -46,6 +46,7 @@ interface
     procedure parse_proc_directives(var pdflags:word);
 
     procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
+    procedure calc_parasymtable_addresses(def:tprocdef);
 
     procedure parse_proc_head(options:tproctypeoption);
     procedure parse_proc_dec;
@@ -282,7 +283,8 @@ implementation
                    { but I suppose the comment is wrong and                         }
                    { it means that the address of var parameters can be placed      }
                    { in a register (FK)                                             }
-                     if (varspez in [vs_var,vs_const,vs_out]) and paramanager.push_addr_param(tt.def) then
+                     if (varspez in [vs_var,vs_const,vs_out]) and
+                        paramanager.push_addr_param(tt.def,false) then
                        include(vs.varoptions,vo_regable);
 
                    { insert the sym in the parasymtable }
@@ -291,7 +293,7 @@ implementation
                    { do we need a local copy? Then rename the varsym, do this after the
                      insert so the dup id checking is done correctly }
                      if (varspez=vs_value) and
-                        paramanager.push_addr_param(tt.def) and
+                        paramanager.push_addr_param(tt.def,aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
                         not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
                        tprocdef(aktprocdef).parast.rename(vs.name,'val'+vs.name);
 
@@ -1462,14 +1464,10 @@ const
 
 
     procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
-      var
-        st,parast : tsymtable;
-        lastps,
-        highps,ps : tsym;
       begin
       { set the default calling convention }
         if def.proccalloption=pocall_none then
-         def.proccalloption:=aktdefproccall;
+          def.proccalloption:=aktdefproccall;
         case def.proccalloption of
           pocall_cdecl :
             begin
@@ -1485,8 +1483,8 @@ const
                   internalerror(200110234);
                  { do not copy on local !! }
                  tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
-                 { Adjust positions of args for cdecl or stdcall }
-                 tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
+                 { Adjust alignment to match cdecl or stdcall }
+                 tprocdef(def).parast.dataalignment:=std_param_align;
                end;
             end;
           pocall_cppdecl :
@@ -1505,18 +1503,19 @@ const
                   internalerror(200110235);
                  { do not copy on local !! }
                  tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
-                 { Adjust positions of args for cdecl or stdcall }
-                 tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
+                 { Adjust alignment to match cdecl or stdcall }
+                 tprocdef(def).parast.dataalignment:=std_param_align;
                end;
             end;
           pocall_stdcall :
             begin
               include(def.procoptions,po_savestdregs);
-              if (def.deftype=procdef) and
-                 assigned(tprocdef(def).parast) then
+              if (def.deftype=procdef) then
                begin
-                 { Adjust positions of args for cdecl or stdcall }
-                 tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
+                 if not assigned(tprocdef(def).parast) then
+                  internalerror(200110236);
+                 { Adjust alignment to match cdecl or stdcall }
+                 tprocdef(def).parast.dataalignment:=std_param_align;
                end;
             end;
           pocall_safecall :
@@ -1533,44 +1532,6 @@ const
           pocall_pascal :
             begin
               include(def.procoptions,po_leftright);
-              if def.deftype=procdef then
-               begin
-                 st:=tparasymtable.create;
-                 st.symindex.noclear:=true;
-                 parast:=tprocdef(def).parast;
-                 highps:=nil;
-                 lastps:=nil;
-                 while assigned(parast.symindex.first) and (lastps<>tsym(parast.symindex.first)) do
-                  begin
-                    ps:=tsym(parast.symindex.first);
-                    while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
-                      ps:=tsym(ps.indexnext);
-                    { Wait with inserting the high value, it needs to be inserted
-                      after the corresponding parameter }
-                    if Copy(ps.name,1,4)='high' then
-                     highps:=ps
-                    else
-                     begin
-                       { recalculate the corrected offset by inserting it into
-                         the new symtable and then reset the owner back }
-                       ps.owner:=st;
-                       tstoredsym(ps).insert_in_data;
-                       ps.owner:=parast;
-                       { add also the high tree if it was saved }
-                       if assigned(highps) then
-                        begin
-                          highps.owner:=st;
-                          tstoredsym(highps).insert_in_data;
-                          highps.owner:=parast;
-                          highps:=nil;
-                        end;
-                     end;
-                    lastps:=ps;
-                  end;
-                 st.free;
-                 if assigned(highps) then
-                  internalerror(200205111);
-               end;
             end;
           pocall_register :
             begin
@@ -1602,7 +1563,7 @@ const
                  { do not copy on local !! }
                  tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
                  { Adjust positions of args for cdecl or stdcall }
-                 tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
+                 tprocdef(def).parast.dataalignment:=std_param_align;
                end;
             end;
           pocall_inline :
@@ -1623,6 +1584,59 @@ const
       end;
 
 
+    procedure calc_parasymtable_addresses(def:tprocdef);
+      var
+        lastps,
+        highps,ps : tsym;
+        st : tsymtable;
+      begin
+        st:=def.parast;
+        if po_leftright in def.procoptions then
+         begin
+           { pushed in reversed order, left to right }
+           highps:=nil;
+           lastps:=nil;
+           while assigned(st.symindex.first) and (lastps<>tsym(st.symindex.first)) do
+            begin
+              ps:=tsym(st.symindex.first);
+              while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
+                ps:=tsym(ps.indexnext);
+              if ps.typ=varsym then
+               begin
+                 { Wait with inserting the high value, it needs to be inserted
+                   after the corresponding parameter }
+                 if Copy(ps.name,1,4)='high' then
+                  highps:=ps
+                 else
+                  begin
+                    st.insertvardata(ps);
+                    { add also the high tree if it was saved }
+                    if assigned(highps) then
+                     begin
+                       st.insertvardata(highps);
+                       highps:=nil;
+                     end;
+                  end;
+               end;
+              lastps:=ps;
+            end;
+           if assigned(highps) then
+            internalerror(200208257);
+         end
+        else
+         begin
+           { pushed in normal order, right to left }
+           ps:=tsym(st.symindex.first);
+           while assigned(ps) do
+            begin
+              if ps.typ=varsym then
+               st.insertvardata(ps);
+              ps:=tsym(ps.indexnext);
+            end;
+         end;
+      end;
+
+
     procedure parse_proc_directives(var pdflags:word);
       {
         Parse the procedure directives. It does not matter if procedure directives
@@ -1662,6 +1676,9 @@ const
             break;
          end;
         handle_calling_convention(aktprocsym,aktprocdef);
+        { calculate addresses in parasymtable }
+        if aktprocdef.deftype=procdef then
+          calc_parasymtable_addresses(aktprocdef);
       end;
 
 
@@ -1944,16 +1961,15 @@ const
               if paramanager.ret_in_param(aprocdef.rettype.def) then
                begin
                  aprocdef.parast.insert(otsym);
-                 { this increases the data size }
-                 { correct this to get the right ret $value }
-                 dec(aprocdef.parast.datasize,
-                     align(otsym.getpushsize,aktprocdef.parast.dataalignment));
                  { this allows to read the funcretoffset }
                  otsym.address:=-4;
                  otsym.varspez:=vs_var;
                end
               else
-               aprocdef.localst.insert(otsym);
+               begin
+                 aprocdef.localst.insert(otsym);
+                 aprocdef.localst.insertvardata(otsym);
+               end;
             end
            else
             begin
@@ -1969,7 +1985,17 @@ const
 end.
 {
   $Log$
-  Revision 1.67  2002-08-25 11:33:06  peter
+  Revision 1.68  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.67  2002/08/25 11:33:06  peter
     * also check the paratypes when a forward was found
 
   Revision 1.66  2002/08/19 19:36:44  peter

+ 29 - 6
compiler/pdecvar.pas

@@ -67,7 +67,7 @@ implementation
         var
            s : string;
            filepos : tfileposinfo;
-           ss : tvarsym;
+           ss,ss2 : tvarsym;
         begin
            filepos:=akttokenpos;
            while not sc.empty do
@@ -81,8 +81,14 @@ implementation
                 if (st.symtabletype=objectsymtable) and
                    (sp_static in current_object_option) then
                   begin
-                     s:='$'+lower(st.name^)+'_'+upper(s);
-                     st.defowner.owner.insert(tvarsym.create(s,tt));
+                     ss2:=tvarsym.create('$'+lower(st.name^)+'_'+upper(s),tt);
+                     st.defowner.owner.insert(ss2);
+                     st.defowner.owner.insertvardata(ss2);
+                  end
+                else
+                  begin
+                    { external data is not possible here }
+                    st.insertvardata(ss);
                   end;
              end;
 {$ifdef fixLeaksOnError}
@@ -190,6 +196,7 @@ implementation
                   aktvarsym:=tvarsym.create_C(s,target_info.Cprefix+C_name,tt);
                   include(aktvarsym.varoptions,vo_is_external);
                   symtablestack.insert(aktvarsym);
+                  { external, so no insert in the data }
                   akttokenpos:=storetokenpos;
                   symdone:=true;
                end;
@@ -317,6 +324,7 @@ implementation
                     Message(parser_e_initialized_only_one_var);
                   tconstsym:=ttypedconstsym.createtype(s,tt,true);
                   symtablestack.insert(tconstsym);
+                  symtablestack.insertconstdata(tconstsym);
                   akttokenpos:=storetokenpos;
                   consume(_EQUAL);
                   readtypedconst(tt,tconstsym,true);
@@ -415,8 +423,11 @@ implementation
                     end;
                    if extern_aktvarsym then
                     include(aktvarsym.varoptions,vo_is_external);
-                   { insert in the stack/datasegment }
+                   { insert in the symtable }
                    symtablestack.insert(aktvarsym);
+                   { insert in the datasegment when it is not external }
+                   if not extern_aktvarsym then
+                     symtablestack.insertvardata(aktvarsym);
                    akttokenpos:=storetokenpos;
                    { now we can insert it in the import lib if its a dll, or
                      add it to the externals }
@@ -497,7 +508,9 @@ implementation
                   symtablestack:=symtablestack.next;
                   read_type(casetype,'');
                   symtablestack:=oldsymtablestack;
-                  symtablestack.insert(tvarsym.create(s,casetype));
+                  aktvarsym:=tvarsym.create(s,casetype);
+                  symtablestack.insert(aktvarsym);
+                  symtablestack.insertvardata(aktvarsym);
                 end;
               if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def)  then
                Message(type_e_ordinal_expr_expected);
@@ -584,7 +597,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.30  2002-07-29 21:23:44  florian
+  Revision 1.31  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.30  2002/07/29 21:23:44  florian
     * more fixes for the ppc
     + wrappers for the tcnvnode.first_* stuff introduced
 

+ 11 - 2
compiler/pmodules.pas

@@ -1247,7 +1247,6 @@ implementation
           begin
             gen_main_procsym(current_module.modulename^+'_main',potype_proginit,st);
             aktprocdef.aliasnames.insert(target_info.cprefix+current_module.modulename^+'_main');
-            aktprocdef.aliasnames.insert('PASCALMAIN');
             { this code is called from C so we need to save some
               registers }
             include(aktprocdef.procoptions,po_savestdregs);
@@ -1388,7 +1387,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.73  2002-08-18 20:06:25  peter
+  Revision 1.74  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.73  2002/08/18 20:06:25  peter
     * inlining is now also allowed in interface
     * renamed write/load to ppuwrite/ppuload
     * tnode storing in ppu

+ 14 - 3
compiler/pstatmnt.pas

@@ -1089,6 +1089,7 @@ implementation
               { insert in local symtable }
               { but with another name, so that recursive calls are possible }
               symtablestack.insert(aktprocdef.funcretsym);
+              symtablestack.insertvardata(aktprocdef.funcretsym);
               symtablestack.rename(aktprocdef.funcretsym.name,'$result');
               { update the symtablesize back to 0 if there were no locals }
               if not haslocals then
@@ -1096,7 +1097,7 @@ implementation
 
               { set the used registers depending on the function result }
               procinfo.update_usedinproc_result;
-              
+
             end;
          { force the asm statement }
          if token<>_ASM then
@@ -1144,7 +1145,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.72  2002-08-17 09:23:40  florian
+  Revision 1.73  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.72  2002/08/17 09:23:40  florian
     * first part of procinfo rewrite
 
   Revision 1.71  2002/08/16 14:24:58  carl
@@ -1279,4 +1290,4 @@ end.
   Revision 1.45  2002/01/24 18:25:49  peter
    * implicit result variable generation for assembler routines
    * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
-}
+}

+ 14 - 2
compiler/psub.pas

@@ -105,6 +105,7 @@ implementation
               aktprocdef.funcretsym:=tfuncretsym.create(aktprocsym.name,aktprocdef.rettype);
               { insert in local symtable }
               symtablestack.insert(aktprocdef.funcretsym);
+              symtablestack.insertvardata(aktprocdef.funcretsym);
               akttokenpos:=storepos;
 
               procinfo.set_result_offset;
@@ -455,6 +456,7 @@ implementation
                  vs.fileinfo:=fileinfo;
                  vs.varspez:=varspez;
                  aktprocdef.localst.insert(vs);
+                 aktprocdef.localst.insertvardata(vs);
                  include(vs.varoptions,vo_is_local_copy);
                  vs.varstate:=vs_assigned;
                  localvarsym:=vs;
@@ -786,7 +788,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.68  2002-08-17 09:23:41  florian
+  Revision 1.69  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.68  2002/08/17 09:23:41  florian
     * first part of procinfo rewrite
 
   Revision 1.67  2002/08/16 14:24:59  carl
@@ -933,4 +945,4 @@ end.
   Revision 1.42  2002/01/19 15:12:34  peter
     * check for unresolved forward classes in the interface
 
-}
+}

+ 13 - 3
compiler/rautils.pas

@@ -874,7 +874,7 @@ Begin
                 end;
               if (tvarsym(sym).varspez=vs_var) or
                  ((tvarsym(sym).varspez=vs_const) and
-                 paramanager.push_addr_param(tvarsym(sym).vartype.def)) then
+                  paramanager.push_addr_param(tvarsym(sym).vartype.def,false)) then
                 SetSize(pointer_size,false);
             end;
           localsymtable :
@@ -914,7 +914,7 @@ Begin
                 end;
               if (tvarsym(sym).varspez in [vs_var,vs_out]) or
                  ((tvarsym(sym).varspez=vs_const) and
-                  paramanager.push_addr_param(tvarsym(sym).vartype.def)) then
+                  paramanager.push_addr_param(tvarsym(sym).vartype.def,false)) then
                 SetSize(pointer_size,false);
             end;
         end;
@@ -1592,7 +1592,17 @@ end;
 end.
 {
   $Log$
-  Revision 1.44  2002-08-17 09:23:41  florian
+  Revision 1.45  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.44  2002/08/17 09:23:41  florian
     * first part of procinfo rewrite
 
   Revision 1.43  2002/08/16 14:24:59  carl

+ 13 - 3
compiler/regvars.pas

@@ -178,7 +178,7 @@ implementation
                       { call by reference/const ? }
                       if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or
                          ((regvarinfo^.regvars[i].varspez=vs_const) and
-                           paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def)) then
+                           paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def,false)) then
                         begin
                            regvarinfo^.regvars[i].reg:=varregs[i];
                         end
@@ -316,7 +316,7 @@ implementation
           hr.base:=procinfo.framepointer;
           if (vsym.varspez in [vs_var,vs_out]) or
              ((vsym.varspez=vs_const) and
-               paramanager.push_addr_param(vsym.vartype.def)) then
+               paramanager.push_addr_param(vsym.vartype.def,false)) then
             opsize := OS_ADDR
           else
             opsize := def_cgsize(vsym.vartype.def);
@@ -469,7 +469,17 @@ end.
 
 {
   $Log$
-  Revision 1.40  2002-08-18 20:06:25  peter
+  Revision 1.41  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.40  2002/08/18 20:06:25  peter
     * inlining is now also allowed in interface
     * renamed write/load to ppuwrite/ppuload
     * tnode storing in ppu

+ 13 - 5
compiler/symbase.pas

@@ -116,6 +116,8 @@ interface
           procedure foreach(proc2call : tnamedindexcallback;arg:pointer);
           procedure foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
           procedure insert(sym : tsymentry);virtual;
+          procedure insertvardata(sym : tsymentry);virtual;abstract;
+          procedure insertconstdata(sym : tsymentry);virtual;abstract;
           function  search(const s : stringid) : tsymentry;
           function  speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;virtual;
           procedure registerdef(p : tdefentry);
@@ -304,14 +306,20 @@ implementation
       begin
       end;
 
-
-
-
-
 end.
 {
   $Log$
-  Revision 1.6  2002-05-18 13:34:18  peter
+  Revision 1.7  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.6  2002/05/18 13:34:18  peter
     * readded missing revisions
 
   Revision 1.5  2002/05/16 19:46:44  carl

+ 14 - 2
compiler/symdef.pas

@@ -3209,8 +3209,10 @@ implementation
       var
          pdc : TParaItem;
          l : longint;
+         is_cdecl : boolean;
       begin
          l:=0;
+         is_cdecl:=(proccalloption in [pocall_cdecl,pocall_cppdecl]);
          pdc:=TParaItem(Para.first);
          while assigned(pdc) do
           begin
@@ -3218,7 +3220,7 @@ implementation
               vs_out,
               vs_var   : inc(l,POINTER_SIZE);
               vs_value,
-              vs_const : if paramanager.push_addr_param(pdc.paratype.def) then
+              vs_const : if paramanager.push_addr_param(pdc.paratype.def,is_cdecl) then
                           inc(l,POINTER_SIZE)
                          else
                           inc(l,pdc.paratype.def.size);
@@ -5507,7 +5509,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.90  2002-08-18 20:06:25  peter
+  Revision 1.91  2002-08-25 19:25:20  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.90  2002/08/18 20:06:25  peter
     * inlining is now also allowed in interface
     * renamed write/load to ppuwrite/ppuload
     * tnode storing in ppu

+ 19 - 273
compiler/symsym.pas

@@ -63,7 +63,6 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
           procedure writesym(ppufile:tcompilerppufile);
           procedure deref;override;
-          procedure insert_in_data;virtual;
 {$ifdef GDB}
           function  stabstring : pchar;virtual;
           procedure concatstabto(asmlist : taasmoutput);virtual;
@@ -180,10 +179,9 @@ interface
           procedure deref;override;
           procedure generate_mangledname;override;
           procedure set_mangledname(const s:string);
-          procedure insert_in_data;override;
           function  getsize : longint;
           function  getvaluesize : longint;
-          function  getpushsize : longint;
+          function  getpushsize(is_cdecl:boolean): longint;
 {$ifdef GDB}
           function  stabstring : pchar;override;
           procedure concatstabto(asmlist : taasmoutput);override;
@@ -223,7 +221,6 @@ interface
           destructor  destroy;override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure deref;override;
-          procedure insert_in_data;override;
 {$ifdef GDB}
           procedure concatstabto(asmlist : taasmoutput);override;
 {$endif GDB}
@@ -239,7 +236,6 @@ interface
           procedure deref;override;
           function  mangledname : string;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
-          procedure insert_in_data;override;
 {$ifdef GDB}
           procedure concatstabto(asmlist : taasmoutput);override;
 {$endif GDB}
@@ -256,7 +252,6 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure deref;override;
           function  getsize:longint;
-          procedure insert_in_data;override;
 {$ifdef GDB}
           function  stabstring : pchar;override;
 {$endif GDB}
@@ -537,12 +532,6 @@ implementation
       end;
 
 
-    { for most symbol types there is nothing to do at all }
-    procedure tstoredsym.insert_in_data;
-      begin
-      end;
-
-
 {$ifdef GDB}
     function tstoredsym.stabstring : pchar;
 
@@ -1366,30 +1355,6 @@ implementation
       end;
 {$endif GDB}
 
-    procedure tfuncretsym.insert_in_data;
-      var
-        varalign,l : longint;
-      begin
-        { if retoffset is already set then reuse it, this is needed
-          when inserting the result variable }
-        if procinfo.return_offset<>0 then
-         address:=procinfo.return_offset
-        else
-         begin
-           { allocate space in local if ret in register }
-           if paramanager.ret_in_reg(returntype.def) then
-            begin
-              l:=returntype.def.size;
-              varalign:=size_2_align(l);
-              varalign:=used_align(varalign,aktalignment.localalignmin,owner.dataalignment);
-              address:=align(owner.datasize+l,varalign);
-              owner.datasize:=address;
-              procinfo.return_offset:=-address;
-            end;
-         end;
-      end;
-
-
 {****************************************************************************
                                   TABSOLUTESYM
 ****************************************************************************}
@@ -1498,11 +1463,6 @@ implementation
       end;
 
 
-    procedure tabsolutesym.insert_in_data;
-      begin
-      end;
-
-
 {$ifdef GDB}
     procedure tabsolutesym.concatstabto(asmlist : taasmoutput);
       begin
@@ -1639,8 +1599,9 @@ implementation
       end;
 
 
-    function tvarsym.getpushsize : longint;
+    function tvarsym.getpushsize(is_cdecl:boolean) : longint;
       begin
+         getpushsize:=-1;
          if assigned(vartype.def) then
            begin
               case varspez of
@@ -1650,205 +1611,21 @@ implementation
                 vs_value,
                 vs_const :
                   begin
-                      if paramanager.push_addr_param(vartype.def) then
+                      if paramanager.push_addr_param(vartype.def,is_cdecl) then
                         getpushsize:=pointer_size
                       else
                         getpushsize:=vartype.def.size;
                   end;
               end;
-           end
-         else
-           getpushsize:=0;
+           end;
       end;
 
 
-    procedure tvarsym.insert_in_data;
-      var
-         varalign,
-         l,modulo : longint;
-         storefilepos : tfileposinfo;
-      begin
-        if (vo_is_external in varoptions) then
-          exit;
-        { handle static variables of objects especially }
-        if read_member and (owner.symtabletype=objectsymtable) and
-           (sp_static in symoptions) then
-         begin
-            { the data filed is generated in parser.pas
-              with a tobject_FIELDNAME variable }
-            { this symbol can't be loaded to a register }
-            exclude(varoptions,vo_regable);
-            exclude(varoptions,vo_fpuregable);
-         end
-        else
-         if not(read_member) then
-          begin
-             { made problems with parameters etc. ! (FK) }
-             {  check for instance of an abstract object or class }
-             {
-             if (tvarsym(sym).definition.deftype=objectdef) and
-               ((tobjectdef(tvarsym(sym).definition).options and oo_is_abstract)<>0) then
-               Message(sym_e_no_instance_of_abstract_object);
-             }
-             storefilepos:=aktfilepos;
-             aktfilepos:=akttokenpos;
-             if (vo_is_thread_var in varoptions) then
-               l:=pointer_size
-             else
-               l:=getvaluesize;
-             case owner.symtabletype of
-               stt_exceptsymtable:
-                 { can contain only one symbol, address calculated later }
-                 ;
-               localsymtable :
-                 begin
-                   varstate:=vs_declared;
-                   varalign:=size_2_align(l);
-                   varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
-{$ifdef powerpc}
-                   { on the powerpc, the local variables are accessed with a positiv offset }
-                   address:=align(owner.datasize,varalign);
-                   owner.datasize:=address+l;
-{$else powerpc}
-                   address:=align(owner.datasize+l,varalign);
-                   owner.datasize:=address;
-{$endif powerpc}
-                 end;
-               staticsymtable :
-                 begin
-                   { enable unitialized warning for local symbols }
-                   varstate:=vs_declared;
-                   varalign:=size_2_align(l);
-                   varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
-                   address:=align(owner.datasize,varalign);
-                   { insert cut for smartlinking or alignment }
-                   if (cs_create_smart in aktmoduleswitches) then
-                     bssSegment.concat(Tai_cut.Create)
-                   else if (address<>owner.datasize) then
-                     bssSegment.concat(Tai_align.create(varalign));
-                   owner.datasize:=address+l;
-{$ifdef GDB}
-                   if cs_debuginfo in aktmoduleswitches then
-                      concatstabto(bsssegment);
-{$endif GDB}
-                   if (cs_create_smart in aktmoduleswitches) or
-                      DLLSource or
-                      (vo_is_exported in varoptions) or
-                      (vo_is_C_var in varoptions) then
-                     bssSegment.concat(Tai_datablock.Create_global(mangledname,l))
-                   else
-                     bssSegment.concat(Tai_datablock.Create(mangledname,l));
-                   {Global variables (in implementation part of course)
-                    *can* be loaded into registers, they just may not be
-                    accessed from procedures. The lexlevel  test in nld.pas,
-                    Tloadnode.pass_1, should take care of this.
-
-                    If for some reason you think it isn't safe, try isolating
-                    and disabling those specific cases, because small programs
-                    without procedures can be very speed critical. For example,
-                    think of benchmarks and programming contests. Also, new
-                    users often test the quality of the code the compiler
-                    generates and they do that with small programs, we should
-                    show them the full optimizing power. (DM)}
-                   {exclude(varoptions,vo_regable);
-                   exclude(varoptions,vo_fpuregable);}
-                 end;
-               globalsymtable :
-                 begin
-                   varalign:=size_2_align(l);
-                   varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
-                   address:=align(owner.datasize,varalign);
-                   { insert cut for smartlinking or alignment }
-                   if (cs_create_smart in aktmoduleswitches) then
-                     bssSegment.concat(Tai_cut.Create)
-                   else if (address<>owner.datasize) then
-                     bssSegment.concat(Tai_align.create(varalign));
-                   owner.datasize:=address+l;
-{$ifdef GDB}
-                   if cs_debuginfo in aktmoduleswitches then
-                     concatstabto(bsssegment);
-{$endif GDB}
-                   bssSegment.concat(Tai_datablock.Create_global(mangledname,l));
-                   { this symbol can't be loaded to a register }
-                   exclude(varoptions,vo_regable);
-                   exclude(varoptions,vo_fpuregable);
-                 end;
-               recordsymtable,
-               objectsymtable :
-                 begin
-                 { this symbol can't be loaded to a register }
-                   exclude(varoptions,vo_regable);
-                   exclude(varoptions,vo_fpuregable);
-                 { get the alignment size }
-                   if (aktalignment.recordalignmax=-1) then
-                    begin
-                      varalign:=vartype.def.alignment;
-                      if (varalign>4) and ((varalign mod 4)<>0) and
-                        (vartype.def.deftype=arraydef) then
-                        begin
-                          Message1(sym_w_wrong_C_pack,vartype.def.typename);
-                        end;
-                      if varalign=0 then
-                        varalign:=l;
-                      if (owner.dataalignment<aktalignment.maxCrecordalign) then
-                       begin
-                         if (varalign>16) and (owner.dataalignment<32) then
-                          owner.dataalignment:=32
-                         else if (varalign>12) and (owner.dataalignment<16) then
-                          owner.dataalignment:=16
-                         { 12 is needed for long double }
-                         else if (varalign>8) and (owner.dataalignment<12) then
-                          owner.dataalignment:=12
-                         else if (varalign>4) and (owner.dataalignment<8) then
-                          owner.dataalignment:=8
-                         else if (varalign>2) and (owner.dataalignment<4) then
-                          owner.dataalignment:=4
-                         else if (varalign>1) and (owner.dataalignment<2) then
-                          owner.dataalignment:=2;
-                       end;
-                      owner.dataalignment:=max(owner.dataalignment,aktalignment.maxCrecordalign);
-                    end
-                   else
-                    varalign:=vartype.def.alignment;
-                   if varalign=0 then
-                     varalign:=size_2_align(l);
-                   varalign:=used_align(varalign,aktalignment.recordalignmin,owner.dataalignment);
-                   address:=align(owner.datasize,varalign);
-                   owner.datasize:=address+l;
-                 end;
-               parasymtable :
-                 begin
-                   { here we need the size of a push instead of the
-                     size of the data }
-                   l:=getpushsize;
-                   varalign:=size_2_align(l);
-                   varstate:=vs_assigned;
-                   { we need the new datasize already aligned so we can't
-                     use the align_address here }
-                   address:=owner.datasize;
-                   varalign:=used_align(varalign,owner.dataalignment,owner.dataalignment);
-                   owner.datasize:=align(address+l,varalign);
-                 end
-               else
-                 begin
-                     modulo:=owner.datasize and 3;
-                     if (l>=4) and (modulo<>0) then
-                       inc(owner.datasize,4-modulo)
-                     else
-                       if (l>=2) and ((modulo and 1)<>0) then
-                         inc(owner.datasize);
-                   address:=owner.datasize;
-                   inc(owner.datasize,l);
-                 end;
-               end;
-             aktfilepos:=storefilepos;
-        end;
-      end;
-
 {$ifdef GDB}
     function tvarsym.stabstring : pchar;
      var
        st : string;
+       is_cdecl : boolean;
      begin
        st:=tstoreddef(vartype.def).numberstring;
        if (owner.symtabletype = objectsymtable) and
@@ -1876,11 +1653,12 @@ implementation
          end
        else if (owner.symtabletype in [parasymtable,inlineparasymtable]) then
          begin
+            is_cdecl:=(tprocdef(owner.defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
             case varspez of
                vs_out,
                vs_var   : st := 'v'+st;
                vs_value,
-               vs_const : if paramanager.push_addr_param(vartype.def) then
+               vs_const : if paramanager.push_addr_param(vartype.def,is_cdecl) then
                             st := 'v'+st { should be 'i' but 'i' doesn't work }
                           else
                             st := 'p'+st;
@@ -1998,48 +1776,6 @@ implementation
       end;
 
 
-    procedure ttypedconstsym.insert_in_data;
-      var
-        curconstsegment : taasmoutput;
-        address,l,varalign : longint;
-        storefilepos : tfileposinfo;
-      begin
-        storefilepos:=aktfilepos;
-        aktfilepos:=akttokenpos;
-        if is_writable then
-          curconstsegment:=datasegment
-        else
-          curconstsegment:=consts;
-        l:=getsize;
-        varalign:=size_2_align(l);
-        varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
-        address:=align(owner.datasize,varalign);
-        { insert cut for smartlinking or alignment }
-        if (cs_create_smart in aktmoduleswitches) then
-          curconstSegment.concat(Tai_cut.Create)
-        else if (address<>owner.datasize) then
-          curconstSegment.concat(Tai_align.create(varalign));
-        owner.datasize:=address+l;
-{$ifdef GDB}
-        if cs_debuginfo in aktmoduleswitches then
-          concatstabto(curconstsegment);
-{$endif GDB}
-        if (owner.symtabletype=globalsymtable) then
-          begin
-             if (owner.unitid=0) then
-               curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize));
-          end
-        else
-          begin
-             if (cs_create_smart in aktmoduleswitches) or
-                DLLSource then
-               curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize))
-             else
-               curconstSegment.concat(Tai_symbol.Createdataname(mangledname,getsize));
-          end;
-        aktfilepos:=storefilepos;
-      end;
-
 {$ifdef GDB}
     function ttypedconstsym.stabstring : pchar;
     var
@@ -2679,7 +2415,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.56  2002-08-25 09:06:21  peter
+  Revision 1.57  2002-08-25 19:25:21  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.56  2002/08/25 09:06:21  peter
     * fixed loop in concat_procdefs
 
   Revision 1.55  2002/08/20 16:54:40  peter

+ 294 - 43
compiler/symtable.pas

@@ -29,13 +29,15 @@ interface
        { common }
        cutils,cclasses,
        { global }
-       globtype,tokens,
+       cpuinfo,globtype,tokens,
        { symtable }
        symconst,symbase,symtype,symdef,symsym,
        { ppu }
        ppu,symppu,
        { assembler }
-       aasmbase,aasmtai
+       aasmbase,aasmtai,aasmcpu,
+       { cg }
+       paramgr
        ;
 
 
@@ -96,6 +98,7 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
+          procedure insertvardata(sym : tsymentry);override;
        end;
 
        trecordsymtable = class(tabstractrecordsymtable)
@@ -122,14 +125,15 @@ interface
        public
           constructor create;
           procedure insert(sym : tsymentry);override;
+          procedure insertvardata(sym : tsymentry);override;
+          procedure insertconstdata(sym : tsymentry);override;
        end;
 
        tparasymtable = class(tabstractlocalsymtable)
        public
           constructor create;
           procedure insert(sym : tsymentry);override;
-          { change alignment for args  only parasymtable }
-          procedure set_alignment(_alignment : longint);
+          procedure insertvardata(sym : tsymentry);override;
        end;
 
        tabstractunitsymtable = class(tstoredsymtable)
@@ -144,6 +148,8 @@ interface
 {$ifdef GDB}
           procedure concattypestabto(asmlist : taasmoutput);
 {$endif GDB}
+          procedure insertvardata(sym : tsymentry);override;
+          procedure insertconstdata(sym : tsymentry);override;
        end;
 
        tglobalsymtable = class(tabstractunitsymtable)
@@ -155,6 +161,7 @@ interface
           procedure ppuload(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure insert(sym : tsymentry);override;
+          procedure insertvardata(sym : tsymentry);override;
 {$ifdef GDB}
           function getnewtypecount : word; override;
 {$endif}
@@ -168,6 +175,7 @@ interface
           procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure insert(sym : tsymentry);override;
+          procedure insertvardata(sym : tsymentry);override;
        end;
 
        twithsymtable = class(tsymtable)
@@ -281,10 +289,6 @@ implementation
       ;
 
 
-    var
-      in_loading : boolean;  { remove !!! }
-
-
 {*****************************************************************************
                              TStoredSymtable
 *****************************************************************************}
@@ -541,10 +545,6 @@ implementation
       begin
          { set owner and sym indexnb }
          sym.owner:=self;
-         { writes the symbol in data segment if required }
-         { also sets the datasize of owner             }
-         if not in_loading then
-           tstoredsym(sym).insert_in_data;
 
          { check the current symtable }
          hsym:=tsym(search(sym.name));
@@ -830,7 +830,6 @@ implementation
 
     procedure tstoredsymtable.chainoperators;
       var
-        pd : pprocdeflist;
         t : ttoken;
         srsym : tsym;
         srsymtable,
@@ -931,6 +930,17 @@ implementation
 {$endif}
 
 
+    procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
+      begin
+         if (not b_needs_init_final) and
+            (tsym(p).typ=varsym) and
+            assigned(tvarsym(p).vartype.def) and
+            not is_class(tvarsym(p).vartype.def) and
+            tstoreddef(tvarsym(p).vartype.def).needs_inittable then
+           b_needs_init_final:=true;
+      end;
+
+
     { returns true, if p contains data which needs init/final code }
     function tstoredsymtable.needs_init_final : boolean;
       begin
@@ -1000,14 +1010,53 @@ implementation
       end;
 
 
-    procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
-      begin
-         if (not b_needs_init_final) and
-            (tsym(p).typ=varsym) and
-            assigned(tvarsym(p).vartype.def) and
-            not is_class(tvarsym(p).vartype.def) and
-            tstoreddef(tvarsym(p).vartype.def).needs_inittable then
-           b_needs_init_final:=true;
+    procedure tabstractrecordsymtable.insertvardata(sym : tsymentry);
+      var
+        l,varalign : longint;
+        vardef : tdef;
+      begin
+        if sym.typ<>varsym then
+         internalerror(200208251);
+        l:=tvarsym(sym).getvaluesize;
+        vardef:=tvarsym(sym).vartype.def;
+        { this symbol can't be loaded to a register }
+        exclude(tvarsym(sym).varoptions,vo_regable);
+        exclude(tvarsym(sym).varoptions,vo_fpuregable);
+        { get the alignment size }
+        if (aktalignment.recordalignmax=-1) then
+         begin
+           varalign:=vardef.alignment;
+           if (varalign>4) and
+              ((varalign mod 4)<>0) and
+              (vardef.deftype=arraydef) then
+             Message1(sym_w_wrong_C_pack,vardef.typename);
+           if varalign=0 then
+             varalign:=l;
+           if (dataalignment<aktalignment.maxCrecordalign) then
+            begin
+              if (varalign>16) and (dataalignment<32) then
+               dataalignment:=32
+              else if (varalign>12) and (dataalignment<16) then
+               dataalignment:=16
+              { 12 is needed for long double }
+              else if (varalign>8) and (dataalignment<12) then
+               dataalignment:=12
+              else if (varalign>4) and (dataalignment<8) then
+               dataalignment:=8
+              else if (varalign>2) and (dataalignment<4) then
+               dataalignment:=4
+              else if (varalign>1) and (dataalignment<2) then
+               dataalignment:=2;
+            end;
+           dataalignment:=max(dataalignment,aktalignment.maxCrecordalign);
+         end
+        else
+         varalign:=vardef.alignment;
+        if varalign=0 then
+          varalign:=size_2_align(l);
+        varalign:=used_align(varalign,aktalignment.recordalignmin,dataalignment);
+        tvarsym(sym).address:=align(datasize,varalign);
+        datasize:=tvarsym(sym).address+l;
       end;
 
 
@@ -1233,6 +1282,96 @@ implementation
       end;
 
 
+    procedure tlocalsymtable.insertvardata(sym : tsymentry);
+      var
+        l,varalign : longint;
+      begin
+        if not(sym.typ in [varsym,funcretsym]) then
+          internalerror(200208255);
+        case sym.typ of
+          varsym :
+            begin
+              tvarsym(sym).varstate:=vs_declared;
+              l:=tvarsym(sym).getvaluesize;
+              varalign:=size_2_align(l);
+              varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
+{$ifdef powerpc}
+              { on the powerpc, the local variables are accessed with a positiv offset }
+              tvarsym(sym).address:=align(datasize,varalign);
+              datasize:=tvarsym(sym).address+l;
+{$else powerpc}
+              tvarsym(sym).address:=align(datasize+l,varalign);
+              datasize:=tvarsym(sym).address;
+{$endif powerpc}
+            end;
+          funcretsym :
+            begin
+              { if retoffset is already set then reuse it, this is needed
+                when inserting the result variable }
+              if procinfo.return_offset<>0 then
+               tfuncretsym(sym).address:=procinfo.return_offset
+              else
+               begin
+                 { allocate space in local if ret in register }
+                 if paramanager.ret_in_reg(tfuncretsym(sym).returntype.def) then
+                  begin
+                    l:=tfuncretsym(sym).returntype.def.size;
+                    varalign:=size_2_align(l);
+                    varalign:=used_align(varalign,aktalignment.localalignmin,dataalignment);
+                    tfuncretsym(sym).address:=align(datasize+l,varalign);
+                    datasize:=tfuncretsym(sym).address;
+                    procinfo.return_offset:=-tfuncretsym(sym).address;
+                  end;
+               end;
+            end;
+        end;
+      end;
+
+
+    procedure tlocalsymtable.insertconstdata(sym : tsymentry);
+      var
+        storefilepos : tfileposinfo;
+        curconstsegment : taasmoutput;
+        address,l,varalign : longint;
+      begin
+        { Note: this is the same code as tabstractunitsymtable.insertconstdata }
+        if sym.typ<>typedconstsym then
+         internalerror(200208254);
+        storefilepos:=aktfilepos;
+        aktfilepos:=tsym(sym).fileinfo;
+        if ttypedconstsym(sym).is_writable then
+          curconstsegment:=datasegment
+        else
+          curconstsegment:=consts;
+        l:=ttypedconstsym(sym).getsize;
+        varalign:=size_2_align(l);
+        varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
+        address:=align(datasize,varalign);
+        { insert cut for smartlinking or alignment }
+        if (cs_create_smart in aktmoduleswitches) then
+          curconstSegment.concat(Tai_cut.Create)
+        else if (address<>datasize) then
+          curconstSegment.concat(Tai_align.create(varalign));
+        datasize:=address+l;
+{$ifdef GDB}
+        if cs_debuginfo in aktmoduleswitches then
+          concatstabto(curconstsegment);
+{$endif GDB}
+        if (cs_create_smart in aktmoduleswitches) or
+           DLLSource then
+          begin
+            curconstSegment.concat(Tai_symbol.Createdataname_global(
+                ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
+          end
+        else
+          begin
+            curconstSegment.concat(Tai_symbol.Createdataname(
+                ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
+          end;
+        aktfilepos:=storefilepos;
+      end;
+
+
 {****************************************************************************
                               TParaSymtable
 ****************************************************************************}
@@ -1279,31 +1418,30 @@ implementation
       end;
 
 
-    procedure tparasymtable.set_alignment(_alignment : longint);
+    procedure tparasymtable.insertvardata(sym : tsymentry);
       var
-         sym : tvarsym;
-         l : longint;
-      begin
-        dataalignment:=_alignment;
-        sym:=tvarsym(symindex.first);
-        datasize:=0;
-        { there can be only varsyms      }
-        { no, default parameters         }
-        { lead to constsyms as well (FK) }
-        while assigned(sym) do
-          begin
-             if sym.typ=varsym then
-               begin
-                  l:=sym.getpushsize;
-                  sym.address:=datasize;
-                  datasize:=align(datasize+l,dataalignment);
-               end;
-             sym:=tvarsym(sym.indexnext);
-          end;
+        l,varalign : longint;
+        is_cdecl : boolean;
+      begin
+        if sym.typ<>varsym then
+          internalerror(200208253);
+        { retrieve cdecl status }
+        if defowner.deftype<>procdef then
+          internalerror(200208256);
+        is_cdecl:=(tprocdef(defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
+        { here we need the size of a push instead of the
+          size of the data }
+        l:=tvarsym(sym).getpushsize(is_cdecl);
+        varalign:=size_2_align(l);
+        tvarsym(sym).varstate:=vs_assigned;
+        { we need the new datasize already aligned so we can't
+          use the align_address here }
+        tvarsym(sym).address:=datasize;
+        varalign:=used_align(varalign,dataalignment,dataalignment);
+        datasize:=align(tvarsym(sym).address+l,varalign);
       end;
 
 
-
 {****************************************************************************
                          TAbstractUnitSymtable
 ****************************************************************************}
@@ -1322,6 +1460,88 @@ implementation
       end;
 
 
+    procedure tabstractunitsymtable.insertvardata(sym : tsymentry);
+      var
+        l,varalign : longint;
+        storefilepos : tfileposinfo;
+      begin
+        if sym.typ<>varsym then
+         internalerror(200208252);
+        storefilepos:=aktfilepos;
+        aktfilepos:=tsym(sym).fileinfo;
+        if (vo_is_thread_var in tvarsym(sym).varoptions) then
+          l:=pointer_size
+        else
+          l:=tvarsym(sym).getvaluesize;
+        varalign:=size_2_align(l);
+        varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
+        tvarsym(sym).address:=align(datasize,varalign);
+        { insert cut for smartlinking or alignment }
+        if (cs_create_smart in aktmoduleswitches) then
+          bssSegment.concat(Tai_cut.Create)
+        else if (tvarsym(sym).address<>datasize) then
+          bssSegment.concat(Tai_align.create(varalign));
+        datasize:=tvarsym(sym).address+l;
+{$ifdef GDB}
+        if cs_debuginfo in aktmoduleswitches then
+           concatstabto(bsssegment);
+{$endif GDB}
+        if (symtabletype=globalsymtable) or
+           (cs_create_smart in aktmoduleswitches) or
+           DLLSource or
+           (vo_is_exported in tvarsym(sym).varoptions) or
+           (vo_is_C_var in tvarsym(sym).varoptions) then
+          bssSegment.concat(Tai_datablock.Create_global(tvarsym(sym).mangledname,l))
+        else
+          bssSegment.concat(Tai_datablock.Create(tvarsym(sym).mangledname,l));
+        aktfilepos:=storefilepos;
+      end;
+
+
+    procedure tabstractunitsymtable.insertconstdata(sym : tsymentry);
+      var
+        storefilepos : tfileposinfo;
+        curconstsegment : taasmoutput;
+        address,l,varalign : longint;
+      begin
+        if sym.typ<>typedconstsym then
+         internalerror(200208254);
+        storefilepos:=aktfilepos;
+        aktfilepos:=tsym(sym).fileinfo;
+        if ttypedconstsym(sym).is_writable then
+          curconstsegment:=datasegment
+        else
+          curconstsegment:=consts;
+        l:=ttypedconstsym(sym).getsize;
+        varalign:=size_2_align(l);
+        varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
+        address:=align(datasize,varalign);
+        { insert cut for smartlinking or alignment }
+        if (cs_create_smart in aktmoduleswitches) then
+          curconstSegment.concat(Tai_cut.Create)
+        else if (address<>datasize) then
+          curconstSegment.concat(Tai_align.create(varalign));
+        datasize:=address+l;
+{$ifdef GDB}
+        if cs_debuginfo in aktmoduleswitches then
+          concatstabto(curconstsegment);
+{$endif GDB}
+        if (symtabletype=globalsymtable) or
+           (cs_create_smart in aktmoduleswitches) or
+           DLLSource then
+          begin
+            curconstSegment.concat(Tai_symbol.Createdataname_global(
+                ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
+          end
+        else
+          begin
+            curconstSegment.concat(Tai_symbol.Createdataname(
+                ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
+          end;
+        aktfilepos:=storefilepos;
+      end;
+
+
 {$ifdef GDB}
       procedure tabstractunitsymtable.concattypestabto(asmlist : taasmoutput);
         var prev_dbx_count : plongint;
@@ -1451,6 +1671,15 @@ implementation
       end;
 
 
+    procedure tstaticsymtable.insertvardata(sym : tsymentry);
+      begin
+        inherited insertvardata(sym);
+        { enable unitialized warning for local symbols }
+        if sym.typ=varsym then
+          tvarsym(sym).varstate:=vs_declared;
+      end;
+
+
 {****************************************************************************
                               TGlobalSymtable
 ****************************************************************************}
@@ -1587,6 +1816,18 @@ implementation
       end;
 
 
+    procedure tglobalsymtable.insertvardata(sym : tsymentry);
+      begin
+        inherited insertvardata(sym);
+        { this symbol can't be loaded to a register }
+        if sym.typ=varsym then
+         begin
+           exclude(tvarsym(sym).varoptions,vo_regable);
+           exclude(tvarsym(sym).varoptions,vo_fpuregable);
+         end;
+      end;
+
+
 {$ifdef GDB}
    function tglobalsymtable.getnewtypecount : word;
       begin
@@ -2058,7 +2299,17 @@ implementation
 end.
 {
   $Log$
-  Revision 1.68  2002-08-18 20:06:27  peter
+  Revision 1.69  2002-08-25 19:25:21  peter
+    * sym.insert_in_data removed
+    * symtable.insertvardata/insertconstdata added
+    * removed insert_in_data call from symtable.insert, it needs to be
+      called separatly. This allows to deref the address calculation
+    * procedures now calculate the parast addresses after the procedure
+      directives are parsed. This fixes the cdecl parast problem
+    * push_addr_param has an extra argument that specifies if cdecl is used
+      or not
+
+  Revision 1.68  2002/08/18 20:06:27  peter
     * inlining is now also allowed in interface
     * renamed write/load to ppuwrite/ppuload
     * tnode storing in ppu