소스 검색

* fixed unit interdependency with circular uses

peter 27 년 전
부모
커밋
226a917014
4개의 변경된 파일69개의 추가작업 그리고 29개의 파일을 삭제
  1. 24 3
      compiler/files.pas
  2. 7 14
      compiler/parser.pas
  3. 28 8
      compiler/pmodules.pas
  4. 10 4
      compiler/scanner.pas

+ 24 - 3
compiler/files.pas

@@ -116,6 +116,7 @@ unit files;
           do_compile,               { need to compile the sources }
           sources_avail,            { if all sources are reachable }
           is_unit,
+          in_second_compile,        { is this unit being compiled for the 2nd time? }
           in_implementation,        { processing the implementation part? }
           in_global     : boolean;  { allow global settings }
 
@@ -126,6 +127,8 @@ unit files;
 {$ifdef UseBrowser}
           implsymtable  : pointer;
 {$endif UseBrowser}
+          scanner       : pointer;  { scanner object used }
+          loaded_from   : pmodule;
           uses_imports  : boolean;  { Set if the module imports from DLL's.}
           imports       : plinkedlist;
 
@@ -135,8 +138,6 @@ unit files;
           linkofiles    : tstringcontainer;
           used_units    : tlinkedlist;
 
-          { used in firstpass for faster settings }
-          scanner       : pointer;
 
           path,                     { path where the module is find/created }
           modulename,               { name of the module in uppercase }
@@ -151,6 +152,7 @@ unit files;
 
           constructor init(const s:string;_is_unit:boolean);
           destructor done;virtual;
+          procedure reset;
           procedure setfilename(const fn:string;allowoutput:boolean);
           function  openppu:boolean;
           function  search_unit(const n : string):boolean;
@@ -770,6 +772,20 @@ unit files;
          search_unit:=Found;
       end;
 
+    procedure tmodule.reset;
+      begin
+        sourcefiles^.done;
+        sourcefiles^.init;
+        used_units.done;
+        used_units.init;
+        linkofiles.done;
+        linkofiles.init;
+        linkstaticlibs.done;
+        linkstaticlibs.init;
+        linksharedlibs.done;
+        linksharedlibs.init;
+      end;
+
 
     constructor tmodule.init(const s:string;_is_unit:boolean);
       var
@@ -814,6 +830,7 @@ unit files;
 {$ifdef UseBrowser}
          implsymtable:=nil;
 {$endif UseBrowser}
+         loaded_from:=nil;
          flags:=0;
          crc:=0;
          unitcount:=1;
@@ -823,6 +840,7 @@ unit files;
          do_compile:=false;
          sources_avail:=true;
          compiled:=false;
+         in_second_compile:=false;
          in_implementation:=false;
          in_global:=true;
          is_unit:=_is_unit;
@@ -907,7 +925,10 @@ unit files;
 end.
 {
   $Log$
-  Revision 1.49  1998-09-28 16:57:20  pierre
+  Revision 1.50  1998-09-30 16:43:34  peter
+    * fixed unit interdependency with circular uses
+
+  Revision 1.49  1998/09/28 16:57:20  pierre
     * changed all length(p^.value_str^) into str_length(p)
       to get it work with and without ansistrings
     * changed sourcefiles field of tmodule to a pointer

+ 7 - 14
compiler/parser.pas

@@ -204,18 +204,7 @@ unit parser;
 
        { reset the unit or create a new program }
          if assigned(current_module) then
-          begin
-            current_module^.sourcefiles^.done;
-            current_module^.sourcefiles^.init;
-            current_module^.used_units.done;
-            current_module^.used_units.init;
-            current_module^.linkofiles.done;
-            current_module^.linkofiles.init;
-            current_module^.linkstaticlibs.done;
-            current_module^.linkstaticlibs.init;
-            current_module^.linksharedlibs.done;
-            current_module^.linksharedlibs.init;
-          end
+          current_module^.reset
          else
           begin
             current_module:=new(pmodule,init(filename,false));
@@ -235,9 +224,10 @@ unit parser;
          if compile_system then
           aktmoduleswitches:=aktmoduleswitches+[cs_compilesystem];
 
-       { startup scanner }
+       { startup scanner, and save in current_module }
          current_scanner:=new(pscannerfile,Init(filename));
          current_scanner^.readtoken;
+         current_module^.scanner:=current_scanner;
 
        { init code generator for a new module }
          codegen_newmodule;
@@ -374,7 +364,10 @@ unit parser;
 end.
 {
   $Log$
-  Revision 1.52  1998-09-28 16:57:22  pierre
+  Revision 1.53  1998-09-30 16:43:36  peter
+    * fixed unit interdependency with circular uses
+
+  Revision 1.52  1998/09/28 16:57:22  pierre
     * changed all length(p^.value_str^) into str_length(p)
       to get it work with and without ansistrings
     * changed sourcefiles field of tmodule to a pointer

+ 28 - 8
compiler/pmodules.pas

@@ -35,7 +35,7 @@ unit pmodules;
     uses
        cobjects,comphook,systems,globals,
        symtable,aasm,files,
-       hcodegen,verbose, { don't use hcodegen.message !! }
+       hcodegen,verbose,
        link,assemble,import,gendef,ppu
 {$ifdef i386}
        ,i386
@@ -184,6 +184,7 @@ unit pmodules;
         fillchar(current_module^.map^,sizeof(tunitmap),#0);
         nextmapentry:=1;
       { load the used units from interface }
+        current_module^.in_implementation:=false;
         pu:=pused_unit(current_module^.used_units.first);
         while assigned(pu) do
          begin
@@ -270,10 +271,12 @@ unit pmodules;
 
 
     function loadunit(const s : string;compile_system:boolean) : pmodule;
+      const
+        ImplIntf : array[boolean] of string[15]=('interface','implementation');
       var
         st : punitsymtable;
         old_current_ppu : pppufile;
-        old_current_module,hp : pmodule;
+        old_current_module,hp,hp2 : pmodule;
 
         procedure loadppufile;
         begin
@@ -286,7 +289,7 @@ unit pmodules;
         { recompile if set }
           if current_module^.do_compile then
            begin
-           { we needn't the ppufile }
+           { we don't need the ppufile anymore }
              if assigned(current_module^.ppufile) then
               begin
                 dispose(current_module^.ppufile,done);
@@ -321,8 +324,8 @@ unit pmodules;
       begin
          old_current_module:=current_module;
          old_current_ppu:=current_ppu;
-         { be sure not to mix lines from different files }
-         { update_line; }
+         { Info }
+         Message3(unit_t_load_unit,current_module^.modulename^,ImplIntf[current_module^.in_implementation],s);
          { unit not found }
          st:=nil;
          { search all loaded units }
@@ -339,9 +342,21 @@ unit pmodules;
                      st:=punitsymtable(hp^.symtable)
                    else
                     begin
-                    { recompile the unit ? }
+                    { both units in interface ? }
                       if (not current_module^.in_implementation) and (not hp^.in_implementation) then
-                       Message(unit_f_circular_unit_reference);
+                       begin
+                       { check for a cycle }
+                         hp2:=current_module^.loaded_from;
+                         while assigned(hp2) and (hp2<>hp) do
+                          begin
+                            if hp2^.in_implementation then
+                             hp2:=nil
+                            else
+                             hp2:=hp2^.loaded_from;
+                          end;
+                         if assigned(hp2) then
+                          Message2(unit_f_circular_unit_reference,current_module^.modulename^,hp^.modulename^);
+                       end;
                     end;
                    break;
                 end;
@@ -360,12 +375,14 @@ unit pmodules;
                hp^.done;
                hp^.init(s,true);
                current_module:=hp;
+               current_module^.in_second_compile:=true;
              end
             else
           { generates a new unit info record }
              current_module:=new(pmodule,init(s,true));
             current_ppu:=current_module^.ppufile;
           { now we can register the unit }
+            current_module^.loaded_from:=old_current_module;
             loaded_units.insert(current_module);
           { now realy load the ppu }
             loadppufile;
@@ -982,7 +999,10 @@ unit pmodules;
 end.
 {
   $Log$
-  Revision 1.57  1998-09-30 12:11:52  peter
+  Revision 1.58  1998-09-30 16:43:37  peter
+    * fixed unit interdependency with circular uses
+
+  Revision 1.57  1998/09/30 12:11:52  peter
     * fixed circular uses which looped forever
 
   Revision 1.56  1998/09/28 11:22:15  pierre

+ 10 - 4
compiler/scanner.pas

@@ -226,9 +226,12 @@ implementation
     destructor tscannerfile.done;
       begin
         checkpreprocstack;
-      { close file }
-        if not inputfile^.closed then
-         closeinputfile;
+      { close file, but only if we are the first compile }
+        if not current_module^.in_second_compile then
+         begin
+           if not inputfile^.closed then
+            closeinputfile;
+         end;
        end;
 
 
@@ -1424,7 +1427,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.55  1998-09-28 16:57:26  pierre
+  Revision 1.56  1998-09-30 16:43:38  peter
+    * fixed unit interdependency with circular uses
+
+  Revision 1.55  1998/09/28 16:57:26  pierre
     * changed all length(p^.value_str^) into str_length(p)
       to get it work with and without ansistrings
     * changed sourcefiles field of tmodule to a pointer