Browse Source

reintegrate paul/namespaces branch into trunk:
r18890 | paul | 2011-08-29 16:45:23 +0800 (Пн, 29 авг 2011) | 1 line

compiler: also parse dots in package name and in units which package contains (although package support is not implemented yet in FPC it can parse packages)
------------------------------------------------------------------------
r18886 | paul | 2011-08-29 10:46:13 +0800 (Пн, 29 авг 2011) | 1 line

compiler: replace "string" with ansistring where we concatenate substrings to prevent 255 chars limit overflow
------------------------------------------------------------------------
r18859 | paul | 2011-08-27 11:52:07 +0800 (Сб, 27 авг 2011) | 1 line

compiler: implement delphi like namespaces

git-svn-id: trunk@18911 -

paul 14 years ago
parent
commit
adceaf438c

+ 3 - 0
compiler/dbgbase.pas

@@ -420,6 +420,9 @@ implementation
             appendsym_absolute(list,tabsolutevarsym(sym));
             appendsym_absolute(list,tabsolutevarsym(sym));
           propertysym :
           propertysym :
             appendsym_property(list,tpropertysym(sym));
             appendsym_property(list,tpropertysym(sym));
+          namespacesym :
+            { ignore namespace syms, they are only of internal use }
+            ;
           else
           else
             internalerror(200601242);
             internalerror(200601242);
         end;
         end;

+ 1 - 1
compiler/fmodule.pas

@@ -471,7 +471,7 @@ implementation
       var
       var
         n : string;
         n : string;
       begin
       begin
-        n:=ChangeFileExt(ExtractFileName(s),'');
+        n:=s;
         { Programs have the name 'Program' to don't conflict with dup id's }
         { Programs have the name 'Program' to don't conflict with dup id's }
         if _is_unit then
         if _is_unit then
          inherited create(n)
          inherited create(n)

+ 33 - 3
compiler/pbase.pas

@@ -243,12 +243,13 @@ implementation
     function try_consume_unitsym(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id:boolean):boolean;
     function try_consume_unitsym(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id:boolean):boolean;
       var
       var
         hmodule: tmodule;
         hmodule: tmodule;
+        ns:ansistring;
+        nssym:tsym;
       begin
       begin
-        // TODO: dot units
         result:=false;
         result:=false;
         tokentoconsume:=_ID;
         tokentoconsume:=_ID;
-        if assigned(srsym) and
-           (srsym.typ=unitsym) then
+
+        if assigned(srsym) and (srsym.typ in [unitsym,namespacesym]) then
           begin
           begin
             if not(srsym.owner.symtabletype in [staticsymtable,globalsymtable]) then
             if not(srsym.owner.symtabletype in [staticsymtable,globalsymtable]) then
               internalerror(200501154);
               internalerror(200501154);
@@ -264,6 +265,35 @@ implementation
                 if consume_id then
                 if consume_id then
                   consume(_ID);
                   consume(_ID);
                 consume(_POINT);
                 consume(_POINT);
+                if srsym.typ=namespacesym then
+                  begin
+                    ns:=srsym.name;
+                    nssym:=srsym;
+                    while assigned(srsym) and (srsym.typ=namespacesym) do
+                      begin
+                        { we have a namespace. the next identifier should be either a namespace or a unit }
+                        searchsym_in_module(hmodule,ns+'.'+pattern,srsym,srsymtable);
+                        if assigned(srsym) and (srsym.typ in [namespacesym,unitsym]) then
+                          begin
+                            ns:=ns+'.'+pattern;
+                            nssym:=srsym;
+                            consume(_ID);
+                            consume(_POINT);
+                          end;
+                      end;
+                    { check if there is a hidden unit with this pattern in the namespace }
+                    if not assigned(srsym) and
+                       assigned(nssym) and (nssym.typ=namespacesym) and assigned(tnamespacesym(nssym).unitsym) then
+                      srsym:=tnamespacesym(nssym).unitsym;
+                    if assigned(srsym) and (srsym.typ<>unitsym) then
+                      internalerror(201108260);
+                    if not assigned(srsym) then
+                      begin
+                        result:=true;
+                        srsymtable:=nil;
+                        exit;
+                      end;
+                  end;
                 case token of
                 case token of
                   _ID:
                   _ID:
                      searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);
                      searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);

+ 71 - 21
compiler/pmodules.pas

