فهرست منبع

* symtablestack cleanup and rewrite

git-svn-id: trunk@2448 -
peter 19 سال پیش
والد
کامیت
232555904e

+ 2 - 3
compiler/browlog.pas

@@ -286,7 +286,7 @@ implementation
           looking for the symbol !! }
           looking for the symbol !! }
          make_ref:=false;
          make_ref:=false;
          s:=sr;
          s:=sr;
-         symt:=symtablestack;
+         symt:=symtablestack.top;
          next_substring;
          next_substring;
          if assigned(symt) then
          if assigned(symt) then
            begin
            begin
@@ -299,7 +299,7 @@ implementation
          if assigned(sym) and (sym.typ=unitsym) and (s<>'') then
          if assigned(sym) and (sym.typ=unitsym) and (s<>'') then
            begin
            begin
               addlog('Unitsym found !');
               addlog('Unitsym found !');
-              symt:=tunitsym(sym).unitsymtable;
+              symt:=tmodule(tunitsym(sym).module).globalsymtable;
               if assigned(symt) then
               if assigned(symt) then
                 begin
                 begin
                    next_substring;
                    next_substring;
@@ -432,7 +432,6 @@ implementation
     procedure writesymtable(p:tsymtable);
     procedure writesymtable(p:tsymtable);
       var
       var
         hp : tsym;
         hp : tsym;
-        prdef : pprocdeflist;
       begin
       begin
         if cs_browser in aktmoduleswitches then
         if cs_browser in aktmoduleswitches then
          begin
          begin

+ 1 - 6
compiler/cg64f32.pas

@@ -89,7 +89,7 @@ unit cg64f32;
     uses
     uses
        globtype,systems,
        globtype,systems,
        verbose,
        verbose,
-       symbase,symconst,symdef,defutil,paramgr;
+       symbase,symconst,symdef,symtable,defutil,paramgr;
 
 
 {****************************************************************************
 {****************************************************************************
                                      Helpers
                                      Helpers
@@ -566,7 +566,6 @@ unit cg64f32;
         hreg   : tregister;
         hreg   : tregister;
         hdef   :  torddef;
         hdef   :  torddef;
         opsize   : tcgsize;
         opsize   : tcgsize;
-        oldregisterdef: boolean;
         from_signed,to_signed: boolean;
         from_signed,to_signed: boolean;
         temploc : tlocation;
         temploc : tlocation;
 
 
@@ -576,9 +575,6 @@ unit cg64f32;
 
 
          if not is_64bit(todef) then
          if not is_64bit(todef) then
            begin
            begin
-             oldregisterdef := registerdef;
-             registerdef := false;
-
              { get the high dword in a register }
              { get the high dword in a register }
              if l.loc in [LOC_REGISTER,LOC_CREGISTER] then
              if l.loc in [LOC_REGISTER,LOC_CREGISTER] then
                begin
                begin
@@ -650,7 +646,6 @@ unit cg64f32;
                  hdef.free;
                  hdef.free;
                  cg.a_label(list,endlabel);
                  cg.a_label(list,endlabel);
                end;
                end;
-             registerdef := oldregisterdef;
            end
            end
          else
          else
            { todef = 64bit int }
            { todef = 64bit int }

+ 2 - 12
compiler/dbgdwarf.pas

@@ -1855,17 +1855,7 @@ implementation
 
 
 
 
     procedure TDebugInfoDwarf.inserttypeinfo;
     procedure TDebugInfoDwarf.inserttypeinfo;
-
-      function gettypedef(const s : string) : tdef;
-        var
-          srsym : ttypesym;
-        begin
-          if not(searchsystype('TVARDATA',srsym)) then
-            internalerror(200602022);
-          result:=ttypesym(srsym).restype.def;
-        end;
-
-      var
+     var
         storefilepos  : tfileposinfo;
         storefilepos  : tfileposinfo;
         lenstartlabel : tasmlabel;
         lenstartlabel : tasmlabel;
       begin
       begin
@@ -1875,7 +1865,7 @@ implementation
         currabbrevnumber:=0;
         currabbrevnumber:=0;
         writing_def_dwarf:=false;
         writing_def_dwarf:=false;
 
 
-        vardatadef:=gettypedef('TVARDATA');
+        vardatadef:=search_system_type('TVARDATA').restype.def;
 
 
         { not exported (FK)
         { not exported (FK)
         filerecdef:=gettypedef('FILEREC');
         filerecdef:=gettypedef('FILEREC');

+ 23 - 25
compiler/htypechk.pas

@@ -869,7 +869,6 @@ implementation
       var
       var
         hp : tnode;
         hp : tnode;
         gotstring,
         gotstring,
-        gotwith,
         gotsubscript,
         gotsubscript,
         gotrecord,
         gotrecord,
         gotpointer,
         gotpointer,
@@ -892,7 +891,6 @@ implementation
         gotrecord:=false;
         gotrecord:=false;
         gotclass:=false;
         gotclass:=false;
         gotpointer:=false;
         gotpointer:=false;
-        gotwith:=false;
         gotdynarray:=false;
         gotdynarray:=false;
         gotstring:=false;
         gotstring:=false;
         hp:=p;
         hp:=p;
@@ -947,7 +945,7 @@ implementation
                          (gotstring and gotvec) or
                          (gotstring and gotvec) or
                          (
                          (
                           (gotclass or gotrecord) and
                           (gotclass or gotrecord) and
-                          (gotsubscript or gotwith)
+                          (gotsubscript)
                          ) or
                          ) or
                          (
                          (
                            (gotvec and gotdynarray)
                            (gotvec and gotdynarray)
@@ -1067,7 +1065,7 @@ implementation
                        CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname)
                        CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname)
                      else
                      else
                        exit;
                        exit;
-                   end;                     
+                   end;
                  { a class/interface access is an implicit }
                  { a class/interface access is an implicit }
                  { dereferencing                           }
                  { dereferencing                           }
                  hp:=tsubscriptnode(hp).left;
                  hp:=tsubscriptnode(hp).left;
@@ -1152,7 +1150,7 @@ implementation
                    3. string is returned }
                    3. string is returned }
                  if (gotstring and gotvec) or
                  if (gotstring and gotvec) or
                     (gotpointer and gotderef) or
                     (gotpointer and gotderef) or
-                    (gotclass and (gotsubscript or gotwith)) then
+                    (gotclass and gotsubscript) then
                   result:=true
                   result:=true
                  else
                  else
                  { Temp strings are stored in memory, for compatibility with
                  { Temp strings are stored in memory, for compatibility with
@@ -1206,19 +1204,8 @@ implementation
                             CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
                             CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
                           exit;
                           exit;
                         end;
                         end;
-                       { Are we at a with symtable, then we need to process the
-                         withrefnode also to check for maybe a const load }
-                       if (tloadnode(hp).symtable.symtabletype=withsymtable) then
-                        begin
-                          { continue with processing the withref node }
-                          hp:=tnode(twithsymtable(tloadnode(hp).symtable).withrefnode);
-                          gotwith:=true;
-                        end
-                       else
-                        begin
-                          result:=true;
-                          exit;
-                        end;
+                       result:=true;
+                       exit;
                      end;
                      end;
                    typedconstsym :
                    typedconstsym :
                      begin
                      begin
@@ -1456,7 +1443,7 @@ implementation
         srsymtable : tsymtable;
         srsymtable : tsymtable;
         srprocsym  : tprocsym;
         srprocsym  : tprocsym;
         pt         : tcallparanode;
         pt         : tcallparanode;
-
+        checkstack : psymtablestackitem;
       begin
       begin
         if not assigned(sym) then
         if not assigned(sym) then
           internalerror(200411015);
           internalerror(200411015);
@@ -1543,9 +1530,18 @@ implementation
         if has_overload_directive and
         if has_overload_directive and
            (sym.owner.symtabletype<>objectsymtable) then
            (sym.owner.symtabletype<>objectsymtable) then
           begin
           begin
-            srsymtable:=sym.owner.next;
-            while assigned(srsymtable) do
+            srsymtable:=sym.owner;
+            checkstack:=symtablestack.stack;
+            while assigned(checkstack) and
+                  (checkstack^.symtable<>srsymtable) do
+              checkstack:=checkstack^.next;
+            { we've already processed the current symtable, start with
+              the next symtable in the stack }
+            if assigned(checkstack) then
+              checkstack:=checkstack^.next;
+            while assigned(checkstack) do
              begin
              begin
+               srsymtable:=checkstack^.symtable;
                if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
                if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
                 begin
                 begin
                   srprocsym:=tprocsym(srsymtable.speedsearch(sym.name,sym.speedvalue));
                   srprocsym:=tprocsym(srsymtable.speedsearch(sym.name,sym.speedvalue));
@@ -1589,7 +1585,7 @@ implementation
                       end;
                       end;
                    end;
                    end;
                 end;
                 end;
-               srsymtable:=srsymtable.next;
+               checkstack:=checkstack^.next;
              end;
              end;
           end;
           end;
       end;
       end;
@@ -1605,6 +1601,7 @@ implementation
         srprocsym  : tprocsym;
         srprocsym  : tprocsym;
         pt         : tcallparanode;
         pt         : tcallparanode;
         sv         : cardinal;
         sv         : cardinal;
+        checkstack : psymtablestackitem;
       begin
       begin
         FProcSym:=nil;
         FProcSym:=nil;
         FProcs:=nil;
         FProcs:=nil;
@@ -1628,9 +1625,10 @@ implementation
           entries are only added to the procs list and not the procsym, because
           entries are only added to the procs list and not the procsym, because
           the list can change in every situation }
           the list can change in every situation }
         sv:=getspeedvalue(overloaded_names[op]);
         sv:=getspeedvalue(overloaded_names[op]);
-        srsymtable:=symtablestack;
-        while assigned(srsymtable) do
+        checkstack:=symtablestack.stack;
+        while assigned(checkstack) do
           begin
           begin
+            srsymtable:=checkstack^.symtable;
             if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
             if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
               begin
               begin
                 srprocsym:=tprocsym(srsymtable.speedsearch(overloaded_names[op],sv));
                 srprocsym:=tprocsym(srsymtable.speedsearch(overloaded_names[op],sv));
@@ -1668,7 +1666,7 @@ implementation
                       end;
                       end;
                   end;
                   end;
               end;
               end;
-            srsymtable:=srsymtable.next;
+            checkstack:=checkstack^.next;
           end;
           end;
       end;
       end;
 
 

+ 1 - 3
compiler/nadd.pas

@@ -1612,9 +1612,7 @@ implementation
         srsym: ttypesym;
         srsym: ttypesym;
       begin
       begin
         { get the sym that represents the fpc_normal_set type }
         { get the sym that represents the fpc_normal_set type }
-        if not searchsystype('FPC_NORMAL_SET',srsym) then
-          internalerror(200108313);
-
+        srsym:=search_system_type('FPC_NORMAL_SET');
         case nodetype of
         case nodetype of
           equaln,unequaln,lten,gten:
           equaln,unequaln,lten,gten:
             begin
             begin

+ 5 - 13
compiler/ncal.pas

@@ -834,23 +834,15 @@ type
      constructor tcallnode.createintern(const name: string; params: tnode);
      constructor tcallnode.createintern(const name: string; params: tnode);
        var
        var
          srsym: tsym;
          srsym: tsym;
-         symowner: tsymtable;
        begin
        begin
-         if not (cs_compilesystem in aktmoduleswitches) then
-           begin
-             srsym := searchsymonlyin(systemunit,name);
-             symowner := systemunit;
-           end
-         else
-           begin
-             searchsym(name,srsym,symowner);
-             if not assigned(srsym) then
-               searchsym(upper(name),srsym,symowner);
-           end;
+         srsym := tsym(systemunit.search(name));
+         if not assigned(srsym) and
+            (cs_compilesystem in aktmoduleswitches) then
+           srsym := tsym(systemunit.search(upper(name)));
          if not assigned(srsym) or
          if not assigned(srsym) or
             (srsym.typ<>procsym) then
             (srsym.typ<>procsym) then
            Message1(cg_f_unknown_compilerproc,name);
            Message1(cg_f_unknown_compilerproc,name);
-         self.create(params,tprocsym(srsym),symowner,nil,[]);
+         self.create(params,tprocsym(srsym),srsym.owner,nil,[]);
        end;
        end;
 
 
 
 

+ 5 - 5
compiler/ncgutil.pas

@@ -144,7 +144,7 @@ interface
 
 
     procedure location_free(list: taasmoutput; const location : TLocation);
     procedure location_free(list: taasmoutput; const location : TLocation);
 
 
-    function getprocalign : longint;
+    function getprocalign : shortint;
 
 
     procedure gen_pic_helpers(list : taasmoutput);
     procedure gen_pic_helpers(list : taasmoutput);
     procedure gen_got_load(list : taasmoutput);
     procedure gen_got_load(list : taasmoutput);
@@ -350,12 +350,12 @@ implementation
 
 
     procedure get_exception_temps(list:taasmoutput;var t:texceptiontemps);
     procedure get_exception_temps(list:taasmoutput;var t:texceptiontemps);
       var
       var
-        sym : ttypesym;
+        srsym : ttypesym;
       begin
       begin
         if jmp_buf_size=-1 then
         if jmp_buf_size=-1 then
           begin
           begin
-            searchsystype('JMP_BUF',sym);
-            jmp_buf_size:=sym.restype.def.size;
+            srsym:=search_system_type('JMP_BUF');
+            jmp_buf_size:=srsym.restype.def.size;
           end;
           end;
         tg.GetTemp(list,EXCEPT_BUF_SIZE,tt_persistent,t.envbuf);
         tg.GetTemp(list,EXCEPT_BUF_SIZE,tt_persistent,t.envbuf);
         tg.GetTemp(list,jmp_buf_size,tt_persistent,t.jmpbuf);
         tg.GetTemp(list,jmp_buf_size,tt_persistent,t.jmpbuf);
@@ -2425,7 +2425,7 @@ implementation
       end;
       end;
 
 
 
 
-    function getprocalign : longint;
+    function getprocalign : shortint;
       begin
       begin
         { gprof uses 16 byte granularity }
         { gprof uses 16 byte granularity }
         if (cs_profile in aktmoduleswitches) then
         if (cs_profile in aktmoduleswitches) then

+ 1 - 2
compiler/ncnv.pas

@@ -2011,8 +2011,7 @@ implementation
         p: tcallparanode;
         p: tcallparanode;
 
 
       begin
       begin
-        if not searchsystype('FPC_SMALL_SET',srsym) then
-          internalerror(200108313);
+        srsym:=search_system_type('FPC_SMALL_SET');
         p := ccallparanode.create(left,nil);
         p := ccallparanode.create(left,nil);
         { reused }
         { reused }
         left := nil;
         left := nil;

+ 2 - 3
compiler/ninl.pas

@@ -399,8 +399,7 @@ implementation
             { create a new fileparameter as follows: file_type(temp^)    }
             { create a new fileparameter as follows: file_type(temp^)    }
             { (so that we pass the value and not the address of the temp }
             { (so that we pass the value and not the address of the temp }
             { to the read/write routine)                                 }
             { to the read/write routine)                                 }
-            if not searchsystype('TEXT',textsym) then
-              internalerror(200108313);
+            textsym:=search_system_type('TEXT');
             filepara := ccallparanode.create(ctypeconvnode.create_internal(
             filepara := ccallparanode.create(ctypeconvnode.create_internal(
               cderefnode.create(ctemprefnode.create(filetemp)),textsym.restype),nil);
               cderefnode.create(ctemprefnode.create(filetemp)),textsym.restype),nil);
           end
           end
@@ -1692,7 +1691,7 @@ implementation
                 begin
                 begin
                   resulttype:=voidtype;
                   resulttype:=voidtype;
                   { now we know the type of buffer }
                   { now we know the type of buffer }
-                  srsym:=searchsymonlyin(systemunit,'SETTEXTBUF');
+                  srsym:=search_system_type('SETTEXTBUF');
                   hp:=ccallparanode.create(cordconstnode.create(
                   hp:=ccallparanode.create(cordconstnode.create(
                      tcallparanode(left).left.resulttype.def.size,s32inttype,true),left);
                      tcallparanode(left).left.resulttype.def.size,s32inttype,true),left);
                   result:=ccallnode.create(hp,tprocsym(srsym),systemunit,nil,[]);
                   result:=ccallnode.create(hp,tprocsym(srsym),systemunit,nil,[]);

+ 14 - 72
compiler/nmem.pas

@@ -100,10 +100,7 @@ interface
        tvecnodeclass = class of tvecnode;
        tvecnodeclass = class of tvecnode;
 
 
        twithnode = class(tunarynode)
        twithnode = class(tunarynode)
-          withsymtable  : twithsymtable;
-          tablecount    : longint;
-          withrefnode   : tnode;
-          constructor create(l:tnode;symtable:twithsymtable;count:longint;r:tnode);
+          constructor create(l:tnode);
           destructor destroy;override;
           destructor destroy;override;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -697,16 +694,18 @@ implementation
            pointerdef :
            pointerdef :
              begin
              begin
                { are we accessing a pointer[], then convert the pointer to
                { are we accessing a pointer[], then convert the pointer to
-                 an array first, in FPC this is allowed for all pointers in
-                 delphi/tp7 it's only allowed for pchars }
-               if (m_fpc in aktmodeswitches) or
-                  is_pchar(left.resulttype.def) or
-                  is_pwidechar(left.resulttype.def) then
+                 an array first, in FPC this is allowed for all pointers
+                 (except voidpointer) in delphi/tp7 it's only allowed for pchars. }
+               if not is_voidpointer(left.resulttype.def) and
+                  (
+                   (m_fpc in aktmodeswitches) or
+                   is_pchar(left.resulttype.def) or
+                   is_pwidechar(left.resulttype.def)
+                  ) then
                 begin
                 begin
                   { convert pointer to array }
                   { convert pointer to array }
                   htype.setdef(tarraydef.create_from_pointer(tpointerdef(left.resulttype.def).pointertype));
                   htype.setdef(tarraydef.create_from_pointer(tpointerdef(left.resulttype.def).pointertype));
                   inserttypeconv(left,htype);
                   inserttypeconv(left,htype);
-
                   resulttype:=tarraydef(htype.def).elementtype;
                   resulttype:=tarraydef(htype.def).elementtype;
                 end
                 end
                else
                else
@@ -843,32 +842,15 @@ implementation
                                TWITHNODE
                                TWITHNODE
 *****************************************************************************}
 *****************************************************************************}
 
 
-    constructor twithnode.create(l:tnode;symtable:twithsymtable;count:longint;r:tnode);
+    constructor twithnode.create(l:tnode);
       begin
       begin
          inherited create(withn,l);
          inherited create(withn,l);
-         withrefnode:=r;
-         withsymtable:=symtable;
-         tablecount:=count;
          fileinfo:=l.fileinfo;
          fileinfo:=l.fileinfo;
       end;
       end;
 
 
 
 
     destructor twithnode.destroy;
     destructor twithnode.destroy;
-      var
-        hsymt,
-        symt : tsymtable;
-        i    : longint;
       begin
       begin
-        symt:=withsymtable;
-        for i:=1 to tablecount do
-         begin
-           if assigned(symt) then
-            begin
-              hsymt:=symt.next;
-              symt.free;
-              symt:=hsymt;
-            end;
-         end;
         inherited destroy;
         inherited destroy;
       end;
       end;
 
 
@@ -876,30 +858,20 @@ implementation
     constructor twithnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
     constructor twithnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
       begin
       begin
         inherited ppuload(t,ppufile);
         inherited ppuload(t,ppufile);
-        internalerror(200208192);
       end;
       end;
 
 
 
 
     procedure twithnode.ppuwrite(ppufile:tcompilerppufile);
     procedure twithnode.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
         inherited ppuwrite(ppufile);
         inherited ppuwrite(ppufile);
-        internalerror(200208193);
       end;
       end;
 
 
 
 
     function twithnode._getcopy : tnode;
     function twithnode._getcopy : tnode;
-
       var
       var
          p : twithnode;
          p : twithnode;
-
       begin
       begin
          p:=twithnode(inherited _getcopy);
          p:=twithnode(inherited _getcopy);
-         p.withsymtable:=withsymtable;
-         p.tablecount:=tablecount;
-         if assigned(p.withrefnode) then
-           p.withrefnode:=withrefnode._getcopy
-         else
-           p.withrefnode:=nil;
          result:=p;
          result:=p;
       end;
       end;
 
 
@@ -908,16 +880,6 @@ implementation
       begin
       begin
         result:=nil;
         result:=nil;
         resulttype:=voidtype;
         resulttype:=voidtype;
-
-        resulttypepass(withrefnode);
-        set_varstate(withrefnode,vs_read,[vsf_must_be_valid]);
-        if codegenerror then
-         exit;
-
-        if (withrefnode.nodetype=vecn) and
-           (nf_memseg in withrefnode.flags) then
-          CGMessage(parser_e_no_with_for_variable_in_other_segments);
-
         if assigned(left) then
         if assigned(left) then
           resulttypepass(left);
           resulttypepass(left);
       end;
       end;
@@ -927,38 +889,18 @@ implementation
       begin
       begin
         result:=nil;
         result:=nil;
         expectloc:=LOC_VOID;
         expectloc:=LOC_VOID;
-
-        if assigned(left) then
-         begin
-           firstpass(left);
-           registersint:=left.registersint;
-           registersfpu:=left.registersfpu;
-{$ifdef SUPPORT_MMX}
-           registersmmx:=left.registersmmx;
-{$endif SUPPORT_MMX}
-         end;
-        if assigned(withrefnode) then
-          begin
-            firstpass(withrefnode);
-            if withrefnode.registersint > registersint then
-              registersint:=withrefnode.registersint;
-            if withrefnode.registersfpu > registersfpu then
-              registersint:=withrefnode.registersfpu;
+        registersint:=left.registersint;
+        registersfpu:=left.registersfpu;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
-            if withrefnode.registersmmx > registersmmx then
-              registersmmx:=withrefnode.registersmmx;
+        registersmmx:=left.registersmmx;
 {$endif SUPPORT_MMX}
 {$endif SUPPORT_MMX}
-          end;
       end;
       end;
 
 
 
 
     function twithnode.docompare(p: tnode): boolean;
     function twithnode.docompare(p: tnode): boolean;
       begin
       begin
         docompare :=
         docompare :=
-          inherited docompare(p) and
-          (withsymtable = twithnode(p).withsymtable) and
-          (tablecount = twithnode(p).tablecount) and
-          (withrefnode.isequal(twithnode(p).withrefnode));
+          inherited docompare(p);
       end;
       end;
 
 
 begin
 begin

+ 0 - 16
compiler/nset.pas

@@ -102,17 +102,9 @@ interface
     { counts the labels }
     { counts the labels }
     function case_count_labels(root : pcaselabel) : longint;
     function case_count_labels(root : pcaselabel) : longint;
     { searches the highest label }
     { searches the highest label }
-{$ifdef int64funcresok}
     function case_get_max(root : pcaselabel) : tconstexprint;
     function case_get_max(root : pcaselabel) : tconstexprint;
-{$else int64funcresok}
-    function case_get_max(root : pcaselabel) : longint;
-{$endif int64funcresok}
     { searches the lowest label }
     { searches the lowest label }
-{$ifdef int64funcresok}
     function case_get_min(root : pcaselabel) : tconstexprint;
     function case_get_min(root : pcaselabel) : tconstexprint;
-{$else int64funcresok}
-    function case_get_min(root : pcaselabel) : longint;
-{$endif int64funcresok}
 
 
 
 
 implementation
 implementation
@@ -399,11 +391,7 @@ implementation
       end;
       end;
 
 
 
 
-{$ifdef int64funcresok}
     function case_get_max(root : pcaselabel) : tconstexprint;
     function case_get_max(root : pcaselabel) : tconstexprint;
-{$else int64funcresok}
-    function case_get_max(root : pcaselabel) : longint;
-{$endif int64funcresok}
       var
       var
          hp : pcaselabel;
          hp : pcaselabel;
       begin
       begin
@@ -414,11 +402,7 @@ implementation
       end;
       end;
 
 
 
 
-{$ifdef int64funcresok}
     function case_get_min(root : pcaselabel) : tconstexprint;
     function case_get_min(root : pcaselabel) : tconstexprint;
-{$else int64funcresok}
-    function case_get_min(root : pcaselabel) : longint;
-{$endif int64funcresok}
       var
       var
          hp : pcaselabel;
          hp : pcaselabel;
       begin
       begin

+ 2 - 4
compiler/nutils.pas

@@ -276,14 +276,12 @@ implementation
     function load_high_value_node(vs:tparavarsym):tnode;
     function load_high_value_node(vs:tparavarsym):tnode;
       var
       var
         srsym : tsym;
         srsym : tsym;
-        srsymtable : tsymtable;
       begin
       begin
         result:=nil;
         result:=nil;
-        srsymtable:=vs.owner;
-        srsym:=searchsymonlyin(srsymtable,'high'+vs.name);
+        srsym:=tsym(vs.owner.search('high'+vs.name));
         if assigned(srsym) then
         if assigned(srsym) then
           begin
           begin
-            result:=cloadnode.create(srsym,srsymtable);
+            result:=cloadnode.create(srsym,vs.owner);
             resulttypepass(result);
             resulttypepass(result);
           end
           end
         else
         else

+ 0 - 1
compiler/options.pas

@@ -382,7 +382,6 @@ var
   error : integer;
   error : integer;
   j,l  : longint;
   j,l  : longint;
   d    : DirStr;
   d    : DirStr;
-  e    : ExtStr;
   s    : string;
   s    : string;
 begin
 begin
   if opt='' then
   if opt='' then

+ 110 - 119
compiler/parser.pas

@@ -178,7 +178,6 @@ implementation
          current_module.localmacrosymtable:= tmacrosymtable.create(false);
          current_module.localmacrosymtable:= tmacrosymtable.create(false);
          current_module.localmacrosymtable.next:= initialmacrosymtable;
          current_module.localmacrosymtable.next:= initialmacrosymtable;
          macrosymtablestack:= current_module.localmacrosymtable;
          macrosymtablestack:= current_module.localmacrosymtable;
-         ConsolidateMode;
 
 
          main_module:=current_module;
          main_module:=current_module;
        { startup scanner, and save in current_module }
        { startup scanner, and save in current_module }
@@ -306,11 +305,8 @@ implementation
           oldorgpattern  : string;
           oldorgpattern  : string;
           old_block_type : tblock_type;
           old_block_type : tblock_type;
         { symtable }
         { symtable }
-          oldrefsymtable,
-          olddefaultsymtablestack,
-          oldsymtablestack : tsymtable;
-          olddefaultmacrosymtablestack,
-          oldmacrosymtablestack : tsymtable;
+          oldsymtablestack,
+          oldmacrosymtablestack : tsymtablestack;
           oldaktprocsym    : tprocsym;
           oldaktprocsym    : tprocsym;
         { cg }
         { cg }
           oldparse_only  : boolean;
           oldparse_only  : boolean;
@@ -355,9 +351,6 @@ implementation
           { save symtable state }
           { save symtable state }
             oldsymtablestack:=symtablestack;
             oldsymtablestack:=symtablestack;
             oldmacrosymtablestack:=macrosymtablestack;
             oldmacrosymtablestack:=macrosymtablestack;
-            olddefaultsymtablestack:=defaultsymtablestack;
-            olddefaultmacrosymtablestack:=defaultmacrosymtablestack;
-            oldrefsymtable:=refsymtable;
             oldcurrent_procinfo:=current_procinfo;
             oldcurrent_procinfo:=current_procinfo;
             oldaktdefproccall:=aktdefproccall;
             oldaktdefproccall:=aktdefproccall;
           { save scanner state }
           { save scanner state }
@@ -408,14 +401,10 @@ implementation
          Message1(parser_i_compiling,filename);
          Message1(parser_i_compiling,filename);
 
 
        { reset symtable }
        { reset symtable }
-         symtablestack:=nil;
-         macrosymtablestack:=nil;
-         defaultsymtablestack:=nil;
-         defaultmacrosymtablestack:=nil;
+         symtablestack:=tsymtablestack.create;
+         macrosymtablestack:=tsymtablestack.create;
          systemunit:=nil;
          systemunit:=nil;
-         refsymtable:=nil;
          aktdefproccall:=initdefproccall;
          aktdefproccall:=initdefproccall;
-         registerdef:=true;
          aktexceptblock:=0;
          aktexceptblock:=0;
          exceptblockcounter:=0;
          exceptblockcounter:=0;
          aktmaxfpuregisters:=-1;
          aktmaxfpuregisters:=-1;
@@ -461,10 +450,9 @@ implementation
          current_module.scanner:=current_scanner;
          current_module.scanner:=current_scanner;
 
 
          { init macros before anything in the file is parsed.}
          { init macros before anything in the file is parsed.}
-         macrosymtablestack:= initialmacrosymtable;
          current_module.localmacrosymtable:= tmacrosymtable.create(false);
          current_module.localmacrosymtable:= tmacrosymtable.create(false);
-         current_module.localmacrosymtable.next:= initialmacrosymtable;
-         macrosymtablestack:= current_module.localmacrosymtable;
+         macrosymtablestack.push(initialmacrosymtable);
+         macrosymtablestack.push(current_module.localmacrosymtable);
 
 
          { read the first token }
          { read the first token }
          current_scanner.readtoken(false);
          current_scanner.readtoken(false);
@@ -499,117 +487,120 @@ implementation
            done_module;
            done_module;
 
 
            if assigned(current_module) then
            if assigned(current_module) then
-            begin
-              { module is now compiled }
-              tppumodule(current_module).state:=ms_compiled;
-
-              { free ppu }
-              if assigned(tppumodule(current_module).ppufile) then
-               begin
-                 tppumodule(current_module).ppufile.free;
-                 tppumodule(current_module).ppufile:=nil;
-               end;
+             begin
+               { module is now compiled }
+               tppumodule(current_module).state:=ms_compiled;
 
 
-              { free scanner }
-              if assigned(current_module.scanner) then
-               begin
-                 if current_scanner=tscannerfile(current_module.scanner) then
-                   current_scanner:=nil;
-                 tscannerfile(current_module.scanner).free;
-                 current_module.scanner:=nil;
-               end;
-            end;
+               { free ppu }
+               if assigned(tppumodule(current_module).ppufile) then
+                 begin
+                   tppumodule(current_module).ppufile.free;
+                   tppumodule(current_module).ppufile:=nil;
+                 end;
 
 
-           if (compile_level>1) then
-             begin
-                with olddata^ do
+               { free scanner }
+               if assigned(current_module.scanner) then
                  begin
                  begin
-                   { restore scanner }
-                   c:=oldc;
-                   pattern:=oldpattern;
-                   orgpattern:=oldorgpattern;
-                   token:=oldtoken;
-                   idtoken:=oldidtoken;
-                   akttokenpos:=oldtokenpos;
-                   block_type:=old_block_type;
-                   { restore cg }
-                   parse_only:=oldparse_only;
-                   { restore asmlists }
-                   exprasmlist:=oldexprasmlist;
-                   asmlist:=oldasmlist;
-                   { object data }
-                   resourcestrings:=oldresourcestrings;
-                   objectlibrary:=oldobjectlibrary;
-                   { restore previous scanner }
-                   if assigned(old_compiled_module) then
-                     current_scanner:=tscannerfile(old_compiled_module.scanner)
-                   else
+                   if current_scanner=tscannerfile(current_module.scanner) then
                      current_scanner:=nil;
                      current_scanner:=nil;
-                   if assigned(current_scanner) then
-                     parser_current_file:=current_scanner.inputfile.name^;
-                   { restore symtable state }
-                   refsymtable:=oldrefsymtable;
-                   symtablestack:=oldsymtablestack;
-                   macrosymtablestack:=oldmacrosymtablestack;
-                   defaultsymtablestack:=olddefaultsymtablestack;
-                   defaultmacrosymtablestack:=olddefaultmacrosymtablestack;
-                   aktdefproccall:=oldaktdefproccall;
-                   current_procinfo:=oldcurrent_procinfo;
-                   aktsourcecodepage:=oldsourcecodepage;
-                   aktlocalswitches:=oldaktlocalswitches;
-                   aktmoduleswitches:=oldaktmoduleswitches;
-                   aktalignment:=oldaktalignment;
-                   aktpackenum:=oldaktpackenum;
-                   aktpackrecords:=oldaktpackrecords;
-                   aktmaxfpuregisters:=oldaktmaxfpuregisters;
-                   aktoptprocessor:=oldaktoptprocessor;
-                   aktspecificoptprocessor:=oldaktspecificoptprocessor;
-                   aktfputype:=oldaktfputype;
-                   aktasmmode:=oldaktasmmode;
-                   aktinterfacetype:=oldaktinterfacetype;
-                   aktfilepos:=oldaktfilepos;
-                   aktmodeswitches:=oldaktmodeswitches;
-                   aktexceptblock:=0;
-                   exceptblockcounter:=0;
+                   tscannerfile(current_module.scanner).free;
+                   current_module.scanner:=nil;
                  end;
                  end;
-             end
-           else
-             begin
-               { Shut down things when the last file is compiled succesfull }
-               if (compile_level=1) and
-                  (status.errorcount=0) then
+
+               { free symtable stack }
+               if assigned(symtablestack) then
+                 begin
+                   symtablestack.free;
+                   symtablestack:=nil;
+                 end;
+               if assigned(macrosymtablestack) then
+                 begin
+                   macrosymtablestack.free;
+                   macrosymtablestack:=nil;
+                 end;
+             end;
+
+            with olddata^ do
+              begin
+                { restore scanner }
+                c:=oldc;
+                pattern:=oldpattern;
+                orgpattern:=oldorgpattern;
+                token:=oldtoken;
+                idtoken:=oldidtoken;
+                akttokenpos:=oldtokenpos;
+                block_type:=old_block_type;
+                { restore cg }
+                parse_only:=oldparse_only;
+                { restore asmlists }
+                exprasmlist:=oldexprasmlist;
+                asmlist:=oldasmlist;
+                { object data }
+                resourcestrings:=oldresourcestrings;
+                objectlibrary:=oldobjectlibrary;
+                { restore previous scanner }
+                if assigned(old_compiled_module) then
+                  current_scanner:=tscannerfile(old_compiled_module.scanner)
+                else
+                  current_scanner:=nil;
+                if assigned(current_scanner) then
+                  parser_current_file:=current_scanner.inputfile.name^;
+                { restore symtable state }
+                symtablestack:=oldsymtablestack;
+                macrosymtablestack:=oldmacrosymtablestack;
+                aktdefproccall:=oldaktdefproccall;
+                current_procinfo:=oldcurrent_procinfo;
+                aktsourcecodepage:=oldsourcecodepage;
+                aktlocalswitches:=oldaktlocalswitches;
+                aktmoduleswitches:=oldaktmoduleswitches;
+                aktalignment:=oldaktalignment;
+                aktpackenum:=oldaktpackenum;
+                aktpackrecords:=oldaktpackrecords;
+                aktmaxfpuregisters:=oldaktmaxfpuregisters;
+                aktoptprocessor:=oldaktoptprocessor;
+                aktspecificoptprocessor:=oldaktspecificoptprocessor;
+                aktfputype:=oldaktfputype;
+                aktasmmode:=oldaktasmmode;
+                aktinterfacetype:=oldaktinterfacetype;
+                aktfilepos:=oldaktfilepos;
+                aktmodeswitches:=oldaktmodeswitches;
+                aktexceptblock:=0;
+                exceptblockcounter:=0;
+              end;
+            { Shut down things when the last file is compiled succesfull }
+            if (compile_level=1) and
+                (status.errorcount=0) then
+              begin
+                parser_current_file:='';
+                { Close script }
+                if (not AsmRes.Empty) then
+                begin
+                  Message1(exec_i_closing_script,AsmRes.Fn);
+                  AsmRes.WriteToDisk;
+                end;
+
+                { do not create browsers on errors !! }
+                if status.errorcount=0 then
                 begin
                 begin
-                  parser_current_file:='';
-                  { Close script }
-                  if (not AsmRes.Empty) then
-                   begin
-                     Message1(exec_i_closing_script,AsmRes.Fn);
-                     AsmRes.WriteToDisk;
-                   end;
-
-                  { do not create browsers on errors !! }
-                  if status.errorcount=0 then
-                   begin
 {$ifdef BrowserLog}
 {$ifdef BrowserLog}
-                     { Write Browser Log }
-                     if (cs_browser_log in aktglobalswitches) and
-                        (cs_browser in aktmoduleswitches) then
+                  { Write Browser Log }
+                  if (cs_browser_log in aktglobalswitches) and
+                      (cs_browser in aktmoduleswitches) then
+                    begin
+                      if browserlog.elements_to_list.empty then
                       begin
                       begin
-                        if browserlog.elements_to_list.empty then
-                         begin
-                           Message1(parser_i_writing_browser_log,browserlog.Fname);
-                           WriteBrowserLog;
-                         end
-                        else
-                         browserlog.list_elements;
-                      end;
+                        Message1(parser_i_writing_browser_log,browserlog.Fname);
+                        WriteBrowserLog;
+                      end
+                      else
+                      browserlog.list_elements;
+                    end;
 {$endif BrowserLog}
 {$endif BrowserLog}
-                     { Write Browser Collections, also used by the TextMode IDE to
-                       retrieve a list of sourcefiles }
-                     do_extractsymbolinfo{$ifdef FPC}(){$endif};
-                   end;
+                  { Write Browser Collections, also used by the TextMode IDE to
+                    retrieve a list of sourcefiles }
+                  do_extractsymbolinfo{$ifdef FPC}(){$endif};
                 end;
                 end;
-             end;
+              end;
 
 
            dec(compile_level);
            dec(compile_level);
            compiled_module:=olddata^.old_compiled_module;
            compiled_module:=olddata^.old_compiled_module;

+ 46 - 37
compiler/pbase.pas

@@ -52,9 +52,6 @@ interface
        { for operators }
        { for operators }
        optoken : ttoken;
        optoken : ttoken;
 
 
-       { symtable were unit references are stored }
-       refsymtable : tsymtable;
-
        { true, if only routine headers should be parsed }
        { true, if only routine headers should be parsed }
        parse_only : boolean;
        parse_only : boolean;
 
 
@@ -85,6 +82,8 @@ interface
       and return an errorsym }
       and return an errorsym }
     function consume_sym(var srsym:tsym;var srsymtable:tsymtable):boolean;
     function consume_sym(var srsym:tsym;var srsymtable:tsymtable):boolean;
 
 
