1 (* M2Comp.mod continually calls the compiler for every source file.
3 Copyright (C) 2001-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. *)
22 IMPLEMENTATION MODULE M2Comp ;
25 FROM M2Pass IMPORT SetPassToPass0, SetPassToPass1, SetPassToPass2, SetPassToPassC,
26 SetPassToPass3, SetPassToNoPass, SetPassToPassHidden ;
28 FROM M2Reserved IMPORT toktype ;
29 FROM M2Search IMPORT FindSourceDefFile, FindSourceModFile ;
30 FROM M2Code IMPORT Code ;
32 FROM M2LexBuf IMPORT OpenSource, CloseSource, ResetForNewPass, currenttoken, GetToken,
33 ReInitialize, currentstring, GetTokenNo ;
35 FROM M2FileName IMPORT CalculateFileName ;
36 FROM M2Preprocess IMPORT PreprocessModule, MakeSaveTempsFileNameExt, OnExitDelete ;
37 FROM libc IMPORT exit ;
39 FROM M2Error IMPORT ErrorStringAt, ErrorStringAt2, ErrorStringsAt2,
40 WriteFormat0, FlushErrors, FlushWarnings, ResetErrorScope ;
42 FROM M2MetaError IMPORT MetaErrorString0, MetaErrorString1, MetaError0, MetaError1,
45 FROM FormatStrings IMPORT Sprintf1 ;
46 FROM P0SymBuild IMPORT P0Init, P1Init ;
47 FROM M2Debug IMPORT Assert ;
50 IMPORT P0SyntaxCheck ;
57 IMPORT DynamicStrings ;
59 FROM M2Batch IMPORT GetSource, GetModuleNo, GetDefinitionModuleFile, GetModuleFile,
60 AssociateModule, AssociateDefinition, MakeImplementationSource,
63 FROM SymbolTable IMPORT GetSymName, IsDefImp, NulSym,
64 IsHiddenTypeDeclared, GetFirstUsed, GetMainModule, SetMainModule,
65 ResolveConstructorTypes, SanityCheckConstants, IsDefinitionForC,
66 IsBuiltinInModule, PutModLink, IsDefLink, IsModLink, PutLibName,
67 GetModuleDefImportStatementList, GetModuleModImportStatementList,
68 GetImportModule, IsImportStatement, IsImport,
69 GetImportStatementList ;
71 FROM M2Search IMPORT FindSourceDefFile ;
73 FROM FIO IMPORT File, StdErr, StdOut, Close, EOF, IsNoError, WriteLine,
74 WriteChar, FlushOutErr ;
76 FROM SFIO IMPORT WriteS, OpenToRead, OpenToWrite, ReadS, WriteS ;
77 FROM NameKey IMPORT Name, GetKey, KeyToCharStar, makekey ;
78 FROM M2Printf IMPORT fprintf0, fprintf1 ;
79 FROM M2Quiet IMPORT qprintf0, qprintf1, qprintf2 ;
81 FROM M2Options IMPORT Verbose, GetM2Prefix, GetM, GetMM, GetDepTarget, GetMF, GetMP,
82 GetObj, PPonly, Statistics, Quiet, WholeProgram, GetMD, GetMMD,
83 ExtendedOpaque, GenModuleList ;
85 FROM PathName IMPORT DumpPathName ;
86 FROM Lists IMPORT List, NoOfItemsInList, GetItemFromList ;
87 FROM Indexing IMPORT Index, InitIndex, KillIndex, GetIndice, PutIndice, HighIndice ;
89 FROM DynamicStrings IMPORT String, InitString, KillString, InitStringCharStar,
90 Dup, Mark, EqualArray, string, Length, ConCat, ConCatChar,
91 InitStringChar, RIndex, Slice, Equal, RemoveWhitePrefix ;
98 ModuleType : (None, Definition, Implementation, Program) ;
104 CompilingDefinitionModule - returns true if the current module being
105 compiled is a definition module.
108 PROCEDURE CompilingDefinitionModule() : BOOLEAN ;
110 RETURN( ModuleType=Definition )
111 END CompilingDefinitionModule ;
115 CompilingImplementationModule - returns true if the current module being
116 compiled is an implementation module.
119 PROCEDURE CompilingImplementationModule() : BOOLEAN ;
121 RETURN( ModuleType=Implementation )
122 END CompilingImplementationModule ;
126 CompilingProgramModule - returns true if the current module being
127 compiled is a program module.
130 PROCEDURE CompilingProgramModule() : BOOLEAN ;
132 RETURN( ModuleType=Program )
133 END CompilingProgramModule ;
137 NeedToParseImplementation -
140 PROCEDURE NeedToParseImplementation (sym: CARDINAL) : BOOLEAN ;
142 RETURN (IsDefImp(sym) AND IsHiddenTypeDeclared(sym) AND ExtendedOpaque) OR
143 (IsDefImp(sym) AND IsBuiltinInModule(sym)) OR
144 (WholeProgram AND (NOT IsDefinitionForC(sym)))
145 END NeedToParseImplementation ;
149 GenerateDefDependency - generate a single dependency for the definition module
150 providing that it can be found and is not blocked by -MM.
153 PROCEDURE GenerateDefDependency (module: CARDINAL) ;
159 stem := InitStringCharStar (KeyToCharStar (GetSymName (module))) ;
161 IF FindSourceDefFile (stem, fullpath, named)
163 IF EqualArray (named, '') OR (NOT GetMM ())
165 MergeDep (DepContent, fullpath)
167 fullpath := KillString (fullpath)
170 stem := KillString (stem) ;
171 named := KillString (named)
172 END GenerateDefDependency ;
176 GenerateDependenciesFromImport - lookup the module associated with the import
177 and call GenerateDefDependency.
180 PROCEDURE GenerateDependenciesFromImport (import: CARDINAL) ;
184 Assert (IsImport (import)) ;
185 module := GetImportModule (import) ;
186 GenerateDefDependency (module)
187 END GenerateDependenciesFromImport ;
191 GenerateDependenciesFromList - iterative over the import lists and for
192 each module issue a dependency.
195 PROCEDURE GenerateDependenciesFromList (dep: List) ;
199 i, n, j, m: CARDINAL ;
201 n := NoOfItemsInList (dep) ;
204 import := GetItemFromList (dep, i) ;
205 IF IsImportStatement (import)
207 importList := GetImportStatementList (import) ;
209 m := NoOfItemsInList (importList) ;
211 import := GetItemFromList (importList, j) ;
212 GenerateDependenciesFromImport (import) ;
216 GenerateDependenciesFromImport (import)
220 END GenerateDependenciesFromList ;
224 GenerateDependencies - generate a list of dependencies for the main module where
225 the source code is found in sourcefile.
228 PROCEDURE GenerateDependencies (sourcefile: String) ;
230 IF IsDefImp (GetMainModule ())
232 GenerateDependenciesFromList (GetModuleDefImportStatementList (GetMainModule ())) ;
233 GenerateDefDependency (GetMainModule ())
235 GenerateDependenciesFromList (GetModuleModImportStatementList (GetMainModule ())) ;
236 WriteDepContents (DepOutput, DepContent)
237 END GenerateDependencies ;
241 Compile - compile file, s, using a 5 pass technique.
244 PROCEDURE Compile (s: String) ;
247 FlushWarnings ; FlushErrors ;
248 ResetForNewPass ; ResetErrorScope ;
249 qprintf0('Pass 1: scopes, enumerated types, imports and exports\n') ;
251 FlushWarnings ; FlushErrors ;
252 IF GetM () OR GetMM ()
254 GenerateDependencies (s)
258 qprintf0('Pass 2: constants and types\n') ;
259 ResetForNewPass ; ResetErrorScope ;
261 FlushWarnings ; FlushErrors ;
262 qprintf0('Pass C: aggregate constants\n') ;
263 ResetForNewPass ; ResetErrorScope ;
265 FlushWarnings ; FlushErrors ;
266 qprintf0('Pass 3: quadruple generation\n') ;
267 ResetForNewPass ; ResetErrorScope ;
269 FlushWarnings ; FlushErrors ;
270 qprintf0('Pass 4: gcc tree generation\n') ;
272 FlushWarnings ; FlushErrors
278 compile - compile the filename.
281 PROCEDURE compile (filename: ADDRESS) ;
285 f := InitStringCharStar (filename) ;
292 ExamineCompilationUnit - opens the source file to obtain the module name and kind of module.
295 PROCEDURE ExamineCompilationUnit (VAR name: ADDRESS; VAR isdefimp: BOOLEAN) ;
299 isdefimp := FALSE ; (* default to program module *)
300 (* stop if we see eof, ';' or '[' *)
301 WHILE (currenttoken#eoftok) AND (currenttoken#semicolontok) AND (currenttoken#lsbratok) DO
302 IF (currenttoken=implementationtok) OR (currenttoken=definitiontok)
307 IF currenttoken=identtok
309 name := currentstring ;
314 Message := MetaString0 (InitString ('no {%kMODULE} name found')) ;
315 m2flex.M2Error (string (Message)) ;
317 END ExamineCompilationUnit ;
321 PeepInto - peeps into source, s, and initializes a definition/implementation or
322 program module accordingly.
325 PROCEDURE PeepInto (s: String) ;
332 ExamineCompilationUnit (name, isdefimp) ;
335 SetMainModule (MakeImplementationSource (GetTokenNo (), makekey (name)))
337 SetMainModule (MakeProgramSource (GetTokenNo (), makekey (name)))
342 fprintf1 (StdErr, 'failed to open %s\n', s) ;
349 qprintLibName - print the libname.
352 PROCEDURE qprintLibName (LibName: String) ;
354 IF (LibName # NIL) AND (NOT EqualArray (LibName, ''))
356 qprintf1 (' [%s]', LibName)
362 CreateFileStem - create a stem using the template LibName_ModuleName.
365 PROCEDURE CreateFileStem (SymName, LibName: String) : String ;
367 IF Length (LibName) > 0
369 RETURN ConCat (Dup (LibName), ConCat (InitStringChar ('_'), SymName))
377 Return basename of path. CutExt determines whether the .extension
381 PROCEDURE BaseName (Path: String; CutExt: BOOLEAN) : String ;
386 basename := RIndex (Path, '/', 0) ;
391 basename := basename + 1
395 ext := RIndex (Path, '.', 0) ;
403 RETURN Slice (Path, basename, ext)
408 IsLibrary - return TRUE if line contains a library module.
411 PROCEDURE IsLibrary (line: String) : BOOLEAN ;
414 libname, filename: String ;
418 moduleName := BaseName (line, TRUE) ;
421 IF FindSourceDefFile (moduleName, filename, libname)
423 moduleName := KillString (moduleName) ;
424 IF Length (libname) > 0
426 moduleName := BaseName (line, FALSE) ;
427 line := BaseName (line, FALSE) ;
428 result := Equal (line, moduleName) ;
429 line := KillString (line) ;
432 libname := KillString (libname) ;
433 filename := KillString (filename) ;
434 moduleName := KillString (moduleName) ;
440 IsUnique - return TRUE if line is unique in array content.
443 PROCEDURE IsUnique (content: Index; line: String) : BOOLEAN ;
447 high := HighIndice (content) ;
450 IF Equal (line, GetIndice (content, i))
461 Append - append line to array content.
464 PROCEDURE Append (content: Index; line: String) ;
468 high := HighIndice (content) ;
469 PutIndice (content, high+1, line)
474 MergeDep - if line is unique in array content then append.
475 Check to see (and ignore) if line is a library module and -MM
479 PROCEDURE MergeDep (content: Index; line: String) ;
481 line := RemoveWhitePrefix (line) ;
482 IF (NOT EqualArray (line, "\")) AND (Length (line) > 0)
484 (* Ignore if -MM and is a library module. *)
485 IF NOT (GetMM () AND IsLibrary (line))
487 IF IsUnique (content, line)
489 Append (content, line)
497 splitLine - split a line into words separated by spaces
498 and call MergeDep on each word.
501 PROCEDURE splitLine (content: Index; line: String) ;
507 line := RemoveWhitePrefix (line) ;
508 space := DynamicStrings.Index (line, ' ', 0) ;
511 word := Slice (line, 0, space) ;
512 word := RemoveWhitePrefix (word) ;
515 MergeDep (content, word)
517 line := Slice (line, space, 0) ;
520 MergeDep (content, line)
527 MergeDeps - foreach dependency in ChildDep do
528 add dependency to ChildDep if not already present.
529 ignore all ChildDep if -MM and libname # "".
532 PROCEDURE MergeDeps (content: Index; ChildDep, LibName: String) ;
537 IF (content # NIL) AND (NOT (GetMM () AND (Length (LibName) > 0)))
539 in := OpenToRead (ChildDep) ;
542 line := ReadS (in) ; (* Skip over first line containing the module object. *)
543 WHILE NOT EOF (in) DO
545 splitLine (content, line)
554 GetRuleTarget - return the rule target which is derived from the -MT arg
555 or -o arg or filename.mod.
558 PROCEDURE GetRuleTarget (filename: String) : String ;
560 IF GetDepTarget () # NIL
562 RETURN InitStringCharStar (GetDepTarget ())
565 RETURN InitStringCharStar (GetMF ())
567 RETURN ConCat (BaseName (filename, TRUE), InitString ('.o'))
573 ReadDepContents - reads the contents of file dep into a dynamic array
574 and return the array. The file will be split into words
575 and each word stored as an entry in the array.
578 PROCEDURE ReadDepContents (filename, dep: String) : Index ;
585 IF GetM () OR GetMM ()
587 in := OpenToRead (dep) ;
588 (* The file might not be created (if -MD or -MMD is used as these options
589 operate without preprocessing) in which case we create an dynamic
590 array with the source filename and target. *)
591 content := InitIndex (1) ;
592 IF GetMD () OR GetMMD () OR (NOT IsNoError (in))
594 (* No preprocessing done therefore create first two lines using
595 target and source. *)
596 PutIndice (content, 1, ConCatChar (GetRuleTarget (filename), ':')) ;
597 PutIndice (content, 2, Dup (filename))
599 (* Preprocessing (using cc1) has created one for us, so we read it. *)
600 WHILE NOT EOF (in) DO
602 splitLine (content, line)
608 END ReadDepContents ;
612 WriteDep - write the dependencies and target to file out.
615 PROCEDURE WriteDep (dep: String; contents: Index; out: File) ;
621 h := HighIndice (contents) ;
623 line := GetIndice (contents, i) ;
624 line := RemoveWhitePrefix (line) ;
629 (* First line is always the target. *)
630 IF GetDepTarget () # NIL
632 line := ConCatChar (InitStringCharStar (GetDepTarget ()), ':')
638 line := WriteS (out, line) ;
641 WriteChar (out, ' ') ;
652 WritePhonyDep - write the dependencies and target to file out.
655 PROCEDURE WritePhonyDep (dep: String; contents: Index; out: File) ;
660 (* The first line is always the target and the second line is always
661 the top level source file. *)
663 h := HighIndice (contents) ;
665 line := GetIndice (contents, i) ;
666 line := RemoveWhitePrefix (line) ;
669 line := WriteS (out, line) ;
670 WriteChar (out, ':') ;
679 WriteDepContents - write the dynamic array to filename dep (or StdOut) if
680 the GetMF file is NIL.
683 PROCEDURE WriteDepContents (dep: String; contents: Index) ;
687 IF (contents # NIL) AND (GetM () OR GetMM ())
692 dep := OnExitDelete (dep)
694 out := OpenToWrite (dep)
698 WriteDep (dep, contents, out) ;
701 WritePhonyDep (dep, contents, out)
710 contents := KillIndex (contents)
712 END WriteDepContents ;
716 CreateDepFilename - return a dependency filename associated with filename or use GetMF.
719 PROCEDURE CreateDepFilename (filename: String) : String ;
725 depfile := MakeSaveTempsFileNameExt (filename, InitString ('.d')) ;
726 RETURN OnExitDelete (depfile)
728 RETURN InitStringCharStar (GetMF ())
730 END CreateDepFilename ;
737 PROCEDURE Pass0CheckDef (sym: CARDINAL) : BOOLEAN ;
746 SymName := InitStringCharStar (KeyToCharStar (GetSymName (sym))) ;
749 IF FindSourceDefFile (SymName, FileName, LibName)
751 ModuleType := Definition ;
752 ChildDep := MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), InitString ('.def.d')) ;
753 IF OpenSource (AssociateDefinition (PreprocessModule (FileName, FALSE, TRUE,
756 IF NOT P0SyntaxCheck.CompilationUnit ()
758 WriteFormat0 ('compilation failed') ;
760 SymName := KillString (SymName) ;
761 FileName := KillString (FileName) ;
762 LibName := KillString (LibName) ;
765 qprintf2 (' Module %-20s : %s', SymName, FileName) ;
766 qprintLibName (LibName) ;
767 PutLibName (sym, makekey (string (LibName))) ;
768 IF IsDefinitionForC (sym)
770 qprintf0 (' (for C)')
774 qprintf0 (' (linking)')
778 MergeDeps (DepContent, ChildDep, LibName)
780 (* Unrecoverable error. *)
781 MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
785 (* Unrecoverable error. *)
786 MetaError1 ('the file containing the definition module {%1EMAa} cannot be found', sym)
788 ModuleType := Implementation
790 ModuleType := Program
792 SymName := KillString (SymName) ;
793 FileName := KillString (FileName) ;
794 LibName := KillString (LibName) ;
803 PROCEDURE Pass0CheckMod (sym: CARDINAL; PPSource: String) : BOOLEAN ;
811 SymName := InitStringCharStar (KeyToCharStar (GetSymName (sym))) ;
814 Main := GetMainModule () ;
815 IF (Main = sym) OR NeedToParseImplementation (sym)
817 (* Only need to read implementation module if hidden types are
818 declared or it is the main module. *)
821 FileName := Dup (PPSource) ;
822 LibName := InitStringCharStar (GetM2Prefix ()) ;
823 PutLibName (sym, makekey (string (LibName)))
825 IF FindSourceModFile (SymName, FileName, LibName)
827 ChildDep := MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), InitString ('.mod.d')) ;
828 FileName := PreprocessModule (FileName, FALSE, TRUE, ChildDep) ;
829 PutLibName (sym, makekey (string (LibName))) ;
830 MergeDeps (DepContent, ChildDep, LibName)
832 qprintf1 (' Module %-20s : implementation source file not found\n', SymName)
838 IF OpenSource (AssociateModule (Dup (FileName), sym))
840 IF NOT P0SyntaxCheck.CompilationUnit ()
842 WriteFormat0 ('compilation failed') ;
844 SymName := KillString (SymName) ;
845 FileName := KillString (FileName) ;
846 LibName := KillString (LibName) ;
849 qprintf2 (' Module %-20s : %s', SymName, FileName) ;
850 qprintLibName (LibName) ;
853 qprintf0 (' (linking)')
858 (* It is quite legitimate to implement a module in C (and pretend it was a M2
859 implementation) providing that it is not the main program module and the
860 definition module does not declare a hidden type when -fextended-opaque
862 IF (NOT WholeProgram) OR (sym = Main) OR IsHiddenTypeDeclared (sym)
864 (* Unrecoverable error. *)
865 MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
872 IF NOT IsDefinitionForC (sym)
874 (* The implementation module is only useful if -fgen-module-list= is
875 used (to gather all dependencies) although we do not insist upon finding the
876 implementation module. *)
878 IF FindSourceModFile (SymName, FileName, LibName)
880 PutLibName (sym, makekey (string (LibName))) ;
881 qprintf2 (' Module %-20s : %s' , SymName, FileName) ;
882 qprintLibName (LibName) ;
883 qprintf0 (' (linking)\n') ;
884 ChildDep := MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), InitString ('.mod.d')) ;
885 IF OpenSource (AssociateModule (PreprocessModule (FileName, FALSE, TRUE, ChildDep), sym))
887 PutModLink (sym, TRUE) ; (* This source is only used to determine link time info. *)
888 IF NOT P0SyntaxCheck.CompilationUnit ()
890 WriteFormat0 ('compilation failed') ;
892 SymName := KillString (SymName) ;
893 FileName := KillString (FileName) ;
894 LibName := KillString (LibName) ;
898 MergeDeps (DepContent, ChildDep, LibName)
903 SymName := KillString (SymName) ;
904 FileName := KillString (FileName) ;
905 LibName := KillString (LibName) ;
914 PROCEDURE DoPass0 (filename: String) ;
922 (* Maybe preprocess the main file. *)
923 DepOutput := CreateDepFilename (filename) ;
924 PPSource := PreprocessModule (filename, TRUE, FALSE, DepOutput) ;
925 DepContent := ReadDepContents (filename, DepOutput) ;
926 PeepInto (PPSource) ;
928 sym := GetModuleNo (i) ;
929 qprintf1 ('Compiling: %s\n', PPSource) ;
932 DumpPathName ('DoPass0')
936 fprintf1 (StdOut, 'Compiling: %s\n', PPSource)
938 qprintf0 ('Pass 0: lexical analysis, parsing, modules and associated filenames\n') ;
939 WHILE sym # NulSym DO
940 IF NOT Pass0CheckDef (sym)
944 IF NOT Pass0CheckMod (sym, PPSource)
949 sym := GetModuleNo (i)
956 DoPass1 - parses the sources of all modules necessary to compile
957 the required module, Main.
970 Sym := GetModuleNo(i) ;
972 FileName := GetDefinitionModuleFile(Sym) ;
977 name := GetSymName(Sym) ;
978 qprintf1(' Module %a\n', name)
980 IF OpenSource(FileName)
982 ModuleType := Definition ;
983 IF NOT P1Build.CompilationUnit()
985 MetaError0('compilation failed') ;
991 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
994 ModuleType := Implementation
996 ModuleType := Program
998 FileName := GetModuleFile(Sym) ;
1003 name := GetSymName(Sym) ;
1004 qprintf1(' Module %a\n', name)
1006 IF OpenSource(FileName)
1008 IF NOT P1Build.CompilationUnit()
1010 MetaError0('compilation failed') ;
1016 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1021 Sym := GetModuleNo(i)
1028 DoPass2 - parses the sources of all modules necessary to compile
1029 the required module, Main.
1041 Sym := GetModuleNo(i) ;
1043 FileName := GetDefinitionModuleFile(Sym) ;
1048 name := GetSymName(Sym) ;
1049 qprintf1(' Module %a\n', name)
1051 IF OpenSource(FileName)
1053 ModuleType := Definition ;
1054 IF NOT P2Build.CompilationUnit()
1056 MetaError0('compilation failed') ;
1062 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1065 ModuleType := Implementation
1067 ModuleType := Program
1069 FileName := GetModuleFile(Sym) ;
1074 name := GetSymName(Sym) ;
1075 qprintf1(' Module %a\n', name)
1077 IF OpenSource(FileName)
1079 IF NOT P2Build.CompilationUnit()
1081 MetaError0('compilation failed') ;
1087 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1092 Sym := GetModuleNo(i)
1099 DoPassC - parses the sources of all modules necessary to compile
1100 the required module, Main.
1112 Sym := GetModuleNo(i) ;
1114 FileName := GetDefinitionModuleFile(Sym) ;
1119 name := GetSymName(Sym) ;
1120 qprintf1(' Module %a\n', name)
1122 IF OpenSource(FileName)
1124 ModuleType := Definition ;
1125 IF NOT PCBuild.CompilationUnit()
1127 MetaError0('compilation failed') ;
1133 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1136 ModuleType := Implementation
1138 ModuleType := Program
1140 FileName := GetModuleFile(Sym) ;
1145 name := GetSymName(Sym) ;
1146 qprintf1(' Module %a\n', name)
1148 IF OpenSource(FileName)
1150 IF NOT PCBuild.CompilationUnit()
1152 MetaError0('compilation failed') ;
1158 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1163 Sym := GetModuleNo(i)
1165 PCSymBuild.ResolveConstTypes ;
1166 ResolveConstructorTypes ;
1167 SanityCheckConstants ;
1173 DoPass3 - parses the sources of all modules necessary to compile
1174 the required module, Main.
1185 Main := GetMainModule() ;
1187 Sym := GetModuleNo(i) ;
1189 FileName := GetDefinitionModuleFile(Sym) ;
1192 IF OpenSource(FileName)
1194 ModuleType := Definition ;
1195 IF NOT P3Build.CompilationUnit()
1197 MetaError0('compilation failed') ;
1203 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1206 ModuleType := Implementation
1208 ModuleType := Program
1210 FileName := GetModuleFile(Sym) ;
1213 IF OpenSource(FileName)
1215 IF (Main=Sym) OR WholeProgram
1217 IF NOT P3Build.CompilationUnit()
1219 MetaError0('compilation failed') ;
1225 not the main module .mod therefore must be implementing
1226 a hidden type - we dont want to generate any
1227 StatementSequence quadrupes but we do want to build TYPEs
1228 and ConstExpressions.
1231 SetPassToPassHidden ;
1232 IF NOT PHBuild.CompilationUnit()
1234 MetaError0('compilation failed') ;
1243 fprintf1(StdErr, 'failed to open %s\n', FileName) ;
1248 Sym := GetModuleNo(i)
1255 ModuleType := None ;