@@ -533,7 +533,7 @@ implementation
         { insert unitsym }
         { insert unitsym }
         unitsym:=tunitsym.create(s,hp);
         unitsym:=tunitsym.create(s,hp);
         inc(unitsym.refs);
         inc(unitsym.refs);
-        current_module.localsymtable.insert(unitsym);
+        tabstractunitsymtable(current_module.localsymtable).insertunit(unitsym);
         { add to used units }
         { add to used units }
         current_module.addusedunit(hp,false,unitsym);
         current_module.addusedunit(hp,false,unitsym);
       end;
       end;
@@ -737,7 +737,7 @@ implementation
 
 
     procedure loadunits;
     procedure loadunits;
       var
       var
-         s,sorg  : TIDString;
+         s,sorg  : ansistring;
          fn      : string;
          fn      : string;
          pu      : tused_unit;
          pu      : tused_unit;
          hp2     : tmodule;
          hp2     : tmodule;
@@ -748,6 +748,13 @@ implementation
            s:=pattern;
            s:=pattern;
            sorg:=orgpattern;
            sorg:=orgpattern;
            consume(_ID);
            consume(_ID);
+           while token=_POINT do
+             begin
+               consume(_POINT);
+               s:=s+'.'+pattern;
+               sorg:=sorg+'.'+orgpattern;
+               consume(_ID);
+             end;
            { support "<unit> in '<file>'" construct, but not for tp7 }
            { support "<unit> in '<file>'" construct, but not for tp7 }
            fn:='';
            fn:='';
            if not(m_tp7 in current_settings.modeswitches) and
            if not(m_tp7 in current_settings.modeswitches) and
@@ -786,7 +793,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);
-              current_module.localsymtable.insert(unitsym);
+              tabstractunitsymtable(current_module.localsymtable).insertunit(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
@@ -1071,6 +1078,7 @@ implementation
          force_init_final : boolean;
          force_init_final : boolean;
          init_procinfo,
          init_procinfo,
          finalize_procinfo : tcgprocinfo;
          finalize_procinfo : tcgprocinfo;
+         unitname : ansistring;
          unitname8 : string[8];
          unitname8 : string[8];
          ag: boolean;
          ag: boolean;
 {$ifdef debug_devirt}
 {$ifdef debug_devirt}
@@ -1087,8 +1095,15 @@ implementation
          if compile_level=1 then
          if compile_level=1 then
           Status.IsExe:=false;
           Status.IsExe:=false;
 
 
-         if token=_ID then
+         unitname:=orgpattern;
+         consume(_ID);
+         while token=_POINT do
           begin
           begin
+             consume(_POINT);
+             unitname:=unitname+'.'+orgpattern;
+             consume(_ID);
+           end;
+
              { create filenames and unit name }
              { create filenames and unit name }
              main_file := current_scanner.inputfile;
              main_file := current_scanner.inputfile;
              while assigned(main_file.next) do
              while assigned(main_file.next) do
@@ -1097,7 +1112,7 @@ implementation
              new(s1);
              new(s1);
              s1^:=current_module.modulename^;
              s1^:=current_module.modulename^;
              current_module.SetFileName(main_file.path^+main_file.name^,true);
              current_module.SetFileName(main_file.path^+main_file.name^,true);
-             current_module.SetModuleName(orgpattern);
+         current_module.SetModuleName(unitname);
 
 
              { check for system unit }
              { check for system unit }
              new(s2);
              new(s2);
@@ -1123,13 +1138,10 @@ implementation
               include(current_settings.moduleswitches,cs_compilesystem);
               include(current_settings.moduleswitches,cs_compilesystem);
              dispose(s2);
              dispose(s2);
              dispose(s1);
              dispose(s1);
-          end;
 
 
          if (target_info.system in systems_unit_program_exports) then
          if (target_info.system in systems_unit_program_exports) then
            exportlib.preparelib(current_module.realmodulename^);
            exportlib.preparelib(current_module.realmodulename^);
 
 
-         consume(_ID);
-
          { parse hint directives }
          { parse hint directives }
          try_consume_hintdirective(current_module.moduleoptions, current_module.deprecatedmsg);
          try_consume_hintdirective(current_module.moduleoptions, current_module.deprecatedmsg);
 
 
@@ -1162,7 +1174,7 @@ implementation
 
 
          { insert unitsym of this unit to prevent other units having
          { insert unitsym of this unit to prevent other units having
            the same name }
            the same name }
-         current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
+         tabstractunitsymtable(current_module.localsymtable).insertunit(tunitsym.create(current_module.realmodulename^,current_module));
 
 
          { load default units, like the system unit }
          { load default units, like the system unit }
          loaddefaultunits;
          loaddefaultunits;
@@ -1769,6 +1781,7 @@ implementation
         main_procinfo : tcgprocinfo;}
         main_procinfo : tcgprocinfo;}
         force_init_final : boolean;
         force_init_final : boolean;
         uu : tused_unit;
         uu : tused_unit;