+    function try_consume_unitsym(var srsym:tsym;var srsymtable:tsymtable):boolean;
+
     function try_consume_hintdirective(var symopt:tsymoptions):boolean;
     function try_consume_hintdirective(var symopt:tsymoptions):boolean;
 
 
     { just for an accurate position of the end of a procedure (PM) }
     { just for an accurate position of the end of a procedure (PM) }
@@ -179,43 +178,53 @@ implementation
       begin
       begin
         { first check for identifier }
         { first check for identifier }
         if token<>_ID then
         if token<>_ID then
-         begin
-           consume(_ID);
-           srsym:=generrorsym;
-           srsymtable:=nil;
-           consume_sym:=false;
-           exit;
-         end;
+          begin
+            consume(_ID);
+            srsym:=generrorsym;
+            srsymtable:=nil;
+            result:=false;
+            exit;
+          end;
         searchsym(pattern,srsym,srsymtable);
         searchsym(pattern,srsym,srsymtable);
-        if assigned(srsym) then
-         begin
-           check_hints(srsym,srsym.symoptions);
-           if (srsym.typ=unitsym) then
-            begin
-              if not(srsym.owner.symtabletype in [staticsymtable,globalsymtable]) then
-                internalerror(200501154);
-              { only allow unit.symbol access if the name was
-                found in the current module }
-              if srsym.owner.iscurrentunit then
-               begin
-                 consume(_ID);
-                 consume(_POINT);
-                 srsymtable:=tunitsym(srsym).unitsymtable;
-                 srsym:=searchsymonlyin(srsymtable,pattern);
-               end
-              else
-               srsym:=nil;
-            end;
-         end;
+        { handle unit specification like System.Writeln }
+        try_consume_unitsym(srsym,srsymtable);
         { if nothing found give error and return errorsym }
         { if nothing found give error and return errorsym }
-        if srsym=nil then
-         begin
-           identifier_not_found(orgpattern);
-           srsym:=generrorsym;
-           srsymtable:=nil;
-         end;
+        if assigned(srsym) then
+          check_hints(srsym,srsym.symoptions)
+        else
+          begin
+            identifier_not_found(orgpattern);
+            srsym:=generrorsym;
+            srsymtable:=nil;
+          end;
         consume(_ID);
         consume(_ID);
-        consume_sym:=assigned(srsym);
+        result:=assigned(srsym);
+      end;
+
+
+    function try_consume_unitsym(var srsym:tsym;var srsymtable:tsymtable):boolean;
+      begin
+        result:=false;
+        if assigned(srsym) and
+           (srsym.typ=unitsym) then
+          begin
+            if not(srsym.owner.symtabletype in [staticsymtable,globalsymtable]) then
+              internalerror(200501154);
+            { only allow unit.symbol access if the name was
+              found in the current module }
+            if srsym.owner.iscurrentunit then
+              begin
+                consume(_ID);
+                consume(_POINT);
+                searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);
+              end
+            else
+              begin
+                srsym:=nil;
+                srsymtable:=nil;
+              end;
+            result:=true;
+          end;
       end;
       end;
 
 
 
 

+ 12 - 14
compiler/pdecl.pas

@@ -182,7 +182,7 @@ implementation
                    if assigned(sym) then
                    if assigned(sym) then
                      begin
                      begin
                        sym.symoptions:=sym.symoptions+dummysymoptions;
                        sym.symoptions:=sym.symoptions+dummysymoptions;
-                       symtablestack.insert(sym);
+                       symtablestack.top.insert(sym);
                      end;
                      end;
                    consume(_SEMICOLON);
                    consume(_SEMICOLON);
                 end;
                 end;
@@ -203,7 +203,7 @@ implementation
                    akttokenpos:=filepos;
                    akttokenpos:=filepos;
                    sym:=ttypedconstsym.createtype(orgname,tt,(cs_typed_const_writable in aktlocalswitches));
                    sym:=ttypedconstsym.createtype(orgname,tt,(cs_typed_const_writable in aktlocalswitches));
                    akttokenpos:=storetokenpos;
                    akttokenpos:=storetokenpos;
-                   symtablestack.insert(sym);
+                   symtablestack.top.insert(sym);
                    { procvar can have proc directives, but not type references }
                    { procvar can have proc directives, but not type references }
                    if (tt.def.deftype=procvardef) and
                    if (tt.def.deftype=procvardef) and
                       (tt.sym=nil) then
                       (tt.sym=nil) then
@@ -248,8 +248,6 @@ implementation
 
 
 
 
     procedure label_dec;
     procedure label_dec;
-      var
-         hl : tasmlabel;
       begin
       begin
          consume(_LABEL);
          consume(_LABEL);
          if not(cs_support_goto in aktmoduleswitches) then
          if not(cs_support_goto in aktmoduleswitches) then
@@ -260,9 +258,9 @@ implementation
            else
            else
              begin
              begin
                 if token=_ID then
                 if token=_ID then
-                 symtablestack.insert(tlabelsym.create(orgpattern))
+                 symtablestack.top.insert(tlabelsym.create(orgpattern))
                 else
                 else
-                 symtablestack.insert(tlabelsym.create(pattern));
+                 symtablestack.top.insert(tlabelsym.create(pattern));
                 consume(token);
                 consume(token);
              end;
              end;
            if token<>_SEMICOLON then consume(_COMMA);
            if token<>_SEMICOLON then consume(_COMMA);
@@ -482,7 +480,7 @@ implementation
               tt:=generrortype;
               tt:=generrortype;
               storetokenpos:=akttokenpos;
               storetokenpos:=akttokenpos;
               newtype:=ttypesym.create(orgtypename,tt);
               newtype:=ttypesym.create(orgtypename,tt);
-              symtablestack.insert(newtype);
+              symtablestack.top.insert(newtype);
               akttokenpos:=defpos;
               akttokenpos:=defpos;
               akttokenpos:=storetokenpos;
               akttokenpos:=storetokenpos;
               { read the type definition }
               { read the type definition }
@@ -602,7 +600,7 @@ implementation
             end;
             end;
          until token<>_ID;
          until token<>_ID;
          typecanbeforward:=false;
          typecanbeforward:=false;
-         symtablestack.foreach_static(@resolve_type_forward,nil);
+         symtablestack.top.foreach_static(@resolve_type_forward,nil);
          block_type:=old_block_type;
          block_type:=old_block_type;
       end;
       end;
 
 
@@ -612,7 +610,7 @@ implementation
     { the top symbol table of symtablestack         }
     { the top symbol table of symtablestack         }
       begin
       begin
         consume(_VAR);
         consume(_VAR);
-        read_var_decs([]);
+        read_var_decls([]);
       end;
       end;
 
 
 
 
@@ -621,7 +619,7 @@ implementation
          old_block_type : tblock_type;
          old_block_type : tblock_type;
       begin
       begin
          consume(_PROPERTY);
          consume(_PROPERTY);
-         if not(symtablestack.symtabletype in [staticsymtable,globalsymtable]) then
+         if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
            message(parser_e_resourcestring_only_sg);
            message(parser_e_resourcestring_only_sg);
          old_block_type:=block_type;
          old_block_type:=block_type;
          block_type:=bt_const;
          block_type:=bt_const;
@@ -638,9 +636,9 @@ implementation
     { the top symbol table of symtablestack                }
     { the top symbol table of symtablestack                }
       begin
       begin
         consume(_THREADVAR);
         consume(_THREADVAR);
-        if not(symtablestack.symtabletype in [staticsymtable,globalsymtable]) then
+        if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
           message(parser_e_threadvars_only_sg);
           message(parser_e_threadvars_only_sg);
-        read_var_decs([vd_threadvar]);
+        read_var_decls([vd_threadvar]);
       end;
       end;
 
 
 
 
@@ -655,7 +653,7 @@ implementation
          sym : tsym;
          sym : tsym;
       begin
       begin
          consume(_RESOURCESTRING);
          consume(_RESOURCESTRING);
-         if not(symtablestack.symtabletype in [staticsymtable,globalsymtable]) then
+         if not(symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) then
            message(parser_e_resourcestring_only_sg);
            message(parser_e_resourcestring_only_sg);
          old_block_type:=block_type;
          old_block_type:=block_type;
          block_type:=bt_const;
          block_type:=bt_const;
@@ -701,7 +699,7 @@ implementation
                    if assigned(sym) then
                    if assigned(sym) then
                      begin
                      begin
                        sym.symoptions:=sym.symoptions+dummysymoptions;
                        sym.symoptions:=sym.symoptions+dummysymoptions;
-                       symtablestack.insert(sym);
+                       symtablestack.top.insert(sym);
                      end;
                      end;
                    consume(_SEMICOLON);
                    consume(_SEMICOLON);
                    p.free;
                    p.free;

+ 10 - 8
compiler/pdecobj.pas

@@ -37,7 +37,7 @@ implementation
     uses
     uses
       cutils,
       cutils,
       globals,verbose,systems,tokens,
       globals,verbose,systems,tokens,
-      symconst,symbase,symsym,
+      symconst,symbase,symsym,symtable,
       node,nld,nmem,ncon,ncnv,ncal,
       node,nld,nmem,ncon,ncnv,ncal,
       scanner,
       scanner,
       pbase,pexpr,pdecsub,pdecvar,ptype
       pbase,pexpr,pdecsub,pdecvar,ptype
@@ -175,7 +175,8 @@ implementation
           for i:=1 to defs.count do
           for i:=1 to defs.count do
             begin
             begin
               pd:=tdef(defs.search(i));
               pd:=tdef(defs.search(i));
-              if pd.deftype=procdef then
+              if assigned(pd) and
+                 (pd.deftype=procdef) then
                 begin
                 begin
                   tprocdef(pd).extnumber:=aktobjectdef.lastvtableindex;
                   tprocdef(pd).extnumber:=aktobjectdef.lastvtableindex;
                   inc(aktobjectdef.lastvtableindex);
                   inc(aktobjectdef.lastvtableindex);
@@ -503,7 +504,7 @@ implementation
          old_object_option:=current_object_option;
          old_object_option:=current_object_option;
 
 
          { objects and class types can't be declared local }
          { objects and class types can't be declared local }
-         if not(symtablestack.symtabletype in [globalsymtable,staticsymtable]) then
+         if not(symtablestack.top.symtabletype in [globalsymtable,staticsymtable]) then
            Message(parser_e_no_local_objects);
            Message(parser_e_no_local_objects);
 
 
          storetypecanbeforward:=typecanbeforward;
          storetypecanbeforward:=typecanbeforward;
@@ -537,8 +538,7 @@ implementation
          { set class flags and inherits published }
          { set class flags and inherits published }
          setclassattributes;
          setclassattributes;
 
 
-         aktobjectdef.symtable.next:=symtablestack;
-         symtablestack:=aktobjectdef.symtable;
+         symtablestack.push(aktobjectdef.symtable);
          testcurobject:=1;
          testcurobject:=1;
 
 
          { add generic type parameters }
          { add generic type parameters }
@@ -552,7 +552,7 @@ implementation
                    include(aktobjectdef.defoptions,df_generic)
                    include(aktobjectdef.defoptions,df_generic)
                  else
                  else
                    include(aktobjectdef.defoptions,df_specialization);
                    include(aktobjectdef.defoptions,df_specialization);
-                 symtablestack.insert(generictype);
+                 symtablestack.top.insert(generictype);
                  generictype:=ttypesym(generictype.listnext);
                  generictype:=ttypesym(generictype.listnext);
                end;
                end;
            end;
            end;
@@ -635,7 +635,7 @@ implementation
                               not(oo_can_have_published in aktobjectdef.objectoptions) then
                               not(oo_can_have_published in aktobjectdef.objectoptions) then
                               Message(parser_e_cant_have_published);
                               Message(parser_e_cant_have_published);
 
 
-                            read_var_decs([vd_object]);
+                            read_record_fields([vd_object]);
                           end;
                           end;
                     end;
                     end;
                   end;
                   end;
@@ -790,6 +790,9 @@ implementation
          if is_interface(aktobjectdef) then
          if is_interface(aktobjectdef) then
            setinterfacemethodoptions;
            setinterfacemethodoptions;
 
 
+         { remove symtable from stack }
+         symtablestack.pop(aktobjectdef.symtable);
+
          { return defined objectdef }
          { return defined objectdef }
          result:=aktobjectdef;
          result:=aktobjectdef;
 
 
@@ -797,7 +800,6 @@ implementation
          aktobjectdef:=nil;
          aktobjectdef:=nil;
          testcurobject:=0;
          testcurobject:=0;
          typecanbeforward:=storetypecanbeforward;
          typecanbeforward:=storetypecanbeforward;
-         symtablestack:=symtablestack.next;
          current_object_option:=old_object_option;
          current_object_option:=old_object_option;
       end;
       end;
 
 

+ 57 - 62
compiler/pdecsub.pas

@@ -71,7 +71,7 @@ implementation
        { symtable }
        { symtable }
        symbase,symtable,defutil,defcmp,paramgr,cpupara,
        symbase,symtable,defutil,defcmp,paramgr,cpupara,
        { pass 1 }
        { pass 1 }
-       node,htypechk,
+       fmodule,node,htypechk,
        nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
        nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
        { parser }
        { parser }
        scanner,
        scanner,
@@ -234,7 +234,7 @@ implementation
            sl.addsym(sl_load,pd.funcretsym);
            sl.addsym(sl_load,pd.funcretsym);
            aliasvs:=tabsolutevarsym.create_ref(pd.resultname,pd.rettype,sl);
            aliasvs:=tabsolutevarsym.create_ref(pd.resultname,pd.rettype,sl);
            include(aliasvs.varoptions,vo_is_funcret);
            include(aliasvs.varoptions,vo_is_funcret);
-           pd.localst.insert(aliasvs);
+           tlocalsymtable(pd.localst).insert(aliasvs);
 
 
            { insert result also if support is on }
            { insert result also if support is on }
            if (m_result in aktmodeswitches) then
            if (m_result in aktmodeswitches) then
@@ -244,7 +244,7 @@ implementation
               aliasvs:=tabsolutevarsym.create_ref('RESULT',pd.rettype,sl);
               aliasvs:=tabsolutevarsym.create_ref('RESULT',pd.rettype,sl);
               include(aliasvs.varoptions,vo_is_funcret);
               include(aliasvs.varoptions,vo_is_funcret);
               include(aliasvs.varoptions,vo_is_result);
               include(aliasvs.varoptions,vo_is_result);
-              pd.localst.insert(aliasvs);
+              tlocalsymtable(pd.localst).insert(aliasvs);
             end;
             end;
 
 
            akttokenpos:=storepos;
            akttokenpos:=storepos;
@@ -504,9 +504,7 @@ implementation
                 if (token=_CONST) and (m_objpas in aktmodeswitches) then
                 if (token=_CONST) and (m_objpas in aktmodeswitches) then
                  begin
                  begin
                    consume(_CONST);
                    consume(_CONST);
-                   srsym:=searchsymonlyin(systemunit,'TVARREC');
-                   if not assigned(srsym) then
-                     InternalError(200404181);
+                   srsym:=search_system_type('TVARREC');
                    tarraydef(tt.def).setelementtype(ttypesym(srsym).restype);
                    tarraydef(tt.def).setelementtype(ttypesym(srsym).restype);
                    tarraydef(tt.def).IsArrayOfConst:=true;
                    tarraydef(tt.def).IsArrayOfConst:=true;
                  end
                  end
@@ -637,16 +635,16 @@ implementation
       var
       var
         hs       : string;
         hs       : string;
         orgsp,sp : stringid;
         orgsp,sp : stringid;
-        sym : tsym;
         srsym : tsym;
         srsym : tsym;
-        oldsymtablestack,
         srsymtable : tsymtable;
         srsymtable : tsymtable;
+        checkstack : psymtablestackitem;
         storepos,
         storepos,
         procstartfilepos : tfileposinfo;
         procstartfilepos : tfileposinfo;
         searchagain : boolean;
         searchagain : boolean;
         i : longint;
         i : longint;
         st : tsymtable;
         st : tsymtable;
         aprocsym : tprocsym;
         aprocsym : tprocsym;
+        popclass : boolean;
       begin
       begin
         { Save the position where this procedure really starts }
         { Save the position where this procedure really starts }
         procstartfilepos:=akttokenpos;
         procstartfilepos:=akttokenpos;
@@ -676,17 +674,17 @@ implementation
            storepos:=akttokenpos;
            storepos:=akttokenpos;
            akttokenpos:=procstartfilepos;
            akttokenpos:=procstartfilepos;
            { get interface syms}
            { get interface syms}
-           searchsym(sp,sym,srsymtable);
-           if not assigned(sym) then
+           searchsym(sp,srsym,srsymtable);
+           if not assigned(srsym) then
             begin
             begin
               identifier_not_found(orgsp);
               identifier_not_found(orgsp);
-              sym:=generrorsym;
+              srsym:=generrorsym;
             end;
             end;
            akttokenpos:=storepos;
            akttokenpos:=storepos;
            { qualifier is interface? }
            { qualifier is interface? }
-           if (sym.typ=typesym) and
-              (ttypesym(sym).restype.def.deftype=objectdef) then
-             i:=aclass.implementedinterfaces.searchintf(ttypesym(sym).restype.def)
+           if (srsym.typ=typesym) and
+              (ttypesym(srsym).restype.def.deftype=objectdef) then
+             i:=aclass.implementedinterfaces.searchintf(ttypesym(srsym).restype.def)
            else
            else
              i:=-1;
              i:=-1;
            if (i=-1) then
            if (i=-1) then
@@ -705,17 +703,17 @@ implementation
         { method  ? }
         { method  ? }
         if not assigned(aclass) and
         if not assigned(aclass) and
            (potype<>potype_operator) and
            (potype<>potype_operator) and
-           (symtablestack.symtablelevel=main_program_level) and
+           (symtablestack.top.symtablelevel=main_program_level) and
            try_to_consume(_POINT) then
            try_to_consume(_POINT) then
          begin
          begin
            { search for object name }
            { search for object name }
            storepos:=akttokenpos;
            storepos:=akttokenpos;
            akttokenpos:=procstartfilepos;
            akttokenpos:=procstartfilepos;
-           searchsym(sp,sym,srsymtable);
-           if not assigned(sym) then
+           searchsym(sp,srsym,srsymtable);
+           if not assigned(srsym) then
             begin
             begin
               identifier_not_found(orgsp);
               identifier_not_found(orgsp);
-              sym:=generrorsym;
+              srsym:=generrorsym;
             end;
             end;
            akttokenpos:=storepos;
            akttokenpos:=storepos;
            { consume proc name }
            { consume proc name }
@@ -724,10 +722,10 @@ implementation
            procstartfilepos:=akttokenpos;
            procstartfilepos:=akttokenpos;
            consume(_ID);
            consume(_ID);
            { qualifier is class name ? }
            { qualifier is class name ? }
-           if (sym.typ=typesym) and
-              (ttypesym(sym).restype.def.deftype=objectdef) then
+           if (srsym.typ=typesym) and
+              (ttypesym(srsym).restype.def.deftype=objectdef) then
             begin
             begin
-              aclass:=tobjectdef(ttypesym(sym).restype.def);
+              aclass:=tobjectdef(ttypesym(srsym).restype.def);
               aprocsym:=tprocsym(aclass.symtable.search(sp));
               aprocsym:=tprocsym(aclass.symtable.search(sp));
               { we solve this below }
               { we solve this below }
               if assigned(aprocsym) then
               if assigned(aprocsym) then
@@ -765,23 +763,17 @@ implementation
            repeat
            repeat
              searchagain:=false;
              searchagain:=false;
              akttokenpos:=procstartfilepos;
              akttokenpos:=procstartfilepos;
-             srsym:=tsym(symtablestack.search(sp));
 
 
-             if not(parse_only) and
-                not assigned(srsym) and
-                (symtablestack.symtabletype=staticsymtable) and
-                assigned(symtablestack.next) and
-                (symtablestack.next.iscurrentunit) then
-               begin
-                 { The procedure we prepare for is in the implementation
-                   part of the unit we compile. It is also possible that we
-                   are compiling a program, which is also some kind of
-                   implementaion part.
-
-                   We need to find out if the procedure is global. If it is
-                   global, it is in the global symtable.}
-                 srsym:=tsym(symtablestack.next.search(sp));
-               end;
+             srsymtable:=symtablestack.top;
+             srsym:=tsym(srsymtable.search(sp));
+
+             { Also look in the globalsymtable if we didn't found
+               the symbol in the localsymtable }
+             if not assigned(srsym) and
+                not(parse_only) and
+                (srsymtable=current_module.localsymtable) and
+                assigned(current_module.globalsymtable) then
+               srsym:=tsym(current_module.globalsymtable.search(sp));
 
 
              { Check if overloaded is a procsym }
              { Check if overloaded is a procsym }
              if assigned(srsym) then
              if assigned(srsym) then
@@ -822,19 +814,25 @@ implementation
              operation }
              operation }
            if (potype=potype_operator) then
            if (potype=potype_operator) then
              begin
              begin
-               Aprocsym:=Tprocsym(symtablestack.search(sp));
+               Aprocsym:=Tprocsym(symtablestack.top.search(sp));
                if Aprocsym=nil then
                if Aprocsym=nil then
                  Aprocsym:=tprocsym.create('$'+sp);
                  Aprocsym:=tprocsym.create('$'+sp);
              end
              end
             else
             else
              aprocsym:=tprocsym.create(orgsp);
              aprocsym:=tprocsym.create(orgsp);
-            symtablestack.insert(aprocsym);
+            symtablestack.top.insert(aprocsym);
          end;
          end;
 
 
         { to get the correct symtablelevel we must ignore objectsymtables }
         { to get the correct symtablelevel we must ignore objectsymtables }
-        st:=symtablestack;
-        while not(st.symtabletype in [staticsymtable,globalsymtable,localsymtable]) do
-         st:=st.next;
+        st:=nil;
+        checkstack:=symtablestack.stack;
+        while assigned(checkstack) do
+          begin
+            st:=checkstack^.symtable;
+            if st.symtabletype in [staticsymtable,globalsymtable,localsymtable] then
+              break;
+            checkstack:=checkstack^.next;
+          end;
         pd:=tprocdef.create(st.symtablelevel+1);
         pd:=tprocdef.create(st.symtablelevel+1);
         pd._class:=aclass;
         pd._class:=aclass;
         pd.procsym:=aprocsym;
         pd.procsym:=aprocsym;
@@ -867,8 +865,8 @@ implementation
         { methods need to be exported }
         { methods need to be exported }
         if assigned(aclass) and
         if assigned(aclass) and
            (
            (
-            (symtablestack.symtabletype=objectsymtable) or
-            (symtablestack.symtablelevel=main_program_level)
+            (symtablestack.top.symtabletype=objectsymtable) or
+            (symtablestack.top.symtablelevel=main_program_level)
            ) then
            ) then
           include(pd.procoptions,po_global);
           include(pd.procoptions,po_global);
 
 
@@ -880,22 +878,22 @@ implementation
         if token=_LKLAMMER then
         if token=_LKLAMMER then
           begin
           begin
             { Add objectsymtable to be able to find generic type definitions }
             { Add objectsymtable to be able to find generic type definitions }
-            oldsymtablestack:=symtablestack;
+            popclass:=false;
             if assigned(pd._class) and
             if assigned(pd._class) and
                (pd.parast.symtablelevel=normal_function_level) and
                (pd.parast.symtablelevel=normal_function_level) and
-               (symtablestack.symtabletype<>objectsymtable) then
+               (symtablestack.top.symtabletype<>objectsymtable) then
               begin
               begin
-                pd._class.symtable.next:=symtablestack;
-                symtablestack:=pd._class.symtable;
+                symtablestack.push(pd._class.symtable);
+                popclass:=true;
               end;
               end;
             { Add parameter symtable }
             { Add parameter symtable }
             if pd.parast.symtabletype<>staticsymtable then
             if pd.parast.symtabletype<>staticsymtable then
-              begin
-                 pd.parast.next:=symtablestack;
-                 symtablestack:=pd.parast;
-              end;
+              symtablestack.push(pd.parast);
             parse_parameter_dec(pd);
             parse_parameter_dec(pd);
-            symtablestack:=oldsymtablestack;
+            if pd.parast.symtabletype<>staticsymtable then
+              symtablestack.pop(pd.parast);
+            if popclass then
+              symtablestack.pop(pd._class.symtable);
           end;
           end;
 
 
         result:=true;
         result:=true;
