Browse Source

* fixed alignment calculation for variant records
* fixed alignment padding of records

peter 21 years ago
parent
commit
dfb7fe9d9d
3 changed files with 60 additions and 27 deletions
  1. 7 4
      compiler/pdecvar.pas
  2. 7 4
      compiler/ptype.pas
  3. 46 19
      compiler/symtable.pas

+ 7 - 4
compiler/pdecvar.pas

@@ -1112,8 +1112,7 @@ implementation
               uniontype.sym:=nil;
               uniontype.sym:=nil;
               UnionSym:=tvarsym.create('$case',vs_value,uniontype);
               UnionSym:=tvarsym.create('$case',vs_value,uniontype);
               symtablestack:=symtablestack.next;
               symtablestack:=symtablestack.next;
-              { we do NOT call symtablestack.insert
-               on purpose PM }
+              { Align the offset where the union symtable is added }
               if trecordsymtable(symtablestack).usefieldalignment=-1 then
               if trecordsymtable(symtablestack).usefieldalignment=-1 then
                begin
                begin
 {$ifdef i386}
 {$ifdef i386}
@@ -1137,7 +1136,7 @@ implementation
               trecordsymtable(symtablestack).datasize:=offset+unionsymtable.datasize;
               trecordsymtable(symtablestack).datasize:=offset+unionsymtable.datasize;
               if maxalignment>trecordsymtable(symtablestack).fieldalignment then
               if maxalignment>trecordsymtable(symtablestack).fieldalignment then
                 trecordsymtable(symtablestack).fieldalignment:=maxalignment;
                 trecordsymtable(symtablestack).fieldalignment:=maxalignment;
-              Unionsymtable.Insert_in(trecordsymtable(symtablestack),offset);
+              trecordsymtable(symtablestack).insertunionst(Unionsymtable,offset);
               Unionsym.owner:=nil;
               Unionsym.owner:=nil;
               unionsym.free;
               unionsym.free;
               uniondef.owner:=nil;
               uniondef.owner:=nil;
@@ -1152,7 +1151,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.61  2004-01-28 22:16:31  peter
+  Revision 1.62  2004-01-29 16:51:29  peter
+    * fixed alignment calculation for variant records
+    * fixed alignment padding of records
+
+  Revision 1.61  2004/01/28 22:16:31  peter
     * more record alignment fixes
     * more record alignment fixes
 
 
   Revision 1.60  2004/01/28 20:30:18  peter
   Revision 1.60  2004/01/28 20:30:18  peter

+ 7 - 4
compiler/ptype.pas

@@ -243,9 +243,8 @@ implementation
          consume(_END);
          consume(_END);
          typecanbeforward:=storetypecanbeforward;
          typecanbeforward:=storetypecanbeforward;
          current_object_option:=old_object_option;
          current_object_option:=old_object_option;
-         { may be scale record size to a size of n*4 ? }
-         trecordsymtable(symtablestack).datasize:=align(trecordsymtable(symtablestack).datasize,
-             trecordsymtable(symtablestack).fieldalignment);
+         { make the record size aligned }
+         trecordsymtable(symtablestack).addalignmentpadding;
          { restore symtable stack }
          { restore symtable stack }
          symtablestack:=symtable.next;
          symtablestack:=symtable.next;
       end;
       end;
@@ -644,7 +643,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.62  2004-01-28 22:16:31  peter
+  Revision 1.63  2004-01-29 16:51:29  peter
+    * fixed alignment calculation for variant records
+    * fixed alignment padding of records
+
+  Revision 1.62  2004/01/28 22:16:31  peter
     * more record alignment fixes
     * more record alignment fixes
 
 
   Revision 1.61  2004/01/28 20:30:18  peter
   Revision 1.61  2004/01/28 20:30:18  peter

+ 46 - 19
compiler/symtable.pas

@@ -102,12 +102,13 @@ interface
           procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
           procedure insertfield(sym:tvarsym;addsym:boolean);
           procedure insertfield(sym:tvarsym;addsym:boolean);
+          procedure addalignmentpadding;
        end;
        end;
 
 
        trecordsymtable = class(tabstractrecordsymtable)
        trecordsymtable = class(tabstractrecordsymtable)
        public
        public
           constructor create(usealign:shortint);
           constructor create(usealign:shortint);
-          procedure insert_in(tsymt : trecordsymtable;offset : longint);
+          procedure insertunionst(unionst : trecordsymtable;offset : longint);
        end;
        end;
 
 
        tobjectsymtable = class(tabstractrecordsymtable)
        tobjectsymtable = class(tabstractrecordsymtable)
