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