@@ -1875,7 +1873,7 @@ const
             if ((not isprocvar) or
             if ((not isprocvar) or
                (pd_procvar in proc_direcdata[i].pd_flags)) and
                (pd_procvar in proc_direcdata[i].pd_flags)) and
                { don't eat a public directive in classes }
                { don't eat a public directive in classes }
-               not((idtoken=_PUBLIC) and (symtablestack.symtabletype=objectsymtable)) then
+               not((idtoken=_PUBLIC) and (symtablestack.top.symtabletype=objectsymtable)) then
               result:=true;
               result:=true;
             exit;
             exit;
           end;
           end;
@@ -1939,7 +1937,7 @@ const
         { check if method and directive not for object, like public.
         { check if method and directive not for object, like public.
           This needs to be checked also for procvars }
           This needs to be checked also for procvars }
         if (pd_notobject in proc_direcdata[p].pd_flags) and
         if (pd_notobject in proc_direcdata[p].pd_flags) and
-           (symtablestack.symtabletype=objectsymtable) then
+           (symtablestack.top.symtabletype=objectsymtable) then
            exit;
            exit;
 
 
         { Conflicts between directives ? }
         { Conflicts between directives ? }
@@ -2335,7 +2333,6 @@ const
       var
       var
         hd    : tprocdef;
         hd    : tprocdef;
         ad,fd : tsym;
         ad,fd : tsym;
-        s1,s2 : stringid;
         i     : cardinal;
         i     : cardinal;
         forwardfound : boolean;
         forwardfound : boolean;
         po_comp : tprocoptions;
         po_comp : tprocoptions;
@@ -2485,17 +2482,15 @@ const
                         { stop when one of the two lists is at the end }
                         { stop when one of the two lists is at the end }
                         if not assigned(ad) or not assigned(fd) then
                         if not assigned(ad) or not assigned(fd) then
                          break;
                          break;
-                        { retrieve names, remove reg for register parameters }
+                        { compare names of parameters, ignore implictly
+                          renamed parameters }
                         if not(sp_implicitrename in ad.symoptions) and
                         if not(sp_implicitrename in ad.symoptions) and
                            not(sp_implicitrename in fd.symoptions) then
                            not(sp_implicitrename in fd.symoptions) then
                           begin
                           begin
-                            s1:=ad.name;
-                            s2:=fd.name;
-                            { compare names }
-                            if (s1<>s2) then
+                            if (ad.name<>fd.name) then
                              begin
                              begin
                                MessagePos3(pd.fileinfo,parser_e_header_different_var_names,
                                MessagePos3(pd.fileinfo,parser_e_header_different_var_names,
-                                           aprocsym.name,s1,s2);
+                                           aprocsym.realname,ad.realname,fd.realname);
                                break;
                                break;
                              end;
                              end;
                           end;
                           end;

+ 332 - 339
compiler/pdecvar.pas

@@ -29,12 +29,15 @@ interface
     uses
     uses
       symsym,symdef;
       symsym,symdef;
 
 
-    type   Tvar_dec_option=(vd_record,vd_object,vd_threadvar);
-           Tvar_dec_options=set of Tvar_dec_option;
+    type
+      tvar_dec_option=(vd_record,vd_object,vd_threadvar);
+      tvar_dec_options=set of tvar_dec_option;
 
 
-    function read_property_dec(aclass:tobjectdef):tpropertysym;
+    function  read_property_dec(aclass:tobjectdef):tpropertysym;
+
+    procedure read_var_decls(options:Tvar_dec_options);
 
 
-    procedure read_var_decs(options:Tvar_dec_options);
+    procedure read_record_fields(options:Tvar_dec_options);
 
 
 
 
 implementation
 implementation
@@ -121,7 +124,7 @@ implementation
                           st:=def.getsymtable(gs_record);
                           st:=def.getsymtable(gs_record);
                           if assigned(st) then
                           if assigned(st) then
                            begin
                            begin
-                             sym:=searchsymonlyin(st,pattern);
+                             sym:=tsym(st.search(pattern));
                              if assigned(sym) then
                              if assigned(sym) then
                               begin
                               begin
                                 pl.addsym(sl_subscript,sym);
                                 pl.addsym(sl_subscript,sym);
@@ -211,24 +214,18 @@ implementation
          arraytype : ttype;
          arraytype : ttype;
          def : tdef;
          def : tdef;
          pt : tnode;
          pt : tnode;
-         propname : stringid;
          sc : tsinglelist;
          sc : tsinglelist;
          paranr : word;
          paranr : word;
-         oldregisterdef : boolean;
          hreadparavs,
          hreadparavs,
          hparavs      : tparavarsym;
          hparavs      : tparavarsym;
          readprocdef,
          readprocdef,
          writeprocdef : tprocvardef;
          writeprocdef : tprocvardef;
-         oldsymtablestack : tsymtable;
       begin
       begin
          { Generate temp procvardefs to search for matching read/write
          { Generate temp procvardefs to search for matching read/write
            procedures. the readprocdef will store all definitions }
            procedures. the readprocdef will store all definitions }
-         oldregisterdef:=registerdef;
-         registerdef:=false;
          paranr:=0;
          paranr:=0;
          readprocdef:=tprocvardef.create(normal_function_level);
          readprocdef:=tprocvardef.create(normal_function_level);
          writeprocdef:=tprocvardef.create(normal_function_level);
          writeprocdef:=tprocvardef.create(normal_function_level);
-         registerdef:=oldregisterdef;
 
 
          { make it method pointers }
          { make it method pointers }
          if assigned(aclass) then
          if assigned(aclass) then
@@ -245,39 +242,24 @@ implementation
            end;
            end;
          { Generate propertysym and insert in symtablestack }
          { Generate propertysym and insert in symtablestack }
          p:=tpropertysym.create(orgpattern);
          p:=tpropertysym.create(orgpattern);
-         symtablestack.insert(p);
-         propname:=pattern;
+         symtablestack.top.insert(p);
          consume(_ID);
          consume(_ID);
-         { Set the symtablestack to the parast of readprop so
-           temp defs will be destroyed after declaration }
-         readprocdef.parast.next:=symtablestack;
-         symtablestack:=readprocdef.parast;
          { property parameters ? }
          { property parameters ? }
-         if token=_LECKKLAMMER then
+         if try_to_consume(_LECKKLAMMER) then
            begin
            begin
               if (sp_published in current_object_option) then
               if (sp_published in current_object_option) then
                 Message(parser_e_cant_publish_that_property);
                 Message(parser_e_cant_publish_that_property);
-
               { create a list of the parameters }
               { create a list of the parameters }
+              symtablestack.push(readprocdef.parast);
               sc:=tsinglelist.create;
               sc:=tsinglelist.create;
-              consume(_LECKKLAMMER);
               inc(testcurobject);
               inc(testcurobject);
               repeat
               repeat
-                if token=_VAR then
-                  begin
-                     consume(_VAR);
-                     varspez:=vs_var;
-                  end
-                else if token=_CONST then
-                  begin
-                     consume(_CONST);
-                     varspez:=vs_const;
-                  end
-                else if (idtoken=_OUT) and (m_out in aktmodeswitches) then
-                  begin
-                     consume(_OUT);
-                     varspez:=vs_out;
-                  end
+                if try_to_consume(_VAR) then
+                  varspez:=vs_var
+                else if try_to_consume(_CONST) then
+                  varspez:=vs_const
+                else if (m_out in aktmodeswitches) and try_to_consume(_OUT) then
+                  varspez:=vs_out
                 else
                 else
                   varspez:=vs_value;
                   varspez:=vs_value;
                 sc.reset;
                 sc.reset;
@@ -290,10 +272,6 @@ implementation
                 until not try_to_consume(_COMMA);
                 until not try_to_consume(_COMMA);
                 if try_to_consume(_COLON) then
                 if try_to_consume(_COLON) then
                   begin
                   begin
-                    { for records, don't search the recordsymtable for
-                     the symbols of the types }
-                    oldsymtablestack:=symtablestack;
-                    symtablestack:=symtablestack.next;
                     if try_to_consume(_ARRAY) then
                     if try_to_consume(_ARRAY) then
                       begin
                       begin
                         consume(_OF);
                         consume(_OF);
@@ -305,7 +283,6 @@ implementation
                       end
                       end
                     else
                     else
                       single_type(tt,false);
                       single_type(tt,false);
-                    symtablestack:=oldsymtablestack;
                   end
                   end
                 else
                 else
                   tt:=cformaltype;
                   tt:=cformaltype;
@@ -321,6 +298,7 @@ implementation
               until not try_to_consume(_SEMICOLON);
               until not try_to_consume(_SEMICOLON);
               sc.free;
               sc.free;
               dec(testcurobject);
               dec(testcurobject);
+              symtablestack.pop(readprocdef.parast);
               consume(_RECKKLAMMER);
               consume(_RECKKLAMMER);
 
 
               { the parser need to know if a property has parameters, the
               { the parser need to know if a property has parameters, the
@@ -335,12 +313,7 @@ implementation
          if (token=_COLON) or (paranr>0) or (aclass=nil) then
          if (token=_COLON) or (paranr>0) or (aclass=nil) then
            begin
            begin
               consume(_COLON);
               consume(_COLON);
-              { insert types in global symtable }
-              oldsymtablestack:=symtablestack;
-              while not(symtablestack.symtabletype in [globalsymtable,staticsymtable]) do
-                symtablestack:=symtablestack.next;
               single_type(p.proptype,false);
               single_type(p.proptype,false);
-              symtablestack:=oldsymtablestack;
               if (idtoken=_INDEX) then
               if (idtoken=_INDEX) then
                 begin
                 begin
                    consume(_INDEX);
                    consume(_INDEX);
@@ -375,7 +348,7 @@ implementation
          else
          else
            begin
            begin
               { do an property override }
               { do an property override }
-              overriden:=search_class_member(aclass.childof,propname);
+              overriden:=search_class_member(aclass.childof,p.name);
               if assigned(overriden) and (overriden.typ=propertysym) then
               if assigned(overriden) and (overriden.typ=propertysym) then
                 begin
                 begin
                   p.dooverride(tpropertysym(overriden));
                   p.dooverride(tpropertysym(overriden));
@@ -579,66 +552,36 @@ implementation
               p.default:=0;
               p.default:=0;
            end;
            end;
          { remove temporary procvardefs }
          { remove temporary procvardefs }
-         symtablestack:=symtablestack.next;
          readprocdef.free;
          readprocdef.free;
          writeprocdef.free;
          writeprocdef.free;
          result:=p;
          result:=p;
       end;
       end;
 
 
 
 
+     function maybe_parse_proc_directives(const tt:ttype):boolean;
+       var
+         newtype : ttypesym;
+       begin
+         result:=false;
+         { Process procvar directives before = and ; }
+         if (tt.def.deftype=procvardef) and
+            (tt.def.typesym=nil) and
+            check_proc_directive(true) then
+           begin
+              newtype:=ttypesym.create('unnamed',tt);
+              parse_var_proc_directives(tsym(newtype));
+              newtype.restype.def:=nil;
+              tt.def.typesym:=nil;
+              newtype.free;
+              result:=true;
+           end;
+       end;
+
+
     const
     const
        variantrecordlevel : longint = 0;
        variantrecordlevel : longint = 0;
 
 
-    procedure read_var_decs(options:Tvar_dec_options);
-    { reads the filed of a record into a        }
-    { symtablestack, if record=false        }
-    { variants are forbidden, so this procedure }
-    { can be used to read object fields  }
-    { if absolute is true, ABSOLUTE and file    }
-    { types are allowed                  }
-    { => the procedure is also used to read     }
-    { a sequence of variable declaration        }
-
-      procedure insert_syms(sc : tsinglelist;tt : ttype;is_threadvar : boolean; addsymopts : tsymoptions);
-      { inserts the symbols of sc in st with def as definition or sym as ttypesym, sc is disposed }
-        var
-          vs : tabstractvarsym;
-          hstaticvs : tglobalvarsym;
-        begin
-           vs:=tabstractvarsym(sc.first);
-           while assigned(vs) do
-             begin
-                vs.vartype:=tt;
-                { insert any additional hint directives }
-                vs.symoptions := vs.symoptions + addsymopts;
-                if (sp_static in current_object_option) then
-                  include(vs.symoptions,sp_static);
-                if is_threadvar then
-                  include(vs.varoptions,vo_is_thread_var);
-                { static data fields are inserted in the globalsymtable }
-                if (symtablestack.symtabletype=objectsymtable) and
-                   (sp_static in current_object_option) then
-                  begin
-                     hstaticvs:=tglobalvarsym.create('$'+lower(symtablestack.name^)+'_'+vs.name,vs_value,tt,[]);
-                     symtablestack.defowner.owner.insert(hstaticvs);
-                     insertbssdata(hstaticvs);
-                  end
-                else
-                  begin
-                    { external data is not possible here }
-                    case symtablestack.symtabletype of
-                      globalsymtable,
-                      staticsymtable :
-                        insertbssdata(tglobalvarsym(vs));
-                      recordsymtable,
-                      objectsymtable :
-                        tabstractrecordsymtable(symtablestack).insertfield(tfieldvarsym(vs),false);
-                    end;
-                  end;
-                vs:=tabstractvarsym(vs.listnext);
-             end;
-        end;
-
+    procedure read_var_decls(options:Tvar_dec_options);
 
 
       procedure read_default_value(sc : tsinglelist;tt : ttype;is_threadvar : boolean);
       procedure read_default_value(sc : tsinglelist;tt : ttype;is_threadvar : boolean);
         var
         var
@@ -650,13 +593,13 @@ implementation
              Message(parser_e_initialized_only_one_var);
              Message(parser_e_initialized_only_one_var);
           if is_threadvar then
           if is_threadvar then
              Message(parser_e_initialized_not_for_threadvar);
              Message(parser_e_initialized_not_for_threadvar);
-          if symtablestack.symtabletype=localsymtable then
+          if symtablestack.top.symtabletype=localsymtable then
             begin
             begin
               consume(_EQUAL);
               consume(_EQUAL);
               tcsym:=ttypedconstsym.createtype('$default'+vs.realname,tt,false);
               tcsym:=ttypedconstsym.createtype('$default'+vs.realname,tt,false);
               include(tcsym.symoptions,sp_internal);
               include(tcsym.symoptions,sp_internal);
               vs.defaultconstsym:=tcsym;
               vs.defaultconstsym:=tcsym;
-              symtablestack.insert(tcsym);
+              symtablestack.top.insert(tcsym);
               readtypedconst(tt,tcsym,false);
               readtypedconst(tt,tcsym,false);
               { The variable has a value assigned }
               { The variable has a value assigned }
               vs.varstate:=vs_initialised;
               vs.varstate:=vs_initialised;
@@ -665,7 +608,7 @@ implementation
             begin
             begin
               tcsym:=ttypedconstsym.createtype(vs.realname,tt,true);
               tcsym:=ttypedconstsym.createtype(vs.realname,tt,true);
               tcsym.fileinfo:=vs.fileinfo;
               tcsym.fileinfo:=vs.fileinfo;
-              symtablestack.replace(vs,tcsym);
+              symtablestack.top.replace(vs,tcsym);
               vs.free;
               vs.free;
               consume(_EQUAL);
               consume(_EQUAL);
               readtypedconst(tt,tcsym,true);
               readtypedconst(tt,tcsym,true);
@@ -679,56 +622,30 @@ implementation
          { to handle absolute }
          { to handle absolute }
          abssym : tabsolutevarsym;
          abssym : tabsolutevarsym;
          { c var }
          { c var }
-         newtype : ttypesym;
          is_dll,
          is_dll,
          hasdefaultvalue,
          hasdefaultvalue,
          is_gpc_name,is_cdecl,
          is_gpc_name,is_cdecl,
          extern_var,export_var : boolean;
          extern_var,export_var : boolean;
          old_current_object_option : tsymoptions;
          old_current_object_option : tsymoptions;
          hs,sorg,C_name,dll_name : string;
          hs,sorg,C_name,dll_name : string;
-         tt,casetype : ttype;
-         { maxsize contains the max. size of a variant }
-         { startvarrec contains the start of the variant part of a record }
-         maxsize, startvarrecsize : longint;
-         usedalign,
-         maxalignment,startvarrecalign,
-         maxpadalign, startpadalign: shortint;
+         tt : ttype;
          hp,pt : tnode;
          hp,pt : tnode;
-         fieldvs   : tfieldvarsym;
-         vs,vs2    : tabstractvarsym;
-         srsym : tsym;
-         oldsymtablestack,
-         srsymtable : tsymtable;
-         unionsymtable : trecordsymtable;
-         offset : longint;
-         uniondef : trecorddef;
-         unionsym : tfieldvarsym;
-         uniontype : ttype;
-         dummysymoptions : tsymoptions;
+         vs    : tabstractvarsym;
+         hintsymoptions : tsymoptions;
          semicolonatend,semicoloneaten: boolean;
          semicolonatend,semicoloneaten: boolean;
-{$ifdef powerpc}
-         tempdef: tdef;
-         is_first_field: boolean;
-{$endif powerpc}
       begin
       begin
-{$ifdef powerpc}
-        is_first_field := true;
-{$endif powerpc}
          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 }
-         if not(vd_object in options) then
-          current_object_option:=[sp_public];
+         current_object_option:=[sp_public];
          old_block_type:=block_type;
          old_block_type:=block_type;
          block_type:=bt_type;
          block_type:=bt_type;
          is_gpc_name:=false;
          is_gpc_name:=false;
          { Force an expected ID error message }
          { Force an expected ID error message }
          if not (token in [_ID,_CASE,_END]) then
          if not (token in [_ID,_CASE,_END]) then
-          consume(_ID);
+           consume(_ID);
          { read vars }
          { read vars }
          sc:=tsinglelist.create;
          sc:=tsinglelist.create;
-         while (token=_ID) and
-            not((vd_object in options) and
-                (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED,_STRICT])) do
+         while (token=_ID) do
            begin
            begin
              sorg:=orgpattern;
              sorg:=orgpattern;
              semicoloneaten:=false;
              semicoloneaten:=false;
@@ -738,101 +655,40 @@ implementation
              repeat
              repeat
                if (token = _ID) then
                if (token = _ID) then
                  begin
                  begin
-                   case symtablestack.symtabletype of
+                   case symtablestack.top.symtabletype of
                      localsymtable :
                      localsymtable :
                        vs:=tlocalvarsym.create(orgpattern,vs_value,generrortype,[]);
                        vs:=tlocalvarsym.create(orgpattern,vs_value,generrortype,[]);
                      staticsymtable,
                      staticsymtable,
                      globalsymtable :
                      globalsymtable :
                        vs:=tglobalvarsym.create(orgpattern,vs_value,generrortype,[]);
                        vs:=tglobalvarsym.create(orgpattern,vs_value,generrortype,[]);
-                     recordsymtable,
-                     objectsymtable :
-                       vs:=tfieldvarsym.create(orgpattern,vs_value,generrortype,[]);
                      else
                      else
                        internalerror(200411064);
                        internalerror(200411064);
                    end;
                    end;
-                   symtablestack.insert(vs);
-                   if assigned(vs.owner) then
-                     sc.insert(vs)
-                   else
-                     vs.free;
+                   sc.insert(vs);
+                   symtablestack.top.insert(vs);
                  end;
                  end;
                consume(_ID);
                consume(_ID);
              until not try_to_consume(_COMMA);
              until not try_to_consume(_COMMA);
              consume(_COLON);
              consume(_COLON);
-             if (m_gpc in aktmodeswitches) and (options=[]) and
-                (token=_ID) and (orgpattern='__asmname__') then
+
+             if (m_gpc in aktmodeswitches) and
+                (token=_ID) and
+                (orgpattern='__asmname__') then
                begin
                begin
                  consume(_ID);
                  consume(_ID);
                  C_name:=get_stringconst;
                  C_name:=get_stringconst;
                  Is_gpc_name:=true;
                  Is_gpc_name:=true;
                end;
                end;
+
              { this is needed for Delphi mode at least
              { this is needed for Delphi mode at least
                but should be OK for all modes !! (PM) }
                but should be OK for all modes !! (PM) }
              ignore_equal:=true;
              ignore_equal:=true;
-             if ((vd_record in options) or
-                 (vd_object in options)) and
-                not(df_generic in tdef(symtablestack.defowner).defoptions) and
-                not(df_specialization in tdef(symtablestack.defowner).defoptions) then
-              begin
-                { for records, don't search the recordsymtable for
-                  the symbols of the types }
-                oldsymtablestack:=symtablestack;
-                symtablestack:=symtablestack.next;
-                read_anon_type(tt,false);
-                symtablestack:=oldsymtablestack;
-              end
-             else
-              read_anon_type(tt,false);
+             read_anon_type(tt,false);
              ignore_equal:=false;
              ignore_equal:=false;
-             { Process procvar directives }
-             if (tt.def.deftype=procvardef) and
-                (tt.def.typesym=nil) and
-                check_proc_directive(true) then
-               begin
-                  newtype:=ttypesym.create('unnamed',tt);
-                  parse_var_proc_directives(tsym(newtype));
-                  semicoloneaten:=true;
-                  newtype.restype.def:=nil;
-                  tt.def.typesym:=nil;
-                  newtype.free;
-               end;
 
 
-{$ifdef powerpc}
-               { from gcc/gcc/config/rs6000/rs6000.h:
-                /* APPLE LOCAL begin Macintosh alignment 2002-1-22 ff */
-                /* Return the alignment of a struct based on the Macintosh PowerPC
-                   alignment rules.  In general the alignment of a struct is
-                   determined by the greatest alignment of its elements.  However, the
-                   PowerPC rules cause the alignment of a struct to peg at word
-                   alignment except when the first field has greater than word
-                   (32-bit) alignment, in which case the alignment is determined by
-                   the alignment of the first field.  */
-               }
-               if (target_info.system in [system_powerpc_darwin, system_powerpc_macos]) and
-                  (vd_record in options) and
-                  is_first_field and
-                  (trecordsymtable(symtablestack).usefieldalignment = -1) then
-                 begin
-                   tempdef := tt.def;
-                   while tempdef.deftype = arraydef do
-                     tempdef := tarraydef(tempdef).elementtype.def;
-                   if tempdef.deftype <> recorddef then
-                     maxpadalign := tempdef.alignment
-                   else
-                     maxpadalign := trecorddef(tempdef).padalignment;
-
-                   if (maxpadalign > 4) and
-                      (maxpadalign > trecordsymtable(symtablestack).padalignment) then
-                     trecordsymtable(symtablestack).padalignment := maxpadalign;
-                   is_first_field := false;
-                 end;
-{$endif powerpc}
-
-             { types that use init/final are not allowed in variant parts, but
-               classes are allowed }
-             if (variantrecordlevel>0) and
-                (tt.def.needs_inittable and not is_class(tt.def)) then
-               Message(parser_e_cant_use_inittable_here);
+             { Process procvar directives }
+             if maybe_parse_proc_directives(tt) then
+               semicoloneaten:=true;
 
 
              if is_gpc_name then
              if is_gpc_name then
                begin
                begin
@@ -852,9 +708,9 @@ implementation
                end;
                end;
 
 
              { check for absolute }
              { check for absolute }
-             if not symdone and (idtoken=_ABSOLUTE) and (options=[]) then
+             if not symdone and
+                try_to_consume(_ABSOLUTE) then
               begin
               begin
-                consume(_ABSOLUTE);
                 abssym:=nil;
                 abssym:=nil;
                 { only allowed for one var }
                 { only allowed for one var }
                 vs:=tabstractvarsym(sc.first);
                 vs:=tabstractvarsym(sc.first);
@@ -876,7 +732,7 @@ implementation
                    abssym.abstyp:=toasm;
                    abssym.abstyp:=toasm;
                    abssym.asmname:=stringdup(hs);
                    abssym.asmname:=stringdup(hs);
                    { replace the varsym }
                    { replace the varsym }
-                   symtablestack.replace(vs,abssym);
+                   symtablestack.top.replace(vs,abssym);
                    vs.free;
                    vs.free;
                  end
                  end
                 { address }
                 { address }
@@ -906,7 +762,7 @@ implementation
                          Message(type_e_ordinal_expr_expected);
                          Message(type_e_ordinal_expr_expected);
                     end;
                     end;
 {$endif i386}
 {$endif i386}
-                   symtablestack.replace(vs,abssym);
+                   symtablestack.top.replace(vs,abssym);
                    vs.free;
                    vs.free;
                  end
                  end
                 { variable }
                 { variable }
@@ -926,7 +782,7 @@ implementation
                        abssym.fileinfo:=vs.fileinfo;
                        abssym.fileinfo:=vs.fileinfo;
                        abssym.abstyp:=tovar;
                        abssym.abstyp:=tovar;
                        abssym.ref:=node_to_symlist(pt);
                        abssym.ref:=node_to_symlist(pt);
-                       symtablestack.replace(vs,abssym);
+                       symtablestack.top.replace(vs,abssym);
                        vs.free;
                        vs.free;
                      end
                      end
                     else
                     else
@@ -935,55 +791,34 @@ implementation
                 if assigned(abssym) then
                 if assigned(abssym) then
                  begin
                  begin
                    { try to consume the hint directives with absolute symbols }
                    { try to consume the hint directives with absolute symbols }
-                   dummysymoptions:=[];
-                   try_consume_hintdirective(dummysymoptions);
-                   abssym.symoptions := abssym.symoptions + dummysymoptions;
+                   hintsymoptions:=[];
+                   try_consume_hintdirective(hintsymoptions);
+                   abssym.symoptions := abssym.symoptions + hintsymoptions;
                  end;
                  end;
                 pt.free;
                 pt.free;
                 symdone:=true;
                 symdone:=true;
               end;
               end;
 
 
-             { Process procvar directives before = and ; }
-             if (tt.def.deftype=procvardef) and
-                (tt.def.typesym=nil) and
-                check_proc_directive(true) then
-               begin
-                  newtype:=ttypesym.create('unnamed',tt);
-                  parse_var_proc_directives(tsym(newtype));
-                  newtype.restype.def:=nil;
-                  tt.def.typesym:=nil;
-                  newtype.free;
-               end;
-
              { try to parse the hint directives }
              { try to parse the hint directives }
-             dummysymoptions:=[];
-             try_consume_hintdirective(dummysymoptions);
+             hintsymoptions:=[];
+             try_consume_hintdirective(hintsymoptions);
 
 
-             { Records and objects can't have default values }
-             if options*[vd_record,vd_object]<>[] then
+             { Handling of Delphi typed const = initialized vars }
+             if (token=_EQUAL) and
+                not(m_tp7 in aktmodeswitches) and
+                (symtablestack.top.symtabletype<>parasymtable) then
                begin
                begin
-                 { for a record there doesn't need to be a ; before the END or )    }
-                 if not(token in [_END,_RKLAMMER]) and
-                    not(semicoloneaten) then
-                   consume(_SEMICOLON);
+                 { Add calling convention for procvar }
+                 if (tt.def.deftype=procvardef) and
+                    (tt.def.typesym=nil) then
+                   handle_calling_convention(tprocvardef(tt.def));
+                 read_default_value(sc,tt,vd_threadvar in options);
+                 consume(_SEMICOLON);
+                 { for locals we've created typedconstsym with a different name }
+                 if symtablestack.top.symtabletype<>localsymtable then
+                   symdone:=true;
+                 hasdefaultvalue:=true;
                end
                end
-             else
-             { Handling of Delphi typed const = initialized vars }
-               if (token=_EQUAL) and
-                  not(m_tp7 in aktmodeswitches) and
-                  (symtablestack.symtabletype<>parasymtable) then
-                 begin
-                   { Add calling convention for procvar }
-                   if (tt.def.deftype=procvardef) and
-                      (tt.def.typesym=nil) then
-                     handle_calling_convention(tprocvardef(tt.def));
-                   read_default_value(sc,tt,vd_threadvar in options);
-                   consume(_SEMICOLON);
-                   { for locals we've created typedconstsym with a different name }
-                   if symtablestack.symtabletype<>localsymtable then
-                     symdone:=true;
-                   hasdefaultvalue:=true;
-                 end
              else
              else
                begin
                begin
                  if not(semicoloneaten) then
                  if not(semicoloneaten) then
@@ -996,20 +831,13 @@ implementation
                 (tt.def.typesym=nil) then
                 (tt.def.typesym=nil) then
                begin
                begin
                  { Parse procvar directives after ; }
                  { Parse procvar directives after ; }
-                 if check_proc_directive(true) then
-                   begin
-                     newtype:=ttypesym.create('unnamed',tt);
-                     parse_var_proc_directives(tsym(newtype));
-                     newtype.restype.def:=nil;
-                     tt.def.typesym:=nil;
-                     newtype.free;
-                   end;
+                 maybe_parse_proc_directives(tt);
                  { Add calling convention for procvar }
                  { Add calling convention for procvar }
                  handle_calling_convention(tprocvardef(tt.def));
                  handle_calling_convention(tprocvardef(tt.def));
                  { Handling of Delphi typed const = initialized vars }
                  { Handling of Delphi typed const = initialized vars }
-                 if (token=_EQUAL) and (options*[vd_record,vd_object]=[]) and
+                 if (token=_EQUAL) and
                     not(m_tp7 in aktmodeswitches) and
                     not(m_tp7 in aktmodeswitches) and
-                    (symtablestack.symtabletype<>parasymtable) then
+                    (symtablestack.top.symtabletype<>parasymtable) then
                    begin
                    begin
                      read_default_value(sc,tt,vd_threadvar in options);
                      read_default_value(sc,tt,vd_threadvar in options);
                      consume(_SEMICOLON);
                      consume(_SEMICOLON);
@@ -1019,7 +847,7 @@ implementation
                end;
                end;
 
 
              { Check for EXTERNAL etc directives or, in macpas, if cs_external_var is set}
              { Check for EXTERNAL etc directives or, in macpas, if cs_external_var is set}
-             if not symdone and (options=[]) then
+             if not symdone then
               begin
               begin
                 if (
                 if (
                      (token=_ID) and
                      (token=_ID) and
@@ -1037,7 +865,7 @@ implementation
                      Message(parser_e_absolute_only_one_var);
                      Message(parser_e_absolute_only_one_var);
                    { set type of the var }
                    { set type of the var }
                    vs.vartype:=tt;
                    vs.vartype:=tt;
-                   vs.symoptions := vs.symoptions + dummysymoptions;
+                   vs.symoptions := vs.symoptions + hintsymoptions;
                    { defaults }
                    { defaults }
                    is_dll:=false;
                    is_dll:=false;
                    is_cdecl:=false;
                    is_cdecl:=false;
@@ -1046,17 +874,15 @@ implementation
                    C_name:=sorg;
                    C_name:=sorg;
                    semicolonatend:= false;
                    semicolonatend:= false;
                    { cdecl }
                    { cdecl }
-                   if idtoken=_CVAR then
+                   if try_to_consume(_CVAR) then
                     begin
                     begin
-                      consume(_CVAR);
                       consume(_SEMICOLON);
                       consume(_SEMICOLON);
                       is_cdecl:=true;
                       is_cdecl:=true;
                       C_name:=target_info.Cprefix+sorg;
                       C_name:=target_info.Cprefix+sorg;
                     end;
                     end;
                    { external }
                    { external }
-                   if idtoken=_EXTERNAL then
+                   if try_to_consume(_EXTERNAL) then
                     begin
                     begin
-                      consume(_EXTERNAL);
                       extern_var:=true;
                       extern_var:=true;
                       semicolonatend:= true;
                       semicolonatend:= true;
                     end;
                     end;
@@ -1156,78 +982,251 @@ implementation
                  end;
                  end;
               end;
               end;
 
 
-             { Check for STATIC directive }
-             if not symdone and (vd_object in options) and
-               (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
-                  begin
-                    include(current_object_option,sp_static);
-                    consume(_STATIC);
-                    consume(_SEMICOLON);
-                  end;
-
              { insert it in the symtable, if not done yet }
              { insert it in the symtable, if not done yet }
              if not symdone then
              if not symdone then
                begin
                begin
-                  { save object option, because we can turn of the sp_published }
-                  if (sp_published in current_object_option) and
-                    not(is_class(tt.def)) then
-                   begin
-                     Message(parser_e_cant_publish_that);
-                     exclude(current_object_option,sp_published);
-                     { recover by changing access type to public }
-                     vs2:=tabstractvarsym(sc.first);
-                     while assigned (vs2) do
-                       begin
-                         exclude(vs2.symoptions,sp_published);
-                         include(vs2.symoptions,sp_public);
-                         vs2:=tabstractvarsym(vs2.listnext);
-                       end;
-                   end
-                  else
-                   if (sp_published in current_object_option) and
-                      not(oo_can_have_published in tobjectdef(tt.def).objectoptions) then
+                  vs:=tabstractvarsym(sc.first);
+                  while assigned(vs) do
                     begin
                     begin
-                      Message(parser_e_only_publishable_classes_can__be_published);
-                      exclude(current_object_option,sp_published);
+                       vs.vartype:=tt;
+                       { insert any additional hint directives }
+                       vs.symoptions := vs.symoptions + hintsymoptions;
+                       if vd_threadvar in options then
+                         include(vs.varoptions,vo_is_thread_var);
+                       { static data fields are inserted in the globalsymtable }
+                       if vs.typ=globalvarsym then
+                         insertbssdata(tglobalvarsym(vs));
+                       vs:=tabstractvarsym(vs.listnext);
                     end;
                     end;
-                  insert_syms(sc,tt,vd_threadvar in options,dummysymoptions);
-                  current_object_option:=old_current_object_option;
                end;
                end;
+           end;
+         block_type:=old_block_type;
+         current_object_option:=old_current_object_option;
+         { free the list }
+         sc.free;
+      end;
+
+
+    procedure read_record_fields(options:Tvar_dec_options);
+      var
+         sc : tsinglelist;
+         old_block_type : tblock_type;
+         old_current_object_option : tsymoptions;
+         hs,sorg : string;
+         tt,casetype : ttype;
+         { maxsize contains the max. size of a variant }
+         { startvarrec contains the start of the variant part of a record }
+         maxsize, startvarrecsize : longint;
+         usedalign,
+         maxalignment,startvarrecalign,
+         maxpadalign, startpadalign: shortint;
+         pt : tnode;
+         fieldvs   : tfieldvarsym;
+         hstaticvs : tglobalvarsym;
+         vs    : tabstractvarsym;
+         srsym : tsym;
+         srsymtable : tsymtable;
+         recst : tabstractrecordsymtable;
+         unionsymtable : trecordsymtable;
+         offset : longint;
+         uniondef : trecorddef;
+         unionsym : tfieldvarsym;
+         uniontype : ttype;
+         hintsymoptions : tsymoptions;
+         semicoloneaten: boolean;
+{$ifdef powerpc}
+         tempdef: tdef;
+         is_first_field: boolean;
+{$endif powerpc}
+      begin
+         recst:=tabstractrecordsymtable(symtablestack.top);
+{$ifdef powerpc}
+         is_first_field := true;
+{$endif powerpc}
+         old_current_object_option:=current_object_option;
+         { all variables are public if not in a object declaration }
+         if not(vd_object in options) then
+          current_object_option:=[sp_public];
+         old_block_type:=block_type;
+         block_type:=bt_type;
+         { Force an expected ID error message }
+         if not (token in [_ID,_CASE,_END]) then
+          consume(_ID);
+         { read vars }
+         sc:=tsinglelist.create;
+         while (token=_ID) and
+            not((vd_object in options) and
+                (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED,_STRICT])) do
+           begin
+             sorg:=orgpattern;
+             semicoloneaten:=false;
+             sc.reset;
+             repeat
+               if try_to_consume(_ID) then
+                 begin
+                   vs:=tfieldvarsym.create(orgpattern,vs_value,generrortype,[]);
+                   sc.insert(vs)
+                 end;
+             until not try_to_consume(_COMMA);
+             consume(_COLON);
+
+             { Don't search in the recordsymtable for types }
+             if (df_generic in tdef(recst.defowner).defoptions) or
+                (df_specialization in tdef(recst.defowner).defoptions) then
+               symtablestack.pop(recst);
+             ignore_equal:=true;
+             read_anon_type(tt,false);
+             ignore_equal:=false;
+             if (df_generic in tdef(recst.defowner).defoptions) or
+                (df_specialization in tdef(recst.defowner).defoptions) then
+               symtablestack.push(recst);
+
+             fieldvs:=tfieldvarsym(sc.first);
+             while assigned (fieldvs) do
+               begin
+                 symtablestack.top.insert(fieldvs);
+                 fieldvs:=tfieldvarsym(fieldvs.listnext);
+               end;
+
+             { Process procvar directives }
+             if maybe_parse_proc_directives(tt) then
+               semicoloneaten:=true;
+
+{$ifdef powerpc}
+             { from gcc/gcc/config/rs6000/rs6000.h:
+              /* APPLE LOCAL begin Macintosh alignment 2002-1-22 ff */
+              /* Return the alignment of a struct based on the Macintosh PowerPC
+                 alignment rules.  In general the alignment of a struct is
+                 determined by the greatest alignment of its elements.  However, the
+                 PowerPC rules cause the alignment of a struct to peg at word
+                 alignment except when the first field has greater than word
+                 (32-bit) alignment, in which case the alignment is determined by
+                 the alignment of the first field.  */
+             }
+             if (target_info.system in [system_powerpc_darwin, system_powerpc_macos]) and
+                is_first_field and
+                (trecordsymtable(symtablestack).usefieldalignment = -1) then
+               begin
+                 tempdef := tt.def;
+                 while tempdef.deftype = arraydef do
+                   tempdef := tarraydef(tempdef).elementtype.def;
+                 if tempdef.deftype <> recorddef then
+                   maxpadalign := tempdef.alignment
+                 else
+                   maxpadalign := trecorddef(tempdef).padalignment;
+
+                 if (maxpadalign > 4) and
+                    (maxpadalign > trecordsymtable(symtablestack).padalignment) then
+                   trecordsymtable(symtablestack).padalignment := maxpadalign;
+                 is_first_field := false;
+               end;
+{$endif powerpc}
+
+             { types that use init/final are not allowed in variant parts, but
+               classes are allowed }
+             if (variantrecordlevel>0) and
+                (tt.def.needs_inittable and not is_class(tt.def)) then
+               Message(parser_e_cant_use_inittable_here);
+
+             { try to parse the hint directives }
+             hintsymoptions:=[];
+             try_consume_hintdirective(hintsymoptions);
+
+             { Records and objects can't have default values }
+             { for a record there doesn't need to be a ; before the END or )    }
+             if not(token in [_END,_RKLAMMER]) and
+                not(semicoloneaten) then
+               consume(_SEMICOLON);
+
+             { Parse procvar directives after ; }
+             maybe_parse_proc_directives(tt);
 
 
+             { Add calling convention for procvar }
+             if (tt.def.deftype=procvardef) and
+                (tt.def.typesym=nil) then
+               handle_calling_convention(tprocvardef(tt.def));
+
+             { Check for STATIC directive }
+             if (vd_object in options) and
+                (cs_static_keyword in aktmoduleswitches) and
+                (try_to_consume(_STATIC)) then
+               begin
+                 include(current_object_option,sp_static);
+                 consume(_SEMICOLON);
+               end;
+
+             if (sp_published in current_object_option) and
+                not(is_class(tt.def)) then
+               begin
+                 Message(parser_e_cant_publish_that);
+                 exclude(current_object_option,sp_published);
+                 { recover by changing access type to public }
+                 fieldvs:=tfieldvarsym(sc.first);
+                 while assigned (fieldvs) do
+                   begin
+                     exclude(fieldvs.symoptions,sp_published);
+                     include(fieldvs.symoptions,sp_public);
+                     fieldvs:=tfieldvarsym(fieldvs.listnext);
+                   end;
+               end
+             else
+              if (sp_published in current_object_option) and
+                 not(oo_can_have_published in tobjectdef(tt.def).objectoptions) then
+               begin
+                 Message(parser_e_only_publishable_classes_can__be_published);
+                 exclude(current_object_option,sp_published);
+               end;
+
+             { update variable options }
+             fieldvs:=tfieldvarsym(sc.first);
+             while assigned(fieldvs) do
+               begin
+                  fieldvs.vartype:=tt;
+                  { insert any additional hint directives }
+                  fieldvs.symoptions := fieldvs.symoptions + hintsymoptions;
+                  if (sp_static in current_object_option) then
+                    include(fieldvs.symoptions,sp_static);
+                  { static data fields are inserted in the globalsymtable }
+                  if (sp_static in current_object_option) then
+                    begin
+                       hstaticvs:=tglobalvarsym.create('$'+lower(symtablestack.top.name^)+'_'+fieldvs.name,vs_value,tt,[]);
+                       recst.defowner.owner.insert(hstaticvs);
+                       insertbssdata(hstaticvs);
+                    end
+                  else
+                    recst.addfield(fieldvs);
+                  fieldvs:=tfieldvarsym(fieldvs.listnext);
+               end;
+
+             { restore current_object_option, it can be changed for
+               publishing or static }
+             current_object_option:=old_current_object_option;
            end;
            end;
 
 
          { Check for Case }
          { Check for Case }
-         if (vd_record in options) and (token=_CASE) then
+         if (vd_record in options) and
+            try_to_consume(_CASE) then
            begin
            begin
               maxsize:=0;
               maxsize:=0;
               maxalignment:=0;
               maxalignment:=0;
               maxpadalign:=0;
               maxpadalign:=0;
-              consume(_CASE);
+              { including a field declaration? }
+              fieldvs:=nil;
               sorg:=orgpattern;
               sorg:=orgpattern;
               hs:=pattern;
               hs:=pattern;
               searchsym(hs,srsym,srsymtable);
               searchsym(hs,srsym,srsymtable);
-              { may be only a type: }
-              if assigned(srsym) and (srsym.typ in [typesym,unitsym]) then
-               begin
-                 { for records, don't search the recordsymtable for
-                   the symbols of the types }
-                 oldsymtablestack:=symtablestack;
-                 symtablestack:=symtablestack.next;
-                 read_anon_type(casetype,true);
-                 symtablestack:=oldsymtablestack;
-               end
-              else
+              if not(assigned(srsym) and (srsym.typ in [typesym,unitsym])) then
                 begin
                 begin
                   consume(_ID);
                   consume(_ID);
                   consume(_COLON);
                   consume(_COLON);
-                  { for records, don't search the recordsymtable for
-                    the symbols of the types }
-                  oldsymtablestack:=symtablestack;
-                  symtablestack:=symtablestack.next;
-                  read_anon_type(casetype,true);
-                  symtablestack:=oldsymtablestack;
-                  fieldvs:=tfieldvarsym.create(sorg,vs_value,casetype,[]);
-                  tabstractrecordsymtable(symtablestack).insertfield(fieldvs,true);
+                  fieldvs:=tfieldvarsym.create(sorg,vs_value,generrortype,[]);
+                  symtablestack.top.insert(fieldvs);
+                end;
+              read_anon_type(casetype,true);
+              if assigned(fieldvs) then
+                begin
+                  fieldvs.vartype:=casetype;
+                  recst.addfield(fieldvs);
                 end;
                 end;
               if not(is_ordinal(casetype.def))
               if not(is_ordinal(casetype.def))
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
@@ -1236,18 +1235,14 @@ implementation
                  then
                  then
                 Message(type_e_ordinal_expr_expected);
                 Message(type_e_ordinal_expr_expected);
               consume(_OF);
               consume(_OF);
+
               UnionSymtable:=trecordsymtable.create(aktpackrecords);
               UnionSymtable:=trecordsymtable.create(aktpackrecords);
-              Unionsymtable.next:=symtablestack;
-              registerdef:=false;
               UnionDef:=trecorddef.create(unionsymtable);
               UnionDef:=trecorddef.create(unionsymtable);
               uniondef.isunion:=true;
               uniondef.isunion:=true;
-              if assigned(symtablestack.defowner) then
-                Uniondef.owner:=symtablestack.defowner.owner;
-              registerdef:=true;
               startvarrecsize:=UnionSymtable.datasize;
               startvarrecsize:=UnionSymtable.datasize;
               startvarrecalign:=UnionSymtable.fieldalignment;
               startvarrecalign:=UnionSymtable.fieldalignment;
               startpadalign:=Unionsymtable.padalignment;
               startpadalign:=Unionsymtable.padalignment;
-              symtablestack:=UnionSymtable;
+              symtablestack.push(UnionSymtable);
               repeat
               repeat
                 repeat
                 repeat
                   pt:=comp_expr(true);
                   pt:=comp_expr(true);
@@ -1255,16 +1250,16 @@ implementation
                     Message(parser_e_illegal_expression);
                     Message(parser_e_illegal_expression);
                   pt.free;
                   pt.free;
                   if token=_COMMA then
                   if token=_COMMA then
-                   consume(_COMMA)
+                    consume(_COMMA)
                   else
                   else
-                   break;
+                    break;
                 until false;
                 until false;
                 consume(_COLON);
                 consume(_COLON);
                 { read the vars }
                 { read the vars }
                 consume(_LKLAMMER);
                 consume(_LKLAMMER);
                 inc(variantrecordlevel);
                 inc(variantrecordlevel);
                 if token<>_RKLAMMER then
                 if token<>_RKLAMMER then
-                  read_var_decs([vd_record]);
+                  read_record_fields([vd_record]);
                 dec(variantrecordlevel);
                 dec(variantrecordlevel);
                 consume(_RKLAMMER);
                 consume(_RKLAMMER);
                 { calculates maximal variant size }
                 { calculates maximal variant size }
@@ -1280,38 +1275,36 @@ implementation
                 else
                 else
                   break;
                   break;
               until (token=_END) or (token=_RKLAMMER);
               until (token=_END) or (token=_RKLAMMER);
+              symtablestack.pop(UnionSymtable);
               { at last set the record size to that of the biggest variant }
               { at last set the record size to that of the biggest variant }
               unionsymtable.datasize:=maxsize;
               unionsymtable.datasize:=maxsize;
               unionsymtable.fieldalignment:=maxalignment;
               unionsymtable.fieldalignment:=maxalignment;
               uniontype.def:=uniondef;
               uniontype.def:=uniondef;
               uniontype.sym:=nil;
               uniontype.sym:=nil;
               UnionSym:=tfieldvarsym.create('$case',vs_value,uniontype,[]);
               UnionSym:=tfieldvarsym.create('$case',vs_value,uniontype,[]);
-              symtablestack:=symtablestack.next;
               unionsymtable.addalignmentpadding;
               unionsymtable.addalignmentpadding;
 {$ifdef powerpc}
 {$ifdef powerpc}
               { parent inherits the alignment padding if the variant is the first "field" of the parent record/variant }
               { parent inherits the alignment padding if the variant is the first "field" of the parent record/variant }
               if (target_info.system in [system_powerpc_darwin, system_powerpc_macos]) and
               if (target_info.system in [system_powerpc_darwin, system_powerpc_macos]) and
                  is_first_field and
                  is_first_field and
-                 (trecordsymtable(symtablestack).usefieldalignment = -1) and
-                 (maxpadalign > trecordsymtable(symtablestack).padalignment) then
-                trecordsymtable(symtablestack).padalignment:=maxpadalign;
+                 (recst.usefieldalignment = -1) and
+                 (maxpadalign > recst.padalignment) then
+                recst.padalignment:=maxpadalign;
 {$endif powerpc}
 {$endif powerpc}
               { Align the offset where the union symtable is added }
               { Align the offset where the union symtable is added }
-              if (trecordsymtable(symtablestack).usefieldalignment=-1) then
+              if (recst.usefieldalignment=-1) then
                 usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
                 usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
               else
               else
                 usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.recordalignmax);
                 usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.recordalignmax);
 
 
-              offset:=align(trecordsymtable(symtablestack).datasize,usedalign);
-              trecordsymtable(symtablestack).datasize:=offset+unionsymtable.datasize;
+              offset:=align(recst.datasize,usedalign);
+              recst.datasize:=offset+unionsymtable.datasize;
 
 
-              if unionsymtable.recordalignment>trecordsymtable(symtablestack).fieldalignment then
-                trecordsymtable(symtablestack).fieldalignment:=unionsymtable.recordalignment;
+              if unionsymtable.recordalignment>recst.fieldalignment then
+                recst.fieldalignment:=unionsymtable.recordalignment;
 
 
-              trecordsymtable(symtablestack).insertunionst(Unionsymtable,offset);
-              Unionsym.owner:=nil;
+              trecordsymtable(recst).insertunionst(Unionsymtable,offset);
               unionsym.free;
               unionsym.free;
-              uniondef.owner:=nil;
               uniondef.free;
               uniondef.free;
            end;
            end;
          block_type:=old_block_type;
          block_type:=old_block_type;

+ 91 - 94
compiler/pexpr.pas

@@ -50,12 +50,7 @@ interface
     { the ID token has to be consumed before calling this function }
     { the ID token has to be consumed before calling this function }
     procedure do_member_read(classh:tobjectdef;getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callflags:tcallnodeflags);
     procedure do_member_read(classh:tobjectdef;getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callflags:tcallnodeflags);
 
 
-{$ifdef int64funcresok}
     function get_intconst:TConstExprInt;
     function get_intconst:TConstExprInt;
-{$else int64funcresok}
-    function get_intconst:longint;
-{$endif int64funcresok}
-
     function get_stringconst:string;
     function get_stringconst:string;
 
 
 implementation
 implementation
@@ -328,7 +323,7 @@ implementation
        end;
        end;
 
 
 
 
-     function statement_syssym(l : longint) : tnode;
+     function statement_syssym(l : byte) : tnode;
       var
       var
         p1,p2,paras  : tnode;
         p1,p2,paras  : tnode;
         err,
         err,
@@ -1159,7 +1154,7 @@ implementation
                         begin
                         begin
                            static_name:=lower(sym.owner.name^)+'_'+sym.name;
                            static_name:=lower(sym.owner.name^)+'_'+sym.name;
                            searchsym(static_name,sym,srsymtable);
                            searchsym(static_name,sym,srsymtable);
-			   if assigned(sym) then
+                           if assigned(sym) then
                              check_hints(sym,sym.symoptions);
                              check_hints(sym,sym.symoptions);
                            p1.free;
                            p1.free;
                            p1:=cloadnode.create(sym,srsymtable);
                            p1:=cloadnode.create(sym,srsymtable);
@@ -1203,7 +1198,7 @@ implementation
            srsym : tsym;
            srsym : tsym;
            possible_error : boolean;
            possible_error : boolean;
            srsymtable : tsymtable;
            srsymtable : tsymtable;
-           storesymtablestack : tsymtable;
+           hdef  : tdef;
            htype : ttype;
            htype : ttype;
            static_name : string;
            static_name : string;
          begin
          begin
@@ -1226,6 +1221,17 @@ implementation
                )
                )
               ) then
               ) then
             begin
             begin
+              hdef:=tdef(srsym.owner.defowner);
+              if assigned(hdef) and
+                 (hdef.deftype=procdef) then
+                srsym:=tprocdef(hdef).procsym
+              else
+                begin
+                  Message(parser_e_illegal_expression);
+                  srsym:=generrorsym;
+                end;
+              srsymtable:=srsym.owner;
+{
               storesymtablestack:=symtablestack;
               storesymtablestack:=symtablestack;
               symtablestack:=srsym.owner.next;
               symtablestack:=srsym.owner.next;
               searchsym(srsym.name,srsym,srsymtable);
               searchsym(srsym.name,srsym,srsymtable);
@@ -1234,6 +1240,7 @@ implementation
               if (srsym.typ<>procsym) then
               if (srsym.typ<>procsym) then
                Message(parser_e_illegal_expression);
                Message(parser_e_illegal_expression);
               symtablestack:=storesymtablestack;
               symtablestack:=storesymtablestack;
+}
             end;
             end;
 
 
             begin
             begin
@@ -1260,7 +1267,7 @@ implementation
                      begin
                      begin
                        static_name:=lower(srsym.owner.name^)+'_'+srsym.name;
                        static_name:=lower(srsym.owner.name^)+'_'+srsym.name;
                        searchsym(static_name,srsym,srsymtable);
                        searchsym(static_name,srsym,srsymtable);
-		       if assigned(srsym) then
+                       if assigned(srsym) then
                          check_hints(srsym,srsym.symoptions);
                          check_hints(srsym,srsym.symoptions);
                      end
                      end
                     else
                     else
@@ -1334,8 +1341,8 @@ implementation
                                begin
                                begin
                                  p1:=ctypenode.create(htype);
                                  p1:=ctypenode.create(htype);
                                  { search also in inherited methods }
                                  { search also in inherited methods }
-                                 srsym:=searchsym_in_class(tobjectdef(htype.def),pattern);
-				 if assigned(srsym) then
+                                 searchsym_in_class(tobjectdef(htype.def),pattern,srsym,srsymtable);
+                                 if assigned(srsym) then
                                    check_hints(srsym,srsym.symoptions);
                                    check_hints(srsym,srsym.symoptions);
                                  consume(_ID);
                                  consume(_ID);
                                  do_member_read(tobjectdef(htype.def),false,srsym,p1,again,[]);
                                  do_member_read(tobjectdef(htype.def),false,srsym,p1,again,[]);
@@ -1355,17 +1362,17 @@ implementation
                               { defined in an anchestor class              }
                               { defined in an anchestor class              }
                               srsym:=search_class_member(tobjectdef(htype.def),pattern);
                               srsym:=search_class_member(tobjectdef(htype.def),pattern);
                               if assigned(srsym) then
                               if assigned(srsym) then
-			        begin
+                                begin
                                   check_hints(srsym,srsym.symoptions);
                                   check_hints(srsym,srsym.symoptions);
-  				  if not(getaddr) and not(sp_static in srsym.symoptions) then
+                                  if not(getaddr) and not(sp_static in srsym.symoptions) then
                                     Message(sym_e_only_static_in_static)
                                     Message(sym_e_only_static_in_static)
                                   else
                                   else
                                     begin
                                     begin
                                       consume(_ID);
                                       consume(_ID);
                                       do_member_read(tobjectdef(htype.def),getaddr,srsym,p1,again,[]);
                                       do_member_read(tobjectdef(htype.def),getaddr,srsym,p1,again,[]);
-				    end;  
+                                    end;
                                 end
                                 end
-			      else	
+                              else
                                 Message1(sym_e_id_no_member,orgpattern);
                                 Message1(sym_e_id_no_member,orgpattern);
                             end;
                             end;
                          end
                          end
@@ -1389,11 +1396,11 @@ implementation
                                    consume(_ID);
                                    consume(_ID);
                                    do_member_read(tobjectdef(htype.def),getaddr,srsym,p1,again,[]);
                                    do_member_read(tobjectdef(htype.def),getaddr,srsym,p1,again,[]);
                                  end
                                  end
-				else 
-				 begin
+                                else
+                                 begin
                                    Message1(sym_e_id_no_member,orgpattern);
                                    Message1(sym_e_id_no_member,orgpattern);
                                    consume(_ID);
                                    consume(_ID);
-				 end;
+                                 end;
                               end
                               end
                              else
                              else
                               begin
                               begin
@@ -1678,9 +1685,10 @@ implementation
         var
         var
           store_static : boolean;
           store_static : boolean;
           protsym  : tpropertysym;
           protsym  : tpropertysym;
-          p2,p3 : tnode;
-          hsym  : tsym;
-          classh : tobjectdef;
+          p2,p3  : tnode;
+          srsym  : tsym;
+          srsymtable : tsymtable;
+          classh     : tobjectdef;
 
 
         label
         label
           skipreckklammercheck;
           skipreckklammercheck;
@@ -1835,13 +1843,13 @@ implementation
                         begin
                         begin
                           if token=_ID then
                           if token=_ID then
                             begin
                             begin
-                              hsym:=tsym(trecorddef(p1.resulttype.def).symtable.search(pattern));
-                              if assigned(hsym) and
-                                 (hsym.typ=fieldvarsym) then
-				begin 
-                                  check_hints(hsym,hsym.symoptions);
-                                  p1:=csubscriptnode.create(hsym,p1)
-				end  
+                              srsym:=tsym(trecorddef(p1.resulttype.def).symtable.search(pattern));
+                              if assigned(srsym) and
+                                 (srsym.typ=fieldvarsym) then
+                                begin
+                                  check_hints(srsym,srsym.symoptions);
+                                  p1:=csubscriptnode.create(srsym,p1)
+                                end
                               else
                               else
                                 begin
                                 begin
                                   Message1(sym_e_illegal_field,pattern);
                                   Message1(sym_e_illegal_field,pattern);
@@ -1859,20 +1867,20 @@ implementation
                            if token=_ID then
                            if token=_ID then
                              begin
                              begin
                                classh:=tobjectdef(tclassrefdef(p1.resulttype.def).pointertype.def);
                                classh:=tobjectdef(tclassrefdef(p1.resulttype.def).pointertype.def);
-                               hsym:=searchsym_in_class(classh,pattern);
-                               if hsym=nil then
+                               searchsym_in_class(classh,pattern,srsym,srsymtable);
+                               if assigned(srsym) then
                                  begin
                                  begin
-                                   Message1(sym_e_id_no_member,orgpattern);
-                                   p1.destroy;
-                                   p1:=cerrornode.create;
-                                   { try to clean up }
+                                   check_hints(srsym,srsym.symoptions);
                                    consume(_ID);
                                    consume(_ID);
+                                   do_member_read(classh,getaddr,srsym,p1,again,[]);
                                  end
                                  end
                                else
                                else
                                  begin
                                  begin
-                                   check_hints(hsym,hsym.symoptions);
+                                   Message1(sym_e_id_no_member,orgpattern);
+                                   p1.destroy;
+                                   p1:=cerrornode.create;
+                                   { try to clean up }
                                    consume(_ID);
                                    consume(_ID);
-                                   do_member_read(classh,getaddr,hsym,p1,again,[]);
                                  end;
                                  end;
                              end
                              end
                            else { Error }
                            else { Error }
@@ -1885,21 +1893,21 @@ implementation
                                store_static:=allow_only_static;
                                store_static:=allow_only_static;
                                allow_only_static:=false;
                                allow_only_static:=false;
                                classh:=tobjectdef(p1.resulttype.def);
                                classh:=tobjectdef(p1.resulttype.def);
-                               hsym:=searchsym_in_class(classh,pattern);
+                               searchsym_in_class(classh,pattern,srsym,srsymtable);
                                allow_only_static:=store_static;
                                allow_only_static:=store_static;
-                               if hsym=nil then
+                               if assigned(srsym) then
                                  begin
                                  begin
-                                    Message1(sym_e_id_no_member,orgpattern);
-                                    p1.destroy;
-                                    p1:=cerrornode.create;
-                                    { try to clean up }
+                                    check_hints(srsym,srsym.symoptions);
                                     consume(_ID);
                                     consume(_ID);
+                                    do_member_read(classh,getaddr,srsym,p1,again,[]);
                                  end
                                  end
                                else
                                else
                                  begin
                                  begin
-                                    check_hints(hsym,hsym.symoptions);
+                                    Message1(sym_e_id_no_member,orgpattern);
+                                    p1.destroy;
+                                    p1:=cerrornode.create;
+                                    { try to clean up }
                                     consume(_ID);
                                     consume(_ID);
-                                    do_member_read(classh,getaddr,hsym,p1,again,[]);
                                  end;
                                  end;
                              end
                              end
                            else { Error }
                            else { Error }
@@ -1964,39 +1972,24 @@ implementation
       ---------------------------------------------}
       ---------------------------------------------}
 
 
       var
       var
-         l        : longint;
-         ic       : int64;
-         qc       : qword;
+         l          : longint;
+         ic         : int64;
+         qc         : qword;
 {$ifndef cpu64}
 {$ifndef cpu64}
-         card     : cardinal;
+         card       : cardinal;
 {$endif cpu64}
 {$endif cpu64}
          oldp1,
          oldp1,
-         p1       : tnode;
-         code     : integer;
-         again    : boolean;
-         sym      : tsym;
-         pd       : tprocdef;
-         classh   : tobjectdef;
-         d        : bestreal;
-         hs,hsorg : string;
-         htype    : ttype;
-         filepos  : tfileposinfo;
-
-         {---------------------------------------------
-                           Helpers
-         ---------------------------------------------}
-
-        procedure check_tokenpos;
-        begin
-          if (p1<>oldp1) then
-           begin
-             if assigned(p1) then
-               p1.fileinfo:=filepos;
-             oldp1:=p1;
-             filepos:=akttokenpos;
-           end;
-        end;
-
+         p1         : tnode;
+         code       : integer;
+         again      : boolean;
+         srsym      : tsym;
+         srsymtable : tsymtable;
+         pd         : tprocdef;
+         classh     : tobjectdef;
+         d          : bestreal;
+         hs,hsorg   : string;
+         htype      : ttype;
+         filepos    : tfileposinfo;
       begin
       begin
         oldp1:=nil;
         oldp1:=nil;
         p1:=nil;
         p1:=nil;
@@ -2017,10 +2010,16 @@ implementation
              end
              end
            else
            else
              factor_read_id(p1,again);
              factor_read_id(p1,again);
+
            if again then
            if again then
             begin
             begin
-              check_tokenpos;
-
+              if (p1<>oldp1) then
+               begin
+                 if assigned(p1) then
+                   p1.fileinfo:=filepos;
+                 oldp1:=p1;
+                 filepos:=akttokenpos;
+               end;
               { handle post fix operators }
               { handle post fix operators }
               postfixoperators(p1,again);
               postfixoperators(p1,again);
             end;
             end;
@@ -2051,12 +2050,12 @@ implementation
                        number or string }
                        number or string }
                      pd:=tprocsym(current_procinfo.procdef.procsym).first_procdef;
                      pd:=tprocsym(current_procinfo.procdef.procsym).first_procdef;
                      if (po_msgint in pd.procoptions) then
                      if (po_msgint in pd.procoptions) then
-                      sym:=searchsym_in_class_by_msgint(classh,pd.messageinf.i)
+                       searchsym_in_class_by_msgint(classh,pd.messageinf.i,srsym,srsymtable)
                      else
                      else
                       if (po_msgstr in pd.procoptions) then
                       if (po_msgstr in pd.procoptions) then
-                       sym:=searchsym_in_class_by_msgstr(classh,pd.messageinf.str)
+                        searchsym_in_class_by_msgstr(classh,pd.messageinf.str,srsym,srsymtable)
                      else
                      else
-                      sym:=searchsym_in_class(classh,hs);
+                       searchsym_in_class(classh,hs,srsym,srsymtable);
                    end
                    end
                   else
                   else
                    begin
                    begin
@@ -2064,16 +2063,16 @@ implementation
                      hsorg:=orgpattern;
                      hsorg:=orgpattern;
                      consume(_ID);
                      consume(_ID);
                      anon_inherited:=false;
                      anon_inherited:=false;
-                     sym:=searchsym_in_class(classh,hs);
+                     searchsym_in_class(classh,hs,srsym,srsymtable);
                    end;
                    end;
-                  if assigned(sym) then
+                  if assigned(srsym) then
                    begin
                    begin
-                     check_hints(sym,sym.symoptions);
+                     check_hints(srsym,srsym.symoptions);
                      { load the procdef from the inherited class and
                      { load the procdef from the inherited class and
                        not from self }
                        not from self }
-                     if sym.typ in [procsym,propertysym] then
+                     if srsym.typ in [procsym,propertysym] then
                       begin
                       begin
-                        if (sym.typ = procsym) then
+                        if (srsym.typ = procsym) then
                           begin
                           begin
                             htype.setdef(classh);
                             htype.setdef(classh);
                             if (po_classmethod in current_procinfo.procdef.procoptions) or
                             if (po_classmethod in current_procinfo.procdef.procoptions) or
@@ -2087,7 +2086,7 @@ implementation
                         Message(parser_e_methode_id_expected);
                         Message(parser_e_methode_id_expected);
                         p1:=cerrornode.create;
                         p1:=cerrornode.create;
                       end;
                       end;
-                     do_member_read(classh,false,sym,p1,again,[cnf_inherited,cnf_anon_inherited]);
+                     do_member_read(classh,false,srsym,p1,again,[cnf_inherited,cnf_anon_inherited]);
                    end
                    end
                   else
                   else
                    begin
                    begin
@@ -2097,12 +2096,12 @@ implementation
                         if (po_msgint in pd.procoptions) or
                         if (po_msgint in pd.procoptions) or
                            (po_msgstr in pd.procoptions) then
                            (po_msgstr in pd.procoptions) then
                           begin
                           begin
-                            sym:=searchsym_in_class(classh,'DEFAULTHANDLER');
-                            if not assigned(sym) or
-                               (sym.typ<>procsym) then
+                            searchsym_in_class(classh,'DEFAULTHANDLER',srsym,srsymtable);
+                            if not assigned(srsym) or
+                               (srsym.typ<>procsym) then
                               internalerror(200303171);
                               internalerror(200303171);
                             p1:=nil;
                             p1:=nil;
-                            do_proc_call(sym,sym.owner,classh,false,again,p1,[]);
+                            do_proc_call(srsym,srsym.owner,classh,false,again,p1,[]);
                           end
                           end
                         else
                         else
                           begin
                           begin
@@ -2440,8 +2439,10 @@ implementation
         if (not assigned(p1.resulttype.def)) then
         if (not assigned(p1.resulttype.def)) then
          do_resulttypepass(p1);
          do_resulttypepass(p1);
 
 
+        if assigned(p1) and
+           (p1<>oldp1) then
+          p1.fileinfo:=filepos;
         factor:=p1;
         factor:=p1;
-        check_tokenpos;
       end;
       end;
 {$ifdef fpc}
 {$ifdef fpc}
   {$maxfpuregisters default}
   {$maxfpuregisters default}
@@ -2632,11 +2633,7 @@ implementation
          expr:=p1;
          expr:=p1;
       end;
       end;
 
 
-{$ifdef int64funcresok}
     function get_intconst:TConstExprInt;
     function get_intconst:TConstExprInt;
-{$else int64funcresok}
-    function get_intconst:longint;
-{$endif int64funcresok}
     {Reads an expression, tries to evalute it and check if it is an integer
     {Reads an expression, tries to evalute it and check if it is an integer
      constant. Then the constant is returned.}
      constant. Then the constant is returned.}
     var
     var

+ 5 - 4
compiler/pinline.pas

@@ -49,7 +49,7 @@ implementation
        globtype,tokens,verbose,
        globtype,tokens,verbose,
        systems,
        systems,
        { symtable }
        { symtable }
-       symconst,symdef,symsym,symtable,defutil,
+       symbase,symconst,symdef,symsym,symtable,defutil,
        { pass 1 }
        { pass 1 }
        pass_1,htypechk,
        pass_1,htypechk,
        nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,
        nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,
@@ -335,7 +335,8 @@ implementation
         para         : tcallparanode;
         para         : tcallparanode;
         p1,p2  : tnode;
         p1,p2  : tnode;
         classh : tobjectdef;
         classh : tobjectdef;
-        sym    : tsym;
+        srsym    : tsym;
+        srsymtable : tsymtable;
         again  : boolean; { dummy for do_proc_call }
         again  : boolean; { dummy for do_proc_call }
       begin
       begin
         consume(_LKLAMMER);
         consume(_LKLAMMER);
@@ -420,9 +421,9 @@ implementation
             { search the constructor also in the symbol tables of
             { search the constructor also in the symbol tables of
               the parents }
               the parents }
             afterassignment:=false;
             afterassignment:=false;
-            sym:=searchsym_in_class(classh,pattern);
+            searchsym_in_class(classh,pattern,srsym,srsymtable);
             consume(_ID);
             consume(_ID);
-            do_member_read(classh,false,sym,p1,again,[cnf_new_call]);
+            do_member_read(classh,false,srsym,p1,again,[cnf_new_call]);
             { we need to know which procedure is called }
             { we need to know which procedure is called }
             do_resulttypepass(p1);
             do_resulttypepass(p1);
             if not(
             if not(

+ 101 - 236
compiler/pmodules.pas

@@ -399,17 +399,14 @@ implementation
         hp.loadppu;
         hp.loadppu;
         hp.adddependency(current_module);
         hp.adddependency(current_module);
         { add to symtable stack }
         { add to symtable stack }
-        tsymtable(hp.globalsymtable).next:=symtablestack;
-        symtablestack:=hp.globalsymtable;
-        if (m_mac in aktmodeswitches) and assigned(hp.globalmacrosymtable) then
-          begin
-            tsymtable(hp.globalmacrosymtable).next:=macrosymtablestack;
-            macrosymtablestack:=hp.globalmacrosymtable;
-          end;
+        symtablestack.push(hp.globalsymtable);
+        if (m_mac in aktmodeswitches) and
+           assigned(hp.globalmacrosymtable) then
+          macrosymtablestack.push(hp.globalmacrosymtable);
         { insert unitsym }
         { insert unitsym }
-        unitsym:=tunitsym.create(s,hp.globalsymtable);
+        unitsym:=tunitsym.create(s,hp);
         inc(unitsym.refs);
         inc(unitsym.refs);
-        refsymtable.insert(unitsym);
+        current_module.localsymtable.insert(unitsym);
         { add to used units }
         { add to used units }
         current_module.addusedunit(hp,false,unitsym);
         current_module.addusedunit(hp,false,unitsym);
       end;
       end;
@@ -440,32 +437,38 @@ implementation
 
 
     procedure loaddefaultunits;
     procedure loaddefaultunits;
       begin
       begin
-      { are we compiling the system unit? }
+        { we are going to rebuild the symtablestack, clear it first }
+        symtablestack.clear;
+        macrosymtablestack.clear;
+
+        { macro symtable }
+        macrosymtablestack.push(initialmacrosymtable);
+
+        { are we compiling the system unit? }
         if (cs_compilesystem in aktmoduleswitches) then
         if (cs_compilesystem in aktmoduleswitches) then
          begin
          begin
-         { create system defines }
-           createconstdefs;
-         { we don't need to reset anything, it's already done in parser.pas }
+           systemunit:=tglobalsymtable(current_module.localsymtable);
+           { create system defines }
+           create_intern_symbols;
+           create_intern_types;
            exit;
            exit;
          end;
          end;
-        { insert the system unit, it is allways the first }
-        symtablestack:=nil;
-        macrosymtablestack:=initialmacrosymtable;
+
+        { insert the system unit, it is allways the first. Load also the
+          internal types from the system unit }
         AddUnit('System');
         AddUnit('System');
-        SystemUnit:=TGlobalSymtable(Symtablestack);
-        { read default constant definitions }
-        make_ref:=false;
-        readconstdefs;
-        make_ref:=true;
+        systemunit:=tglobalsymtable(symtablestack.top);
+        load_intern_types;
+
         { Set the owner of errorsym and errortype to symtable to
         { Set the owner of errorsym and errortype to symtable to
           prevent crashes when accessing .owner }
           prevent crashes when accessing .owner }
         generrorsym.owner:=systemunit;
         generrorsym.owner:=systemunit;
         generrortype.def.owner:=systemunit;
         generrortype.def.owner:=systemunit;
+
         { Units only required for main module }
         { Units only required for main module }
-        { load heaptrace before any other units especially objpas }
         if not(current_module.is_unit) then
         if not(current_module.is_unit) then
          begin
          begin
-           { Heaptrc unit }
+           { Heaptrc unit, load heaptrace before any other units especially objpas }
            if (cs_use_heaptrc in aktglobalswitches) then
            if (cs_use_heaptrc in aktglobalswitches) then
              AddUnit('HeapTrc');
              AddUnit('HeapTrc');
            { Lineinfo unit }
            { Lineinfo unit }
@@ -495,9 +498,6 @@ implementation
             AddUnit('FPCylix');
             AddUnit('FPCylix');
             AddUnit('DynLibs');
             AddUnit('DynLibs');
           end;
           end;
-        { save default symtablestack }
-        defaultsymtablestack:=symtablestack;
-        defaultmacrosymtablestack:=macrosymtablestack;
       end;
       end;
 
 
 
 
@@ -521,15 +521,9 @@ implementation
          fn      : string;
          fn      : string;
          pu      : tused_unit;
          pu      : tused_unit;
          hp2     : tmodule;
          hp2     : tmodule;
-         hp3     : tsymtable;
          unitsym : tunitsym;
          unitsym : tunitsym;
-         top_of_macrosymtable : tsymtable;
-
       begin
       begin
          consume(_USES);
          consume(_USES);
-{$ifdef DEBUG}
-         test_symtablestack;
-{$endif DEBUG}
          repeat
          repeat
            s:=pattern;
            s:=pattern;
            sorg:=orgpattern;
            sorg:=orgpattern;
@@ -568,7 +562,7 @@ implementation
                 can not use the modulename because that can be different
                 can not use the modulename because that can be different
                 when -Un is used }
                 when -Un is used }
               unitsym:=tunitsym.create(sorg,nil);
               unitsym:=tunitsym.create(sorg,nil);
-              refsymtable.insert(unitsym);
+              current_module.localsymtable.insert(unitsym);
               { the current module uses the unit hp2 }
               { the current module uses the unit hp2 }
               current_module.addusedunit(hp2,true,unitsym);
               current_module.addusedunit(hp2,true,unitsym);
             end
             end
@@ -584,7 +578,6 @@ implementation
          until false;
          until false;
 
 
          { Load the units }
          { Load the units }
-         top_of_macrosymtable:= macrosymtablestack;
          pu:=tused_unit(current_module.used_units.first);
          pu:=tused_unit(current_module.used_units.first);
          while assigned(pu) do
          while assigned(pu) do
           begin
           begin
@@ -602,53 +595,17 @@ implementation
                { save crc values }
                { save crc values }
                pu.checksum:=pu.u.crc;
                pu.checksum:=pu.u.crc;
                pu.interface_checksum:=pu.u.interface_crc;
                pu.interface_checksum:=pu.u.interface_crc;
-               { connect unitsym to the globalsymtable of the unit }
-               pu.unitsym.unitsymtable:=pu.u.globalsymtable;
+               { connect unitsym to the module }
+               pu.unitsym.module:=pu.u;
+               { add to symtable stack }
+               symtablestack.push(pu.u.globalsymtable);
+               if (m_mac in aktmodeswitches) and
+                  assigned(pu.u.globalmacrosymtable) then
+                 macrosymtablestack.push(pu.u.globalmacrosymtable);
              end;
              end;
             pu:=tused_unit(pu.next);
             pu:=tused_unit(pu.next);
           end;
           end;
 
 
-         { set the symtable to systemunit so it gets reorderd correctly,
-           then insert the units in the symtablestack }
-         pu:=tused_unit(current_module.used_units.first);
-         symtablestack:=defaultsymtablestack;
-         macrosymtablestack:=defaultmacrosymtablestack;
-         while assigned(pu) do
-           begin
-              if pu.in_uses then
-                begin
-                   { Reinsert in symtablestack }
-                   hp3:=symtablestack;
-                   while assigned(hp3) do
-                     begin
-                        { insert units only once ! }
-                        if pu.u.globalsymtable=hp3 then
-                          break;
-                        hp3:=hp3.next;
-                        { unit isn't inserted }
-                        if hp3=nil then
-                          begin
-                             tsymtable(pu.u.globalsymtable).next:=symtablestack;
-                             symtablestack:=tsymtable(pu.u.globalsymtable);
-                             if (m_mac in aktmodeswitches) and assigned(pu.u.globalmacrosymtable) then
-                               begin
-                                 tsymtable(pu.u.globalmacrosymtable).next:=macrosymtablestack;
-                                 macrosymtablestack:=tsymtable(pu.u.globalmacrosymtable);
-                               end;
-{$ifdef DEBUG}
-                             test_symtablestack;
-{$endif DEBUG}
-                          end;
-                     end;
-                end;
-              pu:=tused_unit(pu.next);
-           end;
-
-         if assigned (current_module.globalmacrosymtable) then
-           top_of_macrosymtable.next.next:= macrosymtablestack
-         else
-           top_of_macrosymtable.next:= macrosymtablestack;
-         macrosymtablestack:= top_of_macrosymtable;
          consume(_SEMICOLON);
          consume(_SEMICOLON);
       end;
       end;
 
 
@@ -718,12 +675,7 @@ implementation
     procedure parse_implementation_uses;
     procedure parse_implementation_uses;
       begin
       begin
          if token=_USES then
          if token=_USES then
-           begin
-              loadunits;
-{$ifdef DEBUG}
-              test_symtablestack;
-{$endif DEBUG}
-           end;
+           loadunits;
       end;
       end;
 
 
 
 
@@ -740,7 +692,6 @@ implementation
 
 
     function create_main_proc(const name:string;potype:tproctypeoption;st:tsymtable):tprocdef;
     function create_main_proc(const name:string;potype:tproctypeoption;st:tsymtable):tprocdef;
       var
       var
-        stt : tsymtable;
         ps  : tprocsym;
         ps  : tprocsym;
         pd  : tprocdef;
         pd  : tprocdef;
       begin
       begin
@@ -748,22 +699,14 @@ implementation
         if assigned(current_procinfo) then
         if assigned(current_procinfo) then
          internalerror(200304275);
          internalerror(200304275);
         {Generate a procsym for main}
         {Generate a procsym for main}
-        make_ref:=false;
-        { try to insert in in static symtable ! }
-        stt:=symtablestack;
-        symtablestack:=st;
-        { generate procsym }
         ps:=tprocsym.create('$'+name);
         ps:=tprocsym.create('$'+name);
         { main are allways used }
         { main are allways used }
         inc(ps.refs);
         inc(ps.refs);
-        symtablestack.insert(ps);
+        st.insert(ps);
         pd:=tprocdef.create(main_program_level);
         pd:=tprocdef.create(main_program_level);
         include(pd.procoptions,po_global);
         include(pd.procoptions,po_global);
         pd.procsym:=ps;
         pd.procsym:=ps;
         ps.addprocdef(pd);
         ps.addprocdef(pd);
-        { restore symtable }
-        make_ref:=true;
-        symtablestack:=stt;
         { set procdef options }
         { set procdef options }
         pd.proctypeoption:=potype;
         pd.proctypeoption:=potype;
         pd.proccalloption:=pocall_default;
         pd.proccalloption:=pocall_default;
@@ -828,15 +771,13 @@ implementation
         release_main_proc(pd);
         release_main_proc(pd);
       end;
       end;
 
 
-    procedure delete_duplicate_macros(p:TNamedIndexItem; arg:pointer);
-      var
-        hp: tsymentry;
+
+    procedure copy_macro(p:TNamedIndexItem; arg:pointer);
       begin
       begin
-        hp:= current_module.localmacrosymtable.search(p.name);
-        if assigned(hp) then
-          current_module.localmacrosymtable.delete(hp);
+        current_module.globalmacrosymtable.insert(tmacro(p).getcopy);
       end;
       end;
 
 
+
     procedure proc_unit;
     procedure proc_unit;
 
 
       function is_assembler_generated:boolean;
       function is_assembler_generated:boolean;
@@ -857,8 +798,6 @@ implementation
 
 
       var
       var
          main_file: tinputfile;
          main_file: tinputfile;
-         st     : tsymtable;
-         unitst : tglobalsymtable;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
          store_crc,
          store_crc,
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
@@ -871,10 +810,7 @@ implementation
          globalvarsym : tglobalvarsym;
          globalvarsym : tglobalvarsym;
       begin
       begin
          if m_mac in aktmodeswitches then
          if m_mac in aktmodeswitches then
-           begin
-             ConsolidateMode;
-             current_module.mode_switch_allowed:= false;
-           end;
+           current_module.mode_switch_allowed:= false;
 
 
          consume(_UNIT);
          consume(_UNIT);
          if compile_level=1 then
          if compile_level=1 then
@@ -928,7 +864,6 @@ implementation
          current_module.in_global:=false;
          current_module.in_global:=false;
 
 
          { handle the global switches }
          { handle the global switches }
-         ConsolidateMode;
          setupglobalswitches;
          setupglobalswitches;
 
 
          message1(unit_u_loading_interface_units,current_module.modulename^);
          message1(unit_u_loading_interface_units,current_module.modulename^);
@@ -946,62 +881,31 @@ implementation
 
 
          parse_only:=true;
          parse_only:=true;
 
 
-         { generate now the global symboltable }
-         st:=tglobalsymtable.create(current_module.modulename^,current_module.moduleid);
-         refsymtable:=st;
-         unitst:=tglobalsymtable(st);
-         { define first as local to overcome dependency conflicts }
-         current_module.localsymtable:=st;
+         { generate now the global symboltable,
+           define first as local to overcome dependency conflicts }
+         current_module.localsymtable:=tglobalsymtable.create(current_module.modulename^,current_module.moduleid);
 
 
-         { the unit name must be usable as a unit specifier }
-         { inside the unit itself (PM)                }
-         { this also forbids to have another symbol      }
-         { with the same name as the unit                  }
-         refsymtable.insert(tunitsym.create(current_module.realmodulename^,unitst));
-
-         macrosymtablestack:= initialmacrosymtable;
+         { insert unitsym of this unit to prevent other units having
+           the same name }
+         current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
 
 
          { load default units, like the system unit }
          { load default units, like the system unit }
          loaddefaultunits;
          loaddefaultunits;
 
 
-         current_module.localmacrosymtable.next:=macrosymtablestack;
-         if assigned(current_module.globalmacrosymtable) then
-           begin
-             current_module.globalmacrosymtable.next:= current_module.localmacrosymtable;
-             macrosymtablestack:=current_module.globalmacrosymtable;
-           end
-         else
-           macrosymtablestack:=current_module.localmacrosymtable;
-
          { reset }
          { reset }
          make_ref:=true;
          make_ref:=true;
 
 
          { insert qualifier for the system unit (allows system.writeln) }
          { insert qualifier for the system unit (allows system.writeln) }
-         if not(cs_compilesystem in aktmoduleswitches) then
-           begin
-              if token=_USES then
-                begin
-                   loadunits;
-                   { has it been compiled at a higher level ?}
-                   if current_module.state=ms_compiled then
-                     exit;
-                end;
-              { ... but insert the symbol table later }
-              st.next:=symtablestack;
-              symtablestack:=st;
-           end
-         else
-         { while compiling a system unit, some types are directly inserted }
+         if not(cs_compilesystem in aktmoduleswitches) and
+            (token=_USES) then
            begin
            begin
-              st.next:=symtablestack;
-              symtablestack:=st;
-              insert_intern_types(st);
+             loadunits;
+             { has it been compiled at a higher level ?}
+             if current_module.state=ms_compiled then
+               exit;
            end;
            end;
 
 
-         { now we know the place to insert the constants }
-         constsymtable:=symtablestack;
-
-         { move the global symtab from the temporary local to global }
+         { move the global symtable from the temporary local to global }
          current_module.globalsymtable:=current_module.localsymtable;
          current_module.globalsymtable:=current_module.localsymtable;
          current_module.localsymtable:=nil;
          current_module.localsymtable:=nil;
 
 
@@ -1013,7 +917,18 @@ implementation
 
 
          { ... parse the declarations }
          { ... parse the declarations }
          Message1(parser_u_parsing_interface,current_module.realmodulename^);
          Message1(parser_u_parsing_interface,current_module.realmodulename^);
+         symtablestack.push(current_module.globalsymtable);
          read_interface_declarations;
          read_interface_declarations;
+         symtablestack.pop(current_module.globalsymtable);
+
+         { Export macros defined in the interface for macpas. The macros
+           are put in the globalmacrosymtable that will only be used by other
+           units. The current unit continues to use the localmacrosymtable }
+         if (m_mac in aktmodeswitches) then
+          begin
+            current_module.globalmacrosymtable:=tmacrosymtable.create(true);
+            current_module.localmacrosymtable.foreach_static(@copy_macro,nil);
+          end;
 
 
          { leave when we got an error }
          { leave when we got an error }
          if (Errorcount>0) and not status.skip_error then
          if (Errorcount>0) and not status.skip_error then
@@ -1043,8 +958,7 @@ implementation
          parse_only:=false;
          parse_only:=false;
 
 
          { generates static symbol table }
          { generates static symbol table }
-         st:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
-         current_module.localsymtable:=st;
+         current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
 
 
 {$ifdef i386}
 {$ifdef i386}
          if cs_create_pic in aktmoduleswitches then
          if cs_create_pic in aktmoduleswitches then
@@ -1059,23 +973,6 @@ implementation
            end;
            end;
 {$endif i386}
 {$endif i386}
 
 
-         { Swap the positions of the local and global macro sym table}
-         if assigned(current_module.globalmacrosymtable) then
-           begin
-             macrosymtablestack:=current_module.localmacrosymtable;
-             current_module.globalmacrosymtable.next:= current_module.localmacrosymtable.next;
-             current_module.localmacrosymtable.next:=current_module.globalmacrosymtable;
-
-             current_module.globalmacrosymtable.foreach_static(@delete_duplicate_macros, nil);
-           end;
-
-         { remove the globalsymtable from the symtable stack }
-         { to reinsert it after loading the implementation units }
-         symtablestack:=unitst.next;
-
-         { we don't want implementation units symbols in unitsymtable !! PM }
-         refsymtable:=st;
-
          if has_impl then
          if has_impl then
            begin
            begin
              consume(_IMPLEMENTATION);
              consume(_IMPLEMENTATION);
@@ -1093,17 +990,8 @@ implementation
          { All units are read, now give them a number }
          { All units are read, now give them a number }
          current_module.updatemaps;
          current_module.updatemaps;
 
 
-         { now we can change refsymtable }
-         refsymtable:=st;
-
-         { but reinsert the global symtable as lasts }
-         unitst.next:=symtablestack;
-         symtablestack:=unitst;
-
-{$ifdef DEBUG}
-         test_symtablestack;
-{$endif DEBUG}
-         constsymtable:=symtablestack;
+         symtablestack.push(current_module.globalsymtable);
+         symtablestack.push(current_module.localsymtable);
 
 
          if has_impl then
          if has_impl then
            begin
            begin
@@ -1112,7 +1000,7 @@ implementation
                internalerror(200212285);
                internalerror(200212285);
 
 
              { Compile the unit }
              { Compile the unit }
-             pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'init'),potype_unitinit,st);
+             pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'init'),potype_unitinit,current_module.localsymtable);
              pd.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
              pd.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
              tcgprocinfo(current_procinfo).parse_body;
              tcgprocinfo(current_procinfo).parse_body;
              tcgprocinfo(current_procinfo).generate_code;
              tcgprocinfo(current_procinfo).generate_code;
