Browse Source

* align all variants to same start address

pierre 25 years ago
parent
commit
36f461db33
2 changed files with 87 additions and 4 deletions
  1. 38 2
      compiler/pdecl.pas
  2. 49 2
      compiler/symtable.pas

+ 38 - 2
compiler/pdecl.pas

@@ -22,6 +22,8 @@
 }
 }
 unit pdecl;
 unit pdecl;
 
 
+{$define UseUnionSymtable}
+
   interface
   interface
 
 
     uses
     uses
@@ -328,6 +330,13 @@ unit pdecl;
          { startvarrec contains the start of the variant part of a record }
          { startvarrec contains the start of the variant part of a record }
          maxsize,maxalignment,startvarrecalign,startvarrecsize : longint;
          maxsize,maxalignment,startvarrecalign,startvarrecsize : longint;
          pt : ptree;
          pt : ptree;
+{$ifdef UseUnionSymtable}
+         unionsymtable : psymtable;
+         offset : longint;
+         uniondef : precorddef;
+         unionsym : pvarsym;
+         uniontype : ttype;
+{$endif UseUnionSymtable}
       begin
       begin
          old_current_object_option:=current_object_option;
          old_current_object_option:=current_object_option;
          { all variables are public if not in a object declaration }
          { all variables are public if not in a object declaration }
@@ -669,6 +678,14 @@ unit pdecl;
               if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def)  then
               if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def)  then
                Message(type_e_ordinal_expr_expected);
                Message(type_e_ordinal_expr_expected);
               consume(_OF);
               consume(_OF);
+{$ifdef UseUnionSymtable}
+              UnionSymtable:=new(psymtable,init(recordsymtable));
+              UnionSymtable^.next:=symtablestack;
+              registerdef:=false;
+              UnionDef:=new(precorddef,init(unionsymtable));
+              registerdef:=true;
+              symtablestack:=UnionSymtable;
+{$endif UseUnionSymtable}
               startvarrecsize:=symtablestack^.datasize;
               startvarrecsize:=symtablestack^.datasize;
               startvarrecalign:=symtablestack^.dataalignment;
               startvarrecalign:=symtablestack^.dataalignment;
               repeat
               repeat
@@ -705,6 +722,22 @@ unit pdecl;
               { at last set the record size to that of the biggest variant }
               { at last set the record size to that of the biggest variant }
               symtablestack^.datasize:=maxsize;
               symtablestack^.datasize:=maxsize;
               symtablestack^.dataalignment:=maxalignment;
               symtablestack^.dataalignment:=maxalignment;
+{$ifdef UseUnionSymtable}
+              uniontype.def:=uniondef;
+              uniontype.sym:=nil;
+              UnionSym:=new(pvarsym,init('case',uniontype));
+              symtablestack:=symtablestack^.next;
+              { we do NOT call symtablestack^.insert
+               on purpose PM }
+              offset:=align_from_size(symtablestack^.datasize,maxalignment);
+              symtablestack^.datasize:=offset+unionsymtable^.datasize;
+              if maxalignment>symtablestack^.dataalignment then
+                symtablestack^.dataalignment:=maxalignment;
+              UnionSymtable^.Insert_in(symtablestack,offset);
+              UnionSym^.owner:=nil;
+              dispose(unionsym,done);
+              dispose(uniondef,done);
+{$endif UseUnionSymtable}
            end;
            end;
          block_type:=old_block_type;
          block_type:=old_block_type;
          current_object_option:=old_current_object_option;
          current_object_option:=old_current_object_option;
@@ -1217,7 +1250,10 @@ unit pdecl;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.187  2000-06-23 20:14:39  peter
+  Revision 1.188  2000-06-23 21:34:09  pierre
+   * align all variants to same start address
+
+  Revision 1.187  2000/06/23 20:14:39  peter
     * reset current_object_option when reading other symtables than
     * reset current_object_option when reading other symtables than
       object declarations
       object declarations
 
 
@@ -1320,4 +1356,4 @@ end.
   Revision 1.159  1999/10/01 10:05:42  peter
   Revision 1.159  1999/10/01 10:05:42  peter
     + procedure directive support in const declarations, fixes bug 232
     + procedure directive support in const declarations, fixes bug 232
 
 
-}
+}

+ 49 - 2
compiler/symtable.pas

@@ -203,6 +203,7 @@ unit symtable;
           function  rename(const olds,news : stringid):psym;
           function  rename(const olds,news : stringid):psym;
           procedure foreach(proc2call : tnamedindexcallback);
           procedure foreach(proc2call : tnamedindexcallback);
           procedure insert(sym : psym);
           procedure insert(sym : psym);
+          procedure insert_in(psymt : psymtable;offset : longint);
           function  search(const s : stringid) : psym;
           function  search(const s : stringid) : psym;
           function  speedsearch(const s : stringid;speedvalue : longint) : psym;
           function  speedsearch(const s : stringid;speedvalue : longint) : psym;
           procedure registerdef(p : pdef);
           procedure registerdef(p : pdef);
@@ -1646,6 +1647,49 @@ implementation
          end;
          end;
       end;
       end;
 
 
+    { this procedure is reserved for inserting case variant into
+      a record symtable }
+    { the offset is the location of the start of the variant
+      and datasize and dataalignment corresponds to
+      the complete size (see code in pdecl unit) PM }
+    procedure tsymtable.insert_in(psymt : psymtable;offset : longint);
+      var
+        ps,nps : pvarsym;
+        pd,npd : pdef;
+        storesize,storealign : longint;
+      begin
+        storesize:=psymt^.datasize;
+        storealign:=psymt^.dataalignment;
+        psymt^.datasize:=offset;
+        ps:=pvarsym(symindex^.first);
+        while assigned(ps) do
+          begin
+            { this is used to insert case variant into the main
+              record }
+            if ps^.address=0 then
+              psymt^.datasize:=offset;
+            nps:=pvarsym(ps^.next);
+            symindex^.deleteindex(ps);
+            ps^.next:=nil;
+            ps^.left:=nil;
+            ps^.right:=nil;
+            psymt^.insert(ps);
+            ps:=nps;
+          end;
+        pd:=pdef(defindex^.first);
+        while assigned(pd) do
+          begin
+            npd:=pdef(pd^.next);
+            defindex^.deleteindex(pd);
+            pd^.next:=nil;
+            pd^.left:=nil;
+            pd^.right:=nil;
+            psymt^.registerdef(pd);
+            pd:=npd;
+          end;
+        psymt^.datasize:=storesize;
+        psymt^.dataalignment:=storealign;
+      end;
 
 
     constructor tsymtable.loadas(typ : tsymtabletype);
     constructor tsymtable.loadas(typ : tsymtabletype);
       var
       var
@@ -2934,7 +2978,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.100  2000-06-18 18:11:32  peter
+  Revision 1.101  2000-06-23 21:34:10  pierre
+   * align all variants to same start address
+
+  Revision 1.100  2000/06/18 18:11:32  peter
     * C record packing fixed to also check first entry of the record
     * C record packing fixed to also check first entry of the record
       if bigger than the recordalignment itself
       if bigger than the recordalignment itself
     * variant record alignment uses alignment per variant and saves the
     * variant record alignment uses alignment per variant and saves the
@@ -3097,4 +3144,4 @@ end.
   Revision 1.56  1999/11/04 23:13:25  peter
   Revision 1.56  1999/11/04 23:13:25  peter
     * moved unit alias support into ifdef
     * moved unit alias support into ifdef
 
 
-}
+}