Explorar o código

* sym,def resolving partly rewritten to support also parent objects
not directly available through the uses clause

peter %!s(int64=22) %!d(string=hai) anos
pai
achega
bfb8ae2151
Modificáronse 7 ficheiros con 428 adicións e 245 borrados
  1. 16 2
      compiler/ncal.pas
  2. 11 5
      compiler/symbase.pas
  3. 18 11
      compiler/symconst.pas
  4. 102 21
      compiler/symdef.pas
  5. 5 47
      compiler/symtable.pas
  6. 216 117
      compiler/symtype.pas
  7. 60 42
      compiler/utils/ppudump.pp

+ 16 - 2
compiler/ncal.pas

@@ -2068,7 +2068,17 @@ type
                  (paralength<procdefinition.maxparacount) then
                begin
                  currpara:=tparaitem(procdefinition.Para.first);
-                 for i:=1 to paralength do
+                 i:=0;
+                 while (i<paralength) do
+                  begin
+                    if not assigned(currpara) then
+                      internalerror(200306181);
+                    if not currpara.is_hidden then
+                      inc(i);
+                    currpara:=tparaitem(currpara.next);
+                  end;
+                 while assigned(currpara) and
+                       currpara.is_hidden do
                    currpara:=tparaitem(currpara.next);
                  while assigned(currpara) do
                   begin
@@ -2635,7 +2645,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.172  2003-06-17 16:34:44  jonas
+  Revision 1.173  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.172  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
     * renamed all_intregisters to volatile_intregisters and made it
       processor dependent

+ 11 - 5
compiler/symbase.pas

@@ -140,10 +140,12 @@ interface
 
        defaultsymtablestack : tsymtable;  { symtablestack after default units have been loaded }
        symtablestack     : tsymtable;     { linked list of symtables }
-       aktrecordsymtable : tsymtable;     { current record read from ppu symtable }
-       aktstaticsymtable : tsymtable;     { current static for local ppu symtable }
-       aktglobalsymtable : tsymtable;     { current global for local ppu symtable }
-       aktlocalsymtable  : tsymtable;     { current proc local for local ppu symtable }
+
+       aktrecordsymtable : tsymtable;     { current record symtable }
+       aktstaticsymtable : tsymtable;     { current static symtable }
+       aktglobalsymtable : tsymtable;     { current global symtable }
+       aktparasymtable   : tsymtable;     { current proc para symtable }
+       aktlocalsymtable  : tsymtable;     { current proc local symtable }
 
 
 implementation
@@ -319,7 +321,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.13  2003-06-07 20:26:32  peter
+  Revision 1.14  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.13  2003/06/07 20:26:32  peter
     * re-resolving added instead of reloading from ppu
     * tderef object added to store deref info for resolving
 

+ 18 - 11
compiler/symconst.pas

@@ -91,16 +91,19 @@ const
 
 type
   { Deref entry options }