@@ -1133,7 +1021,7 @@ implementation
          { should we force unit initialization? }
          { should we force unit initialization? }
          { this is a hack, but how can it be done better ? }
          { this is a hack, but how can it be done better ? }
          if force_init_final and ((current_module.flags and uf_init)=0) then
          if force_init_final and ((current_module.flags and uf_init)=0) then
-           gen_implicit_initfinal(uf_init,st);
+           gen_implicit_initfinal(uf_init,current_module.localsymtable);
          { finalize? }
          { finalize? }
          if has_impl and (token=_FINALIZATION) then
          if has_impl and (token=_FINALIZATION) then
            begin
            begin
@@ -1141,7 +1029,7 @@ implementation
               current_module.flags:=current_module.flags or uf_finalize;
               current_module.flags:=current_module.flags or uf_finalize;
 
 
               { Compile the finalize }
               { Compile the finalize }
-              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,st);
+              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
               pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
               pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
               tcgprocinfo(current_procinfo).parse_body;
               tcgprocinfo(current_procinfo).parse_body;
               tcgprocinfo(current_procinfo).generate_code;
               tcgprocinfo(current_procinfo).generate_code;
@@ -1149,7 +1037,10 @@ implementation
               release_main_proc(pd);
               release_main_proc(pd);
            end
            end
          else if force_init_final then
          else if force_init_final then
