Browse Source

* store the current field alignment of tobjectdefs that use C_alignment,
because it influences the offset at which the next field in child classes
should be placed in case it also uses C_alignment
* also pad objectdefs based on the packrecords setting (Delphi-compatible)
-> field offset calculation in objcclasses is now correct if they are
compiled with {$packrecords c}

git-svn-id: trunk@18114 -

Jonas Maebe 14 years ago
parent
commit
86b088f398
4 changed files with 21 additions and 1 deletions
  1. 1 0
      compiler/pdecobj.pas
  2. 2 1
      compiler/ppu.pas
  3. 5 0
      compiler/symdef.pas
  4. 13 0
      compiler/symtable.pas

+ 1 - 0
compiler/pdecobj.pas

@@ -1251,6 +1251,7 @@ implementation
                 list.add(current_structdef);
               end;
           end;
+        tabstractrecordsymtable(current_objectdef.symtable).addalignmentpadding;
 
         { return defined objectdef }
         result:=current_objectdef;

+ 2 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 131;
+  CurrentPPUVersion = 132;
 
 { buffer sizes }
   maxentrysize = 1024;
@@ -132,6 +132,7 @@ const
 
   ibmainname       = 90;
   ibsymtableoptions = 91;
+  ibrecsymtableoptions = 91;
   { target-specific things }
   iblinkotherframeworks = 100;
 

+ 5 - 0
compiler/symdef.pas

@@ -4799,6 +4799,11 @@ implementation
             tObjectSymtable(symtable).datasize:=tObjectSymtable(symtable).datasize+tObjectSymtable(c.symtable).datasize;
             { inherit recordalignment }
             tObjectSymtable(symtable).recordalignment:=tObjectSymtable(c.symtable).recordalignment;
+            { if both the parent and this record use C-alignment, also inherit
+              the current field alignment }
+            if (tObjectSymtable(c.symtable).usefieldalignment=C_alignment) and
+               (tObjectSymtable(symtable).usefieldalignment=C_alignment) then
+              tObjectSymtable(symtable).fieldalignment:=tObjectSymtable(c.symtable).fieldalignment;
             if (oo_has_vmt in objectoptions) and
                (oo_has_vmt in c.objectoptions) then
               tObjectSymtable(symtable).datasize:=tObjectSymtable(symtable).datasize-sizeof(pint);

+ 13 - 0
compiler/symtable.pas

@@ -833,6 +833,12 @@ implementation
 
     procedure tabstractrecordsymtable.ppuload(ppufile:tcompilerppufile);
       begin
+        if ppufile.readentry<>ibrecsymtableoptions then
+          Message(unit_f_ppu_read_error);
+        recordalignment:=shortint(ppufile.getbyte);
+        usefieldalignment:=shortint(ppufile.getbyte);
+        if (usefieldalignment=C_alignment) then
+          fieldalignment:=shortint(ppufile.getbyte);
         inherited ppuload(ppufile);
       end;
 
@@ -843,6 +849,13 @@ implementation
       begin
          oldtyp:=ppufile.entrytyp;
          ppufile.entrytyp:=subentryid;
+         { in case of classes using C alignment, the alignment of the parent
+           affects the alignment of fields of the childs }
+         ppufile.putbyte(byte(recordalignment));
+         ppufile.putbyte(byte(usefieldalignment));
+         if (usefieldalignment=C_alignment) then
+           ppufile.putbyte(byte(fieldalignment));
+         ppufile.writeentry(ibrecsymtableoptions);
 
          inherited ppuwrite(ppufile);