@@ -1102,6 +1103,24 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tabstractrecordsymtable.addalignmentpadding;
+      var
+        padalign : shortint;
+      begin
+        { make the record size aligned correctly so it can be
+          used as elements in an array. For C records we
+          use the fieldalignment, because that is updated with the
+          used alignment. For normal records we use minimum from
+          recordalginment or fieldalignment. This is required to
+          be able to override the natural alignment with 'packed' }
+        if usefieldalignment=-1 then
+          padalign:=fieldalignment
+        else
+          padalign:=min(fieldalignment,recordalignment);
+        datasize:=align(datasize,padalign);
+      end;
+
+
 {****************************************************************************
 {****************************************************************************
                               TRecordSymtable
                               TRecordSymtable
 ****************************************************************************}
 ****************************************************************************}
@@ -1118,45 +1137,49 @@ implementation
     { the offset is the location of the start of the variant
     { the offset is the location of the start of the variant
       and datasize and dataalignment corresponds to
       and datasize and dataalignment corresponds to
       the complete size (see code in pdecl unit) PM }
       the complete size (see code in pdecl unit) PM }
-    procedure trecordsymtable.insert_in(tsymt : trecordsymtable;offset : longint);
+    procedure trecordsymtable.insertunionst(unionst : trecordsymtable;offset : longint);
       var
       var
         ps,nps : tvarsym;
         ps,nps : tvarsym;
         pd,npd : tdef;
         pd,npd : tdef;
+        varalignrecord,
         storesize,storealign : longint;
         storesize,storealign : longint;
       begin
       begin
-        storesize:=tsymt.datasize;
-        storealign:=tsymt.fieldalignment;
-        tsymt.datasize:=offset;
-        ps:=tvarsym(symindex.first);
+        storesize:=datasize;
+        storealign:=fieldalignment;
+        datasize:=offset;
+        ps:=tvarsym(unionst.symindex.first);
         while assigned(ps) do
         while assigned(ps) do
           begin
           begin
             nps:=tvarsym(ps.indexnext);
             nps:=tvarsym(ps.indexnext);
             { remove from current symtable }
             { remove from current symtable }
-            symindex.deleteindex(ps);
+            unionst.symindex.deleteindex(ps);
             ps.left:=nil;
             ps.left:=nil;
             ps.right:=nil;
             ps.right:=nil;
-            { add to symt }
-            ps.owner:=tsymt;
-            tsymt.datasize:=ps.fieldoffset+offset;
-            tsymt.symindex.insert(ps);
-            tsymt.symsearch.insert(ps);
+            { add to this record }
+            ps.owner:=self;
+            datasize:=ps.fieldoffset+offset;
+            symindex.insert(ps);
+            symsearch.insert(ps);
             { update address }
             { update address }
-            ps.fieldoffset:=tsymt.datasize;
+            ps.fieldoffset:=datasize;
+            { update alignment of this record }
+            varalignrecord:=used_align(ps.vartype.def.alignment,aktalignment.recordalignmin,aktalignment.recordalignmax);
+            recordalignment:=max(recordalignment,varalignrecord);
             { next }
             { next }
             ps:=nps;
             ps:=nps;
           end;
           end;
-        pd:=tdef(defindex.first);
+        pd:=tdef(unionst.defindex.first);
         while assigned(pd) do
         while assigned(pd) do
           begin
           begin
             npd:=tdef(pd.indexnext);
             npd:=tdef(pd.indexnext);
-            defindex.deleteindex(pd);
+            unionst.defindex.deleteindex(pd);
             pd.left:=nil;
             pd.left:=nil;
             pd.right:=nil;
             pd.right:=nil;
-            tsymt.registerdef(pd);
+            registerdef(pd);
             pd:=npd;
             pd:=npd;
           end;
           end;
-        tsymt.datasize:=storesize;
-        tsymt.fieldalignment:=storealign;
+        datasize:=storesize;
+        fieldalignment:=storealign;
       end;
       end;
 
 
 
 
@@ -2310,7 +2333,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.128  2004-01-28 22:16:31  peter
+  Revision 1.129  2004-01-29 16:51:29  peter
+    * fixed alignment calculation for variant records
+    * fixed alignment padding of records
+
+  Revision 1.128  2004/01/28 22:16:31  peter
     * more record alignment fixes
     * more record alignment fixes
 
 
   Revision 1.127  2004/01/28 20:30:18  peter
   Revision 1.127  2004/01/28 20:30:18  peter