-           gen_implicit_initfinal(uf_finalize,st);
+           gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
+
+         symtablestack.pop(current_module.localsymtable);
+         symtablestack.pop(current_module.globalsymtable);
 
 
          { the last char should always be a point }
          { the last char should always be a point }
          consume(_POINT);
          consume(_POINT);
@@ -1167,18 +1058,18 @@ implementation
          if (Errorcount=0) then
          if (Errorcount=0) then
            begin
            begin
              { tests, if all (interface) forwards are resolved }
              { tests, if all (interface) forwards are resolved }
-             tstoredsymtable(symtablestack).check_forwards;
+             tstoredsymtable(current_module.globalsymtable).check_forwards;
              { check if all private fields are used }
              { check if all private fields are used }
-             tstoredsymtable(symtablestack).allprivatesused;
+             tstoredsymtable(current_module.globalsymtable).allprivatesused;
              { remove cross unit overloads }
              { remove cross unit overloads }
-             tstoredsymtable(symtablestack).unchain_overloaded;
+             tstoredsymtable(current_module.globalsymtable).unchain_overloaded;
 
 
              { test static symtable }
              { test static symtable }
-             tstoredsymtable(st).allsymbolsused;
-             tstoredsymtable(st).allprivatesused;
-             tstoredsymtable(st).check_forwards;
-             tstoredsymtable(st).checklabels;
-             tstoredsymtable(st).unchain_overloaded;
+             tstoredsymtable(current_module.localsymtable).allsymbolsused;
+             tstoredsymtable(current_module.localsymtable).allprivatesused;
+             tstoredsymtable(current_module.localsymtable).check_forwards;
+             tstoredsymtable(current_module.localsymtable).checklabels;
+             tstoredsymtable(current_module.localsymtable).unchain_overloaded;
 
 
              { used units }
              { used units }
              current_module.allunitsused;
              current_module.allunitsused;
@@ -1225,15 +1116,10 @@ implementation
              current_module.flags:=current_module.flags and not uf_has_debuginfo;
              current_module.flags:=current_module.flags and not uf_has_debuginfo;
            end;
            end;
 
 
-         if cs_local_browser in aktmoduleswitches then
-           current_module.localsymtable:=refsymtable;
-
          if ag then
          if ag then
           begin
           begin
             { create dwarf debuginfo }
             { create dwarf debuginfo }
             create_dwarf;
             create_dwarf;
-            { finish asmlist by adding segment starts }
-//            insertsegment;
             { assemble }
             { assemble }
             create_objectfile;
             create_objectfile;
           end;
           end;
@@ -1262,14 +1148,6 @@ implementation
          free_localsymtables(current_module.globalsymtable);
          free_localsymtables(current_module.globalsymtable);
          free_localsymtables(current_module.localsymtable);
          free_localsymtables(current_module.localsymtable);
 
 
-         { remove static symtable (=refsymtable) here to save some mem, possible references
-           (like procsym overloads) should already have been freed above }
-         if not (cs_local_browser in aktmoduleswitches) then
-           begin
-              st.free;
-              current_module.localsymtable:=nil;
-           end;
-
          { leave when we got an error }
          { leave when we got an error }
          if (Errorcount>0) and not status.skip_error then
          if (Errorcount>0) and not status.skip_error then
           begin
           begin
@@ -1285,7 +1163,6 @@ implementation
     procedure proc_program(islibrary : boolean);
     procedure proc_program(islibrary : boolean);
       var
       var
          main_file : tinputfile;
          main_file : tinputfile;
-         st        : tsymtable;
          hp,hp2    : tmodule;
          hp,hp2    : tmodule;
          pd        : tprocdef;
          pd        : tprocdef;
       begin
       begin
@@ -1370,7 +1247,6 @@ implementation
          current_module.in_global:=false;
          current_module.in_global:=false;
 
 
          { setup things using the switches }
          { setup things using the switches }
-         ConsolidateMode;
          setupglobalswitches;
          setupglobalswitches;
 
 
          { set implementation flag }
          { set implementation flag }
@@ -1379,18 +1255,11 @@ implementation
 
 
          { insert after the unit symbol tables the static symbol table }
          { insert after the unit symbol tables the static symbol table }
          { of the program                                             }
          { of the program                                             }
-         st:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
-         current_module.localsymtable:=st;
-         refsymtable:=st;
-
-         macrosymtablestack:= nil;
+         current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
 
 
          { load standard units (system,objpas,profile unit) }
          { load standard units (system,objpas,profile unit) }
          loaddefaultunits;
          loaddefaultunits;
 
 
-         current_module.localmacrosymtable.next:=macrosymtablestack;
-         macrosymtablestack:=current_module.localmacrosymtable;
-
          { Load units provided on the command line }
          { Load units provided on the command line }
          loadautounits;
          loadautounits;
 
 
@@ -1406,32 +1275,28 @@ implementation
 
 
          {Insert the name of the main program into the symbol table.}
          {Insert the name of the main program into the symbol table.}
          if current_module.realmodulename^<>'' then
          if current_module.realmodulename^<>'' then
-           st.insert(tunitsym.create(current_module.realmodulename^,st));
-
-         { ...is also constsymtable, this is the symtable where }
-         { the elements of enumeration types are inserted       }
-         constsymtable:=st;
+           current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
 
 
          Message1(parser_u_parsing_implementation,current_module.mainsource^);
          Message1(parser_u_parsing_implementation,current_module.mainsource^);
 
 
+         symtablestack.push(current_module.localsymtable);
+
          { The program intialization needs an alias, so it can be called
          { The program intialization needs an alias, so it can be called
            from the bootstrap code.}
            from the bootstrap code.}
-
          if islibrary then
          if islibrary then
           begin
           begin
-            pd:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,st);
+            pd:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,current_module.localsymtable);
             { Win32 startup code needs a single name }
             { Win32 startup code needs a single name }
-//            if (target_info.system in [system_i386_win32,system_i386_wdosx]) then
             pd.aliasnames.insert('PASCALMAIN');
             pd.aliasnames.insert('PASCALMAIN');
           end
           end
          else if (target_info.system = system_i386_netware) or
          else if (target_info.system = system_i386_netware) or
                  (target_info.system = system_i386_netwlibc) then
                  (target_info.system = system_i386_netwlibc) then
            begin
            begin
-             pd:=create_main_proc('PASCALMAIN',potype_proginit,st); { main is need by the netware rtl }
+             pd:=create_main_proc('PASCALMAIN',potype_proginit,current_module.localsymtable);
            end
            end
          else
          else
            begin
            begin
-             pd:=create_main_proc(mainaliasname,potype_proginit,st);
+             pd:=create_main_proc(mainaliasname,potype_proginit,current_module.localsymtable);
              pd.aliasnames.insert('PASCALMAIN');
              pd.aliasnames.insert('PASCALMAIN');
            end;
            end;
          tcgprocinfo(current_procinfo).parse_body;
          tcgprocinfo(current_procinfo).parse_body;
@@ -1448,9 +1313,9 @@ implementation
          if tstaticsymtable(current_module.localsymtable).needs_init_final then
          if tstaticsymtable(current_module.localsymtable).needs_init_final then
            begin
            begin
               { initialize section }
               { initialize section }
-              gen_implicit_initfinal(uf_init,st);
+              gen_implicit_initfinal(uf_init,current_module.localsymtable);
               { finalize section }
               { finalize section }
-              gen_implicit_initfinal(uf_finalize,st);
+              gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
            end;
            end;
 
 
          { Add symbol to the exports section for win32 so smartlinking a
          { Add symbol to the exports section for win32 so smartlinking a
@@ -1475,7 +1340,7 @@ implementation
               current_module.flags:=current_module.flags or uf_finalize;
               current_module.flags:=current_module.flags or uf_finalize;
 
 
               { Compile the finalize }
               { Compile the finalize }
-              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,st);
+              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
               pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
               pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
               tcgprocinfo(current_procinfo).parse_body;
               tcgprocinfo(current_procinfo).parse_body;
               tcgprocinfo(current_procinfo).generate_code;
               tcgprocinfo(current_procinfo).generate_code;
@@ -1483,17 +1348,20 @@ implementation
               release_main_proc(pd);
               release_main_proc(pd);
            end;
            end;
 
 
+         symtablestack.pop(current_module.localsymtable);
+
          { consume the last point }
          { consume the last point }
          consume(_POINT);
          consume(_POINT);
 
 
          if (Errorcount=0) then
          if (Errorcount=0) then
            begin
            begin
              { test static symtable }
              { test static symtable }
-             tstoredsymtable(st).allsymbolsused;
-             tstoredsymtable(st).allprivatesused;
-             tstoredsymtable(st).check_forwards;
-             tstoredsymtable(st).checklabels;
-             tstoredsymtable(st).unchain_overloaded;
+             tstoredsymtable(current_module.localsymtable).allsymbolsused;
+             tstoredsymtable(current_module.localsymtable).allprivatesused;
+             tstoredsymtable(current_module.localsymtable).check_forwards;
+             tstoredsymtable(current_module.localsymtable).checklabels;
+             tstoredsymtable(current_module.localsymtable).unchain_overloaded;
+
              current_module.allunitsused;
              current_module.allunitsused;
            end;
            end;
 
 
@@ -1555,9 +1423,6 @@ implementation
          { create dwarf debuginfo }
          { create dwarf debuginfo }
          create_dwarf;
          create_dwarf;
 
 
-         { finish asmlist by adding segment starts }
-//         insertsegment;
-
          { insert own objectfile }
          { insert own objectfile }
          insertobjectfile;
          insertobjectfile;
 
 

+ 115 - 103
compiler/pstatmnt.pas

@@ -39,7 +39,7 @@ implementation
 
 
     uses
     uses
        { common }
        { common }
-       cutils,
+       cutils,cclasses,
        { global }
        { global }
        globtype,globals,verbose,
        globtype,globals,verbose,
        systems,
        systems,
@@ -433,26 +433,46 @@ implementation
     function _with_statement : tnode;
     function _with_statement : tnode;
 
 
       var
       var
-         right,p : tnode;
-         i,levelcount : longint;
-         withsymtable,symtab : tsymtable;
-         obj : tobjectdef;
-         hp : tnode;
+         p   : tnode;
+         i   : longint;
+         st  : tsymtable;
          newblock : tblocknode;
          newblock : tblocknode;
          newstatement : tstatementnode;
          newstatement : tstatementnode;
-         calltempp,
-         loadp : ttempcreatenode;
-         refp : tnode;
+         calltempnode,
+         tempnode : ttempcreatenode;
+         valuenode,
+         hp,
+         refnode  : tnode;
          htype : ttype;
          htype : ttype;
          hasimplicitderef : boolean;
          hasimplicitderef : boolean;
+         withsymtablelist : tlist;
+
+         procedure pushobjchild(obj:tobjectdef);
+         begin
+           if not assigned(obj) then
+             exit;
+           pushobjchild(obj.childof);
+           { keep the original tobjectdef as owner, because that is used for
+             visibility of the symtable }
+           st:=twithsymtable.create(tobjectdef(p.resulttype.def),obj.symtable.symsearch,refnode.getcopy);
+           symtablestack.push(st);
+           withsymtablelist.add(st);
+         end;
+
       begin
       begin
          p:=comp_expr(true);
          p:=comp_expr(true);
          do_resulttypepass(p);
          do_resulttypepass(p);
-         right:=nil;
-         if (not codegenerror) and
-            (p.resulttype.def.deftype in [objectdef,recorddef]) then
+
+         if (p.nodetype=vecn) and
+            (nf_memseg in p.flags) then
+           CGMessage(parser_e_no_with_for_variable_in_other_segments);
+
+         if (p.resulttype.def.deftype in [objectdef,recorddef]) then
           begin
           begin
             newblock:=nil;
             newblock:=nil;
+            valuenode:=nil;
+            tempnode:=nil;
+
             { ignore nodes that don't add instructions in the tree }
             { ignore nodes that don't add instructions in the tree }
             hp:=p;
             hp:=p;
             while { equal type conversions }
             while { equal type conversions }
@@ -472,113 +492,107 @@ implementation
                 (tloadnode(hp).symtable=current_procinfo.procdef.parast) or
                 (tloadnode(hp).symtable=current_procinfo.procdef.parast) or
                 (tloadnode(hp).symtable.symtabletype in [staticsymtable,globalsymtable])
                 (tloadnode(hp).symtable.symtabletype in [staticsymtable,globalsymtable])
                ) then
                ) then
-             begin
-               { simple load, we can reference direct }
-               loadp:=nil;
-               refp:=p;
-             end
+              begin
+                { simple load, we can reference direct }
+                refnode:=p;
+              end
             else
             else
-             begin
-               calltempp:=nil;
-               { complex load, load in temp first }
-               newblock:=internalstatements(newstatement);
-               { when right is a call then load it first in a temp }
-               if p.nodetype=calln then
-                 begin
-                   calltempp:=ctempcreatenode.create(p.resulttype,p.resulttype.def.size,tt_persistent,false);
-                   addstatement(newstatement,calltempp);
-                   addstatement(newstatement,cassignmentnode.create(
-                       ctemprefnode.create(calltempp),
-                       p));
-                   p:=ctemprefnode.create(calltempp);
-                   resulttypepass(p);
-                 end;
-               { classes and interfaces have implicit dereferencing }
-               hasimplicitderef:=is_class_or_interface(p.resulttype.def);
-               if hasimplicitderef then
-                 htype:=p.resulttype
-               else
-                 htype.setdef(tpointerdef.create(p.resulttype));
-{$ifdef WITHNODEDEBUG}
-               { we can't generate debuginfo for a withnode stored in a }
-               { register                                               }
-               if (cs_debuginfo in aktmoduleswitches) then
-                 loadp:=ctempcreatenode.create(htype,sizeof(aint),tt_persistent,false)
-               else
-{$endif WITHNODEDEBUG}
-                 loadp:=ctempcreatenode.create(htype,sizeof(aint),tt_persistent,true);
-               resulttypepass(loadp);
-               if hasimplicitderef then
-                begin
-                  hp:=p;
-                  refp:=ctemprefnode.create(loadp);
-                end
-               else
-                begin
-                  hp:=caddrnode.create_internal(p);
-                  refp:=cderefnode.create(ctemprefnode.create(loadp));
-                end;
-               addstatement(newstatement,loadp);
-               addstatement(newstatement,cassignmentnode.create(
-                   ctemprefnode.create(loadp),
-                   hp));
-               resulttypepass(refp);
-             end;
+              begin
+                calltempnode:=nil;
+                { complex load, load in temp first }
+                newblock:=internalstatements(newstatement);
+                { when right is a call then load it first in a temp }
+                if p.nodetype=calln then
+                  begin
+                    calltempnode:=ctempcreatenode.create(p.resulttype,p.resulttype.def.size,tt_persistent,false);
+                    addstatement(newstatement,calltempnode);
+                    addstatement(newstatement,cassignmentnode.create(
+                        ctemprefnode.create(calltempnode),
+                        p));
+                    p:=ctemprefnode.create(calltempnode);
+                    resulttypepass(p);
+                  end;
+                { classes and interfaces have implicit dereferencing }
+                hasimplicitderef:=is_class_or_interface(p.resulttype.def);
+                if hasimplicitderef then
+                  htype:=p.resulttype
+                else
+                  htype.setdef(tpointerdef.create(p.resulttype));
+                { load address of the value in a temp }
+                tempnode:=ctempcreatenode.create(htype,sizeof(aint),tt_persistent,true);
+                resulttypepass(tempnode);
+                valuenode:=p;
+                refnode:=ctemprefnode.create(tempnode);
+                fillchar(refnode.fileinfo,sizeof(tfileposinfo),0);
+                { add address call for valuenode and deref for refnode if this
+                  is not done implicitly }
+                if not hasimplicitderef then
+                  begin
+                    valuenode:=caddrnode.create_internal(valuenode);
+                    refnode:=cderefnode.create(refnode);
+                    fillchar(refnode.fileinfo,sizeof(tfileposinfo),0);
+                  end;
+                addstatement(newstatement,tempnode);
+                addstatement(newstatement,cassignmentnode.create(
+                    ctemprefnode.create(tempnode),
+                    valuenode));
+                resulttypepass(refnode);
+              end;
 
 
+            withsymtablelist:=tlist.create;
             case p.resulttype.def.deftype of
             case p.resulttype.def.deftype of
               objectdef :
               objectdef :
                 begin
                 begin
-                   obj:=tobjectdef(p.resulttype.def);
-                   withsymtable:=twithsymtable.Create(obj,obj.symtable.symsearch,refp);
-                   { include also all parent symtables }
-                   levelcount:=1;
-                   obj:=obj.childof;
-                   symtab:=withsymtable;
-                   while assigned(obj) do
-                    begin
-                      { keep the original tobjectdef as owner, because that is used for
-                        visibility of the symtable }
-                      symtab.next:=twithsymtable.create(tobjectdef(p.resulttype.def),obj.symtable.symsearch,refp.getcopy);
-                      symtab:=symtab.next;
-                      obj:=obj.childof;
-                      inc(levelcount);
-                    end;
-                   symtab.next:=symtablestack;
-                   symtablestack:=withsymtable;
+                   { push symtables of all parents in reverse order }
+                   pushobjchild(tobjectdef(p.resulttype.def).childof);
+                   { push object symtable }
+                   st:=twithsymtable.Create(tobjectdef(p.resulttype.def),tobjectdef(p.resulttype.def).symtable.symsearch,refnode);
+                   symtablestack.push(st);
+                   withsymtablelist.add(st);
                  end;
                  end;
               recorddef :
               recorddef :
                 begin
                 begin
-                   symtab:=trecorddef(p.resulttype.def).symtable;
-                   levelcount:=1;
-                   withsymtable:=twithsymtable.create(trecorddef(p.resulttype.def),symtab.symsearch,refp);
-                   withsymtable.next:=symtablestack;
-                   symtablestack:=withsymtable;
+                   st:=twithsymtable.create(trecorddef(p.resulttype.def),trecorddef(p.resulttype.def).symtable.symsearch,refnode);
+                   symtablestack.push(st);
+                   withsymtablelist.add(st);
                 end;
                 end;
+              else
+                internalerror(200601271);
             end;
             end;
+
             if try_to_consume(_COMMA) then
             if try_to_consume(_COMMA) then
-              right:=_with_statement()
+              p:=_with_statement()
             else
             else
               begin
               begin
                 consume(_DO);
                 consume(_DO);
                 if token<>_SEMICOLON then
                 if token<>_SEMICOLON then
-                  right:=statement
+                  p:=statement
                 else
                 else
-                  right:=cerrornode.create;
+                  p:=cerrornode.create;
               end;
               end;
-            { remove symtables from the stack }
-            for i:=1 to levelcount do
-              symtablestack:=symtablestack.next;
-            p:=cwithnode.create(right,twithsymtable(withsymtable),levelcount,refp);
+
+            { remove symtables in reverse order from the stack }
+            for i:=withsymtablelist.count-1 downto 0 do
+              begin
+                st:=tsymtable(withsymtablelist[i]);
+                symtablestack.pop(st);
+                st.free;
+              end;
+            withsymtablelist.free;
+
+//            p:=cwithnode.create(right,twithsymtable(withsymtable),levelcount,refnode);
+
             { Finalize complex withnode with destroy of temp }
             { Finalize complex withnode with destroy of temp }
             if assigned(newblock) then
             if assigned(newblock) then
              begin
              begin
                addstatement(newstatement,p);
                addstatement(newstatement,p);
-               addstatement(newstatement,ctempdeletenode.create(loadp));
-               if assigned(calltempp) then
-                 addstatement(newstatement,ctempdeletenode.create(calltempp));
+               if assigned(tempnode) then
+                 addstatement(newstatement,ctempdeletenode.create(tempnode));
+               if assigned(calltempnode) then
+                 addstatement(newstatement,ctempdeletenode.create(calltempnode));
                p:=newblock;
                p:=newblock;
              end;
              end;
-            _with_statement:=p;
+            result:=p;
           end
           end
          else
          else
           begin
           begin
@@ -597,7 +611,7 @@ implementation
                if token<>_SEMICOLON then
                if token<>_SEMICOLON then
                 statement;
                 statement;
              end;
              end;
-            _with_statement:=nil;
+            result:=nil;
           end;
           end;
       end;
       end;
 
 
@@ -734,9 +748,7 @@ implementation
                                  end;
                                  end;
                                exceptsymtable:=tstt_exceptsymtable.create;
                                exceptsymtable:=tstt_exceptsymtable.create;
                                exceptsymtable.insert(sym);
                                exceptsymtable.insert(sym);
-                               { insert the exception symtable stack }
-                               exceptsymtable.next:=symtablestack;
-                               symtablestack:=exceptsymtable;
+                               symtablestack.push(exceptsymtable);
                             end
                             end
                           else
                           else
                             begin
                             begin
@@ -751,7 +763,7 @@ implementation
                                if srsym.typ=unitsym then
                                if srsym.typ=unitsym then
                                  begin
                                  begin
                                     consume(_POINT);
                                     consume(_POINT);
-                                    srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,pattern);
+                                    searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);
                                     if srsym=nil then
                                     if srsym=nil then
                                      begin
                                      begin
                                        identifier_not_found(orgpattern);
                                        identifier_not_found(orgpattern);
@@ -805,7 +817,7 @@ implementation
                      { remove exception symtable }
                      { remove exception symtable }
                      if assigned(exceptsymtable) then
                      if assigned(exceptsymtable) then
                        begin
                        begin
-                         symtablestack:=symtablestack.next;
+                         symtablestack.pop(exceptsymtable);
                          if last.nodetype <> onn then
                          if last.nodetype <> onn then
                            exceptsymtable.free;
                            exceptsymtable.free;
                        end;
                        end;
@@ -1123,7 +1135,7 @@ implementation
       begin
       begin
          { Rename the funcret so that recursive calls are possible }
          { Rename the funcret so that recursive calls are possible }
          if not is_void(current_procinfo.procdef.rettype.def) then
          if not is_void(current_procinfo.procdef.rettype.def) then
-           symtablestack.rename(current_procinfo.procdef.resultname,'$hiddenresult');
+           current_procinfo.procdef.localst.rename(current_procinfo.procdef.resultname,'$hiddenresult');
 
 
          { delphi uses register calling for assembler methods }
          { delphi uses register calling for assembler methods }
          if (m_delphi in aktmodeswitches) and
          if (m_delphi in aktmodeswitches) and

+ 41 - 43
compiler/psub.pas

@@ -229,8 +229,8 @@ implementation
          else
          else
             begin
             begin
                block:=statement_block(_BEGIN);
                block:=statement_block(_BEGIN);
-               if symtablestack.symtabletype=localsymtable then
-                 symtablestack.foreach_static(@initializevars,block);
+               if current_procinfo.procdef.localst.symtabletype=localsymtable then
+                 current_procinfo.procdef.localst.foreach_static(@initializevars,block);
             end;
             end;
       end;
       end;
 
 
@@ -711,8 +711,8 @@ implementation
           cg.t_times:=100;
           cg.t_times:=100;
 
 
         { clear register count }
         { clear register count }
-        symtablestack.foreach_static(@clearrefs,nil);
-        symtablestack.next.foreach_static(@clearrefs,nil);
+        procdef.localst.foreach_static(@clearrefs,nil);
+        procdef.parast.foreach_static(@clearrefs,nil);
 
 
         { there's always a call to FPC_INITIALIZEUNITS/FPC_DO_EXIT in the main program }
         { there's always a call to FPC_INITIALIZEUNITS/FPC_DO_EXIT in the main program }
         if (procdef.localst.symtablelevel=main_program_level) and
         if (procdef.localst.symtablelevel=main_program_level) and
@@ -720,14 +720,14 @@ implementation
           include(flags,pi_do_call);
           include(flags,pi_do_call);
 
 
         { set implicit_finally flag when there are locals/paras to be finalized }
         { set implicit_finally flag when there are locals/paras to be finalized }
-        current_procinfo.procdef.parast.foreach_static(@check_finalize_paras,nil);
-        current_procinfo.procdef.localst.foreach_static(@check_finalize_locals,nil);
+        procdef.parast.foreach_static(@check_finalize_paras,nil);
+        procdef.localst.foreach_static(@check_finalize_locals,nil);
 
 
         { firstpass everything }
         { firstpass everything }
         flowcontrol:=[];
         flowcontrol:=[];
         do_firstpass(code);
         do_firstpass(code);
         if code.registersfpu>0 then
         if code.registersfpu>0 then
-          include(current_procinfo.flags,pi_uses_fpu);
+          include(flags,pi_uses_fpu);
 
 
         { add implicit entry and exit code }
         { add implicit entry and exit code }
         add_entry_exit_code;
         add_entry_exit_code;
@@ -888,7 +888,7 @@ implementation
               generate the call to the helper function }
               generate the call to the helper function }
             if (cs_check_stack in entryswitches) and
             if (cs_check_stack in entryswitches) and
                not(po_assembler in procdef.procoptions) and
                not(po_assembler in procdef.procoptions) and
-               (current_procinfo.procdef.proctypeoption<>potype_proginit) then
+               (procdef.proctypeoption<>potype_proginit) then
               begin
               begin
                 aktfilepos:=entrypos;
                 aktfilepos:=entrypos;
                 gen_stack_check_call(templist);
                 gen_stack_check_call(templist);
@@ -924,7 +924,7 @@ implementation
               parameter that is passed to the stack checking code }
               parameter that is passed to the stack checking code }
             if (cs_check_stack in entryswitches) and
             if (cs_check_stack in entryswitches) and
                not(po_assembler in procdef.procoptions) and
                not(po_assembler in procdef.procoptions) and
-               (current_procinfo.procdef.proctypeoption<>potype_proginit) then
+               (procdef.proctypeoption<>potype_proginit) then
               begin
               begin
                 aktfilepos:=entrypos;
                 aktfilepos:=entrypos;
                 gen_stack_check_size_para(templist);
                 gen_stack_check_size_para(templist);
@@ -1015,9 +1015,6 @@ implementation
       var
       var
         _class,hp : tobjectdef;
         _class,hp : tobjectdef;
       begin
       begin