-  tdereftype = (derefnil,
-    derefaktrecordindex,
-    derefaktstaticindex,
-    derefaktglobalindex,
-    derefaktlocalindex,
-    derefunit,
-    derefrecord,
-    derefindex,
-    dereflocal,
-    derefpara
+  tdereftype = (deref_nil,
+    deref_sym,
+    deref_def,
+    deref_aktrecord,
+    deref_aktstatic,
+    deref_aktglobal,
+    deref_aktlocal,
+    deref_aktpara,
+    deref_unit,
+    deref_record,
+    deref_local,
+    deref_para,
+    deref_parent_object
   );
 
   { symbol options }
@@ -353,7 +356,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.57  2003-06-07 20:26:32  peter
+  Revision 1.58  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.57  2003/06/07 20:26:32  peter
     * re-resolving added instead of reloading from ppu
     * tderef object added to store deref info for resolving
 

+ 102 - 21
compiler/symdef.pas

@@ -276,6 +276,7 @@ interface
           destructor  destroy;override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure deref;override;
+          function  getparentdef:tdef;override;
           function  size : longint;override;
           function  alignment:longint;override;
           function  vmtmethodoffset(index:longint):longint;
@@ -451,6 +452,7 @@ interface
           constructor create(level:byte);
           constructor ppuload(ppufile:tcompilerppufile);
           procedure ppuwrite(ppufile:tcompilerppufile);override;
+          procedure deref;override;
           function  getsymtable(t:tgetsymtable):tsymtable;override;
           function  size : longint;override;
           function  gettypename:string;override;
@@ -3178,15 +3180,11 @@ implementation
     procedure tabstractprocdef.deref;
       var
          hp : TParaItem;
-         oldlocalsymtable : tsymtable;
       begin
          inherited deref;
          rettype.resolve;
          { parast }
-         oldlocalsymtable:=aktlocalsymtable;
-         aktlocalsymtable:=parast;
          tparasymtable(parast).deref;
-         aktlocalsymtable:=oldlocalsymtable;
          { paraitems }
          hp:=TParaItem(Para.first);
          while assigned(hp) do
@@ -3551,7 +3549,14 @@ implementation
     procedure tprocdef.ppuwrite(ppufile:tcompilerppufile);
       var
         oldintfcrc : boolean;
+        oldparasymtable,
+        oldlocalsymtable : tsymtable;
       begin
+         oldparasymtable:=aktparasymtable;
+         oldlocalsymtable:=aktlocalsymtable;
+         aktparasymtable:=parast;
+         aktlocalsymtable:=localst;
+
          inherited ppuwrite(ppufile);
          oldintfcrc:=ppufile.do_interface_crc;
          ppufile.do_interface_crc:=false;
@@ -3608,6 +3613,9 @@ implementation
             tlocalsymtable(localst).ppuwrite(ppufile);
             ppufile.do_crc:=oldintfcrc;
           end;
+
+         aktparasymtable:=oldparasymtable;
+         aktlocalsymtable:=oldlocalsymtable;
       end;
 
 
@@ -3736,7 +3744,14 @@ implementation
       var
         pos : tfileposinfo;
         move_last : boolean;
+        oldparasymtable,
+        oldlocalsymtable : tsymtable;
       begin
+        oldparasymtable:=aktparasymtable;
+        oldlocalsymtable:=aktlocalsymtable;
+        aktparasymtable:=parast;
+        aktlocalsymtable:=localst;
+
         move_last:=lastwritten=lastref;
         while (not ppufile.endofentry) do
          begin
@@ -3755,6 +3770,9 @@ implementation
              tparasymtable(parast).load_references(ppufile,locals);
              tlocalsymtable(localst).load_references(ppufile,locals);
           end;
+
+        aktparasymtable:=oldparasymtable;
+        aktlocalsymtable:=oldlocalsymtable;
       end;
 
 
@@ -3767,6 +3785,8 @@ implementation
         pdo : tobjectdef;
         move_last : boolean;
         d : tderef;
+        oldparasymtable,
+        oldlocalsymtable : tsymtable;
       begin
         d.reset;
         move_last:=lastwritten=lastref;
@@ -3774,6 +3794,10 @@ implementation
            (((current_module.flags and uf_local_browser)=0) or
             not locals) then
           exit;
+        oldparasymtable:=aktparasymtable;
+        oldlocalsymtable:=aktlocalsymtable;
+        aktparasymtable:=parast;
+        aktlocalsymtable:=localst;
       { write address of this symbol }
         ppufile.putderef(self,d);
       { write refs }
@@ -3829,6 +3853,8 @@ implementation
                     pdo:=pdo.childof;
                  end;
           end;
+        aktparasymtable:=oldparasymtable;
+        aktlocalsymtable:=oldlocalsymtable;
       end;
 
 {$ifdef GDB}
@@ -3937,29 +3963,43 @@ implementation
 
 
     procedure tprocdef.deref;
+      var
+        oldparasymtable,
+        oldlocalsymtable : tsymtable;
       begin
+         oldparasymtable:=aktparasymtable;
+         oldlocalsymtable:=aktlocalsymtable;
+         aktparasymtable:=parast;
+         aktlocalsymtable:=localst;
+
          inherited deref;
          _class:=tobjectdef(_classderef.resolve);
          { procsym that originaly defined this definition, should be in the
            same symtable }
          procsym:=tprocsym(procsymderef.resolve);
+
+         aktparasymtable:=oldparasymtable;
+         aktlocalsymtable:=oldlocalsymtable;
       end;
 
 
     procedure tprocdef.derefimpl;
       var
+        oldparasymtable,
         oldlocalsymtable : tsymtable;
       begin
+         oldparasymtable:=aktparasymtable;
+         oldlocalsymtable:=aktlocalsymtable;
+         aktparasymtable:=parast;
+         aktlocalsymtable:=localst;
+
          { locals }
          if assigned(localst) then
           begin
             { localst }
-            oldlocalsymtable:=aktlocalsymtable;
-            aktlocalsymtable:=localst;
             { we can deref both interface and implementation parts }
             tlocalsymtable(localst).deref;
             tlocalsymtable(localst).derefimpl;
-            aktlocalsymtable:=oldlocalsymtable;
             { funcretsym, this is always located in the localst }
             funcretsym:=tsym(funcretsymderef.resolve);
           end
@@ -3972,6 +4012,9 @@ implementation
         { inline tree }
         if (proccalloption=pocall_inline) then
           code.derefimpl;
+
+        aktparasymtable:=oldparasymtable;
+        aktlocalsymtable:=oldlocalsymtable;
       end;
 
 
@@ -4110,22 +4153,50 @@ implementation
 
 
     procedure tprocvardef.ppuwrite(ppufile:tcompilerppufile);
+      var
+        oldparasymtable,
+        oldlocalsymtable : tsymtable;
       begin
-         { here we cannot get a real good value so just give something }
-         { plausible (PM) }
-         { a more secure way would be
-           to allways store in a temp }
-         if is_fpu(rettype.def) then
-           fpu_used:={2}maxfpuregs
-         else
-           fpu_used:=0;
-         inherited ppuwrite(ppufile);
+        oldparasymtable:=aktparasymtable;
+        oldlocalsymtable:=aktlocalsymtable;
+        aktparasymtable:=parast;
+        aktlocalsymtable:=nil;
+
+        { here we cannot get a real good value so just give something }
+        { plausible (PM) }
+        { a more secure way would be
+          to allways store in a temp }
+        if is_fpu(rettype.def) then
+          fpu_used:={2}maxfpuregs
+        else
+          fpu_used:=0;
+        inherited ppuwrite(ppufile);
 
-         { Write this entry }
-         ppufile.writeentry(ibprocvardef);
+        { Write this entry }
+        ppufile.writeentry(ibprocvardef);
 
-         { Save the para symtable, this is taken from the interface }
-         tparasymtable(parast).ppuwrite(ppufile);
+        { Save the para symtable, this is taken from the interface }
+        tparasymtable(parast).ppuwrite(ppufile);
+
+        aktparasymtable:=oldparasymtable;
+        aktlocalsymtable:=oldlocalsymtable;
+      end;
+
+
+    procedure tprocvardef.deref;
+      var
+        oldparasymtable,
+        oldlocalsymtable : tsymtable;
+      begin
+        oldparasymtable:=aktparasymtable;
+        oldlocalsymtable:=aktlocalsymtable;
+        aktparasymtable:=parast;
+        aktlocalsymtable:=nil;
+
+        inherited deref;
+
+        aktparasymtable:=oldparasymtable;
+        aktlocalsymtable:=oldlocalsymtable;
       end;
 
 
@@ -4470,6 +4541,12 @@ implementation
       end;
 
 
+    function tobjectdef.getparentdef:tdef;
+      begin
+        result:=childof;
+      end;
+
+
     procedure tobjectdef.prepareguid;
       begin
         { set up guid }
@@ -5767,7 +5844,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.152  2003-06-17 16:34:44  jonas
+  Revision 1.153  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.152  2003/06/17 16:34:44  jonas
     * lots of newra fixes (need getfuncretparaloc implementation for i386)!
     * renamed all_intregisters to volatile_intregisters and made it
       processor dependent

+ 5 - 47
compiler/symtable.pas

@@ -116,10 +116,7 @@ interface
 
        tabstractlocalsymtable = class(tstoredsymtable)
        public
-          procedure ppuload(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
-          procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
-          procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
        end;
 
        tlocalsymtable = class(tabstractlocalsymtable)
@@ -1185,26 +1182,10 @@ implementation
                           TAbstractLocalSymtable
 ****************************************************************************}
 
-    procedure tabstractlocalsymtable.ppuload(ppufile:tcompilerppufile);
-      var
-        storesymtable : tsymtable;
-      begin
-        storesymtable:=aktlocalsymtable;
-        aktlocalsymtable:=self;
-
-        inherited ppuload(ppufile);
-
-        aktlocalsymtable:=storesymtable;
-      end;
-
-
    procedure tabstractlocalsymtable.ppuwrite(ppufile:tcompilerppufile);
       var
         oldtyp : byte;
-        storesymtable : tsymtable;
       begin
-         storesymtable:=aktlocalsymtable;
-         aktlocalsymtable:=self;
          oldtyp:=ppufile.entrytyp;
          ppufile.entrytyp:=subentryid;
 
@@ -1214,33 +1195,6 @@ implementation
          writesyms(ppufile);
 
          ppufile.entrytyp:=oldtyp;
-         aktlocalsymtable:=storesymtable;
-      end;
-
-
-    procedure tabstractlocalsymtable.load_references(ppufile:tcompilerppufile;locals:boolean);
-      var
-        storesymtable : tsymtable;
-      begin
-        storesymtable:=aktlocalsymtable;
-        aktlocalsymtable:=self;
-
-        inherited load_references(ppufile,locals);
-
-        aktlocalsymtable:=storesymtable;
-      end;
-
-
-    procedure tabstractlocalsymtable.write_references(ppufile:tcompilerppufile;locals:boolean);
-      var
-        storesymtable : tsymtable;
-      begin
-        storesymtable:=aktlocalsymtable;
-        aktlocalsymtable:=self;
-
-        inherited write_references(ppufile,locals);
-
-        aktlocalsymtable:=storesymtable;
       end;
 
 
@@ -2474,7 +2428,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.107  2003-06-13 21:19:31  peter
+  Revision 1.108  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.107  2003/06/13 21:19:31  peter
     * current_procdef removed, use current_procinfo.procdef instead
 
   Revision 1.106  2003/06/09 18:26:27  peter

+ 216 - 117
compiler/symtype.pas

@@ -11,7 +11,8 @@
 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
@@ -77,6 +78,7 @@ interface
          function  getmangledparaname:string;virtual;abstract;
          function  size:longint;virtual;abstract;
          function  alignment:longint;virtual;abstract;
+         function  getparentdef:tdef;virtual;
          function  getsymtable(t:tgetsymtable):tsymtable;virtual;
          function  is_publishable:boolean;virtual;abstract;
          function  needs_inittable:boolean;virtual;abstract;
@@ -216,6 +218,12 @@ implementation
       end;
 
 
+    function tdef.getparentdef:tdef;
+      begin
+        result:=nil;
+      end;
+
+
     function tdef.getsymtable(t:tgetsymtable):tsymtable;
       begin
         getsymtable:=nil;
@@ -515,106 +523,194 @@ implementation
 
     procedure tderef.build(s:tsymtableentry);
 
+        function is_child(currdef,ownerdef:tdef):boolean;
+        begin
+          while assigned(currdef) and
+                (currdef<>ownerdef) do
+            currdef:=currdef.getparentdef;
+          result:=assigned(currdef);
+        end;
+
         procedure addowner(s:tsymtableentry);
-        var
-          typ : tdereftype;
-          idx : word;
         begin
           if not assigned(s.owner) then
             internalerror(200306063);
           case s.owner.symtabletype of
             globalsymtable :
               begin
-                { check if the unit is available in the uses
-                  clause, else it's an error }
-                if s.owner.unitid=$ffff then
-                  internalerror(200306063);
-                data[len]:=ord(derefunit);
-                typ:=derefunit;
-                idx:=s.owner.unitid;
+                if s.owner.unitid=0 then
+                  begin
+                    data[len]:=ord(deref_aktglobal);
+                    inc(len);
+                  end
+                else
+                  begin
+                    { check if the unit is available in the uses
+                      clause, else it's an error }
+                    if s.owner.unitid=$ffff then
+                      internalerror(200306063);
+                    data[len]:=ord(deref_unit);
+                    data[len+1]:=s.owner.unitid shr 8;
+                    data[len+2]:=s.owner.unitid and $ff;
+                    inc(len,3);
+                  end;
+              end;
+            staticsymtable :
+              begin
+                { only references to the current static symtable are allowed }
+                if s.owner<>aktstaticsymtable then
+                  internalerror(200306233);
+                data[len]:=ord(deref_aktstatic);
+                inc(len);
               end;
             localsymtable :
               begin
                 addowner(s.owner.defowner);
-                typ:=dereflocal;
-                idx:=s.owner.defowner.indexnr;
+                data[len]:=ord(deref_def);
+                data[len+1]:=s.owner.defowner.indexnr shr 8;
+                data[len+2]:=s.owner.defowner.indexnr and $ff;
+                data[len+3]:=ord(deref_local);
+                inc(len,4);
               end;
             parasymtable :
               begin
                 addowner(s.owner.defowner);
-                typ:=derefpara;
-                idx:=s.owner.defowner.indexnr;
+                data[len]:=ord(deref_def);
+                data[len+1]:=s.owner.defowner.indexnr shr 8;
+                data[len+2]:=s.owner.defowner.indexnr and $ff;
+                data[len+3]:=ord(deref_para);
+                inc(len,4);
               end;
             objectsymtable,
             recordsymtable :
               begin
                 addowner(s.owner.defowner);
-                typ:=derefrecord;
-                idx:=s.owner.defowner.indexnr;
+                data[len]:=ord(deref_def);
+                data[len+1]:=s.owner.defowner.indexnr shr 8;
+                data[len+2]:=s.owner.defowner.indexnr and $ff;
+                data[len+3]:=ord(deref_record);
+                inc(len,4);
               end;
             else
               internalerror(200306065);
           end;
           if len+3>sizeof(tderefdata) then
             internalerror(200306062);
-          data[len]:=ord(typ);
-          data[len+1]:=idx shr 8;
-          data[len+2]:=idx and $ff;
-          inc(len,3);
+        end;
+
+        procedure addparentobject(currdef,ownerdef:tdef);
+        var
+          nextdef : tdef;
+        begin
+          if not assigned(currdef) then
+            internalerror(200306185);
+          { Already handled by derefaktrecordindex }
+          if currdef=ownerdef then
+            internalerror(200306188);
+          { Generate a direct reference to the top parent
+            class available in the current unit, this is required because
+            the parent class is maybe not resolved yet and therefor
+            has the childof value not available yet }
+          while (currdef<>ownerdef) do
+            begin
+              nextdef:=currdef.getparentdef;
+              { objects are only allowed in globalsymtable,staticsymtable this check is
+                needed because we need the unitid }
+              if not(nextdef.owner.symtabletype in [globalsymtable,staticsymtable]) then
+                internalerror(200306187);
+              { Next parent is in a different unit, then stop }
+              if nextdef.owner.unitid<>0 then
+                break;
+              currdef:=nextdef;
+            end;
+          { Add reference where to start the parent lookup }
+          if currdef=aktrecordsymtable.defowner then
+            begin
+              data[len]:=ord(deref_aktrecord);
+              inc(len);
+            end
+          else
+            begin
+              if currdef.owner.symtabletype=globalsymtable then
+                data[len]:=ord(deref_aktglobal)
+              else
+                data[len]:=ord(deref_aktstatic);
+              data[len+1]:=ord(deref_def);
+              data[len+2]:=currdef.indexnr shr 8;
+              data[len+3]:=currdef.indexnr and $ff;
+              data[len+4]:=ord(deref_record);
+              inc(len,5);
+            end;
+          { When the current found parent in this module is not the owner we
+            add derefs for the parent classes not available in this unit }
+          while (currdef<>ownerdef) do
+            begin
+              data[len]:=ord(deref_parent_object);
+              inc(len);
+              currdef:=currdef.getparentdef;
+              { It should be valid as it is checked by is_child }
+              if not assigned(currdef) then
+                internalerror(200306186);
+            end;
         end;
 
       begin
         len:=0;
         if assigned(s) then
          begin
-           { symtableentry type }
-           if s is tsym then
-             data[len]:=1
-           else
-             data[len]:=2;
-           inc(len);
            { Static symtable of current unit ? }
            if (s.owner.symtabletype=staticsymtable) and
               (s.owner.unitid=0) then
             begin
-              data[len]:=ord(derefaktstaticindex);
-              data[len+1]:=s.indexnr shr 8;
-              data[len+2]:=s.indexnr and $ff;
-              inc(len,3);
+              data[len]:=ord(deref_aktstatic);
+              inc(len);
             end
            { Global symtable of current unit ? }
            else if (s.owner.symtabletype=globalsymtable) and
                    (s.owner.unitid=0) then
             begin
-              data[len]:=ord(derefaktglobalindex);
-              data[len+1]:=s.indexnr shr 8;
-              data[len+2]:=s.indexnr and $ff;
-              inc(len,3);
+              data[len]:=ord(deref_aktglobal);
+              inc(len);
             end
-           { Local record/object symtable ? }
+           { Current record/object symtable ? }
            else if (s.owner=aktrecordsymtable) then
             begin
-              data[len]:=ord(derefaktrecordindex);
-              data[len+1]:=s.indexnr shr 8;
-              data[len+2]:=s.indexnr and $ff;
-              inc(len,3);
+              data[len]:=ord(deref_aktrecord);
+              inc(len);
             end
-           { Local local/para symtable ? }
+           { Current local symtable ? }
            else if (s.owner=aktlocalsymtable) then
             begin
-              data[len]:=ord(derefaktlocalindex);
-              data[len+1]:=s.indexnr shr 8;
-              data[len+2]:=s.indexnr and $ff;
-              inc(len,3);
+              data[len]:=ord(deref_aktlocal);
+              inc(len);
+            end
+           { Current para symtable ? }
+           else if (s.owner=aktparasymtable) then
+            begin
+              data[len]:=ord(deref_aktpara);
+              inc(len);
+            end
+           { Parent class? }
+           else if assigned(aktrecordsymtable) and
+                   (aktrecordsymtable.symtabletype=objectsymtable) and
+                   (s.owner.symtabletype=objectsymtable) and
+                   is_child(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner)) then
+            begin
+              addparentobject(tdef(aktrecordsymtable.defowner),tdef(s.owner.defowner));
             end
            else
+           { Default, start by building from unit symtable }
             begin
               addowner(s);
-              data[len]:=ord(derefindex);
-              data[len+1]:=s.indexnr shr 8;
-              data[len+2]:=s.indexnr and $ff;
-              inc(len,3);
             end;
+           { Add index of the symbol/def }
+           if s is tsym then
+             data[len]:=ord(deref_sym)
+           else
+             data[len]:=ord(deref_def);
+           data[len+1]:=s.indexnr shr 8;
+           data[len+2]:=s.indexnr and $ff;
+           inc(len,3);
          end
         else
          begin
@@ -631,9 +727,7 @@ implementation
         pm     : tmodule;
         typ    : tdereftype;
         st     : tsymtable;
-        idx,
-        symidx : word;
-        issym  : boolean;
+        idx    : word;
         i      : longint;
       begin
         result:=nil;
@@ -641,101 +735,102 @@ implementation
         if len=0 then
           internalerror(200306067);
         st:=nil;
-        symidx:=0;
-        issym:=false;
         i:=0;
-        case data[i] of
-          0 :
-            begin
-              { nil pointer }
-              exit;
-            end;
-          1 :
-            begin
-              { tsym }
-              issym:=true;
-            end;
-          2 :
-            begin
-              { tdef }
-            end;
-          else
-            internalerror(200306066);
-        end;
-        inc(i);
         while (i<len) do
           begin
             typ:=tdereftype(data[i]);
-            idx:=(data[i+1] shl 8) or data[i+2];
-            inc(i,3);
+            inc(i);
             case typ of
-              derefaktrecordindex :
+              deref_nil :
                 begin
-                  st:=aktrecordsymtable;
-                  symidx:=idx;
+                  result:=nil;
+                  { Only allowed when no other deref is available }
+                  if len<>1 then
+                    internalerror(200306232);
                 end;
-              derefaktstaticindex :
+              deref_sym :
                 begin
-                  st:=aktstaticsymtable;
-                  symidx:=idx;
+                  idx:=(data[i] shl 8) or data[i+1];
+                  inc(i,2);
+                  result:=st.getsymnr(idx);
                 end;
-              derefaktglobalindex :
+              deref_def :
                 begin
-                  st:=aktglobalsymtable;
-                  symidx:=idx;
+                  idx:=(data[i] shl 8) or data[i+1];
+                  inc(i,2);
+                  result:=st.getdefnr(idx);
                 end;
-              derefaktlocalindex :
-                begin
-                  st:=aktlocalsymtable;
-                  symidx:=idx;
-                end;
-              derefunit :
+              deref_aktrecord :
+                st:=aktrecordsymtable;
+              deref_aktstatic :
+                st:=aktstaticsymtable;
+              deref_aktglobal :
+                st:=aktglobalsymtable;
+              deref_aktlocal :
+                st:=aktlocalsymtable;
+              deref_aktpara :
+                st:=aktparasymtable;
+              deref_unit :
                 begin
+                  idx:=(data[i] shl 8) or data[i+1];
+                  inc(i,2);
+                  if idx>maxunits then
+                    internalerror(200306231);
                   pm:=current_module.map^[idx];
                   if not assigned(pm) then
                     internalerror(200212273);
                   st:=pm.globalsymtable;
                 end;
-              derefrecord :
-                begin
-                  if not assigned(st) then
-                    internalerror(200306068);
-                  pd:=tdef(st.getdefnr(idx));
-                  st:=pd.getsymtable(gs_record);
-                  if not assigned(st) then
-                    internalerror(200212274);
-                end;
-              dereflocal :
+              deref_local :
                 begin
-                  if not assigned(st) then
+                  if not assigned(result) then
                     internalerror(200306069);
-                  pd:=tdef(st.getdefnr(idx));
-                  st:=pd.getsymtable(gs_local);
+                  st:=tdef(result).getsymtable(gs_local);
+                  result:=nil;
                   if not assigned(st) then
                     internalerror(200212275);
                 end;
-              derefpara :
+              deref_para :
                 begin
-                  if not assigned(st) then
+                  if not assigned(result) then
                     internalerror(2003060610);
-                  pd:=tdef(st.getdefnr(idx));
-                  st:=pd.getsymtable(gs_para);
+                  st:=tdef(result).getsymtable(gs_para);
+                  result:=nil;
                   if not assigned(st) then
                     internalerror(200212276);
                 end;
-              derefindex :
-                symidx:=idx;
+              deref_record :
+                begin
+                  if not assigned(result) then
+                    internalerror(200306068);
+                  st:=tdef(result).getsymtable(gs_record);
+                  result:=nil;
+                  if not assigned(st) then
+                    internalerror(200212274);
+                end;
+              deref_parent_object :
+                begin
+                  { load current object symtable if no
+                    symtable is available yet }
+                  if st=nil then
+                    begin
+                      st:=aktrecordsymtable;
+                      if not assigned(st) then
+                        internalerror(200306068);
+                    end;
+                  if st.symtabletype<>objectsymtable then
+                    internalerror(200306189);
+                  pd:=tdef(st.defowner).getparentdef;
+                  if not assigned(pd) then
+                    internalerror(200306184);
+                  st:=pd.getsymtable(gs_record);
+                  if not assigned(st) then
+                    internalerror(200212274);
+                end;
               else
                 internalerror(200212277);
             end;
           end;
-        if assigned(st) then
-          begin
-            if issym then
-              result:=st.getsymnr(symidx)
-            else
-              result:=st.getdefnr(symidx);
-          end;
       end;
 
 
@@ -766,7 +861,11 @@ finalization
 end.
 {
   $Log$
-  Revision 1.25  2003-06-07 20:26:32  peter
+  Revision 1.26  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.25  2003/06/07 20:26:32  peter
     * re-resolving added instead of reloading from ppu
     * tderef object added to store deref info for resolving
 

+ 60 - 42
compiler/utils/ppudump.pp

@@ -436,16 +436,19 @@ end;
 
 procedure readderef;
 type
-  tdereftype = (derefnil,
-    derefaktrecordindex,
-    derefaktstaticindex,
-    derefaktglobalindex,
-    derefaktlocalindex,
-    derefunit,
-    derefrecord,
-    derefindex,
-    dereflocal,
-    derefpara
+  tdereftype = (deref_nil,
+    deref_sym,
+    deref_def,
+    deref_aktrecord,
+    deref_aktstatic,
+    deref_aktglobal,
+    deref_aktlocal,
+    deref_aktpara,
+    deref_unit,
+    deref_record,
+    deref_local,
+    deref_para,
+    deref_parent_object
   );
 var
   b : tdereftype;
@@ -463,14 +466,6 @@ begin
      writeln('!! Error, deref len < 1');
      exit;
    end;
-  typ:=ppufile.getbyte;
-  case typ of
-    0 : write('Nil');
-    1 : s:='Symbol';
-    2 : s:='Definition';
-    else write('!! Error, unknown deref destination type');
-  end;
-  inc(i);
   while (i<n) do
    begin
      if not first then
@@ -478,30 +473,49 @@ begin
      else
       first:=false;
      b:=tdereftype(ppufile.getbyte);
-     idx:=ppufile.getbyte shl 8;
-     idx:=idx or ppufile.getbyte;
-     inc(i,3);
+     inc(i);
      case b of
-       derefnil :
-         write('!! Error (nil)');
-       derefaktrecordindex :
-         write('AktRecord ',s,' ',idx);
-       derefaktstaticindex :
-         write('AktStatic ',s,' ',idx);
-       derefaktglobalindex :
-         write('AktGlobal ',s,' ',idx);
-       derefaktlocalindex :
-         write('AktLocal ',s,' ',idx);
-       derefunit :
-         write('Unit ',idx);
-       derefrecord :
-         write('RecordDef ',idx);
-       derefpara :
-         write('Parameter of procdef ',idx);
-       dereflocal :
-         write('Local of procdef ',idx);
-       derefindex :
-         write(s,' ',idx);
+       deref_nil :
+         write('Nil');
+       deref_def :
+         begin
+           idx:=ppufile.getbyte shl 8;
+           idx:=idx or ppufile.getbyte;
+           inc(i,2);
+           write('Definition ',idx);
+         end;
+       deref_sym :
+         begin
+           idx:=ppufile.getbyte shl 8;
+           idx:=idx or ppufile.getbyte;
+           inc(i,2);
+           write('Symbol ',idx);
+         end;
+       deref_aktrecord :
+         write('AktRecord');
+       deref_aktstatic :
+         write('AktStatic');
+       deref_aktglobal :
+         write('AktGlobal');
+       deref_aktlocal :
+         write('AktLocal');
+       deref_aktpara :
+         write('AktPara');
+       deref_unit :
+         begin
+           idx:=ppufile.getbyte shl 8;
+           idx:=idx or ppufile.getbyte;
+           inc(i,2);
+           write('Unit ',idx);
+         end;
+       deref_record :
+         write('RecordDef');
+       deref_para :
+         write('Parameter of procdef');
+       deref_local :
+         write('Local of procdef');
+       deref_parent_object :
+         write('Parent object');
        else
          begin
            writeln('!! unsupported dereftyp: ',ord(b));
@@ -1937,7 +1951,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.44  2003-06-09 12:59:00  peter
+  Revision 1.45  2003-06-25 18:31:23  peter
+    * sym,def resolving partly rewritten to support also parent objects
+      not directly available through the uses clause
+
+  Revision 1.44  2003/06/09 12:59:00  peter
     * updated for new deref info
 
   Revision 1.43  2003/06/05 20:06:11  peter