+        module_name: ansistring;
       begin
       begin
          Status.IsPackage:=true;
          Status.IsPackage:=true;
          Status.IsExe:=true;
          Status.IsExe:=true;
@@ -1806,15 +1819,25 @@ implementation
 
 
          current_module.SetFileName(main_file.path^+main_file.name^,true);
          current_module.SetFileName(main_file.path^+main_file.name^,true);
 
 
+         { consume _PACKAGE word }
+         consume(_ID);
+
+         module_name:=orgpattern;
          consume(_ID);
          consume(_ID);
-         current_module.setmodulename(orgpattern);
+         while token=_POINT do
+           begin
+             consume(_POINT);
+             module_name:=module_name+'.'+orgpattern;
+             consume(_ID);
+           end;
+
+         current_module.setmodulename(module_name);
          current_module.ispackage:=true;
          current_module.ispackage:=true;
-         exportlib.preparelib(orgpattern);
+         exportlib.preparelib(module_name);
 
 
          if tf_library_needs_pic in target_info.flags then
          if tf_library_needs_pic in target_info.flags then
            include(current_settings.moduleswitches,cs_create_pic);
            include(current_settings.moduleswitches,cs_create_pic);
 
 
-         consume(_ID);
          consume(_SEMICOLON);
          consume(_SEMICOLON);
 
 
          { global switches are read, so further changes aren't allowed }
          { global switches are read, so further changes aren't allowed }
@@ -1839,12 +1862,24 @@ implementation
          {Load the units used by the program we compile.}
          {Load the units used by the program we compile.}
          if (token=_ID) and (idtoken=_CONTAINS) then
          if (token=_ID) and (idtoken=_CONTAINS) then
            begin
            begin
+             { consume _CONTAINS word }
              consume(_ID);
              consume(_ID);
              while true do
              while true do
                begin
                begin
                  if token=_ID then
                  if token=_ID then
-                   AddUnit(pattern);
+                   begin
+                     module_name:=pattern;
                  consume(_ID);
                  consume(_ID);
+                     while token=_POINT do
+                       begin
+                         consume(_POINT);
+                         module_name:=module_name+'.'+orgpattern;
+                         consume(_ID);
+                       end;
+                     AddUnit(module_name);
+                   end
+                 else
+                   consume(_ID);
                  if token=_COMMA then
                  if token=_COMMA then
                    consume(_COMMA)
                    consume(_COMMA)
                  else break;
                  else break;
@@ -1857,7 +1892,7 @@ 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
-           current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
+           tabstractunitsymtable(current_module.localsymtable).insertunit(tunitsym.create(current_module.realmodulename^,current_module));
 
 
          Message1(parser_u_parsing_implementation,current_module.mainsource^);
          Message1(parser_u_parsing_implementation,current_module.mainsource^);
 
 
@@ -2050,6 +2085,7 @@ implementation
          main_procinfo : tcgprocinfo;
          main_procinfo : tcgprocinfo;
          force_init_final : boolean;
          force_init_final : boolean;
          resources_used : boolean;
          resources_used : boolean;
+         program_name : ansistring;
       begin
       begin
          DLLsource:=islibrary;
          DLLsource:=islibrary;
          Status.IsLibrary:=IsLibrary;
          Status.IsLibrary:=IsLibrary;
@@ -2097,14 +2133,21 @@ implementation
          if islibrary then
          if islibrary then
            begin
            begin
               consume(_LIBRARY);
               consume(_LIBRARY);
-              current_module.setmodulename(orgpattern);
+              program_name:=orgpattern;
+              consume(_ID);
+              while token=_POINT do
+                begin
+                  consume(_POINT);
+                  program_name:=program_name+'.'+orgpattern;
+                  consume(_ID);
+                end;
+              current_module.setmodulename(program_name);
               current_module.islibrary:=true;
               current_module.islibrary:=true;
-              exportlib.preparelib(orgpattern);
+              exportlib.preparelib(program_name);
 
 
               if tf_library_needs_pic in target_info.flags then
               if tf_library_needs_pic in target_info.flags then
                 include(current_settings.moduleswitches,cs_create_pic);
                 include(current_settings.moduleswitches,cs_create_pic);
 
 
-              consume(_ID);
               consume(_SEMICOLON);
               consume(_SEMICOLON);
            end
            end
          else
          else
@@ -2112,10 +2155,17 @@ implementation
            if token=_PROGRAM then
            if token=_PROGRAM then
             begin
             begin
               consume(_PROGRAM);
               consume(_PROGRAM);
-              current_module.setmodulename(orgpattern);
-              if (target_info.system in systems_unit_program_exports) then
-                exportlib.preparelib(orgpattern);
+              program_name:=orgpattern;
               consume(_ID);
               consume(_ID);
+              while token=_POINT do
+                begin
+                  consume(_POINT);
+                  program_name:=program_name+'.'+orgpattern;
+                  consume(_ID);
+                end;
+              current_module.setmodulename(program_name);
+              if (target_info.system in systems_unit_program_exports) then
+                exportlib.preparelib(program_name);
               if token=_LKLAMMER then
               if token=_LKLAMMER then
                 begin
                 begin
                    consume(_LKLAMMER);
                    consume(_LKLAMMER);
@@ -2158,7 +2208,7 @@ 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
-           current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
+           tabstractunitsymtable(current_module.localsymtable).insertunit(tunitsym.create(current_module.realmodulename^,current_module));
 
 
          Message1(parser_u_parsing_implementation,current_module.mainsource^);
          Message1(parser_u_parsing_implementation,current_module.mainsource^);
 
 

+ 2 - 2
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 {$endif Test_Double_checksum}
 
 
 const
 const
-  CurrentPPUVersion = 135;
+  CurrentPPUVersion = 136;
 
 
 { buffer sizes }
 { buffer sizes }
   maxentrysize = 1024;
   maxentrysize = 1024;
@@ -97,7 +97,7 @@ const
   ibunitsym        = 29;
   ibunitsym        = 29;
   iblabelsym       = 30;
   iblabelsym       = 30;
   ibsyssym         = 31;
   ibsyssym         = 31;
-//  ibrttisym        = 32;
+  ibnamespacesym   = 32;
   iblocalvarsym    = 33;
   iblocalvarsym    = 33;
   ibparavarsym     = 34;
   ibparavarsym     = 34;
   ibmacrosym       = 35;
   ibmacrosym       = 35;

+ 2 - 2
compiler/symconst.pas

@@ -487,7 +487,7 @@ type
     staticvarsym,localvarsym,paravarsym,fieldvarsym,
     staticvarsym,localvarsym,paravarsym,fieldvarsym,
     typesym,procsym,unitsym,constsym,enumsym,
     typesym,procsym,unitsym,constsym,enumsym,
     errorsym,syssym,labelsym,absolutevarsym,propertysym,
     errorsym,syssym,labelsym,absolutevarsym,propertysym,
-    macrosym
+    macrosym,namespacesym
   );
   );
 
 
   { State of the variable:
   { State of the variable:
@@ -593,7 +593,7 @@ const
        'abstractsym','globalvar','localvar','paravar','fieldvar',
        'abstractsym','globalvar','localvar','paravar','fieldvar',
        'type','proc','unit','const','enum',
        'type','proc','unit','const','enum',
        'errorsym','system sym','label','absolutevar','property',
        'errorsym','system sym','label','absolutevar','property',
-       'macrosym'
+       'macrosym','namespace'
      );
      );
 
 
      typName : array[tdeftyp] of string[12] = (
      typName : array[tdeftyp] of string[12] = (

+ 46 - 0
compiler/symsym.pas

@@ -78,6 +78,16 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
        end;
        end;
 
 
+       tnamespacesym = class(Tstoredsym)
+          unitsym:tsym;
+          unitsymderef:tderef;
+          constructor create(const n : string);
+          constructor ppuload(ppufile:tcompilerppufile);
+          procedure ppuwrite(ppufile:tcompilerppufile);override;
+          procedure buildderef;override;
+          procedure deref;override;
+       end;
+
        terrorsym = class(Tsym)
        terrorsym = class(Tsym)
           constructor create;
           constructor create;
        end;
        end;
@@ -477,6 +487,42 @@ implementation
          ppufile.writeentry(ibunitsym);
          ppufile.writeentry(ibunitsym);
       end;
       end;
 
 
+{****************************************************************************
+                                TNAMESPACESYM
+****************************************************************************}
+
+    constructor tnamespacesym.create(const n : string);
+      begin
+         inherited create(namespacesym,n);
+         unitsym:=nil;
+      end;
+
+    constructor tnamespacesym.ppuload(ppufile:tcompilerppufile);
+      begin
+         inherited ppuload(namespacesym,ppufile);
+         ppufile.getderef(unitsymderef);
+      end;
+
+    procedure tnamespacesym.ppuwrite(ppufile:tcompilerppufile);
+      begin
+         inherited ppuwrite(ppufile);
+         ppufile.putderef(unitsymderef);
+         ppufile.writeentry(ibnamespacesym);
+      end;
+
+    procedure tnamespacesym.buildderef;
+      begin
+        inherited buildderef;
+        unitsymderef.build(unitsym);
+      end;
+
+    procedure tnamespacesym.deref;
+      begin
+        inherited deref;
+        unitsym:=tsym(unitsymderef.resolve);
+      end;
+
+
 {****************************************************************************
 {****************************************************************************
                                   TPROCSYM
                                   TPROCSYM
 ****************************************************************************}
 ****************************************************************************}

+ 70 - 40
compiler/symtable.pas

@@ -145,7 +145,9 @@ interface
        tabstractuniTSymtable = class(tstoredsymtable)
        tabstractuniTSymtable = class(tstoredsymtable)
        public
        public
           constructor create(const n : string;id:word);
           constructor create(const n : string;id:word);
+          function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
           function iscurrentunit:boolean;override;
           function iscurrentunit:boolean;override;
+          procedure insertunit(sym:TSymEntry);
        end;
        end;
 
 
        tglobalsymtable = class(tabstractuniTSymtable)
        tglobalsymtable = class(tabstractuniTSymtable)
@@ -154,7 +156,6 @@ interface
           constructor create(const n : string;id:word);
           constructor create(const n : string;id:word);
           procedure ppuload(ppufile:tcompilerppufile);override;
           procedure ppuload(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
-          function  checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
        end;
        end;
 
 
        tstaticsymtable = class(tabstractuniTSymtable)
        tstaticsymtable = class(tabstractuniTSymtable)
@@ -455,6 +456,7 @@ implementation
                iblabelsym : sym:=tlabelsym.ppuload(ppufile);
                iblabelsym : sym:=tlabelsym.ppuload(ppufile);
                  ibsyssym : sym:=tsyssym.ppuload(ppufile);
                  ibsyssym : sym:=tsyssym.ppuload(ppufile);
                ibmacrosym : sym:=tmacro.ppuload(ppufile);
                ibmacrosym : sym:=tmacro.ppuload(ppufile);
+           ibnamespacesym : sym:=tnamespacesym.ppuload(ppufile);
                 ibendsyms : break;
                 ibendsyms : break;
                     ibend : Message(unit_f_ppu_read_error);
                     ibend : Message(unit_f_ppu_read_error);
            else
            else
@@ -707,7 +709,7 @@ implementation
            else
            else
             begin
             begin
               if (tsym(sym).refs=0) and
               if (tsym(sym).refs=0) and
-                 not(tsym(sym).typ in [enumsym,unitsym]) and
+                 not(tsym(sym).typ in [enumsym,unitsym,namespacesym]) and
                  not(is_funcret_sym(tsym(sym))) and
                  not(is_funcret_sym(tsym(sym))) and
                  { don't complain about compiler generated syms for specializations, see also #13405 }
                  { don't complain about compiler generated syms for specializations, see also #13405 }
                  not((tsym(sym).typ=typesym) and (df_specialization in ttypesym(sym).typedef.defoptions) and
                  not((tsym(sym).typ=typesym) and (df_specialization in ttypesym(sym).typedef.defoptions) and
@@ -1460,6 +1462,46 @@ implementation
       end;
       end;
 
 
 
 
+    function tabstractuniTSymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
+      var
+        hsym : tsym;
+      begin
+        result:=false;
+        hsym:=tsym(FindWithHash(hashedid));
+        if assigned(hsym) then
+          begin
+            if hsym.typ=symconst.namespacesym then
+              begin                
+                case sym.typ of
+                  symconst.namespacesym:;
+                  symconst.unitsym:
+                    begin
+                      HideSym(sym); { if we add a unit and there is a namespace with the same name then hide the unit name and not the namespace }
+                      tnamespacesym(hsym).unitsym:=tsym(sym);
+                    end
+                else
+                  HideSym(hsym);
+                end;
+              end
+            else
+            { In delphi (contrary to TP) you can have a symbol with the same name as the
+              unit, the unit can then not be accessed anymore using
+              <unit>.<id>, so we can hide the symbol. 
+              Do the same if we add a namespace and there is a unit with the same name }
+            if (hsym.typ=symconst.unitsym) and
+               ((m_delphi in current_settings.modeswitches) or (sym.typ=symconst.namespacesym)) then
+              begin
+                HideSym(hsym);
+                if sym.typ=symconst.namespacesym then
+                  tnamespacesym(sym).unitsym:=tsym(hsym);
+              end
+            else
+              DuplicateSym(hashedid,sym,hsym);
+            result:=true;
+            exit;
+          end;
+      end;
+
     function tabstractuniTSymtable.iscurrentunit:boolean;
     function tabstractuniTSymtable.iscurrentunit:boolean;
       begin
       begin
         result:=assigned(current_module) and
         result:=assigned(current_module) and
@@ -1469,6 +1511,29 @@ implementation
                 );
                 );
       end;
       end;
 
 
+    procedure tabstractuniTSymtable.insertunit(sym:TSymEntry);
+      var
+        p:integer;
+        n,ns:string;
+        oldsym:TSymEntry;
+      begin
+        insert(sym);
+        n:=sym.realname;
+        p:=pos('.',n);
+        ns:='';
+        while p>0 do
+          begin
+            if ns='' then
+              ns:=copy(n,1,p-1)
+            else
+              ns:=ns+'.'+copy(n,1,p-1);
+            system.delete(n,1,p);
+            oldsym:=Find(upper(ns));
+            if not Assigned(oldsym) or (oldsym.typ<>namespacesym) then
+              insert(tnamespacesym.create(ns));
+            p:=pos('.',n);
+          end;
+      end;
 
 
 {****************************************************************************
 {****************************************************************************
                               TStaticSymtable
                               TStaticSymtable
@@ -1501,23 +1566,10 @@ implementation
       var
       var
         hsym : tsym;
         hsym : tsym;
       begin
       begin
-        result:=false;
-        hsym:=tsym(FindWithHash(hashedid));
-        if assigned(hsym) then
-          begin
-            { Delphi (contrary to TP) you can have a symbol with the same name as the
-              unit, the unit can then not be accessed anymore using
-              <unit>.<id>, so we can hide the symbol }
-            if (m_delphi in current_settings.modeswitches) and
-               (hsym.typ=symconst.unitsym) then
-              HideSym(hsym)
-            else
-              DuplicateSym(hashedid,sym,hsym);
-            result:=true;
-            exit;
-          end;
+        result:=inherited checkduplicate(hashedid,sym);
 
 
-        if (current_module.localsymtable=self) and
+        if not result and
+           (current_module.localsymtable=self) and
            assigned(current_module.globalsymtable) then
            assigned(current_module.globalsymtable) then
           result:=tglobalsymtable(current_module.globalsymtable).checkduplicate(hashedid,sym);
           result:=tglobalsymtable(current_module.globalsymtable).checkduplicate(hashedid,sym);
       end;
       end;
@@ -1551,28 +1603,6 @@ implementation
       end;
       end;
 
 
 
 
-    function tglobalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
-      var
-        hsym : tsym;
-      begin
-        result:=false;
-        hsym:=tsym(FindWithHash(hashedid));
-        if assigned(hsym) then
-          begin
-            { Delphi (contrary to TP) you can have a symbol with the same name as the
-              unit, the unit can then not be accessed anymore using
-              <unit>.<id>, so we can hide the symbol }
-            if (m_delphi in current_settings.modeswitches) and
-               (hsym.typ=symconst.unitsym) then
-              HideSym(hsym)
-            else
-              DuplicateSym(hashedid,sym,hsym);
-            result:=true;
-            exit;
-          end;
-      end;
-
-
 {****************************************************************************
 {****************************************************************************
                               TWITHSYMTABLE
                               TWITHSYMTABLE
 ****************************************************************************}
 ****************************************************************************}

+ 7 - 0
compiler/utils/ppudump.pp

@@ -1489,6 +1489,13 @@ begin
          ibunitsym :
          ibunitsym :
            readcommonsym('Unit symbol ');
            readcommonsym('Unit symbol ');
 
 
+         ibnamespacesym :
+           begin
+             readcommonsym('NameSpace symbol ');
+             write(space,'  Hidden Unit : ');
+             readderef('');
+           end;
+
          iblabelsym :
          iblabelsym :
            readcommonsym('Label symbol ');
            readcommonsym('Label symbol ');