-        { allocate the symbol for this procedure }
-        alloc_proc_symbol(procdef);
-
         { insert symtables for the class, but only if it is no nested function }
         { insert symtables for the class, but only if it is no nested function }
         if assigned(procdef._class) and
         if assigned(procdef._class) and
            not(assigned(parent) and
            not(assigned(parent) and
@@ -1031,35 +1028,44 @@ implementation
               while _class.childof<>hp do
               while _class.childof<>hp do
                 _class:=_class.childof;
                 _class:=_class.childof;
               hp:=_class;
               hp:=_class;
-              _class.symtable.next:=symtablestack;
-              symtablestack:=_class.symtable;
+              symtablestack.push(_class.symtable);
             until hp=procdef._class;
             until hp=procdef._class;
           end;
           end;
 
 
         { insert parasymtable in symtablestack when parsing
         { insert parasymtable in symtablestack when parsing
           a function }
           a function }
         if procdef.parast.symtablelevel>=normal_function_level then
         if procdef.parast.symtablelevel>=normal_function_level then
-          begin
-             procdef.parast.next:=symtablestack;
-             symtablestack:=procdef.parast;
-          end;
+          symtablestack.push(procdef.parast);
 
 
-        procdef.localst.next:=symtablestack;
-        symtablestack:=procdef.localst;
+        { insert localsymtable }
+        symtablestack.push(procdef.localst);
       end;
       end;
 
 
 
 
     procedure tcgprocinfo.remove_from_symtablestack;
     procedure tcgprocinfo.remove_from_symtablestack;
+      var
+        _class : tobjectdef;
       begin
       begin
-        { remove localst/parast }
+        { remove localsymtable }
+        symtablestack.pop(procdef.localst);
+
+        { remove parasymtable }
         if procdef.parast.symtablelevel>=normal_function_level then
         if procdef.parast.symtablelevel>=normal_function_level then
-          symtablestack:=symtablestack.next.next
-        else
-          symtablestack:=symtablestack.next;
+          symtablestack.pop(procdef.parast);
 
 
-        { remove class member symbol tables }
-        while symtablestack.symtabletype=objectsymtable do
-          symtablestack:=symtablestack.next;
+        { remove symtables for the class, but only if it is no nested function }
+        if assigned(procdef._class) and
+           not(assigned(parent) and
+               assigned(parent.procdef) and
+               assigned(parent.procdef._class)) then
+          begin
+            _class:=procdef._class;
+            while assigned(_class) do
+              begin
+                symtablestack.pop(_class.symtable);
+                _class:=_class.childof;
+              end;
+          end;
       end;
       end;
 
 
 
 
@@ -1103,12 +1109,10 @@ implementation
       var
       var
          oldprocinfo : tprocinfo;
          oldprocinfo : tprocinfo;
          oldblock_type : tblock_type;
          oldblock_type : tblock_type;
-         oldconstsymtable : tsymtable;
          st : tsymtable;
          st : tsymtable;
       begin
       begin
          oldprocinfo:=current_procinfo;
          oldprocinfo:=current_procinfo;
          oldblock_type:=block_type;
          oldblock_type:=block_type;
-         oldconstsymtable:=constsymtable;
 
 
          { reset break and continue labels }
          { reset break and continue labels }
          block_type:=bt_body;
          block_type:=bt_body;
@@ -1129,6 +1133,9 @@ implementation
 {    aktstate:=Tstate_storage.create;}
 {    aktstate:=Tstate_storage.create;}
     {$endif state_tracking}
     {$endif state_tracking}
 
 
+         { allocate the symbol for this procedure }
+         alloc_proc_symbol(procdef);
+
          { create a local symbol table for this routine }
          { create a local symbol table for this routine }
          if not assigned(procdef.localst) then
          if not assigned(procdef.localst) then
            procdef.insert_localst;
            procdef.insert_localst;
@@ -1136,9 +1143,6 @@ implementation
          { add parast/localst to symtablestack }
          { add parast/localst to symtablestack }
          add_to_symtablestack;
          add_to_symtablestack;
 
 
-         { constant symbols are inserted in this symboltable }
-         constsymtable:=symtablestack;
-
          { save entry info }
          { save entry info }
          entrypos:=aktfilepos;
          entrypos:=aktfilepos;
          entryswitches:=aktlocalswitches;
          entryswitches:=aktlocalswitches;
@@ -1236,7 +1240,6 @@ implementation
          current_procinfo:=oldprocinfo;
          current_procinfo:=oldprocinfo;
 
 
          { Restore old state }
          { Restore old state }
-         constsymtable:=oldconstsymtable;
          block_type:=oldblock_type;
          block_type:=oldblock_type;
       end;
       end;
 
 
@@ -1591,8 +1594,7 @@ implementation
                 read_proc;
                 read_proc;
               _EXPORTS:
               _EXPORTS:
                 begin
                 begin
-                   if not(assigned(current_procinfo.procdef.localst)) or
-                      (current_procinfo.procdef.localst.symtablelevel>main_program_level) then
+                   if (current_procinfo.procdef.localst.symtablelevel>main_program_level) then
                      begin
                      begin
                         Message(parser_e_syntax_error);
                         Message(parser_e_syntax_error);
                         consume_all_until(_SEMICOLON);
                         consume_all_until(_SEMICOLON);
@@ -1635,7 +1637,7 @@ implementation
          { check for incomplete class definitions, this is only required
          { check for incomplete class definitions, this is only required
            for fpc modes }
            for fpc modes }
          if (m_fpc in aktmodeswitches) then
          if (m_fpc in aktmodeswitches) then
-           symtablestack.foreach_static(@check_forward_class,nil);
+           current_procinfo.procdef.localst.foreach_static(@check_forward_class,nil);
       end;
       end;
 
 
 
 
@@ -1676,7 +1678,7 @@ implementation
          { check for incomplete class definitions, this is only required
          { check for incomplete class definitions, this is only required
            for fpc modes }
            for fpc modes }
          if (m_fpc in aktmodeswitches) then
          if (m_fpc in aktmodeswitches) then
-          symtablestack.foreach_static(@check_forward_class,nil);
+          symtablestack.top.foreach_static(@check_forward_class,nil);
       end;
       end;
 
 
 
 
@@ -1721,18 +1723,14 @@ implementation
 
 
 
 
     procedure generate_specialization_procs;
     procedure generate_specialization_procs;
-      var
-        oldsymtablestack : tsymtable;
       begin
       begin
         if assigned(current_module.globalsymtable) then
         if assigned(current_module.globalsymtable) then
           current_module.globalsymtable.foreach_static(@specialize_objectdefs,nil);
           current_module.globalsymtable.foreach_static(@specialize_objectdefs,nil);
         if assigned(current_module.localsymtable) then
         if assigned(current_module.localsymtable) then
           begin
           begin
-            oldsymtablestack:=symtablestack;
-            current_module.localsymtable.next:=symtablestack;
-            symtablestack:=current_module.localsymtable;
+            symtablestack.push(current_module.localsymtable);
             current_module.localsymtable.foreach_static(@specialize_objectdefs,nil);
             current_module.localsymtable.foreach_static(@specialize_objectdefs,nil);
-            symtablestack:=oldsymtablestack;
+            symtablestack.pop(current_module.localsymtable);
           end;
           end;
       end;
       end;
 
 

+ 136 - 154
compiler/psystem.pas

@@ -28,11 +28,10 @@ interface
     uses
     uses
       symbase;
       symbase;
 
 
-    procedure insertinternsyms(p : tsymtable);
-    procedure insert_intern_types(p : tsymtable);
+    procedure create_intern_symbols;
+    procedure create_intern_types;
 
 
-    procedure readconstdefs;
-    procedure createconstdefs;
+    procedure load_intern_types;
 
 
     procedure registernodes;
     procedure registernodes;
     procedure registertais;
     procedure registertais;
@@ -49,52 +48,52 @@ implementation
       ;
       ;
 
 
 
 
-    procedure insertinternsyms(p : tsymtable);
+    procedure create_intern_symbols;
       {
       {
         all intern procedures for the system unit
         all intern procedures for the system unit
       }
       }
       begin
       begin
-        p.insert(tsyssym.create('Concat',in_concat_x));
-        p.insert(tsyssym.create('Write',in_write_x));
-        p.insert(tsyssym.create('WriteLn',in_writeln_x));
-        p.insert(tsyssym.create('Assigned',in_assigned_x));
-        p.insert(tsyssym.create('Read',in_read_x));
-        p.insert(tsyssym.create('ReadLn',in_readln_x));
-        p.insert(tsyssym.create('Ofs',in_ofs_x));
-        p.insert(tsyssym.create('SizeOf',in_sizeof_x));
-        p.insert(tsyssym.create('TypeOf',in_typeof_x));
-        p.insert(tsyssym.create('Low',in_low_x));
-        p.insert(tsyssym.create('High',in_high_x));
-        p.insert(tsyssym.create('Slice',in_slice_x));
-        p.insert(tsyssym.create('Seg',in_seg_x));
-        p.insert(tsyssym.create('Ord',in_ord_x));
-        p.insert(tsyssym.create('Pred',in_pred_x));
-        p.insert(tsyssym.create('Succ',in_succ_x));
-        p.insert(tsyssym.create('Exclude',in_exclude_x_y));
-        p.insert(tsyssym.create('Include',in_include_x_y));
-        p.insert(tsyssym.create('Break',in_break));
-        p.insert(tsyssym.create('Exit',in_exit));
-        p.insert(tsyssym.create('Continue',in_continue));
-        p.insert(tsyssym.create('Leave',in_leave)); {macpas only}
-        p.insert(tsyssym.create('Cycle',in_cycle)); {macpas only}
-        p.insert(tsyssym.create('Dec',in_dec_x));
-        p.insert(tsyssym.create('Inc',in_inc_x));
-        p.insert(tsyssym.create('Str',in_str_x_string));
-        p.insert(tsyssym.create('Assert',in_assert_x_y));
-        p.insert(tsyssym.create('Val',in_val_x));
-        p.insert(tsyssym.create('Addr',in_addr_x));
-        p.insert(tsyssym.create('TypeInfo',in_typeinfo_x));
-        p.insert(tsyssym.create('SetLength',in_setlength_x));
-        p.insert(tsyssym.create('Copy',in_copy_x));
-        p.insert(tsyssym.create('Initialize',in_initialize_x));
-        p.insert(tsyssym.create('Finalize',in_finalize_x));
-        p.insert(tsyssym.create('Length',in_length_x));
-        p.insert(tsyssym.create('New',in_new_x));
-        p.insert(tsyssym.create('Dispose',in_dispose_x));
+        systemunit.insert(tsyssym.create('Concat',in_concat_x));
+        systemunit.insert(tsyssym.create('Write',in_write_x));
+        systemunit.insert(tsyssym.create('WriteLn',in_writeln_x));
+        systemunit.insert(tsyssym.create('Assigned',in_assigned_x));
+        systemunit.insert(tsyssym.create('Read',in_read_x));
+        systemunit.insert(tsyssym.create('ReadLn',in_readln_x));
+        systemunit.insert(tsyssym.create('Ofs',in_ofs_x));
+        systemunit.insert(tsyssym.create('SizeOf',in_sizeof_x));
+        systemunit.insert(tsyssym.create('TypeOf',in_typeof_x));
+        systemunit.insert(tsyssym.create('Low',in_low_x));
+        systemunit.insert(tsyssym.create('High',in_high_x));
+        systemunit.insert(tsyssym.create('Slice',in_slice_x));
+        systemunit.insert(tsyssym.create('Seg',in_seg_x));
+        systemunit.insert(tsyssym.create('Ord',in_ord_x));
+        systemunit.insert(tsyssym.create('Pred',in_pred_x));
+        systemunit.insert(tsyssym.create('Succ',in_succ_x));
+        systemunit.insert(tsyssym.create('Exclude',in_exclude_x_y));
+        systemunit.insert(tsyssym.create('Include',in_include_x_y));
+        systemunit.insert(tsyssym.create('Break',in_break));
+        systemunit.insert(tsyssym.create('Exit',in_exit));
+        systemunit.insert(tsyssym.create('Continue',in_continue));
+        systemunit.insert(tsyssym.create('Leave',in_leave)); {macpas only}
+        systemunit.insert(tsyssym.create('Cycle',in_cycle)); {macpas only}
+        systemunit.insert(tsyssym.create('Dec',in_dec_x));
+        systemunit.insert(tsyssym.create('Inc',in_inc_x));
+        systemunit.insert(tsyssym.create('Str',in_str_x_string));
+        systemunit.insert(tsyssym.create('Assert',in_assert_x_y));
+        systemunit.insert(tsyssym.create('Val',in_val_x));
+        systemunit.insert(tsyssym.create('Addr',in_addr_x));
+        systemunit.insert(tsyssym.create('TypeInfo',in_typeinfo_x));
+        systemunit.insert(tsyssym.create('SetLength',in_setlength_x));
+        systemunit.insert(tsyssym.create('Copy',in_copy_x));
+        systemunit.insert(tsyssym.create('Initialize',in_initialize_x));
+        systemunit.insert(tsyssym.create('Finalize',in_finalize_x));
+        systemunit.insert(tsyssym.create('Length',in_length_x));
+        systemunit.insert(tsyssym.create('New',in_new_x));
+        systemunit.insert(tsyssym.create('Dispose',in_dispose_x));
       end;
       end;
 
 
 
 
-    procedure insert_intern_types(p : tsymtable);
+    procedure create_intern_types;
       {
       {
         all the types inserted into the system unit
         all the types inserted into the system unit
       }
       }
@@ -102,7 +101,7 @@ implementation
         function addtype(const s:string;const t:ttype):ttypesym;
         function addtype(const s:string;const t:ttype):ttypesym;
         begin
         begin
           result:=ttypesym.create(s,t);
           result:=ttypesym.create(s,t);
-          p.insert(result);
+          systemunit.insert(result);
           { add init/final table if required }
           { add init/final table if required }
           if t.def.needs_inittable then
           if t.def.needs_inittable then
            generate_inittable(result);
            generate_inittable(result);
@@ -113,12 +112,93 @@ implementation
           t : ttype;
           t : ttype;
         begin
         begin
           t.setdef(def);
           t.setdef(def);
-          p.insert(ttypesym.create(s,t));
+          systemunit.insert(ttypesym.create(s,t));
         end;
         end;
 
 
       var
       var
         hrecst : trecordsymtable;
         hrecst : trecordsymtable;
       begin
       begin
+        symtablestack.push(systemunit);
+        cundefinedtype.setdef(tundefineddef.create);
+        cformaltype.setdef(tformaldef.create);
+        voidtype.setdef(torddef.create(uvoid,0,0));
+        u8inttype.setdef(torddef.create(u8bit,0,255));
+        s8inttype.setdef(torddef.create(s8bit,-128,127));
+        u16inttype.setdef(torddef.create(u16bit,0,65535));
+        s16inttype.setdef(torddef.create(s16bit,-32768,32767));
+        u32inttype.setdef(torddef.create(u32bit,0,high(longword)));
+        s32inttype.setdef(torddef.create(s32bit,low(longint),high(longint)));
+        u64inttype.setdef(torddef.create(u64bit,low(qword),TConstExprInt(high(qword))));
+        s64inttype.setdef(torddef.create(s64bit,low(int64),high(int64)));
+        booltype.setdef(torddef.create(bool8bit,0,1));
+        cchartype.setdef(torddef.create(uchar,0,255));
+        cwidechartype.setdef(torddef.create(uwidechar,0,65535));
+        cshortstringtype.setdef(tstringdef.createshort(255));
+        { should we give a length to the default long and ansi string definition ?? }
+        clongstringtype.setdef(tstringdef.createlong(-1));
+        cansistringtype.setdef(tstringdef.createansi(-1));
+        cwidestringtype.setdef(tstringdef.createwide(-1));
+        { length=0 for shortstring is open string (needed for readln(string) }
+        openshortstringtype.setdef(tstringdef.createshort(0));
+        openchararraytype.setdef(tarraydef.create(0,-1,s32inttype));
+        tarraydef(openchararraytype.def).setelementtype(cchartype);
+{$ifdef x86}
+        s32floattype.setdef(tfloatdef.create(s32real));
+        s64floattype.setdef(tfloatdef.create(s64real));
+        s80floattype.setdef(tfloatdef.create(s80real));
+        if target_info.system<>system_x86_64_win64 then
+          s64currencytype.setdef(tfloatdef.create(s64currency))
+        else
+          s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
+{$endif x86}
+{$ifdef powerpc}
+        s32floattype.setdef(tfloatdef.create(s32real));
+        s64floattype.setdef(tfloatdef.create(s64real));
+        s80floattype.setdef(tfloatdef.create(s80real));
+        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
+{$endif powerpc}
+{$ifdef POWERPC64}
+        s32floattype.setdef(tfloatdef.create(s32real));
+        s64floattype.setdef(tfloatdef.create(s64real));
+        s80floattype.setdef(tfloatdef.create(s80real));
+        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
+{$endif POWERPC64}
+{$ifdef sparc}
+        s32floattype.setdef(tfloatdef.create(s32real));
+        s64floattype.setdef(tfloatdef.create(s64real));
+        s80floattype.setdef(tfloatdef.create(s80real));
+        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
+{$endif sparc}
+{$ifdef m68k}
+        s32floattype.setdef(tfloatdef.create(s32real));
+        s64floattype.setdef(tfloatdef.create(s64real));
+        s80floattype.setdef(tfloatdef.create(s80real));
+        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
+{$endif}
+{$ifdef arm}
+        s32floattype.setdef(tfloatdef.create(s32real));
+        s64floattype.setdef(tfloatdef.create(s64real));
+        s80floattype.setdef(tfloatdef.create(s80real));
+        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
+{$endif arm}
+{$ifdef cpu64bit}
+        uinttype:=u64inttype;
+        sinttype:=s64inttype;
+        ptrinttype:=u64inttype;
+{$else cpu64bit}
+        uinttype:=u32inttype;
+        sinttype:=s32inttype;
+        ptrinttype:=u32inttype;
+{$endif cpu64bit}
+        { some other definitions }
+        voidpointertype.setdef(tpointerdef.create(voidtype));
+        charpointertype.setdef(tpointerdef.create(cchartype));
+        widecharpointertype.setdef(tpointerdef.create(cwidechartype));
+        voidfarpointertype.setdef(tpointerdef.createfar(voidtype));
+        cfiletype.setdef(tfiledef.createuntyped);
+        cvarianttype.setdef(tvariantdef.create(vt_normalvariant));
+        colevarianttype.setdef(tvariantdef.create(vt_olevariant));
+
         if target_info.system=system_x86_64_win64 then
         if target_info.system=system_x86_64_win64 then
           pbestrealtype:=@s64floattype;
           pbestrealtype:=@s64floattype;
 
 
@@ -214,12 +294,12 @@ implementation
         hrecst:=trecordsymtable.create(aktpackrecords);
         hrecst:=trecordsymtable.create(aktpackrecords);
         vmttype.setdef(trecorddef.create(hrecst));
         vmttype.setdef(trecorddef.create(hrecst));
         pvmttype.setdef(tpointerdef.create(vmttype));
         pvmttype.setdef(tpointerdef.create(vmttype));
-        hrecst.insertfield(tfieldvarsym.create('$parent',vs_value,pvmttype,[]),true);
-        hrecst.insertfield(tfieldvarsym.create('$length',vs_value,s32inttype,[]),true);
-        hrecst.insertfield(tfieldvarsym.create('$mlength',vs_value,s32inttype,[]),true);
+        hrecst.insertfield(tfieldvarsym.create('$parent',vs_value,pvmttype,[]));
+        hrecst.insertfield(tfieldvarsym.create('$length',vs_value,s32inttype,[]));
+        hrecst.insertfield(tfieldvarsym.create('$mlength',vs_value,s32inttype,[]));
         vmtarraytype.setdef(tarraydef.create(0,1,s32inttype));
         vmtarraytype.setdef(tarraydef.create(0,1,s32inttype));
         tarraydef(vmtarraytype.def).setelementtype(voidpointertype);
         tarraydef(vmtarraytype.def).setelementtype(voidpointertype);
-        hrecst.insertfield(tfieldvarsym.create('$__pfn',vs_value,vmtarraytype,[]),true);
+        hrecst.insertfield(tfieldvarsym.create('$__pfn',vs_value,vmtarraytype,[]));
         addtype('$__vtbl_ptr_type',vmttype);
         addtype('$__vtbl_ptr_type',vmttype);
         addtype('$pvmt',pvmttype);
         addtype('$pvmt',pvmttype);
         vmtarraytype.setdef(tarraydef.create(0,1,s32inttype));
         vmtarraytype.setdef(tarraydef.create(0,1,s32inttype));
@@ -227,30 +307,25 @@ implementation
         addtype('$vtblarray',vmtarraytype);
         addtype('$vtblarray',vmtarraytype);
         { Add a type for methodpointers }
         { Add a type for methodpointers }
         hrecst:=trecordsymtable.create(1);
         hrecst:=trecordsymtable.create(1);
-        hrecst.insertfield(tfieldvarsym.create('$proc',vs_value,voidpointertype,[]),true);
-        hrecst.insertfield(tfieldvarsym.create('$self',vs_value,voidpointertype,[]),true);
+        hrecst.insertfield(tfieldvarsym.create('$proc',vs_value,voidpointertype,[]));
+        hrecst.insertfield(tfieldvarsym.create('$self',vs_value,voidpointertype,[]));
         methodpointertype.setdef(trecorddef.create(hrecst));
         methodpointertype.setdef(trecorddef.create(hrecst));
         addtype('$methodpointer',methodpointertype);
         addtype('$methodpointer',methodpointertype);
-      { Add functions that require compiler magic }
-        insertinternsyms(p);
+        symtablestack.pop(systemunit);
       end;
       end;
 
 
 
 
-    procedure readconstdefs;
+    procedure load_intern_types;
       {
       {
         Load all default definitions for consts from the system unit
         Load all default definitions for consts from the system unit
       }
       }
 
 
-
         procedure loadtype(const s:string;var t:ttype);
         procedure loadtype(const s:string;var t:ttype);
         var
         var
-          srsym : tsym;
+          srsym : ttypesym;
         begin
         begin
-          srsym:=searchsymonlyin(systemunit,s);
-          if not(assigned(srsym) and
-                 (srsym.typ=typesym)) then
-            internalerror(200403231);
-          t:=ttypesym(srsym).restype;
+          srsym:=search_system_type(s);
+          t:=srsym.restype;
         end;
         end;
 
 
       var
       var
@@ -306,99 +381,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure createconstdefs;
-      {
-        Create all default definitions for consts for the system unit
-      }
-      var
-        oldregisterdef : boolean;
-      begin
-        { create definitions for constants }
-        oldregisterdef:=registerdef;
-        registerdef:=false;
-        cundefinedtype.setdef(tundefineddef.create);
-        cformaltype.setdef(tformaldef.create);
-        voidtype.setdef(torddef.create(uvoid,0,0));
-        u8inttype.setdef(torddef.create(u8bit,0,255));
-        s8inttype.setdef(torddef.create(s8bit,-128,127));
-        u16inttype.setdef(torddef.create(u16bit,0,65535));
-        s16inttype.setdef(torddef.create(s16bit,-32768,32767));
-        u32inttype.setdef(torddef.create(u32bit,0,high(longword)));
-        s32inttype.setdef(torddef.create(s32bit,low(longint),high(longint)));
-        u64inttype.setdef(torddef.create(u64bit,low(qword),TConstExprInt(high(qword))));
-        s64inttype.setdef(torddef.create(s64bit,low(int64),high(int64)));
-        booltype.setdef(torddef.create(bool8bit,0,1));
-        cchartype.setdef(torddef.create(uchar,0,255));
-        cwidechartype.setdef(torddef.create(uwidechar,0,65535));
-        cshortstringtype.setdef(tstringdef.createshort(255));
-        { should we give a length to the default long and ansi string definition ?? }
-        clongstringtype.setdef(tstringdef.createlong(-1));
-        cansistringtype.setdef(tstringdef.createansi(-1));
-        cwidestringtype.setdef(tstringdef.createwide(-1));
-        { length=0 for shortstring is open string (needed for readln(string) }
-        openshortstringtype.setdef(tstringdef.createshort(0));
-        openchararraytype.setdef(tarraydef.create(0,-1,s32inttype));
-        tarraydef(openchararraytype.def).setelementtype(cchartype);
-{$ifdef x86}
-        s32floattype.setdef(tfloatdef.create(s32real));
-        s64floattype.setdef(tfloatdef.create(s64real));
-        s80floattype.setdef(tfloatdef.create(s80real));
-        if target_info.system<>system_x86_64_win64 then
-          s64currencytype.setdef(tfloatdef.create(s64currency))
-        else
-          s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
-{$endif x86}
-{$ifdef powerpc}
-        s32floattype.setdef(tfloatdef.create(s32real));
-        s64floattype.setdef(tfloatdef.create(s64real));
-        s80floattype.setdef(tfloatdef.create(s80real));
-        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
-{$endif powerpc}
-{$ifdef POWERPC64}
-        s32floattype.setdef(tfloatdef.create(s32real));
-        s64floattype.setdef(tfloatdef.create(s64real));
-        s80floattype.setdef(tfloatdef.create(s80real));
-        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
-{$endif POWERPC64}
-{$ifdef sparc}
-        s32floattype.setdef(tfloatdef.create(s32real));
-        s64floattype.setdef(tfloatdef.create(s64real));
-        s80floattype.setdef(tfloatdef.create(s80real));
-        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
-{$endif sparc}
-{$ifdef m68k}
-        s32floattype.setdef(tfloatdef.create(s32real));
-        s64floattype.setdef(tfloatdef.create(s64real));
-        s80floattype.setdef(tfloatdef.create(s80real));
-        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
-{$endif}
-{$ifdef arm}
-        s32floattype.setdef(tfloatdef.create(s32real));
-        s64floattype.setdef(tfloatdef.create(s64real));
-        s80floattype.setdef(tfloatdef.create(s80real));
-        s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
-{$endif arm}
-{$ifdef cpu64bit}
-        uinttype:=u64inttype;
-        sinttype:=s64inttype;
-        ptrinttype:=u64inttype;
-{$else cpu64bit}
-        uinttype:=u32inttype;
-        sinttype:=s32inttype;
-        ptrinttype:=u32inttype;
-{$endif cpu64bit}
-        { some other definitions }
-        voidpointertype.setdef(tpointerdef.create(voidtype));
-        charpointertype.setdef(tpointerdef.create(cchartype));
-        widecharpointertype.setdef(tpointerdef.create(cwidechartype));
-        voidfarpointertype.setdef(tpointerdef.createfar(voidtype));
-        cfiletype.setdef(tfiledef.createuntyped);
-        cvarianttype.setdef(tvariantdef.create(vt_normalvariant));
-        colevarianttype.setdef(tvariantdef.create(vt_olevariant));
-        registerdef:=oldregisterdef;
-      end;
-
-
     procedure registernodes;
     procedure registernodes;
       {
       {
         Register all possible nodes in the nodeclass array that
         Register all possible nodes in the nodeclass array that

+ 14 - 36
compiler/ptype.pas

@@ -183,8 +183,7 @@ implementation
          { use of current parsed object:
          { use of current parsed object:
             - classes can be used also in classes
             - classes can be used also in classes
             - objects can be parameters }
             - objects can be parameters }
-         if (token=_ID) and
-            assigned(aktobjectdef) and
+         if assigned(aktobjectdef) and
             (aktobjectdef.objname^=pattern) and
             (aktobjectdef.objname^=pattern) and
             (
             (
              (testcurobject=2) or
              (testcurobject=2) or
@@ -195,38 +194,18 @@ implementation
              tt.setdef(aktobjectdef);
              tt.setdef(aktobjectdef);
              exit;
              exit;
            end;
            end;
-         { try to load the symbol to see if it's a unitsym. Use the
-           special searchsym_type that ignores records,objects and
+         { Use the special searchsym_type that ignores records,objects and
            parameters }
            parameters }
-         is_unit_specific:=false;
          searchsym_type(s,srsym,srsymtable);
          searchsym_type(s,srsym,srsymtable);
+         { handle unit specification like System.Writeln }
+         is_unit_specific:=try_consume_unitsym(srsym,srsymtable);
          consume(_ID);
          consume(_ID);
-         if assigned(srsym) and
-            (srsym.typ=unitsym) then
-           begin
-              is_unit_specific:=true;
-              consume(_POINT);
-              if not(srsym.owner.symtabletype in [staticsymtable,globalsymtable]) then
-                internalerror(200501155);
-              { only allow unit.symbol access if the name was
-                found in the current module }
-              if srsym.owner.iscurrentunit then
-               begin
-                 srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,pattern);
-                 pos:=akttokenpos;
-                 s:=pattern;
-               end
-              else
-               srsym:=nil;
-              consume(_ID);
-           end;
          { Types are first defined with an error def before assigning
          { Types are first defined with an error def before assigning
            the real type so check if it's an errordef. if so then
            the real type so check if it's an errordef. if so then
            give an error. Only check for typesyms in the current symbol
            give an error. Only check for typesyms in the current symbol
            table as forwarddef are not resolved directly }
            table as forwarddef are not resolved directly }
          if assigned(srsym) and
          if assigned(srsym) and
             (srsym.typ=typesym) and
             (srsym.typ=typesym) and
-            (srsym.owner=symtablestack) and
             (ttypesym(srsym).restype.def.deftype=errordef) then
             (ttypesym(srsym).restype.def.deftype=errordef) then
           begin
           begin
             Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
             Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
@@ -313,16 +292,15 @@ implementation
     function record_dec : tdef;
     function record_dec : tdef;
 
 
       var
       var
-         symtable : tsymtable;
+         recst : trecordsymtable;
          storetypecanbeforward : boolean;
          storetypecanbeforward : boolean;
          old_object_option : tsymoptions;
          old_object_option : tsymoptions;
       begin
       begin
          { create recdef }
          { create recdef }
-         symtable:=trecordsymtable.create(aktpackrecords);
-         record_dec:=trecorddef.create(symtable);
-         { update symtable stack }
-         symtable.next:=symtablestack;
-         symtablestack:=symtable;
+         recst:=trecordsymtable.create(aktpackrecords);
+         record_dec:=trecorddef.create(recst);
+         { insert in symtablestack }
+         symtablestack.push(recst);
          { parse record }
          { parse record }
          consume(_RECORD);
          consume(_RECORD);
          old_object_option:=current_object_option;
          old_object_option:=current_object_option;
@@ -331,14 +309,14 @@ implementation
          { for tp7 don't allow forward types }
          { for tp7 don't allow forward types }
          if m_tp7 in aktmodeswitches then
          if m_tp7 in aktmodeswitches then
            typecanbeforward:=false;
            typecanbeforward:=false;
-         read_var_decs([vd_record]);
+         read_record_fields([vd_record]);
          consume(_END);
          consume(_END);
          typecanbeforward:=storetypecanbeforward;
          typecanbeforward:=storetypecanbeforward;
          current_object_option:=old_object_option;
          current_object_option:=old_object_option;
          { make the record size aligned }
          { make the record size aligned }
-         trecordsymtable(symtablestack).addalignmentpadding;
+         recst.addalignmentpadding;
          { restore symtable stack }
          { restore symtable stack }
-         symtablestack:=symtable.next;
+         symtablestack.pop(recst);
       end;
       end;
 
 
 
 
@@ -579,7 +557,7 @@ implementation
         pd : tabstractprocdef;
         pd : tabstractprocdef;
         is_func,
         is_func,
         enumdupmsg : boolean;
         enumdupmsg : boolean;
-        newtype : ttypesym;
+        newtype    : ttypesym;
         oldlocalswitches : tlocalswitches;
         oldlocalswitches : tlocalswitches;
       begin
       begin
          tt.reset;
          tt.reset;
@@ -640,7 +618,7 @@ implementation
                     inc(l);
                     inc(l);
                   storepos:=akttokenpos;
                   storepos:=akttokenpos;
                   akttokenpos:=defpos;
                   akttokenpos:=defpos;
-                  constsymtable.insert(tenumsym.create(s,aktenumdef,l));
+                  tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l));
                   akttokenpos:=storepos;
                   akttokenpos:=storepos;
                 until not try_to_consume(_COMMA);
                 until not try_to_consume(_COMMA);
                 tt.setdef(aktenumdef);
                 tt.setdef(aktenumdef);

+ 16 - 13
compiler/rautils.pas

@@ -1160,20 +1160,23 @@ begin
   i:=pos('.',s);
   i:=pos('.',s);
   { allow unit.identifier }
   { allow unit.identifier }
   if i>0 then
   if i>0 then
-   begin
-     searchsym(Copy(s,1,i-1),srsym,srsymtable);
-     if assigned(srsym) then
-      begin
-        if (srsym.typ=unitsym) and
-           (srsym.owner.symtabletype in [staticsymtable,globalsymtable]) and
-           srsym.owner.iscurrentunit then
-         srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,Copy(s,i+1,255))
-        else
-         srsym:=nil;
-      end;
-   end
+    begin
+      searchsym(Copy(s,1,i-1),srsym,srsymtable);
+      if assigned(srsym) then
+       begin
+         if (srsym.typ=unitsym) and
+            (srsym.owner.symtabletype in [staticsymtable,globalsymtable]) and
+            srsym.owner.iscurrentunit then
+           searchsym_in_module(tunitsym(srsym).module,Copy(s,i+1,255),srsym,srsymtable)
+         else
+           begin
+             srsym:=nil;
+             srsymtable:=nil;
+           end;
+       end;
+    end
   else
   else
-   searchsym(s,srsym,srsymtable);
+    searchsym(s,srsym,srsymtable);
 end;
 end;
 
 
 
 

+ 1 - 3
compiler/scandir.pas

@@ -660,9 +660,7 @@ implementation
           if not current_module.mode_switch_allowed and
           if not current_module.mode_switch_allowed and
               not ((m_mac in aktmodeswitches) and (pattern='MACPAS')) then
               not ((m_mac in aktmodeswitches) and (pattern='MACPAS')) then
             Message1(scan_e_mode_switch_not_allowed,pattern)
             Message1(scan_e_mode_switch_not_allowed,pattern)
-          else if SetCompileMode(pattern,false) then
-            ConsolidateMode
-          else
+          else if not SetCompileMode(pattern,false) then
             Message1(scan_w_illegal_switch,pattern)
             Message1(scan_w_illegal_switch,pattern)
         end;
         end;
       current_module.mode_switch_allowed:= false;
       current_module.mode_switch_allowed:= false;

+ 15 - 33
compiler/scanner.pas

@@ -192,7 +192,6 @@ interface
     procedure DoneScanner;
     procedure DoneScanner;
 
 
     {To be called when the language mode is finally determined}
     {To be called when the language mode is finally determined}
-    procedure ConsolidateMode;
     Function SetCompileMode(const s:string; changeInit: boolean):boolean;
     Function SetCompileMode(const s:string; changeInit: boolean):boolean;
 
 
 
 
@@ -247,21 +246,7 @@ implementation
       end;
       end;
 
 
 
 
-    {To be called when the language mode is finally determined}
-    procedure ConsolidateMode;
-
-    begin
-      if m_mac in aktmodeswitches then
-        if current_module.is_unit and not assigned(current_module.globalmacrosymtable) then
-          begin
-            current_module.globalmacrosymtable:= tmacrosymtable.create(true);
-            current_module.globalmacrosymtable.next:= current_module.localmacrosymtable;
-            macrosymtablestack:=current_module.globalmacrosymtable;
-          end;
-    end;
-
-
-      Function SetCompileMode(const s:string; changeInit: boolean):boolean;
+    Function SetCompileMode(const s:string; changeInit: boolean):boolean;
       var
       var
         b : boolean;
         b : boolean;
         oldaktmodeswitches : tmodeswitches;
         oldaktmodeswitches : tmodeswitches;
@@ -1109,7 +1094,7 @@ In case not, the value returned can be arbitrary.
                      CTEError(exprType2, [ctetSet], 'IN');
                      CTEError(exprType2, [ctetSet], 'IN');
                    if exprType = [ctetSet] then
                    if exprType = [ctetSet] then
                      CTEError(exprType, setElementTypes, 'IN');
                      CTEError(exprType, setElementTypes, 'IN');
-    
+
                   if is_number(hs1) and is_number(hs2) then
                   if is_number(hs1) and is_number(hs2) then
                     Message(scan_e_preproc_syntax_error)
                     Message(scan_e_preproc_syntax_error)
                   else if hs2[1] = ',' then
                   else if hs2[1] = ',' then
@@ -1121,7 +1106,7 @@ In case not, the value returned can be arbitrary.
                  begin
                  begin
                    if (exprType * exprType2) = [] then
                    if (exprType * exprType2) = [] then
                      CTEError(exprType2, exprType, tokeninfo^[op].str);
                      CTEError(exprType2, exprType, tokeninfo^[op].str);
-    
+
                    if is_number(hs1) and is_number(hs2) then
                    if is_number(hs1) and is_number(hs2) then
                      begin
                      begin
                        val(hs1,l1,w);
                        val(hs1,l1,w);
@@ -1210,12 +1195,12 @@ In case not, the value returned can be arbitrary.
         current_scanner.skipspace;
         current_scanner.skipspace;
         hs:=current_scanner.readid;
         hs:=current_scanner.readid;
         mac:=tmacro(search_macro(hs));
         mac:=tmacro(search_macro(hs));
-        if not assigned(mac) or (mac.owner <> macrosymtablestack) then
+        if not assigned(mac) or (mac.owner <> current_module.localmacrosymtable) then
           begin
           begin
             mac:=tmacro.create(hs);
             mac:=tmacro.create(hs);
             mac.defined:=true;
             mac.defined:=true;
             Message1(parser_c_macro_defined,mac.name);
             Message1(parser_c_macro_defined,mac.name);
-            macrosymtablestack.insert(mac);
+            current_module.localmacrosymtable.insert(mac);
           end
           end
         else
         else
           begin
           begin
@@ -1232,7 +1217,6 @@ In case not, the value returned can be arbitrary.
         mac.is_used:=true;
         mac.is_used:=true;
         if (cs_support_macro in aktmoduleswitches) then
         if (cs_support_macro in aktmoduleswitches) then
           begin
           begin
-             { !!!!!! handle macro params, need we this? }
              current_scanner.skipspace;
              current_scanner.skipspace;
 
 
              if not macstyle then
              if not macstyle then
@@ -1322,13 +1306,14 @@ In case not, the value returned can be arbitrary.
         current_scanner.skipspace;
         current_scanner.skipspace;
         hs:=current_scanner.readid;
         hs:=current_scanner.readid;
         mac:=tmacro(search_macro(hs));
         mac:=tmacro(search_macro(hs));
-        if not assigned(mac) or (mac.owner <> macrosymtablestack) then
+        if not assigned(mac) or
+           (mac.owner <> current_module.localmacrosymtable) then
           begin
           begin
             mac:=tmacro.create(hs);
             mac:=tmacro.create(hs);
             mac.defined:=true;
             mac.defined:=true;
             mac.is_compiler_var:=true;
             mac.is_compiler_var:=true;
             Message1(parser_c_macro_defined,mac.name);
             Message1(parser_c_macro_defined,mac.name);
-            macrosymtablestack.insert(mac);
+            current_module.localmacrosymtable.insert(mac);
           end
           end
         else
         else
           begin
           begin
@@ -1343,18 +1328,14 @@ In case not, the value returned can be arbitrary.
           end;
           end;
         mac.is_used:=true;
         mac.is_used:=true;
 
 
-
         { key words are never substituted }
         { key words are never substituted }
-           if is_keyword(hs) then
-            Message(scan_e_keyword_cant_be_a_macro);
-         { !!!!!! handle macro params, need we this? }
-           current_scanner.skipspace;
-         { may be a macro? }
+        if is_keyword(hs) then
+          Message(scan_e_keyword_cant_be_a_macro);
 
 
-        { assignment can be both := and = }
+        { macro assignment can be both := and = }
+        current_scanner.skipspace;
         if c=':' then
         if c=':' then
           current_scanner.readchar;
           current_scanner.readchar;
-
         if c='=' then
         if c='=' then
           begin
           begin
              current_scanner.readchar;
              current_scanner.readchar;
@@ -1400,12 +1381,13 @@ In case not, the value returned can be arbitrary.
         current_scanner.skipspace;
         current_scanner.skipspace;
         hs:=current_scanner.readid;
         hs:=current_scanner.readid;
         mac:=tmacro(search_macro(hs));
         mac:=tmacro(search_macro(hs));
-        if not assigned(mac) or (mac.owner <> macrosymtablestack) then
+        if not assigned(mac) or
+           (mac.owner <> current_module.localmacrosymtable) then
           begin
           begin
              mac:=tmacro.create(hs);
              mac:=tmacro.create(hs);
              Message1(parser_c_macro_undefined,mac.name);
              Message1(parser_c_macro_undefined,mac.name);
              mac.defined:=false;
              mac.defined:=false;
-             macrosymtablestack.insert(mac);
+             current_module.localmacrosymtable.insert(mac);
           end
           end
         else
         else
           begin
           begin

+ 18 - 19
compiler/symbase.pas

@@ -94,7 +94,6 @@ interface
           symindex,
           symindex,
           defindex  : TIndexArray;
           defindex  : TIndexArray;
           symsearch : Tdictionary;
           symsearch : Tdictionary;
-          next      : tsymtable;
           defowner  : tdefentry; { for records and objects }
           defowner  : tdefentry; { for records and objects }
           symtabletype  : tsymtabletype;
           symtabletype  : tsymtabletype;
           { level of symtable, used for nested procedures }
           { level of symtable, used for nested procedures }
@@ -109,13 +108,13 @@ interface
           function  rename(const olds,news : stringid):tsymentry;
           function  rename(const olds,news : stringid):tsymentry;
           procedure foreach(proc2call : tnamedindexcallback;arg:pointer);
           procedure foreach(proc2call : tnamedindexcallback;arg:pointer);
           procedure foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
           procedure foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
+          function  checkduplicate(sym : tsymentry):boolean;virtual;
           procedure insert(sym : tsymentry);virtual;
           procedure insert(sym : tsymentry);virtual;
-          { deletes a tsymentry and removes it from the tsymtable}
           procedure delete(sym:tsymentry);
           procedure delete(sym:tsymentry);
           procedure replace(oldsym,newsym:tsymentry);
           procedure replace(oldsym,newsym:tsymentry);
           function  search(const s : stringid) : tsymentry;
           function  search(const s : stringid) : tsymentry;
           function  speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;virtual;
           function  speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;virtual;
-          procedure registerdef(p : tdefentry);
+          procedure insertdef(def:tdefentry);virtual;
           function  iscurrentunit:boolean;virtual;
           function  iscurrentunit:boolean;virtual;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
           procedure dump;
           procedure dump;
@@ -125,13 +124,6 @@ interface
        end;
        end;
 
 
     var
     var
-       registerdef : boolean;      { true, when defs should be registered }
-
-       defaultsymtablestack : tsymtable;  { symtablestack after default units have been loaded }
-       symtablestack     : tsymtable;     { linked list of symtables }
-       defaultmacrosymtablestack : tsymtable;{ macrosymtablestack after default units have been loaded }
-       macrosymtablestack: tsymtable;     { linked list of macro symtables }
-
        aktrecordsymtable : tsymtable;     { current record symtable }
        aktrecordsymtable : tsymtable;     { current record symtable }
        aktparasymtable   : tsymtable;     { current proc para symtable }
        aktparasymtable   : tsymtable;     { current proc para symtable }
        aktlocalsymtable  : tsymtable;     { current proc local symtable }
        aktlocalsymtable  : tsymtable;     { current proc local symtable }
@@ -164,7 +156,6 @@ implementation
          symtabletype:=abstractsymtable;
          symtabletype:=abstractsymtable;
          symtablelevel:=0;
          symtablelevel:=0;
          defowner:=nil;
          defowner:=nil;
-         next:=nil;
          symindex:=tindexarray.create(indexgrowsize);
          symindex:=tindexarray.create(indexgrowsize);
          defindex:=TIndexArray.create(indexgrowsize);
          defindex:=TIndexArray.create(indexgrowsize);
          symsearch:=tdictionary.create;
          symsearch:=tdictionary.create;
@@ -224,14 +215,6 @@ implementation
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
 
 
 
 
-    procedure tsymtable.registerdef(p : tdefentry);
-      begin
-         defindex.insert(p);
-         { set def owner and indexnb }
-         p.owner:=self;
-      end;
-
-
     function tsymtable.iscurrentunit:boolean;
     function tsymtable.iscurrentunit:boolean;
       begin
       begin
         result:=false;
         result:=false;
@@ -261,14 +244,29 @@ implementation
       end;
       end;
 
 
 
 
+    function tsymtable.checkduplicate(sym : tsymentry):boolean;
+      begin
+        result:=(speedsearch(sym.name,sym.speedvalue)<>nil);
+      end;
+
+
     procedure tsymtable.insert(sym:tsymentry);
     procedure tsymtable.insert(sym:tsymentry);
       begin
       begin
+         checkduplicate(sym);
          sym.owner:=self;
          sym.owner:=self;
          { insert in index and search hash }
          { insert in index and search hash }
          symindex.insert(sym);
          symindex.insert(sym);
          symsearch.insert(sym);
          symsearch.insert(sym);
       end;
       end;
 
 
+
+    procedure tsymtable.insertdef(def:tdefentry);
+      begin
+         def.owner:=self;
+         defindex.insert(def);
+      end;
+
+
     procedure tsymtable.delete(sym:tsymentry);
     procedure tsymtable.delete(sym:tsymentry);
       begin
       begin
          sym.owner:=nil;
          sym.owner:=nil;
@@ -277,6 +275,7 @@ implementation
          symindex.delete(sym);
          symindex.delete(sym);
       end;
       end;
 
 
+
     procedure tsymtable.replace(oldsym,newsym:tsymentry);
     procedure tsymtable.replace(oldsym,newsym:tsymentry);
       begin
       begin
          { Replace the entry in the dictionary, this checks
          { Replace the entry in the dictionary, this checks

+ 147 - 206
compiler/symdef.pas

@@ -66,13 +66,12 @@ interface
           genericdef      : tstoreddef;
           genericdef      : tstoreddef;
           genericdefderef : tderef;
           genericdefderef : tderef;
           generictokenbuf : tdynamicarray;
           generictokenbuf : tdynamicarray;
-          constructor create;
-          constructor ppuloaddef(ppufile:tcompilerppufile);
+          constructor create(dt:tdeftype);
+          constructor ppuload(dt:tdeftype;ppufile:tcompilerppufile);
           destructor  destroy;override;
           destructor  destroy;override;
           procedure reset;virtual;
           procedure reset;virtual;
           function getcopy : tstoreddef;virtual;
           function getcopy : tstoreddef;virtual;
-          procedure ppuwritedef(ppufile:tcompilerppufile);
-          procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
+          procedure ppuwrite(ppufile:tcompilerppufile);virtual;
           procedure buildderef;override;
           procedure buildderef;override;
           procedure buildderefimpl;override;
           procedure buildderefimpl;override;
           procedure deref;override;
           procedure deref;override;
@@ -156,21 +155,22 @@ interface
           function  getmangledparaname : string;override;
           function  getmangledparaname : string;override;
        end;
        end;
 
 
-       { tpointerdef and tclassrefdef should get a common
-         base class, but I derived tclassrefdef from tpointerdef
-         to avoid problems with bugs (FK)
-       }
-
-       tpointerdef = class(tstoreddef)
+       tabstractpointerdef = class(tstoreddef)
           pointertype : ttype;
           pointertype : ttype;
+          constructor create(dt:tdeftype;const tt : ttype);
+          constructor ppuload(dt:tdeftype;ppufile:tcompilerppufile);
+          procedure ppuwrite(ppufile:tcompilerppufile);override;
+          procedure buildderef;override;
+          procedure deref;override;
+       end;
+
+       tpointerdef = class(tabstractpointerdef)
           is_far : boolean;
           is_far : boolean;
           constructor create(const tt : ttype);
           constructor create(const tt : ttype);
           constructor createfar(const tt : ttype);
           constructor createfar(const tt : ttype);
           function getcopy : tstoreddef;override;
           function getcopy : tstoreddef;override;
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
-          procedure buildderef;override;
-          procedure deref;override;
           function  gettypename:string;override;
           function  gettypename:string;override;
        end;
        end;
 
 
@@ -313,7 +313,7 @@ interface
        end;
        end;
 
 
 
 
-       tclassrefdef = class(tpointerdef)
+       tclassrefdef = class(tabstractpointerdef)
           constructor create(const t:ttype);
           constructor create(const t:ttype);
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -403,8 +403,8 @@ interface
 {$endif}
 {$endif}
           funcretloc : array[tcallercallee] of TLocation;
           funcretloc : array[tcallercallee] of TLocation;
           has_paraloc_info : boolean; { paraloc info is available }
           has_paraloc_info : boolean; { paraloc info is available }
-          constructor create(level:byte);
-          constructor ppuload(ppufile:tcompilerppufile);
+          constructor create(dt:tdeftype;level:byte);
+          constructor ppuload(dt:tdeftype;ppufile:tcompilerppufile);
           destructor destroy;override;
           destructor destroy;override;
           procedure  ppuwrite(ppufile:tcompilerppufile);override;
           procedure  ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderef;override;
           procedure buildderef;override;
@@ -608,8 +608,6 @@ interface
           { rtti }
           { rtti }
           procedure write_rtti_data(rt:trttitype);override;
           procedure write_rtti_data(rt:trttitype);override;
           procedure write_child_rtti_data(rt:trttitype);override;
           procedure write_child_rtti_data(rt:trttitype);override;
-       private
-          procedure correct_owner_symtable;
        end;
        end;
 
 
        tsetdef = class(tstoreddef)
        tsetdef = class(tstoreddef)
@@ -892,35 +890,52 @@ implementation
                      TDEF (base class for definitions)
                      TDEF (base class for definitions)
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tstoreddef.create;
+    constructor tstoreddef.create(dt:tdeftype);
+      var
+        insertstack : psymtablestackitem;
       begin
       begin
-         inherited create;
+         inherited create(dt);
          savesize := 0;
          savesize := 0;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
          fileinfo := aktfilepos;
          fileinfo := aktfilepos;
 {$endif}
 {$endif}
-         if registerdef then
-           symtablestack.registerdef(self);
          fillchar(localrttilab,sizeof(localrttilab),0);
          fillchar(localrttilab,sizeof(localrttilab),0);
          generictokenbuf:=nil;
          generictokenbuf:=nil;
          genericdef:=nil;
          genericdef:=nil;
+         { Register in symtable stack.
+           Don't register forwarddefs, they are disposed at the
+           end of an type block }
+         if assigned(symtablestack) and
+            (dt<>forwarddef) then
+           begin
+             insertstack:=symtablestack.stack;
+             while assigned(insertstack) and
+                   (insertstack^.symtable.symtabletype=withsymtable) do
+               insertstack:=insertstack^.next;
+             if not assigned(insertstack) then
+               internalerror(200602044);
+             insertstack^.symtable.insertdef(self);
+           end;
       end;
       end;
 
 
 
 
     destructor tstoreddef.destroy;
     destructor tstoreddef.destroy;
       begin
       begin
+        { remove also index from symtable }
+        if assigned(owner) then
+          owner.defindex.deleteindex(self);
         if assigned(generictokenbuf) then
         if assigned(generictokenbuf) then
           generictokenbuf.free;
           generictokenbuf.free;
         inherited destroy;
         inherited destroy;
       end;
       end;
 
 
 
 
-    constructor tstoreddef.ppuloaddef(ppufile:tcompilerppufile);
+    constructor tstoreddef.ppuload(dt:tdeftype;ppufile:tcompilerppufile);
       var
       var
         sizeleft,i : longint;
         sizeleft,i : longint;
         buf  : array[0..255] of byte;
         buf  : array[0..255] of byte;
       begin
       begin
-         inherited create;
+         inherited create(dt);
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
          fillchar(fileinfo,sizeof(fileinfo),0);
          fillchar(fileinfo,sizeof(fileinfo),0);
 {$endif}
 {$endif}
@@ -971,7 +986,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tstoreddef.ppuwritedef(ppufile:tcompilerppufile);
+    procedure tstoreddef.ppuwrite(ppufile:tcompilerppufile);
       var
       var
         sizeleft,i : longint;
         sizeleft,i : longint;
         buf  : array[0..255] of byte;
         buf  : array[0..255] of byte;
@@ -1171,9 +1186,8 @@ implementation
 
 
     constructor tstringdef.createshort(l : byte);
     constructor tstringdef.createshort(l : byte);
       begin
       begin
-         inherited create;
+         inherited create(stringdef);
          string_typ:=st_shortstring;
          string_typ:=st_shortstring;
-         deftype:=stringdef;
          len:=l;
          len:=l;
          savesize:=len+1;
          savesize:=len+1;
       end;
       end;
@@ -1181,9 +1195,8 @@ implementation
 
 
     constructor tstringdef.loadshort(ppufile:tcompilerppufile);
     constructor tstringdef.loadshort(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
+         inherited ppuload(stringdef,ppufile);
          string_typ:=st_shortstring;
          string_typ:=st_shortstring;
-         deftype:=stringdef;
          len:=ppufile.getbyte;
          len:=ppufile.getbyte;
          savesize:=len+1;
          savesize:=len+1;
       end;
       end;
@@ -1191,9 +1204,8 @@ implementation
 
 
     constructor tstringdef.createlong(l : aint);
     constructor tstringdef.createlong(l : aint);
       begin
       begin
-         inherited create;
+         inherited create(stringdef);
          string_typ:=st_longstring;
          string_typ:=st_longstring;
-         deftype:=stringdef;
          len:=l;
          len:=l;
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
       end;
       end;
@@ -1201,8 +1213,7 @@ implementation
 
 
     constructor tstringdef.loadlong(ppufile:tcompilerppufile);
     constructor tstringdef.loadlong(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=stringdef;
+         inherited ppuload(stringdef,ppufile);
          string_typ:=st_longstring;
          string_typ:=st_longstring;
          len:=ppufile.getaint;
          len:=ppufile.getaint;
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
@@ -1211,9 +1222,8 @@ implementation
 
 
     constructor tstringdef.createansi(l:aint);
     constructor tstringdef.createansi(l:aint);
       begin
       begin
-         inherited create;
+         inherited create(stringdef);
          string_typ:=st_ansistring;
          string_typ:=st_ansistring;
-         deftype:=stringdef;
          len:=l;
          len:=l;
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
       end;
       end;
@@ -1221,8 +1231,7 @@ implementation
 
 
     constructor tstringdef.loadansi(ppufile:tcompilerppufile);
     constructor tstringdef.loadansi(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=stringdef;
+         inherited ppuload(stringdef,ppufile);
          string_typ:=st_ansistring;
          string_typ:=st_ansistring;
          len:=ppufile.getaint;
          len:=ppufile.getaint;
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
@@ -1231,9 +1240,8 @@ implementation
 
 
     constructor tstringdef.createwide(l : aint);
     constructor tstringdef.createwide(l : aint);
       begin
       begin
-         inherited create;
+         inherited create(stringdef);
          string_typ:=st_widestring;
          string_typ:=st_widestring;
-         deftype:=stringdef;
          len:=l;
          len:=l;
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
       end;
       end;
@@ -1241,8 +1249,7 @@ implementation
 
 
     constructor tstringdef.loadwide(ppufile:tcompilerppufile);
     constructor tstringdef.loadwide(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=stringdef;
+         inherited ppuload(stringdef,ppufile);
          string_typ:=st_widestring;
          string_typ:=st_widestring;
          len:=ppufile.getaint;
          len:=ppufile.getaint;
          savesize:=sizeof(aint);
          savesize:=sizeof(aint);
@@ -1251,7 +1258,7 @@ implementation
 
 
     function tstringdef.getcopy : tstoreddef;
     function tstringdef.getcopy : tstoreddef;
       begin
       begin
-        result:=tstringdef.create;
+        result:=tstringdef.create(deftype);
         result.deftype:=stringdef;
         result.deftype:=stringdef;
         tstringdef(result).string_typ:=string_typ;
         tstringdef(result).string_typ:=string_typ;
         tstringdef(result).len:=len;
         tstringdef(result).len:=len;
@@ -1271,7 +1278,7 @@ implementation
 
 
     procedure tstringdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tstringdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          if string_typ=st_shortstring then
          if string_typ=st_shortstring then
            begin
            begin
 {$ifdef extdebug}
 {$ifdef extdebug}
@@ -1298,7 +1305,7 @@ implementation
 
 
     function tstringdef.gettypename : string;
     function tstringdef.gettypename : string;
       const
       const
-         names : array[tstringtype] of string[10] = (
+         names : array[tstringtype] of string[11] = (
            'ShortString','LongString','AnsiString','WideString');
            'ShortString','LongString','AnsiString','WideString');
       begin
       begin
          gettypename:=names[string_typ];
          gettypename:=names[string_typ];
@@ -1374,22 +1381,19 @@ implementation
 
 
     constructor tenumdef.create;
     constructor tenumdef.create;
       begin
       begin
-         inherited create;
-         deftype:=enumdef;
+         inherited create(enumdef);
          minval:=0;
          minval:=0;
          maxval:=0;
          maxval:=0;
          calcsavesize;
          calcsavesize;
          has_jumps:=false;
          has_jumps:=false;
          basedef:=nil;
          basedef:=nil;
          firstenum:=nil;
          firstenum:=nil;
-         correct_owner_symtable;
       end;
       end;
 
 
 
 
     constructor tenumdef.create_subrange(_basedef:tenumdef;_min,_max:aint);
     constructor tenumdef.create_subrange(_basedef:tenumdef;_min,_max:aint);
       begin
       begin
-         inherited create;
-         deftype:=enumdef;
+         inherited create(enumdef);
          minval:=_min;
          minval:=_min;
          maxval:=_max;
          maxval:=_max;
          basedef:=_basedef;
          basedef:=_basedef;
@@ -1398,14 +1402,12 @@ implementation
          firstenum:=basedef.firstenum;
          firstenum:=basedef.firstenum;
          while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
          while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
            firstenum:=tenumsym(firstenum).nextenum;
            firstenum:=tenumsym(firstenum).nextenum;
-         correct_owner_symtable;
       end;
       end;
 
 
 
 
     constructor tenumdef.ppuload(ppufile:tcompilerppufile);
     constructor tenumdef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=enumdef;
+         inherited ppuload(enumdef,ppufile);
          ppufile.getderef(basedefderef);
          ppufile.getderef(basedefderef);
          minval:=ppufile.getaint;
          minval:=ppufile.getaint;
          maxval:=ppufile.getaint;
          maxval:=ppufile.getaint;
@@ -1508,7 +1510,7 @@ implementation
 
 
     procedure tenumdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tenumdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putderef(basedefderef);
          ppufile.putderef(basedefderef);
          ppufile.putaint(min);
          ppufile.putaint(min);
          ppufile.putaint(max);
          ppufile.putaint(max);
@@ -1517,24 +1519,6 @@ implementation
       end;
       end;
 
 
 
 
-    { used for enumdef because the symbols are
-      inserted in the owner symtable }
-    procedure tenumdef.correct_owner_symtable;
-      var
-         st : tsymtable;
-      begin
-         if assigned(owner) and
-            (owner.symtabletype in [recordsymtable,objectsymtable]) then
-           begin
-              owner.defindex.deleteindex(self);
-              st:=owner;
-              while (st.symtabletype in [recordsymtable,objectsymtable]) do
-                st:=st.next;
-              st.registerdef(self);
-           end;
-      end;
-
-
     procedure tenumdef.write_child_rtti_data(rt:trttitype);
     procedure tenumdef.write_child_rtti_data(rt:trttitype);
       begin
       begin
          if assigned(basedef) then
          if assigned(basedef) then
@@ -1596,8 +1580,7 @@ implementation
 
 
     constructor torddef.create(t : tbasetype;v,b : TConstExprInt);
     constructor torddef.create(t : tbasetype;v,b : TConstExprInt);
       begin
       begin
-         inherited create;
-         deftype:=orddef;
+         inherited create(orddef);
          low:=v;
          low:=v;
          high:=b;
          high:=b;
          typ:=t;
          typ:=t;
@@ -1607,8 +1590,7 @@ implementation
 
 
     constructor torddef.ppuload(ppufile:tcompilerppufile);
     constructor torddef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=orddef;
+         inherited ppuload(orddef,ppufile);
          typ:=tbasetype(ppufile.getbyte);
          typ:=tbasetype(ppufile.getbyte);
          if sizeof(TConstExprInt)=8 then
          if sizeof(TConstExprInt)=8 then
            begin
            begin
@@ -1664,7 +1646,7 @@ implementation
 
 
     procedure torddef.ppuwrite(ppufile:tcompilerppufile);
     procedure torddef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(typ));
          ppufile.putbyte(byte(typ));
          if sizeof(TConstExprInt)=8 then
          if sizeof(TConstExprInt)=8 then
           begin
           begin
@@ -1779,8 +1761,7 @@ implementation
 
 
     constructor tfloatdef.create(t : tfloattype);
     constructor tfloatdef.create(t : tfloattype);
       begin
       begin
-         inherited create;
-         deftype:=floatdef;
+         inherited create(floatdef);
          typ:=t;
          typ:=t;
          setsize;
          setsize;
       end;
       end;
@@ -1788,8 +1769,7 @@ implementation
 
 
     constructor tfloatdef.ppuload(ppufile:tcompilerppufile);
     constructor tfloatdef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=floatdef;
+         inherited ppuload(floatdef,ppufile);
          typ:=tfloattype(ppufile.getbyte);
          typ:=tfloattype(ppufile.getbyte);
          setsize;
          setsize;
       end;
       end;
@@ -1835,7 +1815,7 @@ implementation
 
 
     procedure tfloatdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tfloatdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(typ));
          ppufile.putbyte(byte(typ));
          ppufile.writeentry(ibfloatdef);
          ppufile.writeentry(ibfloatdef);
       end;
       end;
@@ -1877,8 +1857,7 @@ implementation
 
 
     constructor tfiledef.createtext;
     constructor tfiledef.createtext;
       begin
       begin
-         inherited create;
-         deftype:=filedef;
+         inherited create(filedef);
          filetyp:=ft_text;
          filetyp:=ft_text;
          typedfiletype.reset;
          typedfiletype.reset;
          setsize;
          setsize;
@@ -1887,8 +1866,7 @@ implementation
 
 
     constructor tfiledef.createuntyped;
     constructor tfiledef.createuntyped;
       begin
       begin
-         inherited create;
-         deftype:=filedef;
+         inherited create(filedef);
          filetyp:=ft_untyped;
          filetyp:=ft_untyped;
          typedfiletype.reset;
          typedfiletype.reset;
          setsize;
          setsize;
@@ -1897,8 +1875,7 @@ implementation
 
 
     constructor tfiledef.createtyped(const tt : ttype);
     constructor tfiledef.createtyped(const tt : ttype);
       begin
       begin
-         inherited create;
-         deftype:=filedef;
+         inherited create(filedef);
          filetyp:=ft_typed;
          filetyp:=ft_typed;
          typedfiletype:=tt;
          typedfiletype:=tt;
          setsize;
          setsize;
@@ -1907,8 +1884,7 @@ implementation
 
 
     constructor tfiledef.ppuload(ppufile:tcompilerppufile);
     constructor tfiledef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=filedef;
+         inherited ppuload(filedef,ppufile);
          filetyp:=tfiletyp(ppufile.getbyte);
          filetyp:=tfiletyp(ppufile.getbyte);
          if filetyp=ft_typed then
          if filetyp=ft_typed then
            ppufile.gettype(typedfiletype)
            ppufile.gettype(typedfiletype)
@@ -1979,7 +1955,7 @@ implementation
 
 
     procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
     procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(filetyp));
          ppufile.putbyte(byte(filetyp));
          if filetyp=ft_typed then
          if filetyp=ft_typed then
            ppufile.puttype(typedfiletype);
            ppufile.puttype(typedfiletype);
@@ -2019,18 +1995,16 @@ implementation
 
 
     constructor tvariantdef.create(v : tvarianttype);
     constructor tvariantdef.create(v : tvarianttype);
       begin
       begin
-         inherited create;
+         inherited create(variantdef);
          varianttype:=v;
          varianttype:=v;
-         deftype:=variantdef;
          setsize;
          setsize;
       end;
       end;
 
 
 
 
     constructor tvariantdef.ppuload(ppufile:tcompilerppufile);
     constructor tvariantdef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
+         inherited ppuload(variantdef,ppufile);
          varianttype:=tvarianttype(ppufile.getbyte);
          varianttype:=tvarianttype(ppufile.getbyte);
-         deftype:=variantdef;
          setsize;
          setsize;
       end;
       end;
 
 
@@ -2043,7 +2017,7 @@ implementation
 
 
     procedure tvariantdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tvariantdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(varianttype));
          ppufile.putbyte(byte(varianttype));
          ppufile.writeentry(ibvariantdef);
          ppufile.writeentry(ibvariantdef);
       end;
       end;
@@ -2084,37 +2058,69 @@ implementation
       end;
       end;
 
 
 
 
+{****************************************************************************
+                            TABSTRACTPOINTERDEF
+****************************************************************************}
+
+    constructor tabstractpointerdef.create(dt:tdeftype;const tt : ttype);
+      begin
+        inherited create(dt);
+        pointertype:=tt;
+        savesize:=sizeof(aint);
+      end;
+
+
+    constructor tabstractpointerdef.ppuload(dt:tdeftype;ppufile:tcompilerppufile);
+      begin
+         inherited ppuload(dt,ppufile);
+         ppufile.gettype(pointertype);
+         savesize:=sizeof(aint);
+      end;
+
+
+    procedure tabstractpointerdef.buildderef;
+      begin
+        inherited buildderef;
+        pointertype.buildderef;
+      end;
+
+
+    procedure tabstractpointerdef.deref;
+      begin
+        inherited deref;
+        pointertype.resolve;
+      end;
+
+
+    procedure tabstractpointerdef.ppuwrite(ppufile:tcompilerppufile);
+      begin
+         inherited ppuwrite(ppufile);
+         ppufile.puttype(pointertype);
+      end;
+
+
 {****************************************************************************
 {****************************************************************************
                                TPOINTERDEF
                                TPOINTERDEF
 ****************************************************************************}
 ****************************************************************************}
 
 
     constructor tpointerdef.create(const tt : ttype);
     constructor tpointerdef.create(const tt : ttype);
       begin
       begin
-        inherited create;
-        deftype:=pointerdef;
-        pointertype:=tt;
+        inherited create(pointerdef,tt);
         is_far:=false;
         is_far:=false;
-        savesize:=sizeof(aint);
       end;
       end;
 
 
 
 
     constructor tpointerdef.createfar(const tt : ttype);
     constructor tpointerdef.createfar(const tt : ttype);
       begin
       begin
-        inherited create;
-        deftype:=pointerdef;
-        pointertype:=tt;
+        inherited create(pointerdef,tt);
         is_far:=true;
         is_far:=true;
-        savesize:=sizeof(aint);
       end;
       end;
 
 
 
 
     constructor tpointerdef.ppuload(ppufile:tcompilerppufile);
     constructor tpointerdef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=pointerdef;
-         ppufile.gettype(pointertype);
+         inherited ppuload(pointerdef,ppufile);
          is_far:=(ppufile.getbyte<>0);
          is_far:=(ppufile.getbyte<>0);
-         savesize:=sizeof(aint);
       end;
       end;
 
 
 
 
@@ -2126,24 +2132,9 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tpointerdef.buildderef;
-      begin
-        inherited buildderef;
-        pointertype.buildderef;
-      end;
-
-
-    procedure tpointerdef.deref;
-      begin
-        inherited deref;
-        pointertype.resolve;
-      end;
-
-
     procedure tpointerdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tpointerdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
-         ppufile.puttype(pointertype);
+         inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(is_far));
          ppufile.putbyte(byte(is_far));
          ppufile.writeentry(ibpointerdef);
          ppufile.writeentry(ibpointerdef);
       end;
       end;
@@ -2164,27 +2155,19 @@ implementation
 
 
     constructor tclassrefdef.create(const t:ttype);
     constructor tclassrefdef.create(const t:ttype);
       begin
       begin
-         inherited create(t);
-         deftype:=classrefdef;
+         inherited create(classrefdef,t);
       end;
       end;
 
 
 
 
     constructor tclassrefdef.ppuload(ppufile:tcompilerppufile);
     constructor tclassrefdef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         { be careful, tclassdefref inherits from tpointerdef }
-         inherited ppuloaddef(ppufile);
-         deftype:=classrefdef;
-         ppufile.gettype(pointertype);
-         is_far:=false;
-         savesize:=sizeof(aint);
+         inherited ppuload(classrefdef,ppufile);
       end;
       end;
 
 
 
 
     procedure tclassrefdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tclassrefdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         { be careful, tclassdefref inherits from tpointerdef }
-         inherited ppuwritedef(ppufile);
-         ppufile.puttype(pointertype);
+         inherited ppuwrite(ppufile);
          ppufile.writeentry(ibclassrefdef);
          ppufile.writeentry(ibclassrefdef);
       end;
       end;
 
 
@@ -2197,19 +2180,17 @@ implementation
 
 
     function tclassrefdef.is_publishable : boolean;
     function tclassrefdef.is_publishable : boolean;
       begin
       begin
-         is_publishable:=true;
+         result:=true;
       end;
       end;
 
 
 
 
-
 {***************************************************************************
 {***************************************************************************
                                    TSETDEF
                                    TSETDEF
 ***************************************************************************}
 ***************************************************************************}
 
 
     constructor tsetdef.create(const t:ttype;high : aint);
     constructor tsetdef.create(const t:ttype;high : aint);
       begin
       begin
-         inherited create;
-         deftype:=setdef;
+         inherited create(setdef);
          elementtype:=t;
          elementtype:=t;
          // setbase:=low;
          // setbase:=low;
          setmax:=high;
          setmax:=high;
@@ -2247,8 +2228,7 @@ implementation
 
 
     constructor tsetdef.ppuload(ppufile:tcompilerppufile);
     constructor tsetdef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=setdef;
+         inherited ppuload(setdef,ppufile);
          ppufile.gettype(elementtype);
          ppufile.gettype(elementtype);
          settype:=tsettype(ppufile.getbyte);
          settype:=tsettype(ppufile.getbyte);
          case settype of
          case settype of
@@ -2280,7 +2260,7 @@ implementation
 
 
     procedure tsetdef.ppuwrite(ppufile:tcompilerppufile);
     procedure tsetdef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.puttype(elementtype);
          ppufile.puttype(elementtype);
          ppufile.putbyte(byte(settype));
          ppufile.putbyte(byte(settype));
          if settype=varset then
          if settype=varset then
@@ -2346,35 +2326,22 @@ implementation
 ***************************************************************************}
 ***************************************************************************}
 
 
     constructor tformaldef.create;
     constructor tformaldef.create;
-      var
-         stregdef : boolean;
-      begin
-         stregdef:=registerdef;
-         registerdef:=false;
-         inherited create;
-         deftype:=formaldef;
-         registerdef:=stregdef;
-         { formaldef must be registered at unit level !! }
-         if registerdef and assigned(current_module) then
-            if assigned(current_module.localsymtable) then
-              tsymtable(current_module.localsymtable).registerdef(self)
-            else if assigned(current_module.globalsymtable) then
-              tsymtable(current_module.globalsymtable).registerdef(self);
+      begin
+         inherited create(formaldef);
          savesize:=0;
          savesize:=0;
       end;
       end;
 
 
 
 
     constructor tformaldef.ppuload(ppufile:tcompilerppufile);
     constructor tformaldef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=formaldef;
+         inherited ppuload(formaldef,ppufile);
          savesize:=0;
          savesize:=0;
       end;
       end;
 
 
 
 
     procedure tformaldef.ppuwrite(ppufile:tcompilerppufile);
     procedure tformaldef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.writeentry(ibformaldef);
          ppufile.writeentry(ibformaldef);
       end;
       end;
 
 
@@ -2391,8 +2358,7 @@ implementation
 
 
     constructor tarraydef.create(l,h : aint;const t : ttype);
     constructor tarraydef.create(l,h : aint;const t : ttype);
       begin
       begin
-         inherited create;
-         deftype:=arraydef;
+         inherited create(arraydef);
          lowrange:=l;
          lowrange:=l;
          highrange:=h;
          highrange:=h;
          rangetype:=t;
          rangetype:=t;
@@ -2415,8 +2381,7 @@ implementation
 
 
     constructor tarraydef.ppuload(ppufile:tcompilerppufile);
     constructor tarraydef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=arraydef;
+         inherited ppuload(arraydef,ppufile);
          { the addresses are calculated later }
          { the addresses are calculated later }
          ppufile.gettype(_elementtype);
          ppufile.gettype(_elementtype);
          ppufile.gettype(rangetype);
          ppufile.gettype(rangetype);
@@ -2459,7 +2424,7 @@ implementation
 
 
     procedure tarraydef.ppuwrite(ppufile:tcompilerppufile);
     procedure tarraydef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.puttype(_elementtype);
          ppufile.puttype(_elementtype);
          ppufile.puttype(rangetype);
          ppufile.puttype(rangetype);
          ppufile.putaint(lowrange);
          ppufile.putaint(lowrange);
@@ -2679,8 +2644,7 @@ implementation
 
 
     constructor trecorddef.create(p : tsymtable);
     constructor trecorddef.create(p : tsymtable);
       begin
       begin
-         inherited create;
-         deftype:=recorddef;
+         inherited create(recorddef);
          symtable:=p;
          symtable:=p;
          symtable.defowner:=self;
          symtable.defowner:=self;
          isunion:=false;
          isunion:=false;
@@ -2689,8 +2653,7 @@ implementation
 
 
     constructor trecorddef.ppuload(ppufile:tcompilerppufile);
     constructor trecorddef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=recorddef;
+         inherited ppuload(recorddef,ppufile);
          symtable:=trecordsymtable.create(0);
          symtable:=trecordsymtable.create(0);
          trecordsymtable(symtable).datasize:=ppufile.getaint;
          trecordsymtable(symtable).datasize:=ppufile.getaint;
          trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
          trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
@@ -2758,7 +2721,7 @@ implementation
 
 
     procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
     procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putaint(trecordsymtable(symtable).datasize);
          ppufile.putaint(trecordsymtable(symtable).datasize);
          ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
          ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
          ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
          ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
@@ -2819,12 +2782,11 @@ implementation
                        TABSTRACTPROCDEF
                        TABSTRACTPROCDEF
 ***************************************************************************}
 ***************************************************************************}
 
 
-    constructor tabstractprocdef.create(level:byte);
+    constructor tabstractprocdef.create(dt:tdeftype;level:byte);
       begin
       begin
-         inherited create;
+         inherited create(dt);
          parast:=tparasymtable.create(level);
          parast:=tparasymtable.create(level);
          parast.defowner:=self;
          parast.defowner:=self;
-         parast.next:=owner;
          paras:=nil;
          paras:=nil;
          minparacount:=0;
          minparacount:=0;
          maxparacount:=0;
          maxparacount:=0;
@@ -2962,11 +2924,11 @@ implementation
       end;
       end;
 
 
 
 
-    constructor tabstractprocdef.ppuload(ppufile:tcompilerppufile);
+    constructor tabstractprocdef.ppuload(dt:tdeftype;ppufile:tcompilerppufile);
       var
       var
         b : byte;
         b : byte;
       begin
       begin
-         inherited ppuloaddef(ppufile);
+         inherited ppuload(dt,ppufile);
          parast:=nil;
          parast:=nil;
          Paras:=nil;
          Paras:=nil;
          minparacount:=0;
          minparacount:=0;
@@ -3003,7 +2965,7 @@ implementation
          { released procdef? }
          { released procdef? }
          if not assigned(parast) then
          if not assigned(parast) then
            exit;
            exit;
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.puttype(rettype);
          ppufile.puttype(rettype);
          oldintfcrc:=ppufile.do_interface_crc;
          oldintfcrc:=ppufile.do_interface_crc;
          ppufile.do_interface_crc:=false;
          ppufile.do_interface_crc:=false;
@@ -3132,8 +3094,7 @@ implementation
 
 
     constructor tprocdef.create(level:byte);
     constructor tprocdef.create(level:byte);
       begin
       begin
-         inherited create(level);
-         deftype:=procdef;
+         inherited create(procdef,level);
          _mangledname:=nil;
          _mangledname:=nil;
          fileinfo:=aktfilepos;
          fileinfo:=aktfilepos;
          extnumber:=$ffff;
          extnumber:=$ffff;
@@ -3164,9 +3125,7 @@ implementation
       var
       var
         level : byte;
         level : byte;
       begin
       begin
-         inherited ppuload(ppufile);
-         deftype:=procdef;
-
+         inherited ppuload(procdef,ppufile);
          if po_has_mangledname in procoptions then
          if po_has_mangledname in procoptions then
           _mangledname:=stringdup(ppufile.getstring)
           _mangledname:=stringdup(ppufile.getstring)
          else
          else
@@ -3364,9 +3323,6 @@ implementation
       begin
       begin
          localst:=tlocalsymtable.create(parast.symtablelevel);
          localst:=tlocalsymtable.create(parast.symtablelevel);
          localst.defowner:=self;
          localst.defowner:=self;
-         { this is used by insert
-           to check same names in parast and localst }
-         localst.next:=parast;
       end;
       end;
 
 
 
 
@@ -3910,15 +3866,13 @@ implementation
 
 
     constructor tprocvardef.create(level:byte);
     constructor tprocvardef.create(level:byte);
       begin
       begin
-         inherited create(level);
-         deftype:=procvardef;
+         inherited create(procvardef,level);
       end;
       end;
 
 
 
 
     constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
     constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         deftype:=procvardef;
+         inherited ppuload(procvardef,ppufile);
          { load para symtable }
          { load para symtable }
          parast:=tparasymtable.create(unknown_level);
          parast:=tparasymtable.create(unknown_level);
          tparasymtable(parast).ppuload(ppufile);
          tparasymtable(parast).ppuload(ppufile);
@@ -4228,9 +4182,8 @@ implementation
 
 
    constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
    constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
      begin
      begin
-        inherited create;
+        inherited create(objectdef);
         objecttype:=ot;
         objecttype:=ot;
-        deftype:=objectdef;
         objectoptions:=[];
         objectoptions:=[];
         childof:=nil;
         childof:=nil;
         symtable:=tobjectsymtable.create(n,aktpackrecords);
         symtable:=tobjectsymtable.create(n,aktpackrecords);
@@ -4257,8 +4210,7 @@ implementation
          i,implintfcount: longint;
          i,implintfcount: longint;
          d : tderef;
          d : tderef;
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=objectdef;
+         inherited ppuload(objectdef,ppufile);
          objecttype:=tobjectdeftype(ppufile.getbyte);
          objecttype:=tobjectdeftype(ppufile.getbyte);
          objrealname:=stringdup(ppufile.getstring);
          objrealname:=stringdup(ppufile.getstring);
          objname:=stringdup(upper(objrealname^));
          objname:=stringdup(upper(objrealname^));
@@ -4366,7 +4318,7 @@ implementation
          implintfcount : longint;
          implintfcount : longint;
          i : longint;
          i : longint;
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(objecttype));
          ppufile.putbyte(byte(objecttype));
          ppufile.putstring(objrealname^);
          ppufile.putstring(objrealname^);
          ppufile.putaint(tobjectsymtable(symtable).datasize);
          ppufile.putaint(tobjectsymtable(symtable).datasize);
@@ -5360,16 +5312,8 @@ implementation
 ****************************************************************************}
 ****************************************************************************}
 
 
    constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
    constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
