Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2Comp. */
2 : : /* M2Comp.mod continually calls the compiler for every source file.
3 : :
4 : : Copyright (C) 2001-2025 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "gcc-consolidation.h"
26 : :
27 : : #include <stdbool.h>
28 : : # if !defined (PROC_D)
29 : : # define PROC_D
30 : : typedef void (*PROC_t) (void);
31 : : typedef struct { PROC_t proc; } PROC;
32 : : # endif
33 : :
34 : : # if !defined (TRUE)
35 : : # define TRUE (1==1)
36 : : # endif
37 : :
38 : : # if !defined (FALSE)
39 : : # define FALSE (1==0)
40 : : # endif
41 : :
42 : : # include "Gmcrts.h"
43 : : #if defined(__cplusplus)
44 : : # undef NULL
45 : : # define NULL 0
46 : : #endif
47 : : #define _M2Comp_C
48 : :
49 : : #include "GM2Comp.h"
50 : : # include "GM2Pass.h"
51 : : # include "GM2Reserved.h"
52 : : # include "GM2Search.h"
53 : : # include "GM2Code.h"
54 : : # include "GM2LexBuf.h"
55 : : # include "GM2FileName.h"
56 : : # include "GM2Preprocess.h"
57 : : # include "Glibc.h"
58 : : # include "GM2Error.h"
59 : : # include "GM2MetaError.h"
60 : : # include "GFormatStrings.h"
61 : : # include "GP0SymBuild.h"
62 : : # include "GM2Debug.h"
63 : : # include "Gm2flex.h"
64 : : # include "Gm2block.h"
65 : : # include "GP0SyntaxCheck.h"
66 : : # include "GP1Build.h"
67 : : # include "GP2Build.h"
68 : : # include "GPCBuild.h"
69 : : # include "GP3Build.h"
70 : : # include "GPHBuild.h"
71 : : # include "GPCSymBuild.h"
72 : : # include "GDynamicStrings.h"
73 : : # include "GM2Diagnostic.h"
74 : : # include "GM2Batch.h"
75 : : # include "GSymbolTable.h"
76 : : # include "GFIO.h"
77 : : # include "GSFIO.h"
78 : : # include "GNameKey.h"
79 : : # include "GM2Printf.h"
80 : : # include "GM2Quiet.h"
81 : : # include "GM2Options.h"
82 : : # include "GPathName.h"
83 : : # include "GLists.h"
84 : : # include "GIndexing.h"
85 : :
86 : : # define Debugging false
87 : : static enum {M2Comp_None, M2Comp_Definition, M2Comp_Implementation, M2Comp_Program} ModuleType;
88 : : static Indexing_Index DepContent;
89 : : static DynamicStrings_String DepOutput;
90 : :
91 : : /*
92 : : compile - compile the filename.
93 : : */
94 : :
95 : : extern "C" void M2Comp_compile (void * filename);
96 : :
97 : : /*
98 : : CompilingDefinitionModule - returns true if the current module being
99 : : compiled is a definition module.
100 : : */
101 : :
102 : : extern "C" bool M2Comp_CompilingDefinitionModule (void);
103 : :
104 : : /*
105 : : CompilingImplementationModule - returns true if the current module being
106 : : compiled is an implementation module.
107 : : */
108 : :
109 : : extern "C" bool M2Comp_CompilingImplementationModule (void);
110 : :
111 : : /*
112 : : CompilingProgramModule - returns true if the current module being
113 : : compiled is a program module.
114 : : */
115 : :
116 : : extern "C" bool M2Comp_CompilingProgramModule (void);
117 : :
118 : : /*
119 : : NeedToParseImplementation -
120 : : */
121 : :
122 : : static bool NeedToParseImplementation (unsigned int sym);
123 : :
124 : : /*
125 : : GenerateDefDependency - generate a single dependency for the definition module
126 : : providing that it can be found and is not blocked by -MM.
127 : : */
128 : :
129 : : static void GenerateDefDependency (unsigned int module);
130 : :
131 : : /*
132 : : GenerateDependenciesFromImport - lookup the module associated with the import
133 : : and call GenerateDefDependency.
134 : : */
135 : :
136 : : static void GenerateDependenciesFromImport (unsigned int import);
137 : :
138 : : /*
139 : : GenerateDependenciesFromList - iterative over the import lists and for
140 : : each module issue a dependency.
141 : : */
142 : :
143 : : static void GenerateDependenciesFromList (Lists_List dep);
144 : :
145 : : /*
146 : : GenerateDependencies - generate a list of dependencies for the main module where
147 : : the source code is found in sourcefile.
148 : : */
149 : :
150 : : static void GenerateDependencies (void);
151 : :
152 : : /*
153 : : Compile - compile file, s, using a 5 pass technique.
154 : : */
155 : :
156 : : static void Compile (DynamicStrings_String s);
157 : :
158 : : /*
159 : : PopulateResource -
160 : : */
161 : :
162 : : static void PopulateResource (void);
163 : :
164 : : /*
165 : : ExamineHeader - examines up until the ';', '[' or eof and determines if the source file
166 : : is a program, implementation/definition module.
167 : : */
168 : :
169 : : static void ExamineHeader (void * *name, bool *isdefimp, bool *module);
170 : :
171 : : /*
172 : : ExamineCompilationUnit - opens the source file to obtain the module name and kind of module.
173 : : */
174 : :
175 : : static unsigned int ExamineCompilationUnit (void);
176 : :
177 : : /*
178 : : PeepInto - peeps into source, s, and initializes a definition/implementation or
179 : : program module accordingly.
180 : : */
181 : :
182 : : static void PeepInto (DynamicStrings_String s);
183 : :
184 : : /*
185 : : qprintLibName - print the libname.
186 : : */
187 : :
188 : : static void qprintLibName (DynamicStrings_String LibName);
189 : :
190 : : /*
191 : : CreateFileStem - create a stem using the template LibName_ModuleName.
192 : : */
193 : :
194 : : static DynamicStrings_String CreateFileStem (DynamicStrings_String SymName, DynamicStrings_String LibName);
195 : : static DynamicStrings_String BaseName (DynamicStrings_String Path, bool CutExt);
196 : :
197 : : /*
198 : : IsLibrary - return TRUE if line contains a library module.
199 : : */
200 : :
201 : : static bool IsLibrary (DynamicStrings_String line);
202 : :
203 : : /*
204 : : IsUnique - return TRUE if line is unique in array content.
205 : : */
206 : :
207 : : static bool IsUnique (Indexing_Index content, DynamicStrings_String line);
208 : :
209 : : /*
210 : : Append - append line to array content.
211 : : */
212 : :
213 : : static void Append (Indexing_Index content, DynamicStrings_String line);
214 : :
215 : : /*
216 : : MergeDep - if line is unique in array content then append.
217 : : Check to see (and ignore) if line is a library module and -MM
218 : : is present.
219 : : */
220 : :
221 : : static void MergeDep (Indexing_Index content, DynamicStrings_String line);
222 : :
223 : : /*
224 : : splitLine - split a line into words separated by spaces
225 : : and call MergeDep on each word.
226 : : */
227 : :
228 : : static void splitLine (Indexing_Index content, DynamicStrings_String line);
229 : :
230 : : /*
231 : : MergeDeps - foreach dependency in ChildDep do
232 : : add dependency to ChildDep if not already present.
233 : : ignore all ChildDep if -MM and libname # "".
234 : : */
235 : :
236 : : static void MergeDeps (Indexing_Index content, DynamicStrings_String ChildDep, DynamicStrings_String LibName);
237 : :
238 : : /*
239 : : GetRuleTarget - return the rule target which is derived from the -MT arg
240 : : or -o arg or filename.mod.
241 : : */
242 : :
243 : : static DynamicStrings_String GetRuleTarget (DynamicStrings_String filename);
244 : :
245 : : /*
246 : : ReadDepContents - reads the contents of file dep into a dynamic array
247 : : and return the array. The file will be split into words
248 : : and each word stored as an entry in the array.
249 : : */
250 : :
251 : : static Indexing_Index ReadDepContents (DynamicStrings_String filename, DynamicStrings_String dep);
252 : :
253 : : /*
254 : : WriteDep - write the dependencies and target to file out.
255 : : */
256 : :
257 : : static void WriteDep (Indexing_Index contents, FIO_File out);
258 : :
259 : : /*
260 : : WritePhonyDep - write the dependencies and target to file out.
261 : : */
262 : :
263 : : static void WritePhonyDep (Indexing_Index contents, FIO_File out);
264 : :
265 : : /*
266 : : WriteDepContents - write the dynamic array to filename dep (or StdOut) if
267 : : the GetMF file is NIL.
268 : : */
269 : :
270 : : static void WriteDepContents (DynamicStrings_String dep, Indexing_Index contents);
271 : :
272 : : /*
273 : : CreateDepFilename - return a dependency filename associated with filename or use GetMF.
274 : : */
275 : :
276 : : static DynamicStrings_String CreateDepFilename (DynamicStrings_String filename);
277 : :
278 : : /*
279 : : Pass0CheckDef -
280 : : */
281 : :
282 : : static bool Pass0CheckDef (unsigned int sym);
283 : :
284 : : /*
285 : : Pass0CheckMod -
286 : : */
287 : :
288 : : static bool Pass0CheckMod (unsigned int sym, DynamicStrings_String PPSource);
289 : :
290 : : /*
291 : : DoPass0 -
292 : : */
293 : :
294 : : static void DoPass0 (DynamicStrings_String filename);
295 : :
296 : : /*
297 : : DoPass1 - parses the sources of all modules necessary to compile
298 : : the required module, Main.
299 : : */
300 : :
301 : : static void DoPass1 (void);
302 : :
303 : : /*
304 : : DoPass2 - parses the sources of all modules necessary to compile
305 : : the required module, Main.
306 : : */
307 : :
308 : : static void DoPass2 (void);
309 : :
310 : : /*
311 : : DoPassC - parses the sources of all modules necessary to compile
312 : : the required module, Main.
313 : : */
314 : :
315 : : static void DoPassC (void);
316 : :
317 : : /*
318 : : DoPass3 - parses the sources of all modules necessary to compile
319 : : the required module, Main.
320 : : */
321 : :
322 : : static void DoPass3 (void);
323 : :
324 : :
325 : : /*
326 : : NeedToParseImplementation -
327 : : */
328 : :
329 : 161437 : static bool NeedToParseImplementation (unsigned int sym)
330 : : {
331 : 161437 : return ((((SymbolTable_IsDefImp (sym)) && (SymbolTable_IsHiddenTypeDeclared (sym))) && M2Options_ExtendedOpaque) || ((SymbolTable_IsDefImp (sym)) && (SymbolTable_IsBuiltinInModule (sym)))) || (M2Options_WholeProgram && (! (SymbolTable_IsDefinitionForC (sym))));
332 : : /* static analysis guarentees a RETURN statement will be used before here. */
333 : : __builtin_unreachable ();
334 : : }
335 : :
336 : :
337 : : /*
338 : : GenerateDefDependency - generate a single dependency for the definition module
339 : : providing that it can be found and is not blocked by -MM.
340 : : */
341 : :
342 : 0 : static void GenerateDefDependency (unsigned int module)
343 : : {
344 : 0 : DynamicStrings_String stem;
345 : 0 : DynamicStrings_String fullpath;
346 : 0 : DynamicStrings_String named;
347 : :
348 : 0 : stem = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (module)));
349 : 0 : named = static_cast<DynamicStrings_String> (NULL);
350 : 0 : if (M2Search_FindSourceDefFile (stem, &fullpath, &named))
351 : : {
352 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
353 : 0 : if ((DynamicStrings_EqualArray (named, (const char *) "", 0)) || (! (M2Options_GetMM ())))
354 : : {
355 : 0 : MergeDep (DepContent, fullpath);
356 : : }
357 : : else
358 : : {
359 : 0 : fullpath = DynamicStrings_KillString (fullpath);
360 : : }
361 : : }
362 : 0 : stem = DynamicStrings_KillString (stem);
363 : 0 : named = DynamicStrings_KillString (named);
364 : 0 : }
365 : :
366 : :
367 : : /*
368 : : GenerateDependenciesFromImport - lookup the module associated with the import
369 : : and call GenerateDefDependency.
370 : : */
371 : :
372 : 0 : static void GenerateDependenciesFromImport (unsigned int import)
373 : : {
374 : 0 : unsigned int module;
375 : :
376 : 0 : M2Debug_Assert (SymbolTable_IsImport (import));
377 : 0 : module = SymbolTable_GetImportModule (import);
378 : 0 : GenerateDefDependency (module);
379 : 0 : }
380 : :
381 : :
382 : : /*
383 : : GenerateDependenciesFromList - iterative over the import lists and for
384 : : each module issue a dependency.
385 : : */
386 : :
387 : 0 : static void GenerateDependenciesFromList (Lists_List dep)
388 : : {
389 : 0 : Lists_List importList;
390 : 0 : unsigned int import;
391 : 0 : unsigned int i;
392 : 0 : unsigned int n;
393 : 0 : unsigned int j;
394 : 0 : unsigned int m;
395 : :
396 : 0 : n = Lists_NoOfItemsInList (dep);
397 : 0 : i = 1;
398 : 0 : while (i <= n)
399 : : {
400 : 0 : import = static_cast<unsigned int> (Lists_GetItemFromList (dep, i));
401 : 0 : if (SymbolTable_IsImportStatement (import))
402 : : {
403 : 0 : importList = SymbolTable_GetImportStatementList (import);
404 : 0 : j = 1;
405 : 0 : m = Lists_NoOfItemsInList (importList);
406 : 0 : while (j <= m)
407 : : {
408 : 0 : import = static_cast<unsigned int> (Lists_GetItemFromList (importList, j));
409 : 0 : GenerateDependenciesFromImport (import);
410 : 0 : j += 1;
411 : : }
412 : : }
413 : : else
414 : : {
415 : 0 : GenerateDependenciesFromImport (import);
416 : : }
417 : 0 : i += 1;
418 : : }
419 : 0 : }
420 : :
421 : :
422 : : /*
423 : : GenerateDependencies - generate a list of dependencies for the main module where
424 : : the source code is found in sourcefile.
425 : : */
426 : :
427 : 0 : static void GenerateDependencies (void)
428 : : {
429 : 0 : if (SymbolTable_IsDefImp (SymbolTable_GetMainModule ()))
430 : : {
431 : 0 : GenerateDependenciesFromList (SymbolTable_GetModuleDefImportStatementList (SymbolTable_GetMainModule ()));
432 : 0 : GenerateDefDependency (SymbolTable_GetMainModule ());
433 : : }
434 : 0 : GenerateDependenciesFromList (SymbolTable_GetModuleModImportStatementList (SymbolTable_GetMainModule ()));
435 : 0 : WriteDepContents (DepOutput, DepContent);
436 : 0 : }
437 : :
438 : :
439 : : /*
440 : : Compile - compile file, s, using a 5 pass technique.
441 : : */
442 : :
443 : 15506 : static void Compile (DynamicStrings_String s)
444 : : {
445 : 15506 : DoPass0 (s);
446 : 15465 : M2Error_FlushWarnings ();
447 : 15465 : M2Error_FlushErrors ();
448 : 15375 : M2LexBuf_ResetForNewPass ();
449 : 15375 : M2Error_ResetErrorScope ();
450 : 15375 : M2Quiet_qprintf0 ((const char *) "Pass 1: scopes, enumerated types, imports and exports\\n", 55);
451 : 15375 : DoPass1 ();
452 : 15369 : M2Error_FlushWarnings ();
453 : 15369 : M2Error_FlushErrors ();
454 : 15345 : if ((M2Options_GetM ()) || (M2Options_GetMM ()))
455 : : {
456 : 0 : GenerateDependencies ();
457 : : }
458 : 15345 : if (! M2Options_PPonly)
459 : : {
460 : 15345 : M2Quiet_qprintf0 ((const char *) "Pass 2: constants and types\\n", 29);
461 : 15345 : M2LexBuf_ResetForNewPass ();
462 : 15345 : M2Error_ResetErrorScope ();
463 : 15345 : DoPass2 ();
464 : 15327 : M2Error_FlushWarnings ();
465 : 15327 : M2Error_FlushErrors ();
466 : 15243 : M2Quiet_qprintf0 ((const char *) "Pass C: aggregate constants\\n", 29);
467 : 15243 : M2LexBuf_ResetForNewPass ();
468 : 15243 : M2Error_ResetErrorScope ();
469 : 15243 : DoPassC ();
470 : 15213 : M2Error_FlushWarnings ();
471 : 15213 : M2Error_FlushErrors ();
472 : 15135 : M2Quiet_qprintf0 ((const char *) "Pass 3: quadruple generation\\n", 30);
473 : 15135 : M2LexBuf_ResetForNewPass ();
474 : 15135 : M2Error_ResetErrorScope ();
475 : 15135 : DoPass3 ();
476 : 14924 : M2Error_FlushWarnings ();
477 : 14924 : M2Error_FlushErrors ();
478 : 14515 : M2Quiet_qprintf0 ((const char *) "Pass 4: gcc tree generation\\n", 29);
479 : 14515 : M2Code_Code ();
480 : 14227 : M2Error_FlushWarnings ();
481 : 14227 : M2Error_FlushErrors ();
482 : : }
483 : 13991 : }
484 : :
485 : :
486 : : /*
487 : : PopulateResource -
488 : : */
489 : :
490 : 13991 : static void PopulateResource (void)
491 : : {
492 : 13991 : M2Diagnostic_Diagnostic StatsMemDiag;
493 : :
494 : 13991 : if (M2Options_MemReport)
495 : : {
496 : 0 : StatsMemDiag = M2Diagnostic_InitMemDiagnostic ((const char *) "M2Comp:statistics", 17, (const char *) "total source lines {1d} total constants {2d} total types {3d}", 61);
497 : 0 : M2Diagnostic_MemSet (StatsMemDiag, 1, m2flex_GetTotalLines ());
498 : 0 : M2Diagnostic_MemSet (StatsMemDiag, 2, m2block_GetTotalConstants ());
499 : 0 : M2Diagnostic_MemSet (StatsMemDiag, 3, m2block_GetGlobalTypes ());
500 : : }
501 : 13991 : }
502 : :
503 : :
504 : : /*
505 : : ExamineHeader - examines up until the ';', '[' or eof and determines if the source file
506 : : is a program, implementation/definition module.
507 : : */
508 : :
509 : 15505 : static void ExamineHeader (void * *name, bool *isdefimp, bool *module)
510 : : {
511 : : /* Stop if we see one of eof ';' '['. */
512 : 31004 : while (((M2LexBuf_currenttoken != M2Reserved_eoftok) && (M2LexBuf_currenttoken != M2Reserved_semicolontok)) && (M2LexBuf_currenttoken != M2Reserved_lsbratok))
513 : : {
514 : 15499 : if ((*name) == NULL)
515 : : {
516 : 15499 : if ((M2LexBuf_currenttoken == M2Reserved_implementationtok) || (M2LexBuf_currenttoken == M2Reserved_definitiontok))
517 : : {
518 : 3667 : (*isdefimp) = true;
519 : 3667 : M2LexBuf_GetToken ();
520 : : }
521 : 15499 : if (M2LexBuf_currenttoken == M2Reserved_moduletok)
522 : : {
523 : 15499 : (*module) = true;
524 : 15499 : M2LexBuf_GetToken ();
525 : 15499 : if (M2LexBuf_currenttoken == M2Reserved_identtok)
526 : : {
527 : 15499 : (*name) = M2LexBuf_currentstring;
528 : : }
529 : : }
530 : : }
531 : 15499 : M2LexBuf_GetToken ();
532 : : }
533 : 15505 : }
534 : :
535 : :
536 : : /*
537 : : ExamineCompilationUnit - opens the source file to obtain the module name and kind of module.
538 : : */
539 : :
540 : 15505 : static unsigned int ExamineCompilationUnit (void)
541 : : {
542 : 15505 : DynamicStrings_String Message;
543 : 15505 : void * name;
544 : 15505 : bool module;
545 : 15505 : bool isdefimp;
546 : :
547 : 15505 : name = NULL;
548 : 15505 : isdefimp = false; /* default to program module */
549 : 15505 : module = false; /* Seen module keyword? */
550 : 15505 : ExamineHeader (&name, &isdefimp, &module); /* Seen module keyword? */
551 : 15505 : if (name == NULL)
552 : : {
553 : 6 : if (module)
554 : : {
555 : 0 : Message = M2MetaError_MetaString0 (DynamicStrings_InitString ((const char *) "no {%kMODULE} keyword seen", 26));
556 : : }
557 : : else
558 : : {
559 : 6 : Message = M2MetaError_MetaString0 (DynamicStrings_InitString ((const char *) "no module ident seen", 20));
560 : : }
561 : 6 : m2flex_M2Error (DynamicStrings_string (Message));
562 : 6 : libc_exit (1);
563 : : }
564 : : else
565 : : {
566 : : /* The token used is will be overwritten when P0 is underway.
567 : : At this point we are determining the module kind and the tokens
568 : : read will be discarded (see ReInitialize below). */
569 : 15499 : if (isdefimp)
570 : : {
571 : 3667 : return M2Batch_MakeImplementationSource (M2LexBuf_BuiltinTokenNo, NameKey_makekey (name));
572 : : }
573 : : else
574 : : {
575 : 11832 : return M2Batch_MakeProgramSource (M2LexBuf_BuiltinTokenNo, NameKey_makekey (name));
576 : : }
577 : : }
578 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Comp.def", 20, 1);
579 : : __builtin_unreachable ();
580 : : }
581 : :
582 : :
583 : : /*
584 : : PeepInto - peeps into source, s, and initializes a definition/implementation or
585 : : program module accordingly.
586 : : */
587 : :
588 : 15506 : static void PeepInto (DynamicStrings_String s)
589 : : {
590 : 15506 : unsigned int mainModule;
591 : :
592 : 15506 : if (M2LexBuf_OpenSource (s))
593 : : {
594 : 15505 : mainModule = ExamineCompilationUnit ();
595 : 15499 : if (mainModule != SymbolTable_NulSym)
596 : : {
597 : 15499 : SymbolTable_SetMainModule (mainModule);
598 : : }
599 : 15499 : M2LexBuf_CloseSource ();
600 : 15499 : M2LexBuf_ReInitialize ();
601 : : }
602 : : else
603 : : {
604 : 1 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &s, (sizeof (s)-1));
605 : 1 : libc_exit (1);
606 : : }
607 : 15499 : }
608 : :
609 : :
610 : : /*
611 : : qprintLibName - print the libname.
612 : : */
613 : :
614 : 248275 : static void qprintLibName (DynamicStrings_String LibName)
615 : : {
616 : 248275 : if ((LibName != NULL) && (! (DynamicStrings_EqualArray (LibName, (const char *) "", 0))))
617 : : {
618 : 228395 : M2Quiet_qprintf1 ((const char *) " [%s]", 5, (const unsigned char *) &LibName, (sizeof (LibName)-1));
619 : : }
620 : 248275 : }
621 : :
622 : :
623 : : /*
624 : : CreateFileStem - create a stem using the template LibName_ModuleName.
625 : : */
626 : :
627 : 232846 : static DynamicStrings_String CreateFileStem (DynamicStrings_String SymName, DynamicStrings_String LibName)
628 : : {
629 : 232846 : if ((DynamicStrings_Length (LibName)) > 0)
630 : : {
631 : 227775 : return DynamicStrings_ConCat (DynamicStrings_Dup (LibName), DynamicStrings_ConCat (DynamicStrings_InitStringChar ('_'), SymName));
632 : : }
633 : : else
634 : : {
635 : : return SymName;
636 : : }
637 : : /* static analysis guarentees a RETURN statement will be used before here. */
638 : : __builtin_unreachable ();
639 : : }
640 : :
641 : 0 : static DynamicStrings_String BaseName (DynamicStrings_String Path, bool CutExt)
642 : : {
643 : 0 : int ext;
644 : 0 : int basename;
645 : :
646 : : /*
647 : : Return basename of path. CutExt determines whether the .extension
648 : : should be removed.
649 : : */
650 : 0 : basename = DynamicStrings_RIndex (Path, '/', 0);
651 : 0 : if (basename == -1)
652 : : {
653 : : basename = 0;
654 : : }
655 : : else
656 : : {
657 : 0 : basename = basename+1;
658 : : }
659 : 0 : if (CutExt)
660 : : {
661 : : /* avoid dangling else. */
662 : 0 : ext = DynamicStrings_RIndex (Path, '.', 0);
663 : 0 : if (ext == -1)
664 : : {
665 : 0 : ext = 0;
666 : : }
667 : : }
668 : : else
669 : : {
670 : : ext = 0;
671 : : }
672 : 0 : return DynamicStrings_Slice (Path, basename, ext);
673 : : /* static analysis guarentees a RETURN statement will be used before here. */
674 : : __builtin_unreachable ();
675 : : }
676 : :
677 : :
678 : : /*
679 : : IsLibrary - return TRUE if line contains a library module.
680 : : */
681 : :
682 : 0 : static bool IsLibrary (DynamicStrings_String line)
683 : : {
684 : 0 : DynamicStrings_String moduleName;
685 : 0 : DynamicStrings_String libname;
686 : 0 : DynamicStrings_String filename;
687 : 0 : bool result;
688 : :
689 : 0 : result = false;
690 : 0 : moduleName = BaseName (line, true);
691 : 0 : filename = static_cast<DynamicStrings_String> (NULL);
692 : 0 : libname = static_cast<DynamicStrings_String> (NULL);
693 : 0 : if (M2Search_FindSourceDefFile (moduleName, &filename, &libname))
694 : : {
695 : 0 : moduleName = DynamicStrings_KillString (moduleName);
696 : 0 : if ((DynamicStrings_Length (libname)) > 0)
697 : : {
698 : 0 : moduleName = BaseName (line, false);
699 : 0 : line = BaseName (line, false);
700 : 0 : result = DynamicStrings_Equal (line, moduleName);
701 : 0 : line = DynamicStrings_KillString (line);
702 : : }
703 : : }
704 : 0 : libname = DynamicStrings_KillString (libname);
705 : 0 : filename = DynamicStrings_KillString (filename);
706 : 0 : moduleName = DynamicStrings_KillString (moduleName);
707 : 0 : return result;
708 : : /* static analysis guarentees a RETURN statement will be used before here. */
709 : : __builtin_unreachable ();
710 : : }
711 : :
712 : :
713 : : /*
714 : : IsUnique - return TRUE if line is unique in array content.
715 : : */
716 : :
717 : 0 : static bool IsUnique (Indexing_Index content, DynamicStrings_String line)
718 : : {
719 : 0 : unsigned int high;
720 : 0 : unsigned int i;
721 : :
722 : 0 : high = Indexing_HighIndice (content);
723 : 0 : i = 1;
724 : 0 : while (i <= high)
725 : : {
726 : 0 : if (DynamicStrings_Equal (line, static_cast<DynamicStrings_String> (Indexing_GetIndice (content, i))))
727 : : {
728 : : return false;
729 : : }
730 : 0 : i += 1;
731 : : }
732 : : return true;
733 : : /* static analysis guarentees a RETURN statement will be used before here. */
734 : : __builtin_unreachable ();
735 : : }
736 : :
737 : :
738 : : /*
739 : : Append - append line to array content.
740 : : */
741 : :
742 : 0 : static void Append (Indexing_Index content, DynamicStrings_String line)
743 : : {
744 : 0 : unsigned int high;
745 : :
746 : 0 : high = Indexing_HighIndice (content);
747 : 0 : Indexing_PutIndice (content, high+1, reinterpret_cast <void *> (line));
748 : 0 : }
749 : :
750 : :
751 : : /*
752 : : MergeDep - if line is unique in array content then append.
753 : : Check to see (and ignore) if line is a library module and -MM
754 : : is present.
755 : : */
756 : :
757 : 0 : static void MergeDep (Indexing_Index content, DynamicStrings_String line)
758 : : {
759 : 0 : line = DynamicStrings_RemoveWhitePrefix (line);
760 : 0 : if ((! (DynamicStrings_EqualArray (line, (const char *) "\\", 1))) && ((DynamicStrings_Length (line)) > 0))
761 : : {
762 : : /* Ignore if -MM and is a library module. */
763 : 0 : if (! ((M2Options_GetMM ()) && (IsLibrary (line))))
764 : : {
765 : 0 : if (IsUnique (content, line))
766 : : {
767 : 0 : Append (content, line);
768 : : }
769 : : }
770 : : }
771 : 0 : }
772 : :
773 : :
774 : : /*
775 : : splitLine - split a line into words separated by spaces
776 : : and call MergeDep on each word.
777 : : */
778 : :
779 : 0 : static void splitLine (Indexing_Index content, DynamicStrings_String line)
780 : : {
781 : 0 : DynamicStrings_String word;
782 : 0 : int space;
783 : :
784 : 0 : do {
785 : 0 : line = DynamicStrings_RemoveWhitePrefix (line);
786 : 0 : space = DynamicStrings_Index (line, ' ', 0);
787 : 0 : if (space > 0)
788 : : {
789 : 0 : word = DynamicStrings_Slice (line, 0, space);
790 : 0 : word = DynamicStrings_RemoveWhitePrefix (word);
791 : 0 : if ((DynamicStrings_Length (word)) > 0)
792 : : {
793 : 0 : MergeDep (content, word);
794 : : }
795 : 0 : line = DynamicStrings_Slice (line, space, 0);
796 : : }
797 : 0 : else if (space < 0)
798 : : {
799 : : /* avoid dangling else. */
800 : 0 : MergeDep (content, line);
801 : : }
802 : 0 : } while (! (space <= 0));
803 : 0 : }
804 : :
805 : :
806 : : /*
807 : : MergeDeps - foreach dependency in ChildDep do
808 : : add dependency to ChildDep if not already present.
809 : : ignore all ChildDep if -MM and libname # "".
810 : : */
811 : :
812 : 232840 : static void MergeDeps (Indexing_Index content, DynamicStrings_String ChildDep, DynamicStrings_String LibName)
813 : : {
814 : 232840 : DynamicStrings_String line;
815 : 232840 : FIO_File in;
816 : :
817 : 232840 : if ((content != NULL) && (! ((M2Options_GetMM ()) && ((DynamicStrings_Length (LibName)) > 0))))
818 : : {
819 : 0 : in = SFIO_OpenToRead (ChildDep);
820 : 0 : if (FIO_IsNoError (in))
821 : : {
822 : 0 : line = SFIO_ReadS (in); /* Skip over first line containing the module object. */
823 : 0 : while (! (FIO_EOF (in))) /* Skip over first line containing the module object. */
824 : : {
825 : 0 : line = SFIO_ReadS (in);
826 : 0 : splitLine (content, line);
827 : : }
828 : : }
829 : 0 : FIO_Close (in);
830 : : }
831 : 232840 : }
832 : :
833 : :
834 : : /*
835 : : GetRuleTarget - return the rule target which is derived from the -MT arg
836 : : or -o arg or filename.mod.
837 : : */
838 : :
839 : 0 : static DynamicStrings_String GetRuleTarget (DynamicStrings_String filename)
840 : : {
841 : 0 : if ((M2Options_GetDepTarget ()) != NULL)
842 : : {
843 : 0 : return DynamicStrings_InitStringCharStar (M2Options_GetDepTarget ());
844 : : }
845 : 0 : else if ((M2Options_GetMF ()) != NULL)
846 : : {
847 : : /* avoid dangling else. */
848 : 0 : return DynamicStrings_InitStringCharStar (M2Options_GetMF ());
849 : : }
850 : : else
851 : : {
852 : : /* avoid dangling else. */
853 : 0 : return DynamicStrings_ConCat (BaseName (filename, true), DynamicStrings_InitString ((const char *) ".o", 2));
854 : : }
855 : : /* static analysis guarentees a RETURN statement will be used before here. */
856 : : __builtin_unreachable ();
857 : : }
858 : :
859 : :
860 : : /*
861 : : ReadDepContents - reads the contents of file dep into a dynamic array
862 : : and return the array. The file will be split into words
863 : : and each word stored as an entry in the array.
864 : : */
865 : :
866 : 15506 : static Indexing_Index ReadDepContents (DynamicStrings_String filename, DynamicStrings_String dep)
867 : : {
868 : 15506 : Indexing_Index content;
869 : 15506 : DynamicStrings_String line;
870 : 15506 : FIO_File in;
871 : :
872 : 15506 : content = static_cast<Indexing_Index> (NULL);
873 : 15506 : if ((M2Options_GetM ()) || (M2Options_GetMM ()))
874 : : {
875 : 0 : in = SFIO_OpenToRead (dep);
876 : : /* The file might not be created (if -MD or -MMD is used as these options
877 : : operate without preprocessing) in which case we create an dynamic
878 : : array with the source filename and target. */
879 : 0 : content = Indexing_InitIndex (1);
880 : 0 : if (((M2Options_GetMD ()) || (M2Options_GetMMD ())) || (! (FIO_IsNoError (in))))
881 : : {
882 : : /* No preprocessing done therefore create first two lines using
883 : : target and source. */
884 : 0 : Indexing_PutIndice (content, 1, reinterpret_cast <void *> (DynamicStrings_ConCatChar (GetRuleTarget (filename), ':')));
885 : 0 : Indexing_PutIndice (content, 2, reinterpret_cast <void *> (DynamicStrings_Dup (filename)));
886 : : }
887 : : else
888 : : {
889 : : /* Preprocessing (using cc1) has created one for us, so we read it. */
890 : 0 : while (! (FIO_EOF (in)))
891 : : {
892 : 0 : line = SFIO_ReadS (in);
893 : 0 : splitLine (content, line);
894 : : }
895 : : }
896 : 0 : FIO_Close (in);
897 : : }
898 : 15506 : return content;
899 : : /* static analysis guarentees a RETURN statement will be used before here. */
900 : : __builtin_unreachable ();
901 : : }
902 : :
903 : :
904 : : /*
905 : : WriteDep - write the dependencies and target to file out.
906 : : */
907 : :
908 : 0 : static void WriteDep (Indexing_Index contents, FIO_File out)
909 : : {
910 : 0 : unsigned int i;
911 : 0 : unsigned int h;
912 : 0 : DynamicStrings_String line;
913 : :
914 : 0 : i = 1;
915 : 0 : h = Indexing_HighIndice (contents);
916 : 0 : while (i <= h)
917 : : {
918 : 0 : line = static_cast<DynamicStrings_String> (Indexing_GetIndice (contents, i));
919 : 0 : line = DynamicStrings_RemoveWhitePrefix (line);
920 : 0 : if ((DynamicStrings_Length (line)) > 0)
921 : : {
922 : 0 : if (i == 1)
923 : : {
924 : : /* avoid dangling else. */
925 : : /* First line is always the target. */
926 : 0 : if ((M2Options_GetDepTarget ()) != NULL)
927 : : {
928 : 0 : line = DynamicStrings_ConCatChar (DynamicStrings_InitStringCharStar (M2Options_GetDepTarget ()), ':');
929 : : }
930 : : }
931 : 0 : else if (i > 1)
932 : : {
933 : : /* avoid dangling else. */
934 : 0 : FIO_WriteChar (out, ' ');
935 : : }
936 : 0 : line = SFIO_WriteS (out, line);
937 : 0 : if (i < h)
938 : : {
939 : 0 : FIO_WriteChar (out, ' ');
940 : 0 : FIO_WriteChar (out, '\\');
941 : : }
942 : 0 : FIO_WriteLine (out);
943 : : }
944 : 0 : i += 1;
945 : : }
946 : 0 : }
947 : :
948 : :
949 : : /*
950 : : WritePhonyDep - write the dependencies and target to file out.
951 : : */
952 : :
953 : 0 : static void WritePhonyDep (Indexing_Index contents, FIO_File out)
954 : : {
955 : 0 : unsigned int i;
956 : 0 : unsigned int h;
957 : 0 : DynamicStrings_String line;
958 : :
959 : : /* The first line is always the target and the second line is always
960 : : the top level source file. */
961 : 0 : i = 3;
962 : 0 : h = Indexing_HighIndice (contents);
963 : 0 : while (i <= h)
964 : : {
965 : 0 : line = static_cast<DynamicStrings_String> (Indexing_GetIndice (contents, i));
966 : 0 : line = DynamicStrings_RemoveWhitePrefix (line);
967 : 0 : if ((DynamicStrings_Length (line)) > 0)
968 : : {
969 : 0 : line = SFIO_WriteS (out, line);
970 : 0 : FIO_WriteChar (out, ':');
971 : 0 : FIO_WriteLine (out);
972 : : }
973 : 0 : i += 1;
974 : : }
975 : 0 : }
976 : :
977 : :
978 : : /*
979 : : WriteDepContents - write the dynamic array to filename dep (or StdOut) if
980 : : the GetMF file is NIL.
981 : : */
982 : :
983 : 0 : static void WriteDepContents (DynamicStrings_String dep, Indexing_Index contents)
984 : : {
985 : 0 : FIO_File out;
986 : :
987 : 0 : if ((contents != NULL) && ((M2Options_GetM ()) || (M2Options_GetMM ())))
988 : : {
989 : 0 : if ((M2Options_GetMF ()) == NULL)
990 : : {
991 : 0 : out = FIO_StdOut;
992 : 0 : dep = M2Preprocess_OnExitDelete (dep);
993 : : }
994 : : else
995 : : {
996 : 0 : out = SFIO_OpenToWrite (dep);
997 : : }
998 : 0 : if (FIO_IsNoError (out))
999 : : {
1000 : 0 : WriteDep (contents, out);
1001 : 0 : if (M2Options_GetMP ())
1002 : : {
1003 : 0 : WritePhonyDep (contents, out);
1004 : : }
1005 : : }
1006 : 0 : if ((M2Options_GetMF ()) == NULL)
1007 : : {
1008 : 0 : FIO_FlushOutErr ();
1009 : : }
1010 : : else
1011 : : {
1012 : 0 : FIO_Close (out);
1013 : : }
1014 : 0 : contents = Indexing_KillIndex (contents);
1015 : : }
1016 : 0 : }
1017 : :
1018 : :
1019 : : /*
1020 : : CreateDepFilename - return a dependency filename associated with filename or use GetMF.
1021 : : */
1022 : :
1023 : 15506 : static DynamicStrings_String CreateDepFilename (DynamicStrings_String filename)
1024 : : {
1025 : 15506 : DynamicStrings_String depfile;
1026 : :
1027 : 15506 : if ((M2Options_GetMF ()) == NULL)
1028 : : {
1029 : 15506 : depfile = M2Preprocess_MakeSaveTempsFileNameExt (filename, DynamicStrings_InitString ((const char *) ".d", 2));
1030 : 15506 : return M2Preprocess_OnExitDelete (depfile);
1031 : : }
1032 : : else
1033 : : {
1034 : 0 : return DynamicStrings_InitStringCharStar (M2Options_GetMF ());
1035 : : }
1036 : : /* static analysis guarentees a RETURN statement will be used before here. */
1037 : : __builtin_unreachable ();
1038 : : }
1039 : :
1040 : :
1041 : : /*
1042 : : Pass0CheckDef -
1043 : : */
1044 : :
1045 : 176960 : static bool Pass0CheckDef (unsigned int sym)
1046 : : {
1047 : 176960 : DynamicStrings_String ChildDep;
1048 : 176960 : DynamicStrings_String SymName;
1049 : 176960 : DynamicStrings_String FileName;
1050 : 176960 : DynamicStrings_String LibName;
1051 : :
1052 : 176960 : LibName = static_cast<DynamicStrings_String> (NULL);
1053 : 176960 : FileName = static_cast<DynamicStrings_String> (NULL);
1054 : 176960 : SymName = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (sym)));
1055 : 176960 : if (SymbolTable_IsDefImp (sym))
1056 : : {
1057 : 165128 : if (M2Search_FindSourceDefFile (SymName, &FileName, &LibName))
1058 : : {
1059 : 165106 : ModuleType = M2Comp_Definition;
1060 : 165106 : ChildDep = M2Preprocess_MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), DynamicStrings_InitString ((const char *) ".def.d", 6));
1061 : 165106 : if (M2LexBuf_OpenSource (M2Batch_AssociateDefinition (M2Preprocess_PreprocessModule (FileName, false, true, ChildDep), sym)))
1062 : : {
1063 : 165106 : if (! (P0SyntaxCheck_CompilationUnit ()))
1064 : : {
1065 : 6 : M2Error_WriteFormat0 ((const char *) "compilation failed", 18);
1066 : 6 : M2LexBuf_CloseSource ();
1067 : 6 : SymName = DynamicStrings_KillString (SymName);
1068 : 6 : FileName = DynamicStrings_KillString (FileName);
1069 : 6 : LibName = DynamicStrings_KillString (LibName);
1070 : 6 : return false;
1071 : : }
1072 : 165100 : M2Quiet_qprintf2 ((const char *) " Module %-20s : %s", 20, (const unsigned char *) &SymName, (sizeof (SymName)-1), (const unsigned char *) &FileName, (sizeof (FileName)-1));
1073 : 165100 : qprintLibName (LibName);
1074 : 165100 : SymbolTable_PutLibName (sym, NameKey_makekey (DynamicStrings_string (LibName)));
1075 : 165100 : if (SymbolTable_IsDefinitionForC (sym))
1076 : : {
1077 : 13126 : M2Quiet_qprintf0 ((const char *) " (for C)", 8);
1078 : : }
1079 : 165100 : if (SymbolTable_IsDefLink (sym))
1080 : : {
1081 : 81014 : M2Quiet_qprintf0 ((const char *) " (linking)", 10);
1082 : : }
1083 : 165100 : M2Quiet_qprintf0 ((const char *) "\\n", 2);
1084 : 165100 : M2LexBuf_CloseSource ();
1085 : 165100 : MergeDeps (DepContent, ChildDep, LibName);
1086 : : }
1087 : : else
1088 : : {
1089 : : /* Unrecoverable error. */
1090 : 0 : M2MetaError_MetaErrorString1 (FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) "file {%%1EUAF%s} containing module {%%1a} cannot be found", 57), (const unsigned char *) &FileName, (sizeof (FileName)-1)), sym);
1091 : : }
1092 : : }
1093 : : else
1094 : : {
1095 : : /* Unrecoverable error. */
1096 : 22 : M2MetaError_MetaError1 ((const char *) "the file containing the definition module {%1EMAa} cannot be found", 66, sym);
1097 : : }
1098 : 165100 : ModuleType = M2Comp_Implementation;
1099 : : }
1100 : : else
1101 : : {
1102 : 11832 : ModuleType = M2Comp_Program;
1103 : : }
1104 : 176932 : SymName = DynamicStrings_KillString (SymName);
1105 : 176932 : FileName = DynamicStrings_KillString (FileName);
1106 : 176932 : LibName = DynamicStrings_KillString (LibName);
1107 : 176932 : return true;
1108 : : /* static analysis guarentees a RETURN statement will be used before here. */
1109 : : __builtin_unreachable ();
1110 : : }
1111 : :
1112 : :
1113 : : /*
1114 : : Pass0CheckMod -
1115 : : */
1116 : :
1117 : 176932 : static bool Pass0CheckMod (unsigned int sym, DynamicStrings_String PPSource)
1118 : : {
1119 : 176932 : unsigned int Main;
1120 : 176932 : DynamicStrings_String ChildDep;
1121 : 176932 : DynamicStrings_String SymName;
1122 : 176932 : DynamicStrings_String FileName;
1123 : 176932 : DynamicStrings_String LibName;
1124 : :
1125 : 176932 : SymName = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (sym)));
1126 : 176932 : FileName = static_cast<DynamicStrings_String> (NULL);
1127 : 176932 : LibName = static_cast<DynamicStrings_String> (NULL);
1128 : 176932 : Main = SymbolTable_GetMainModule ();
1129 : 176932 : if ((Main == sym) || (NeedToParseImplementation (sym)))
1130 : : {
1131 : : /* avoid dangling else. */
1132 : : /* Only need to read implementation module if hidden types are
1133 : : declared or it is the main module. */
1134 : 20571 : if (Main == sym)
1135 : : {
1136 : 15495 : FileName = DynamicStrings_Dup (PPSource);
1137 : 15495 : LibName = DynamicStrings_InitStringCharStar (M2Options_GetM2Prefix ());
1138 : 15495 : SymbolTable_PutLibName (sym, NameKey_makekey (DynamicStrings_string (LibName)));
1139 : : }
1140 : : else
1141 : : {
1142 : 5076 : if (M2Search_FindSourceModFile (SymName, &FileName, &LibName))
1143 : : {
1144 : 4908 : ChildDep = M2Preprocess_MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), DynamicStrings_InitString ((const char *) ".mod.d", 6));
1145 : 4908 : FileName = M2Preprocess_PreprocessModule (FileName, false, true, ChildDep);
1146 : 4908 : SymbolTable_PutLibName (sym, NameKey_makekey (DynamicStrings_string (LibName)));
1147 : 4908 : MergeDeps (DepContent, ChildDep, LibName);
1148 : : }
1149 : : else
1150 : : {
1151 : 168 : M2Quiet_qprintf1 ((const char *) " Module %-20s : implementation source file not found\\n", 56, (const unsigned char *) &SymName, (sizeof (SymName)-1));
1152 : : }
1153 : : }
1154 : 20571 : if (FileName != NULL)
1155 : : {
1156 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1157 : 20403 : if (M2LexBuf_OpenSource (M2Batch_AssociateModule (DynamicStrings_Dup (FileName), sym)))
1158 : : {
1159 : 20403 : if (! (P0SyntaxCheck_CompilationUnit ()))
1160 : : {
1161 : 48 : M2Error_WriteFormat0 ((const char *) "compilation failed", 18);
1162 : 48 : M2LexBuf_CloseSource ();
1163 : 48 : SymName = DynamicStrings_KillString (SymName);
1164 : 48 : FileName = DynamicStrings_KillString (FileName);
1165 : 48 : LibName = DynamicStrings_KillString (LibName);
1166 : 48 : return false;
1167 : : }
1168 : 20343 : M2Quiet_qprintf2 ((const char *) " Module %-20s : %s", 20, (const unsigned char *) &SymName, (sizeof (SymName)-1), (const unsigned char *) &FileName, (sizeof (FileName)-1));
1169 : 20343 : qprintLibName (LibName);
1170 : 20343 : if (SymbolTable_IsModLink (sym))
1171 : : {
1172 : 2690 : M2Quiet_qprintf0 ((const char *) " (linking)", 10);
1173 : : }
1174 : 20343 : M2Quiet_qprintf0 ((const char *) "\\n", 2);
1175 : 20343 : M2LexBuf_CloseSource ();
1176 : : }
1177 : : else
1178 : : {
1179 : : /* It is quite legitimate to implement a module in C (and pretend it was a M2
1180 : : implementation) providing that it is not the main program module and the
1181 : : definition module does not declare a hidden type when -fextended-opaque
1182 : : is used. */
1183 : 0 : if ((! M2Options_WholeProgram || (sym == Main)) || (SymbolTable_IsHiddenTypeDeclared (sym)))
1184 : : {
1185 : : /* Unrecoverable error. */
1186 : 0 : M2MetaError_MetaErrorString1 (FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) "file {%%1EUAF%s} containing module {%%1a} cannot be found", 57), (const unsigned char *) &FileName, (sizeof (FileName)-1)), sym);
1187 : : }
1188 : : }
1189 : : }
1190 : : }
1191 : 156361 : else if (M2Options_GenModuleList)
1192 : : {
1193 : : /* avoid dangling else. */
1194 : 91202 : if ((SymbolTable_IsDefImp (sym)) && (! (SymbolTable_IsDefinitionForC (sym))))
1195 : : {
1196 : : /* The implementation module is only useful if -fgen-module-list= is
1197 : : used (to gather all dependencies). Note that we do not insist
1198 : : upon finding the implementation module. */
1199 : 81914 : LibName = static_cast<DynamicStrings_String> (NULL);
1200 : 81914 : if (M2Search_FindSourceModFile (SymName, &FileName, &LibName))
1201 : : {
1202 : 62832 : SymbolTable_PutLibName (sym, NameKey_makekey (DynamicStrings_string (LibName)));
1203 : 62832 : M2Quiet_qprintf2 ((const char *) " Module %-20s : %s", 20, (const unsigned char *) &SymName, (sizeof (SymName)-1), (const unsigned char *) &FileName, (sizeof (FileName)-1));
1204 : 62832 : qprintLibName (LibName);
1205 : 62832 : M2Quiet_qprintf0 ((const char *) " (linking)\\n", 12);
1206 : 62832 : ChildDep = M2Preprocess_MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), DynamicStrings_InitString ((const char *) ".mod.d", 6));
1207 : 62832 : if (M2LexBuf_OpenSource (M2Batch_AssociateModule (M2Preprocess_PreprocessModule (FileName, false, true, ChildDep), sym)))
1208 : : {
1209 : 62832 : SymbolTable_PutModLink (sym, true); /* This source is only used to determine link time info. */
1210 : 62832 : if (! (P0SyntaxCheck_CompilationUnit ())) /* This source is only used to determine link time info. */
1211 : : {
1212 : 0 : M2Error_WriteFormat0 ((const char *) "compilation failed", 18);
1213 : 0 : M2LexBuf_CloseSource ();
1214 : 0 : SymName = DynamicStrings_KillString (SymName);
1215 : 0 : FileName = DynamicStrings_KillString (FileName);
1216 : 0 : LibName = DynamicStrings_KillString (LibName);
1217 : 0 : return false;
1218 : : }
1219 : 62832 : M2LexBuf_CloseSource ();
1220 : 62832 : MergeDeps (DepContent, ChildDep, LibName);
1221 : : }
1222 : : }
1223 : : }
1224 : : }
1225 : 176872 : SymName = DynamicStrings_KillString (SymName);
1226 : 176872 : FileName = DynamicStrings_KillString (FileName);
1227 : 176872 : LibName = DynamicStrings_KillString (LibName);
1228 : 176872 : return true;
1229 : : /* static analysis guarentees a RETURN statement will be used before here. */
1230 : : __builtin_unreachable ();
1231 : : }
1232 : :
1233 : :
1234 : : /*
1235 : : DoPass0 -
1236 : : */
1237 : :
1238 : 15506 : static void DoPass0 (DynamicStrings_String filename)
1239 : : {
1240 : 15506 : unsigned int sym;
1241 : 15506 : unsigned int i;
1242 : 15506 : DynamicStrings_String PPSource;
1243 : :
1244 : 15506 : P0SymBuild_P0Init ();
1245 : 15506 : M2Pass_SetPassToPass0 ();
1246 : : /* Maybe preprocess the main file. */
1247 : 15506 : DepOutput = CreateDepFilename (filename);
1248 : 15506 : PPSource = M2Preprocess_PreprocessModule (filename, true, false, DepOutput);
1249 : 15506 : DepContent = ReadDepContents (filename, DepOutput);
1250 : 15506 : PeepInto (PPSource);
1251 : 15499 : i = 1;
1252 : 15499 : sym = M2Batch_GetModuleNo (i);
1253 : 15499 : M2Quiet_qprintf1 ((const char *) "Compiling: %s\\n", 15, (const unsigned char *) &PPSource, (sizeof (PPSource)-1));
1254 : 15499 : if (Debugging)
1255 : : {
1256 : : PathName_DumpPathName ((const char *) "DoPass0", 7);
1257 : : }
1258 : 15499 : if (M2Options_Verbose)
1259 : : {
1260 : 0 : M2Printf_fprintf1 (FIO_StdOut, (const char *) "Compiling: %s\\n", 15, (const unsigned char *) &PPSource, (sizeof (PPSource)-1));
1261 : : }
1262 : 15499 : M2Quiet_qprintf0 ((const char *) "Pass 0: lexical analysis, parsing, modules and associated filenames\\n", 69);
1263 : 207870 : while (sym != SymbolTable_NulSym)
1264 : : {
1265 : 176960 : if (! (Pass0CheckDef (sym)))
1266 : : {
1267 : 54 : return;
1268 : : }
1269 : 176932 : if (! (Pass0CheckMod (sym, PPSource)))
1270 : : {
1271 : : return;
1272 : : }
1273 : 176872 : i += 1;
1274 : 176872 : sym = M2Batch_GetModuleNo (i);
1275 : : }
1276 : 15411 : M2Pass_SetPassToNoPass ();
1277 : : }
1278 : :
1279 : :
1280 : : /*
1281 : : DoPass1 - parses the sources of all modules necessary to compile
1282 : : the required module, Main.
1283 : : */
1284 : :
1285 : 15375 : static void DoPass1 (void)
1286 : : {
1287 : 15375 : NameKey_Name name;
1288 : 15375 : unsigned int Sym;
1289 : 15375 : unsigned int i;
1290 : 15375 : DynamicStrings_String FileName;
1291 : :
1292 : 15375 : P0SymBuild_P1Init ();
1293 : 15375 : M2Pass_SetPassToPass1 ();
1294 : 15375 : i = 1;
1295 : 15375 : Sym = M2Batch_GetModuleNo (i);
1296 : 206940 : while (Sym != SymbolTable_NulSym)
1297 : : {
1298 : 176196 : FileName = M2Batch_GetDefinitionModuleFile (Sym);
1299 : 176196 : if (FileName != NULL)
1300 : : {
1301 : 164472 : if (Debugging)
1302 : : {
1303 : : name = SymbolTable_GetSymName (Sym);
1304 : : M2Quiet_qprintf1 ((const char *) " Module %a\\n", 14, (const unsigned char *) &name, (sizeof (name)-1));
1305 : : }
1306 : 164472 : if (M2LexBuf_OpenSource (FileName))
1307 : : {
1308 : 164472 : ModuleType = M2Comp_Definition;
1309 : 164472 : if (! (P1Build_CompilationUnit ()))
1310 : : {
1311 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1312 : 0 : M2LexBuf_CloseSource ();
1313 : 0 : return;
1314 : : }
1315 : 164472 : M2LexBuf_CloseSource ();
1316 : : }
1317 : : else
1318 : : {
1319 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1320 : 0 : libc_exit (1);
1321 : : }
1322 : 164472 : ModuleType = M2Comp_Implementation;
1323 : : }
1324 : : else
1325 : : {
1326 : 11724 : ModuleType = M2Comp_Program;
1327 : : }
1328 : 176196 : FileName = M2Batch_GetModuleFile (Sym);
1329 : 176196 : if (FileName != NULL)
1330 : : {
1331 : 83049 : if (Debugging)
1332 : : {
1333 : : name = SymbolTable_GetSymName (Sym);
1334 : : M2Quiet_qprintf1 ((const char *) " Module %a\\n", 14, (const unsigned char *) &name, (sizeof (name)-1));
1335 : : }
1336 : 83049 : if (M2LexBuf_OpenSource (FileName))
1337 : : {
1338 : 83049 : if (! (P1Build_CompilationUnit ()))
1339 : : {
1340 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1341 : 0 : M2LexBuf_CloseSource ();
1342 : 0 : return;
1343 : : }
1344 : 83043 : M2LexBuf_CloseSource ();
1345 : : }
1346 : : else
1347 : : {
1348 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1349 : 0 : libc_exit (1);
1350 : : }
1351 : : }
1352 : 176190 : i += 1;
1353 : 176190 : Sym = M2Batch_GetModuleNo (i);
1354 : : }
1355 : 15369 : M2Pass_SetPassToNoPass ();
1356 : : }
1357 : :
1358 : :
1359 : : /*
1360 : : DoPass2 - parses the sources of all modules necessary to compile
1361 : : the required module, Main.
1362 : : */
1363 : :
1364 : 15345 : static void DoPass2 (void)
1365 : : {
1366 : 15345 : NameKey_Name name;
1367 : 15345 : unsigned int Sym;
1368 : 15345 : unsigned int i;
1369 : 15345 : DynamicStrings_String FileName;
1370 : :
1371 : 15345 : M2Pass_SetPassToPass2 ();
1372 : 15345 : i = 1;
1373 : 15345 : Sym = M2Batch_GetModuleNo (i);
1374 : 206652 : while (Sym != SymbolTable_NulSym)
1375 : : {
1376 : 175980 : FileName = M2Batch_GetDefinitionModuleFile (Sym);
1377 : 175980 : if (FileName != NULL)
1378 : : {
1379 : 164280 : if (Debugging)
1380 : : {
1381 : : name = SymbolTable_GetSymName (Sym);
1382 : : M2Quiet_qprintf1 ((const char *) " Module %a\\n", 14, (const unsigned char *) &name, (sizeof (name)-1));
1383 : : }
1384 : 164280 : if (M2LexBuf_OpenSource (FileName))
1385 : : {
1386 : 164280 : ModuleType = M2Comp_Definition;
1387 : 164280 : if (! (P2Build_CompilationUnit ()))
1388 : : {
1389 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1390 : 0 : M2LexBuf_CloseSource ();
1391 : 0 : return;
1392 : : }
1393 : 164280 : M2LexBuf_CloseSource ();
1394 : : }
1395 : : else
1396 : : {
1397 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1398 : 0 : libc_exit (1);
1399 : : }
1400 : 164280 : ModuleType = M2Comp_Implementation;
1401 : : }
1402 : : else
1403 : : {
1404 : 11700 : ModuleType = M2Comp_Program;
1405 : : }
1406 : 175980 : FileName = M2Batch_GetModuleFile (Sym);
1407 : 175980 : if (FileName != NULL)
1408 : : {
1409 : 82947 : if (Debugging)
1410 : : {
1411 : : name = SymbolTable_GetSymName (Sym);
1412 : : M2Quiet_qprintf1 ((const char *) " Module %a\\n", 14, (const unsigned char *) &name, (sizeof (name)-1));
1413 : : }
1414 : 82947 : if (M2LexBuf_OpenSource (FileName))
1415 : : {
1416 : 82947 : if (! (P2Build_CompilationUnit ()))
1417 : : {
1418 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1419 : 0 : M2LexBuf_CloseSource ();
1420 : 0 : return;
1421 : : }
1422 : 82929 : M2LexBuf_CloseSource ();
1423 : : }
1424 : : else
1425 : : {
1426 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1427 : 0 : libc_exit (1);
1428 : : }
1429 : : }
1430 : 175962 : i += 1;
1431 : 175962 : Sym = M2Batch_GetModuleNo (i);
1432 : : }
1433 : 15327 : M2Pass_SetPassToNoPass ();
1434 : : }
1435 : :
1436 : :
1437 : : /*
1438 : : DoPassC - parses the sources of all modules necessary to compile
1439 : : the required module, Main.
1440 : : */
1441 : :
1442 : 15243 : static void DoPassC (void)
1443 : : {
1444 : 15243 : NameKey_Name name;
1445 : 15243 : unsigned int Sym;
1446 : 15243 : unsigned int i;
1447 : 15243 : DynamicStrings_String FileName;
1448 : :
1449 : 15243 : M2Pass_SetPassToPassC ();
1450 : 15243 : i = 1;
1451 : 15243 : Sym = M2Batch_GetModuleNo (i);
1452 : 205908 : while (Sym != SymbolTable_NulSym)
1453 : : {
1454 : 175446 : FileName = M2Batch_GetDefinitionModuleFile (Sym);
1455 : 175446 : if (FileName != NULL)
1456 : : {
1457 : 163794 : if (Debugging)
1458 : : {
1459 : : name = SymbolTable_GetSymName (Sym);
1460 : : M2Quiet_qprintf1 ((const char *) " Module %a\\n", 14, (const unsigned char *) &name, (sizeof (name)-1));
1461 : : }
1462 : 163794 : if (M2LexBuf_OpenSource (FileName))
1463 : : {
1464 : 163794 : ModuleType = M2Comp_Definition;
1465 : 163794 : if (! (PCBuild_CompilationUnit ()))
1466 : : {
1467 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1468 : 0 : M2LexBuf_CloseSource ();
1469 : 0 : return;
1470 : : }
1471 : 163794 : M2LexBuf_CloseSource ();
1472 : : }
1473 : : else
1474 : : {
1475 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1476 : 0 : libc_exit (1);
1477 : : }
1478 : 163794 : ModuleType = M2Comp_Implementation;
1479 : : }
1480 : : else
1481 : : {
1482 : 11652 : ModuleType = M2Comp_Program;
1483 : : }
1484 : 175446 : FileName = M2Batch_GetModuleFile (Sym);
1485 : 175446 : if (FileName != NULL)
1486 : : {
1487 : 82845 : if (Debugging)
1488 : : {
1489 : : name = SymbolTable_GetSymName (Sym);
1490 : : M2Quiet_qprintf1 ((const char *) " Module %a\\n", 14, (const unsigned char *) &name, (sizeof (name)-1));
1491 : : }
1492 : 82845 : if (M2LexBuf_OpenSource (FileName))
1493 : : {
1494 : 82845 : if (! (PCBuild_CompilationUnit ()))
1495 : : {
1496 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1497 : 0 : M2LexBuf_CloseSource ();
1498 : 0 : return;
1499 : : }
1500 : 82821 : M2LexBuf_CloseSource ();
1501 : : }
1502 : : else
1503 : : {
1504 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1505 : 0 : libc_exit (1);
1506 : : }
1507 : : }
1508 : 175422 : i += 1;
1509 : 175422 : Sym = M2Batch_GetModuleNo (i);
1510 : : }
1511 : 15219 : PCSymBuild_ResolveConstTypes ();
1512 : 15219 : SymbolTable_ResolveConstructorTypes ();
1513 : 15213 : SymbolTable_SanityCheckConstants ();
1514 : 15213 : M2Pass_SetPassToNoPass ();
1515 : : }
1516 : :
1517 : :
1518 : : /*
1519 : : DoPass3 - parses the sources of all modules necessary to compile
1520 : : the required module, Main.
1521 : : */
1522 : :
1523 : 15135 : static void DoPass3 (void)
1524 : : {
1525 : 15135 : unsigned int Main;
1526 : 15135 : unsigned int Sym;
1527 : 15135 : unsigned int i;
1528 : 15135 : DynamicStrings_String FileName;
1529 : :
1530 : 15135 : M2Pass_SetPassToPass3 ();
1531 : 15135 : Main = SymbolTable_GetMainModule ();
1532 : 15135 : i = 1;
1533 : 15135 : Sym = M2Batch_GetModuleNo (i);
1534 : 204826 : while (Sym != SymbolTable_NulSym)
1535 : : {
1536 : 174767 : FileName = M2Batch_GetDefinitionModuleFile (Sym);
1537 : 174767 : if (FileName != NULL)
1538 : : {
1539 : 163205 : if (M2LexBuf_OpenSource (FileName))
1540 : : {
1541 : 163205 : ModuleType = M2Comp_Definition;
1542 : 163205 : if (! (P3Build_CompilationUnit ()))
1543 : : {
1544 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1545 : 0 : M2LexBuf_CloseSource ();
1546 : 0 : return;
1547 : : }
1548 : 163205 : M2LexBuf_CloseSource ();
1549 : : }
1550 : : else
1551 : : {
1552 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1553 : 0 : libc_exit (1);
1554 : : }
1555 : 163205 : ModuleType = M2Comp_Implementation;
1556 : : }
1557 : : else
1558 : : {
1559 : 11562 : ModuleType = M2Comp_Program;
1560 : : }
1561 : 174767 : FileName = M2Batch_GetModuleFile (Sym);
1562 : 174767 : if (FileName != NULL)
1563 : : {
1564 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1565 : 82737 : if (M2LexBuf_OpenSource (FileName))
1566 : : {
1567 : 82737 : if ((Main == Sym) || M2Options_WholeProgram)
1568 : : {
1569 : : /* avoid dangling else. */
1570 : 15663 : if (! (P3Build_CompilationUnit ()))
1571 : : {
1572 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1573 : 0 : M2LexBuf_CloseSource ();
1574 : 0 : return;
1575 : : }
1576 : : }
1577 : : else
1578 : : {
1579 : : /*
1580 : : not the main module .mod therefore must be implementing
1581 : : a hidden type - we dont want to generate any
1582 : : StatementSequence quadrupes but we do want to build TYPEs
1583 : : and ConstExpressions.
1584 : : */
1585 : 67074 : M2Pass_SetPassToNoPass ();
1586 : 67074 : M2Pass_SetPassToPassHidden ();
1587 : 67074 : if (! (PHBuild_CompilationUnit ()))
1588 : : {
1589 : 0 : M2MetaError_MetaError0 ((const char *) "compilation failed", 18);
1590 : 0 : M2LexBuf_CloseSource ();
1591 : 0 : return;
1592 : : }
1593 : 67074 : M2Pass_SetPassToNoPass ();
1594 : 67074 : M2Pass_SetPassToPass3 ();
1595 : : }
1596 : 82526 : M2LexBuf_CloseSource ();
1597 : : }
1598 : : else
1599 : : {
1600 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &FileName, (sizeof (FileName)-1));
1601 : 0 : libc_exit (1);
1602 : : }
1603 : : }
1604 : 174556 : i += 1;
1605 : 174556 : Sym = M2Batch_GetModuleNo (i);
1606 : : }
1607 : 14924 : M2Pass_SetPassToNoPass ();
1608 : : }
1609 : :
1610 : :
1611 : : /*
1612 : : compile - compile the filename.
1613 : : */
1614 : :
1615 : 15506 : extern "C" void M2Comp_compile (void * filename)
1616 : : {
1617 : 15506 : DynamicStrings_String f;
1618 : 15506 : DynamicStrings_String s;
1619 : :
1620 : 15506 : M2Diagnostic_Configure (M2Options_TimeReport, M2Options_MemReport);
1621 : 15506 : f = DynamicStrings_InitStringCharStar (filename);
1622 : 15506 : Compile (f);
1623 : 13991 : f = DynamicStrings_KillString (f);
1624 : 13991 : PopulateResource ();
1625 : 13991 : if (M2Options_TimeReport || M2Options_MemReport)
1626 : : {
1627 : 0 : s = SFIO_WriteS (FIO_StdOut, M2Diagnostic_Generate (false));
1628 : 0 : FIO_FlushOutErr ();
1629 : 0 : s = DynamicStrings_KillString (s);
1630 : : }
1631 : 13991 : }
1632 : :
1633 : :
1634 : : /*
1635 : : CompilingDefinitionModule - returns true if the current module being
1636 : : compiled is a definition module.
1637 : : */
1638 : :
1639 : 147310493 : extern "C" bool M2Comp_CompilingDefinitionModule (void)
1640 : : {
1641 : 147310493 : return ModuleType == M2Comp_Definition;
1642 : : /* static analysis guarentees a RETURN statement will be used before here. */
1643 : : __builtin_unreachable ();
1644 : : }
1645 : :
1646 : :
1647 : : /*
1648 : : CompilingImplementationModule - returns true if the current module being
1649 : : compiled is an implementation module.
1650 : : */
1651 : :
1652 : 9988608 : extern "C" bool M2Comp_CompilingImplementationModule (void)
1653 : : {
1654 : 9988608 : return ModuleType == M2Comp_Implementation;
1655 : : /* static analysis guarentees a RETURN statement will be used before here. */
1656 : : __builtin_unreachable ();
1657 : : }
1658 : :
1659 : :
1660 : : /*
1661 : : CompilingProgramModule - returns true if the current module being
1662 : : compiled is a program module.
1663 : : */
1664 : :
1665 : 93053 : extern "C" bool M2Comp_CompilingProgramModule (void)
1666 : : {
1667 : 93053 : return ModuleType == M2Comp_Program;
1668 : : /* static analysis guarentees a RETURN statement will be used before here. */
1669 : : __builtin_unreachable ();
1670 : : }
1671 : :
1672 : 15506 : extern "C" void _M2_M2Comp_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
1673 : : {
1674 : 15506 : ModuleType = M2Comp_None;
1675 : 15506 : DepContent = static_cast<Indexing_Index> (NULL);
1676 : 15506 : DepOutput = static_cast<DynamicStrings_String> (NULL);
1677 : 15506 : }
1678 : :
1679 : 0 : extern "C" void _M2_M2Comp_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
1680 : : {
1681 : 0 : }
|