From 226a917014181e8816c8f3c1a21c14eb3e9dd8e0 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 30 Sep 1998 16:43:34 +0000 Subject: [PATCH] * fixed unit interdependency with circular uses --- compiler/files.pas | 27 ++++++++++++++++++++++++--- compiler/parser.pas | 21 +++++++-------------- compiler/pmodules.pas | 36 ++++++++++++++++++++++++++++-------- compiler/scanner.pas | 14 ++++++++++---- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/compiler/files.pas b/compiler/files.pas index 1dcda4c439..658bd690f4 100644 --- a/compiler/files.pas +++ b/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 diff --git a/compiler/parser.pas b/compiler/parser.pas index 5f479b4d87..72dc33f4ba 100644 --- a/compiler/parser.pas +++ b/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 diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index c5059363cc..3420aa8f84 100644 --- a/compiler/pmodules.pas +++ b/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 diff --git a/compiler/scanner.pas b/compiler/scanner.pas index a87e44dfa6..5aa399a5f2 100644 --- a/compiler/scanner.pas +++ b/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