-     var
-       oldregisterdef : boolean;
      begin
      begin
-        { never register the forwarddefs, they are disposed at the
-          end of the type declaration block }
-        oldregisterdef:=registerdef;
-        registerdef:=false;
-        inherited create;
-        registerdef:=oldregisterdef;
-        deftype:=forwarddef;
+        inherited create(forwarddef);
         tosymname:=stringdup(s);
         tosymname:=stringdup(s);
         forwardpos:=pos;
         forwardpos:=pos;
      end;
      end;
@@ -5394,15 +5338,13 @@ implementation
 
 
    constructor tundefineddef.create;
    constructor tundefineddef.create;
      begin
      begin
-        inherited create;
-        deftype:=undefineddef;
+        inherited create(undefineddef);
      end;
      end;
 
 
 
 
     constructor tundefineddef.ppuload(ppufile:tcompilerppufile);
     constructor tundefineddef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuloaddef(ppufile);
-         deftype:=undefineddef;
+         inherited ppuload(undefineddef,ppufile);
       end;
       end;
 
 
     function tundefineddef.gettypename:string;
     function tundefineddef.gettypename:string;
@@ -5413,7 +5355,7 @@ implementation
 
 
     procedure tundefineddef.ppuwrite(ppufile:tcompilerppufile);
     procedure tundefineddef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuwritedef(ppufile);
+         inherited ppuwrite(ppufile);
          ppufile.writeentry(ibundefineddef);
          ppufile.writeentry(ibundefineddef);
       end;
       end;
 
 
@@ -5424,8 +5366,7 @@ implementation
 
 
     constructor terrordef.create;
     constructor terrordef.create;
       begin
       begin
-        inherited create;
-        deftype:=errordef;
+        inherited create(errordef);
       end;
       end;
 
 
 
 

+ 86 - 108
compiler/symsym.pas

@@ -32,7 +32,7 @@ interface
        { symtable }
        { symtable }
        symconst,symbase,symtype,symdef,defcmp,
        symconst,symbase,symtype,symdef,defcmp,
        { ppu }
        { ppu }
-       ppu,
+       ppu,finput,
        cclasses,symnot,
        cclasses,symnot,
        { aasm }
        { aasm }
        aasmbase,
        aasmbase,
@@ -43,8 +43,8 @@ interface
        { this class is the base for all symbol objects }
        { this class is the base for all symbol objects }
        tstoredsym = class(tsym)
        tstoredsym = class(tsym)
        public
        public
-          constructor create(const n : string);
-          constructor ppuload(ppufile:tcompilerppufile);
+          constructor create(st:tsymtyp;const n : string);
+          constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
           destructor destroy;override;
           destructor destroy;override;
           procedure ppuwrite(ppufile:tcompilerppufile);virtual;
           procedure ppuwrite(ppufile:tcompilerppufile);virtual;
        end;
        end;
@@ -66,8 +66,8 @@ interface
        end;
        end;
 
 
        tunitsym = class(Tstoredsym)
        tunitsym = class(Tstoredsym)
-          unitsymtable : tsymtable;
-          constructor create(const n : string;ref : tsymtable);
+          module : tobject; { tmodule }
+          constructor create(const n : string;amodule : tobject);
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
           destructor destroy;override;
           destructor destroy;override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -138,8 +138,8 @@ interface
           varregable    : tvarregable;
           varregable    : tvarregable;
           varstate      : tvarstate;
           varstate      : tvarstate;
           notifications : Tlinkedlist;
           notifications : Tlinkedlist;
-          constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
-          constructor ppuload(ppufile:tcompilerppufile);
+          constructor create(st:tsymtyp;const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
+          constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
           destructor  destroy;override;
           destructor  destroy;override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderef;override;
           procedure buildderef;override;
@@ -168,8 +168,8 @@ interface
           defaultconstsym : tsym;
           defaultconstsym : tsym;
           defaultconstsymderef : tderef;
           defaultconstsymderef : tderef;
           localloc      : TLocation; { register/reference for local var }
           localloc      : TLocation; { register/reference for local var }
-          constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
-          constructor ppuload(ppufile:tcompilerppufile);
+          constructor create(st:tsymtyp;const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
+          constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderef;override;
           procedure buildderef;override;
           procedure deref;override;
           procedure deref;override;
@@ -333,6 +333,7 @@ interface
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           destructor  destroy;override;
           destructor  destroy;override;
+          function GetCopy:tmacro;
        end;
        end;
 
 
        { compiler generated symbol to point to rtti and init/finalize tables }
        { compiler generated symbol to point to rtti and init/finalize tables }
@@ -378,13 +379,13 @@ implementation
                           TSYM (base for all symtypes)
                           TSYM (base for all symtypes)
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tstoredsym.create(const n : string);
+    constructor tstoredsym.create(st:tsymtyp;const n : string);
       begin
       begin
-         inherited create(n);
+         inherited create(st,n);
       end;
       end;
 
 
 
 
-    constructor tstoredsym.ppuload(ppufile:tcompilerppufile);
+    constructor tstoredsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
       var
       var
         nr : word;
         nr : word;
         s  : string;
         s  : string;
@@ -396,7 +397,7 @@ implementation
          else
          else
           inherited createname(upper(s));
           inherited createname(upper(s));
          _realname:=stringdup(s);
          _realname:=stringdup(s);
-         typ:=abstractsym;
+         typ:=st;
          { force the correct indexnr. must be after create! }
          { force the correct indexnr. must be after create! }
          indexnr:=nr;
          indexnr:=nr;
          ppufile.getposinfo(fileinfo);
          ppufile.getposinfo(fileinfo);
@@ -442,8 +443,7 @@ implementation
 
 
     constructor tlabelsym.create(const n : string);
     constructor tlabelsym.create(const n : string);
       begin
       begin
-         inherited create(n);
-         typ:=labelsym;
+         inherited create(labelsym,n);
          used:=false;
          used:=false;
          defined:=false;
          defined:=false;
          code:=nil;
          code:=nil;
@@ -452,8 +452,7 @@ implementation
 
 
     constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
     constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=labelsym;
+         inherited ppuload(labelsym,ppufile);
          code:=nil;
          code:=nil;
          used:=false;
          used:=false;
          defined:=true;
          defined:=true;
@@ -476,24 +475,22 @@ implementation
                                   TUNITSYM
                                   TUNITSYM
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tunitsym.create(const n : string;ref : tsymtable);
+    constructor tunitsym.create(const n : string;amodule : tobject);
       var
       var
         old_make_ref : boolean;
         old_make_ref : boolean;
       begin
       begin
          old_make_ref:=make_ref;
          old_make_ref:=make_ref;
          make_ref:=false;
          make_ref:=false;
-         inherited create(n);
+         inherited create(unitsym,n);
          make_ref:=old_make_ref;
          make_ref:=old_make_ref;
-         typ:=unitsym;
-         unitsymtable:=ref;
+         module:=amodule;
       end;
       end;
 
 
     constructor tunitsym.ppuload(ppufile:tcompilerppufile);
     constructor tunitsym.ppuload(ppufile:tcompilerppufile);
 
 
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=unitsym;
-         unitsymtable:=nil;
+         inherited ppuload(unitsym,ppufile);
+         module:=nil;
       end;
       end;
 
 
     destructor tunitsym.destroy;
     destructor tunitsym.destroy;
@@ -514,11 +511,9 @@ implementation
     constructor tprocsym.create(const n : string);
     constructor tprocsym.create(const n : string);
 
 
       begin
       begin
-         inherited create(n);
-         typ:=procsym;
+         inherited create(procsym,n);
          pdlistfirst:=nil;
          pdlistfirst:=nil;
          pdlistlast:=nil;
          pdlistlast:=nil;
-         owner:=nil;
          { the tprocdef have their own symoptions, make the procsym
          { the tprocdef have their own symoptions, make the procsym
            always visible }
            always visible }
          symoptions:=[sp_public];
          symoptions:=[sp_public];
@@ -532,8 +527,7 @@ implementation
          pdderef : tderef;
          pdderef : tderef;
          i,n : longint;
          i,n : longint;
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=procsym;
+         inherited ppuload(procsym,ppufile);
          pdlistfirst:=nil;
          pdlistfirst:=nil;
          pdlistlast:=nil;
          pdlistlast:=nil;
          procdef_count:=0;
          procdef_count:=0;
@@ -1055,8 +1049,7 @@ implementation
 
 
     constructor terrorsym.create;
     constructor terrorsym.create;
       begin
       begin
-        inherited create('');
-        typ:=errorsym;
+        inherited create(errorsym,'');
       end;
       end;
 
 
 {****************************************************************************
 {****************************************************************************
@@ -1065,8 +1058,7 @@ implementation
 
 
     constructor tpropertysym.create(const n : string);
     constructor tpropertysym.create(const n : string);
       begin
       begin
-         inherited create(n);
-         typ:=propertysym;
+         inherited create(propertysym,n);
          propoptions:=[];
          propoptions:=[];
          index:=0;
          index:=0;
          default:=0;
          default:=0;
@@ -1080,8 +1072,7 @@ implementation
 
 
     constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
     constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=propertysym;
+         inherited ppuload(propertysym,ppufile);
          ppufile.getsmallset(propoptions);
          ppufile.getsmallset(propoptions);
          if (ppo_is_override in propoptions) then
          if (ppo_is_override in propoptions) then
           begin
           begin
@@ -1201,9 +1192,9 @@ implementation
                             TABSTRACTVARSYM
                             TABSTRACTVARSYM
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tabstractvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
+    constructor tabstractvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
       begin
       begin
-         inherited create(n);
+         inherited create(st,n);
          vartype:=tt;
          vartype:=tt;
          varspez:=vsp;
          varspez:=vsp;
          varstate:=vs_declared;
          varstate:=vs_declared;
@@ -1211,9 +1202,9 @@ implementation
       end;
       end;
 
 
 
 
-    constructor tabstractvarsym.ppuload(ppufile:tcompilerppufile);
+    constructor tabstractvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
+         inherited ppuload(st,ppufile);
          varstate:=vs_readwritten;
          varstate:=vs_readwritten;
          varspez:=tvarspez(ppufile.getbyte);
          varspez:=tvarspez(ppufile.getbyte);
          varregable:=tvarregable(ppufile.getbyte);
          varregable:=tvarregable(ppufile.getbyte);
@@ -1378,16 +1369,14 @@ implementation
 
 
     constructor tfieldvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
     constructor tfieldvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
       begin
       begin
-         inherited create(n,vsp,tt,vopts);
-         typ:=fieldvarsym;
-         fieldoffset:=0;
+         inherited create(fieldvarsym,n,vsp,tt,vopts);
+         fieldoffset:=-1;
       end;
       end;
 
 
 
 
     constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
     constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=fieldvarsym;
+         inherited ppuload(fieldvarsym,ppufile);
          fieldoffset:=ppufile.getaint;
          fieldoffset:=ppufile.getaint;
       end;
       end;
 
 
@@ -1404,17 +1393,17 @@ implementation
                         TABSTRACTNORMALVARSYM
                         TABSTRACTNORMALVARSYM
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tabstractnormalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
+    constructor tabstractnormalvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
       begin
       begin
-         inherited create(n,vsp,tt,vopts);
+         inherited create(st,n,vsp,tt,vopts);
          fillchar(localloc,sizeof(localloc),0);
          fillchar(localloc,sizeof(localloc),0);
          defaultconstsym:=nil;
          defaultconstsym:=nil;
       end;
       end;
 
 
 
 
-    constructor tabstractnormalvarsym.ppuload(ppufile:tcompilerppufile);
+    constructor tabstractnormalvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
+         inherited ppuload(st,ppufile);
          fillchar(localloc,sizeof(localloc),0);
          fillchar(localloc,sizeof(localloc),0);
          ppufile.getderef(defaultconstsymderef);
          ppufile.getderef(defaultconstsymderef);
       end;
       end;
@@ -1447,8 +1436,7 @@ implementation
 
 
     constructor tglobalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
     constructor tglobalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
       begin
       begin
-         inherited create(n,vsp,tt,vopts);
-         typ:=globalvarsym;
+         inherited create(globalvarsym,n,vsp,tt,vopts);
          _mangledname:=nil;
          _mangledname:=nil;
       end;
       end;
 
 
@@ -1468,8 +1456,7 @@ implementation
 
 
     constructor tglobalvarsym.ppuload(ppufile:tcompilerppufile);
     constructor tglobalvarsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=globalvarsym;
+         inherited ppuload(globalvarsym,ppufile);
          if vo_has_mangledname in varoptions then
          if vo_has_mangledname in varoptions then
            _mangledname:=stringdup(ppufile.getstring)
            _mangledname:=stringdup(ppufile.getstring)
          else
          else
@@ -1534,15 +1521,13 @@ implementation
 
 
     constructor tlocalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
     constructor tlocalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
       begin
       begin
-         inherited create(n,vsp,tt,vopts);
-         typ:=localvarsym;
+         inherited create(localvarsym,n,vsp,tt,vopts);
       end;
       end;
 
 
 
 
     constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
     constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=localvarsym;
+         inherited ppuload(localvarsym,ppufile);
       end;
       end;
 
 
 
 
@@ -1559,8 +1544,7 @@ implementation
 
 
     constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
     constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
       begin
       begin
-         inherited create(n,vsp,tt,vopts);
-         typ:=paravarsym;
+         inherited create(paravarsym,n,vsp,tt,vopts);
          paranr:=nr;
          paranr:=nr;
          paraloc[calleeside].init;
          paraloc[calleeside].init;
          paraloc[callerside].init;
          paraloc[callerside].init;
@@ -1579,7 +1563,7 @@ implementation
       var
       var
         b : byte;
         b : byte;
       begin
       begin
-         inherited ppuload(ppufile);
+         inherited ppuload(paravarsym,ppufile);
          paranr:=ppufile.getword;
          paranr:=ppufile.getword;
          paraloc[calleeside].init;
          paraloc[calleeside].init;
          paraloc[callerside].init;
          paraloc[callerside].init;
@@ -1592,7 +1576,6 @@ implementation
              paraloc[callerside].size:=paraloc[callerside].location^.size;
              paraloc[callerside].size:=paraloc[callerside].location^.size;
              paraloc[callerside].intsize:=tcgsize2size[paraloc[callerside].size];
              paraloc[callerside].intsize:=tcgsize2size[paraloc[callerside].size];
            end;
            end;
-         typ:=paravarsym;
       end;
       end;
 
 
 
 
@@ -1616,16 +1599,14 @@ implementation
 
 
     constructor tabsolutevarsym.create(const n : string;const tt : ttype);
     constructor tabsolutevarsym.create(const n : string;const tt : ttype);
       begin
       begin
-        inherited create(n,vs_value,tt,[]);
-        typ:=absolutevarsym;
+        inherited create(absolutevarsym,n,vs_value,tt,[]);
         ref:=nil;
         ref:=nil;
       end;
       end;
 
 
 
 
     constructor tabsolutevarsym.create_ref(const n : string;const tt : ttype;_ref:tsymlist);
     constructor tabsolutevarsym.create_ref(const n : string;const tt : ttype;_ref:tsymlist);
       begin
       begin
-        inherited create(n,vs_value,tt,[]);
-        typ:=absolutevarsym;
+        inherited create(absolutevarsym,n,vs_value,tt,[]);
         ref:=_ref;
         ref:=_ref;
       end;
       end;
 
 
@@ -1640,8 +1621,7 @@ implementation
 
 
     constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
     constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=absolutevarsym;
+         inherited ppuload(absolutevarsym,ppufile);
          ref:=nil;
          ref:=nil;
          asmname:=nil;
          asmname:=nil;
          abstyp:=absolutetyp(ppufile.getbyte);
          abstyp:=absolutetyp(ppufile.getbyte);
@@ -1721,8 +1701,7 @@ implementation
 
 
     constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
     constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
       begin
       begin
-         inherited create(n);
-         typ:=typedconstsym;
+         inherited create(typedconstsym,n);
          typedconsttype.setdef(p);
          typedconsttype.setdef(p);
          is_writable:=writable;
          is_writable:=writable;
       end;
       end;
@@ -1730,8 +1709,7 @@ implementation
 
 
     constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
     constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
       begin
       begin
-         inherited create(n);
-         typ:=typedconstsym;
+         inherited create(typedconstsym,n);
          typedconsttype:=tt;
          typedconsttype:=tt;
          is_writable:=writable;
          is_writable:=writable;
       end;
       end;
@@ -1739,8 +1717,7 @@ implementation
 
 
     constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
     constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=typedconstsym;
+         inherited ppuload(typedconstsym,ppufile);
          ppufile.gettype(typedconsttype);
          ppufile.gettype(typedconsttype);
          is_writable:=boolean(ppufile.getbyte);
          is_writable:=boolean(ppufile.getbyte);
       end;
       end;
@@ -1812,9 +1789,8 @@ implementation
 
 
     constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
     constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
       begin
       begin
-         inherited create(n);
+         inherited create(constsym,n);
          fillchar(value, sizeof(value), #0);
          fillchar(value, sizeof(value), #0);
-         typ:=constsym;
          consttyp:=t;
          consttyp:=t;
          value.valueord:=v;
          value.valueord:=v;
          ResStrIndex:=0;
          ResStrIndex:=0;
@@ -1824,9 +1800,8 @@ implementation
 
 
     constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
     constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
       begin
       begin
-         inherited create(n);
+         inherited create(constsym,n);
          fillchar(value, sizeof(value), #0);
          fillchar(value, sizeof(value), #0);
-         typ:=constsym;
          consttyp:=t;
          consttyp:=t;
          value.valueordptr:=v;
          value.valueordptr:=v;
          ResStrIndex:=0;
          ResStrIndex:=0;
@@ -1836,9 +1811,8 @@ implementation
 
 
     constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
     constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
       begin
       begin
-         inherited create(n);
+         inherited create(constsym,n);
          fillchar(value, sizeof(value), #0);
          fillchar(value, sizeof(value), #0);
-         typ:=constsym;
          consttyp:=t;
          consttyp:=t;
          value.valueptr:=v;
          value.valueptr:=v;
          ResStrIndex:=0;
          ResStrIndex:=0;
@@ -1848,9 +1822,8 @@ implementation
 
 
     constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
     constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
       begin
       begin
-         inherited create(n);
+         inherited create(constsym,n);
          fillchar(value, sizeof(value), #0);
          fillchar(value, sizeof(value), #0);
-         typ:=constsym;
          consttyp:=t;
          consttyp:=t;
          value.valueptr:=str;
          value.valueptr:=str;
          consttype.reset;
          consttype.reset;
@@ -1862,9 +1835,8 @@ implementation
 
 
     constructor tconstsym.create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
     constructor tconstsym.create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
       begin
       begin
-         inherited create(n);
+         inherited create(constsym,n);
          fillchar(value, sizeof(value), #0);
          fillchar(value, sizeof(value), #0);
-         typ:=constsym;
          consttyp:=t;
          consttyp:=t;
          pcompilerwidestring(value.valueptr):=pw;
          pcompilerwidestring(value.valueptr):=pw;
          consttype.reset;
          consttype.reset;
@@ -1879,8 +1851,7 @@ implementation
          pc : pchar;
          pc : pchar;
          pw : pcompilerwidestring;
          pw : pcompilerwidestring;
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=constsym;
+         inherited ppuload(constsym,ppufile);
          consttype.reset;
          consttype.reset;
          consttyp:=tconsttyp(ppufile.getbyte);
          consttyp:=tconsttyp(ppufile.getbyte);
          fillchar(value, sizeof(value), #0);
          fillchar(value, sizeof(value), #0);
@@ -2021,8 +1992,7 @@ implementation
 
 
     constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
     constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
       begin
       begin
-         inherited create(n);
-         typ:=enumsym;
+         inherited create(enumsym,n);
          definition:=def;
          definition:=def;
          value:=v;
          value:=v;
          { First entry? Then we need to set the minval }
          { First entry? Then we need to set the minval }
@@ -2050,8 +2020,7 @@ implementation
 
 
     constructor tenumsym.ppuload(ppufile:tcompilerppufile);
     constructor tenumsym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=enumsym;
+         inherited ppuload(enumsym,ppufile);
          ppufile.getderef(definitionderef);
          ppufile.getderef(definitionderef);
          value:=ppufile.getlongint;
          value:=ppufile.getlongint;
          nextenum := Nil;
          nextenum := Nil;
@@ -2112,8 +2081,7 @@ implementation
     constructor ttypesym.create(const n : string;const tt : ttype);
     constructor ttypesym.create(const n : string;const tt : ttype);
 
 
       begin
       begin
-         inherited create(n);
-         typ:=typesym;
+         inherited create(typesym,n);
          restype:=tt;
          restype:=tt;
         { register the typesym for the definition }
         { register the typesym for the definition }
         if assigned(restype.def) and
         if assigned(restype.def) and
@@ -2125,8 +2093,7 @@ implementation
 
 
     constructor ttypesym.ppuload(ppufile:tcompilerppufile);
     constructor ttypesym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=typesym;
+         inherited ppuload(typesym,ppufile);
          ppufile.gettype(restype);
          ppufile.gettype(restype);
       end;
       end;
 
 
@@ -2198,15 +2165,13 @@ implementation
 
 
     constructor tsyssym.create(const n : string;l : longint);
     constructor tsyssym.create(const n : string;l : longint);
       begin
       begin
-         inherited create(n);
-         typ:=syssym;
+         inherited create(syssym,n);
          number:=l;
          number:=l;
       end;
       end;
 
 
     constructor tsyssym.ppuload(ppufile:tcompilerppufile);
     constructor tsyssym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=syssym;
+         inherited ppuload(syssym,ppufile);
          number:=ppufile.getlongint;
          number:=ppufile.getlongint;
       end;
       end;
 
 
@@ -2229,21 +2194,18 @@ implementation
 
 
     constructor tmacro.create(const n : string);
     constructor tmacro.create(const n : string);
       begin
       begin
-         inherited create(n);
-         typ:= macrosym;
-         owner:= nil;
-
+         inherited create(macrosym,n);
+         owner:=nil;
          defined:=false;
          defined:=false;
          is_used:=false;
          is_used:=false;
-         is_compiler_var:= false;
+         is_compiler_var:=false;
          buftext:=nil;
          buftext:=nil;
          buflen:=0;
          buflen:=0;
       end;
       end;
 
 
     constructor tmacro.ppuload(ppufile:tcompilerppufile);
     constructor tmacro.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-         inherited ppuload(ppufile);
-         typ:=macrosym;
+         inherited ppuload(macrosym,ppufile);
          name:=ppufile.getstring;
          name:=ppufile.getstring;
          defined:=boolean(ppufile.getbyte);
          defined:=boolean(ppufile.getbyte);
          is_compiler_var:=boolean(ppufile.getbyte);
          is_compiler_var:=boolean(ppufile.getbyte);
@@ -2261,7 +2223,7 @@ implementation
     destructor tmacro.destroy;
     destructor tmacro.destroy;
       begin
       begin
          if assigned(buftext) then
          if assigned(buftext) then
-           freemem(buftext,buflen);
+           freemem(buftext);
          inherited destroy;
          inherited destroy;
       end;
       end;
 
 
@@ -2278,6 +2240,24 @@ implementation
       end;
       end;
 
 
 
 
+    function tmacro.GetCopy:tmacro;
+      var
+        p : tmacro;
+      begin
+        p:=tmacro.create(realname);
+        p.defined:=defined;
+        p.is_used:=is_used;
+        p.is_compiler_var:=is_compiler_var;
+        p.buflen:=buflen;
+        if assigned(buftext) then
+          begin
+            getmem(p.buftext,buflen);
+            move(buftext^,p.buftext^,buflen);
+          end;
+        Result:=p;
+      end;
+
+
 {****************************************************************************
 {****************************************************************************
                                   TRTTISYM
                                   TRTTISYM
 ****************************************************************************}
 ****************************************************************************}
@@ -2286,9 +2266,8 @@ implementation
       const
       const
         prefix : array[trttitype] of string[5]=('$rtti','$init');
         prefix : array[trttitype] of string[5]=('$rtti','$init');
       begin
       begin
-        inherited create(prefix[rt]+n);
+        inherited create(rttisym,prefix[rt]+n);
         include(symoptions,sp_internal);
         include(symoptions,sp_internal);
-        typ:=rttisym;
         lab:=nil;
         lab:=nil;
         rttityp:=rt;
         rttityp:=rt;
       end;
       end;
@@ -2312,8 +2291,7 @@ implementation
 
 
     constructor trttisym.ppuload(ppufile:tcompilerppufile);
     constructor trttisym.ppuload(ppufile:tcompilerppufile);
       begin
       begin
-        inherited ppuload(ppufile);
-        typ:=rttisym;
+        inherited ppuload(rttisym,ppufile);
         lab:=nil;
         lab:=nil;
         rttityp:=trttitype(ppufile.getbyte);
         rttityp:=trttitype(ppufile.getbyte);
       end;
       end;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 498 - 537
compiler/symtable.pas


+ 6 - 6
compiler/symtype.pas

@@ -76,7 +76,7 @@ interface
          stab_number : word;
          stab_number : word;
          dbg_state  : tdefdbgstatus;
          dbg_state  : tdefdbgstatus;
          defoptions : tdefoptions;
          defoptions : tdefoptions;
-         constructor create;
+         constructor create(dt:tdeftype);
          procedure buildderef;virtual;abstract;
          procedure buildderef;virtual;abstract;
          procedure buildderefimpl;virtual;abstract;
          procedure buildderefimpl;virtual;abstract;
          procedure deref;virtual;abstract;
          procedure deref;virtual;abstract;
@@ -112,7 +112,7 @@ interface
          lastwritten : tref;
          lastwritten : tref;
          refcount    : longint;
          refcount    : longint;
          isstabwritten : boolean;
          isstabwritten : boolean;
-         constructor create(const n : string);
+         constructor create(st:tsymtyp;const n : string);
          destructor destroy;override;
          destructor destroy;override;
          function  realname:string;
          function  realname:string;
          function  mangledname:string; virtual;
          function  mangledname:string; virtual;
@@ -240,10 +240,10 @@ implementation
                                 Tdef
                                 Tdef
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tdef.create;
+    constructor tdef.create(dt:tdeftype);
       begin
       begin
          inherited create;
          inherited create;
-         deftype:=abstractdef;
+         deftype:=dt;
          owner := nil;
          owner := nil;
          typesym := nil;
          typesym := nil;
          defoptions:=[];
          defoptions:=[];
@@ -307,14 +307,14 @@ implementation
                           TSYM (base for all symtypes)
                           TSYM (base for all symtypes)
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tsym.create(const n : string);
+    constructor tsym.create(st:tsymtyp;const n : string);
       begin
       begin
          if n[1]='$' then
          if n[1]='$' then
           inherited createname(copy(n,2,255))
           inherited createname(copy(n,2,255))
          else
          else
           inherited createname(upper(n));
           inherited createname(upper(n));
          _realname:=stringdup(n);
          _realname:=stringdup(n);
-         typ:=abstractsym;
+         typ:=st;
          symoptions:=[];
          symoptions:=[];
          defref:=nil;
          defref:=nil;
          refs:=0;
          refs:=0;

+ 7 - 0
compiler/systems.pas

@@ -667,6 +667,7 @@ var
   target  : tsystem;
   target  : tsystem;
   ar      : tar;
   ar      : tar;
   res     : tres;
   res     : tres;
+  dbg     : tdbg;
 begin
 begin
   for target:=low(tsystem) to high(tsystem) do
   for target:=low(tsystem) to high(tsystem) do
    if assigned(targetinfos[target]) then
    if assigned(targetinfos[target]) then
@@ -692,6 +693,12 @@ begin
       freemem(resinfos[res],sizeof(tresinfo));
       freemem(resinfos[res],sizeof(tresinfo));
       resinfos[res]:=nil;
       resinfos[res]:=nil;
     end;
     end;
+  for dbg:=low(tdbg) to high(tdbg) do
+   if assigned(dbginfos[dbg]) then
+    begin
+      freemem(dbginfos[dbg],sizeof(tdbginfo));
+      dbginfos[dbg]:=nil;
+    end;
 end;
 end;
 
 
 
 

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است