Daily bump.
[official-gcc.git] / gcc / m2 / mc-boot / GmcComp.cc
blobe36fa638c9e737096fcb52537df31840ffe8de7f
1 /* do not edit automatically generated by mc from mcComp. */
2 /* Copyright (C) 2015-2025 Free Software Foundation, Inc.
3 This file is part of GNU Modula-2.
5 GNU Modula-2 is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
10 GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
19 #include "config.h"
20 #include "system.h"
21 #include <stdbool.h>
22 # if !defined (PROC_D)
23 # define PROC_D
24 typedef void (*PROC_t) (void);
25 typedef struct { PROC_t proc; } PROC;
26 # endif
28 # if !defined (TRUE)
29 # define TRUE (1==1)
30 # endif
32 # if !defined (FALSE)
33 # define FALSE (1==0)
34 # endif
36 # include "Gmcrts.h"
37 #if defined(__cplusplus)
38 # undef NULL
39 # define NULL 0
40 #endif
41 #define _mcComp_C
43 #include "GmcComp.h"
44 # include "GFIO.h"
45 # include "Glibc.h"
46 # include "Gdecl.h"
47 # include "GsymbolKey.h"
48 # include "GSYSTEM.h"
49 # include "GmcReserved.h"
50 # include "GmcSearch.h"
51 # include "GmcLexBuf.h"
52 # include "GmcFileName.h"
53 # include "GmcPreprocess.h"
54 # include "GFormatStrings.h"
55 # include "Gmcflex.h"
56 # include "Gmcp1.h"
57 # include "Gmcp2.h"
58 # include "Gmcp3.h"
59 # include "Gmcp4.h"
60 # include "Gmcp5.h"
61 # include "GmcComment.h"
62 # include "GmcError.h"
63 # include "GnameKey.h"
64 # include "GmcPrintf.h"
65 # include "GmcQuiet.h"
66 # include "GDynamicStrings.h"
67 # include "GmcOptions.h"
69 # define Debugging false
70 typedef struct mcComp_parserFunction_p mcComp_parserFunction;
72 typedef struct mcComp_openFunction_p mcComp_openFunction;
74 typedef bool (*mcComp_parserFunction_t) (void);
75 struct mcComp_parserFunction_p { mcComp_parserFunction_t proc; };
77 typedef bool (*mcComp_openFunction_t) (decl_node, bool);
78 struct mcComp_openFunction_p { mcComp_openFunction_t proc; };
80 static unsigned int currentPass;
83 compile - check, s, is non NIL before calling doCompile.
86 extern "C" void mcComp_compile (DynamicStrings_String s);
89 getPassNo - return the pass no.
92 extern "C" unsigned int mcComp_getPassNo (void);
95 doCompile - translate file, s, using a 6 pass technique.
98 static void doCompile (DynamicStrings_String s);
101 examineCompilationUnit - opens the source file to obtain the module name and kind of module.
104 static decl_node examineCompilationUnit (void);
107 peepInto - peeps into source, s, and initializes a definition/implementation or
108 program module accordingly.
111 static decl_node peepInto (DynamicStrings_String s);
114 initParser - returns the node of the module found in the source file.
117 static decl_node initParser (DynamicStrings_String s);
120 p1 - wrap the pass procedure with the correct parameter values.
123 static void p1 (decl_node n);
126 p2 - wrap the pass procedure with the correct parameter values.
129 static void p2 (decl_node n);
132 p3 - wrap the pass procedure with the correct parameter values.
135 static void p3 (decl_node n);
138 p4 - wrap the pass procedure with the correct parameter values.
141 static void p4 (decl_node n);
144 p5 - wrap the pass procedure with the correct parameter values.
147 static void p5 (decl_node n);
150 doOpen -
153 static bool doOpen (decl_node n, DynamicStrings_String symName, DynamicStrings_String fileName, bool exitOnFailure);
156 openDef - try and open the definition module source file.
157 Returns true/false if successful/unsuccessful or
158 exitOnFailure.
161 static bool openDef (decl_node n, bool exitOnFailure);
164 openMod - try and open the implementation/program module source file.
165 Returns true/false if successful/unsuccessful or
166 exitOnFailure.
169 static bool openMod (decl_node n, bool exitOnFailure);
172 pass -
175 static void pass (unsigned int no, decl_node n, mcComp_parserFunction f, decl_isNodeF isnode, mcComp_openFunction open);
178 doPass -
181 static void doPass (bool parseDefs, bool parseMain, unsigned int no, symbolKey_performOperation p, const char *desc_, unsigned int _desc_high);
184 setToPassNo -
187 static void setToPassNo (unsigned int n);
190 init - initialise data structures for this module.
193 static void init (void);
197 doCompile - translate file, s, using a 6 pass technique.
200 static void doCompile (DynamicStrings_String s)
202 decl_node n;
204 n = initParser (s);
205 doPass (true, true, 1, (symbolKey_performOperation) {(symbolKey_performOperation_t) p1}, (const char *) "lexical analysis, modules, root decls and C preprocessor", 56);
206 doPass (true, true, 2, (symbolKey_performOperation) {(symbolKey_performOperation_t) p2}, (const char *) "[all modules] type equivalence and enumeration types", 52);
207 doPass (true, true, 3, (symbolKey_performOperation) {(symbolKey_performOperation_t) p3}, (const char *) "[all modules] import lists, types, variables and procedure declarations", 71);
208 doPass (true, true, 4, (symbolKey_performOperation) {(symbolKey_performOperation_t) p4}, (const char *) "[all modules] constant expressions", 34);
209 if (! (decl_isDef (n)))
211 /* avoid gcc warning by using compound statement even if not strictly necessary. */
212 if (decl_isImp (n))
214 mcQuiet_qprintf0 ((const char *) "Parse implementation module\\n", 29);
215 doPass (false, true, 5, (symbolKey_performOperation) {(symbolKey_performOperation_t) p5}, (const char *) "[implementation module] build code tree for all procedures and module initializations", 85);
217 else
219 mcQuiet_qprintf0 ((const char *) "Parse program module\\n", 22);
220 doPass (false, true, 5, (symbolKey_performOperation) {(symbolKey_performOperation_t) p5}, (const char *) "[program module] build code tree for all procedures and module initializations", 78);
223 mcQuiet_qprintf0 ((const char *) "walk tree converting it to C/C++\\n", 34);
224 decl_out ();
229 examineCompilationUnit - opens the source file to obtain the module name and kind of module.
232 static decl_node examineCompilationUnit (void)
234 /* stop if we see eof, ';' or '[' */
235 while (((mcLexBuf_currenttoken != mcReserved_eoftok) && (mcLexBuf_currenttoken != mcReserved_semicolontok)) && (mcLexBuf_currenttoken != mcReserved_lsbratok))
237 if (mcLexBuf_currenttoken == mcReserved_definitiontok)
239 mcLexBuf_getToken ();
240 if (mcLexBuf_currenttoken == mcReserved_moduletok)
242 /* avoid dangling else. */
243 mcLexBuf_getToken ();
244 if (mcLexBuf_currenttoken == mcReserved_fortok)
246 mcLexBuf_getToken ();
247 if (mcLexBuf_currenttoken == mcReserved_stringtok)
249 mcLexBuf_getToken ();
251 else
253 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "expecting language string after FOR keyword", 43)));
254 libc_exit (1);
257 if (mcLexBuf_currenttoken == mcReserved_identtok)
259 return decl_lookupDef (nameKey_makekey (mcLexBuf_currentstring));
262 else
264 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after DEFINITION keyword", 39)));
267 else if (mcLexBuf_currenttoken == mcReserved_implementationtok)
269 /* avoid dangling else. */
270 mcLexBuf_getToken ();
271 if (mcLexBuf_currenttoken == mcReserved_moduletok)
273 /* avoid dangling else. */
274 mcLexBuf_getToken ();
275 if (mcLexBuf_currenttoken == mcReserved_identtok)
277 return decl_lookupImp (nameKey_makekey (mcLexBuf_currentstring));
280 else
282 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after IMPLEMENTATION keyword", 43)));
285 else if (mcLexBuf_currenttoken == mcReserved_moduletok)
287 /* avoid dangling else. */
288 mcLexBuf_getToken ();
289 if (mcLexBuf_currenttoken == mcReserved_identtok)
291 return decl_lookupModule (nameKey_makekey (mcLexBuf_currentstring));
294 mcLexBuf_getToken ();
296 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "failed to find module name", 26)));
297 libc_exit (1);
298 ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1);
299 __builtin_unreachable ();
304 peepInto - peeps into source, s, and initializes a definition/implementation or
305 program module accordingly.
308 static decl_node peepInto (DynamicStrings_String s)
310 decl_node n;
311 DynamicStrings_String fileName;
313 fileName = mcPreprocess_preprocessModule (s);
314 if (mcLexBuf_openSource (fileName))
316 n = examineCompilationUnit ();
317 decl_setSource (n, nameKey_makekey (DynamicStrings_string (fileName)));
318 decl_setMainModule (n);
319 mcLexBuf_closeSource ();
320 mcLexBuf_reInitialize ();
321 return n;
323 else
325 mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &s, (sizeof (s)-1));
326 libc_exit (1);
328 ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1);
329 __builtin_unreachable ();
334 initParser - returns the node of the module found in the source file.
337 static decl_node initParser (DynamicStrings_String s)
339 mcQuiet_qprintf1 ((const char *) "Compiling: %s\\n", 15, (const unsigned char *) &s, (sizeof (s)-1));
340 return peepInto (s);
341 /* static analysis guarentees a RETURN statement will be used before here. */
342 __builtin_unreachable ();
347 p1 - wrap the pass procedure with the correct parameter values.
350 static void p1 (decl_node n)
352 if (decl_isDef (n))
354 /* avoid dangling else. */
355 pass (1, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
356 if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
358 pass (1, decl_lookupImp (decl_getSymName (n)), (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImp}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
361 else
363 pass (1, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
369 p2 - wrap the pass procedure with the correct parameter values.
372 static void p2 (decl_node n)
374 if (decl_isDef (n))
376 /* avoid dangling else. */
377 pass (2, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
378 if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
380 pass (2, decl_lookupImp (decl_getSymName (n)), (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImp}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
383 else
385 pass (2, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
391 p3 - wrap the pass procedure with the correct parameter values.
394 static void p3 (decl_node n)
396 if (decl_isDef (n))
398 /* avoid dangling else. */
399 pass (3, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
400 if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
402 pass (3, decl_lookupImp (decl_getSymName (n)), (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImp}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
405 else
407 pass (3, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
413 p4 - wrap the pass procedure with the correct parameter values.
416 static void p4 (decl_node n)
418 if (decl_isDef (n))
420 /* avoid dangling else. */
421 pass (4, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
422 if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
424 pass (4, decl_lookupImp (decl_getSymName (n)), (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImp}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
427 else
429 pass (4, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
435 p5 - wrap the pass procedure with the correct parameter values.
438 static void p5 (decl_node n)
440 pass (5, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp5_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
445 doOpen -
448 static bool doOpen (decl_node n, DynamicStrings_String symName, DynamicStrings_String fileName, bool exitOnFailure)
450 DynamicStrings_String postProcessed;
452 mcQuiet_qprintf2 ((const char *) " Module %-20s : %s\\n", 22, (const unsigned char *) &symName, (sizeof (symName)-1), (const unsigned char *) &fileName, (sizeof (fileName)-1));
453 postProcessed = mcPreprocess_preprocessModule (fileName);
454 decl_setSource (n, nameKey_makekey (DynamicStrings_string (postProcessed)));
455 decl_setCurrentModule (n);
456 if (mcLexBuf_openSource (postProcessed))
458 return true;
460 mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &fileName, (sizeof (fileName)-1));
461 if (exitOnFailure)
463 libc_exit (1);
465 return false;
466 /* static analysis guarentees a RETURN statement will be used before here. */
467 __builtin_unreachable ();
472 openDef - try and open the definition module source file.
473 Returns true/false if successful/unsuccessful or
474 exitOnFailure.
477 static bool openDef (decl_node n, bool exitOnFailure)
479 nameKey_Name sourceName;
480 DynamicStrings_String symName;
481 DynamicStrings_String fileName;
483 sourceName = decl_getSource (n);
484 symName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n)));
485 if (sourceName == nameKey_NulName)
487 /* avoid dangling else. */
488 if (! (mcSearch_findSourceDefFile (symName, &fileName)))
490 mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find definition module %s.def\\n", 41, (const unsigned char *) &symName, (sizeof (symName)-1));
491 if (exitOnFailure)
493 libc_exit (1);
497 else
499 fileName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName));
501 return doOpen (n, symName, fileName, exitOnFailure);
502 /* static analysis guarentees a RETURN statement will be used before here. */
503 __builtin_unreachable ();
508 openMod - try and open the implementation/program module source file.
509 Returns true/false if successful/unsuccessful or
510 exitOnFailure.
513 static bool openMod (decl_node n, bool exitOnFailure)
515 nameKey_Name sourceName;
516 DynamicStrings_String symName;
517 DynamicStrings_String fileName;
519 sourceName = decl_getSource (n);
520 symName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n)));
521 if (sourceName == nameKey_NulName)
523 /* avoid dangling else. */
524 if (! (mcSearch_findSourceModFile (symName, &fileName)))
526 if (decl_isImp (n))
528 mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find implementation module %s.mod\\n", 45, (const unsigned char *) &symName, (sizeof (symName)-1));
530 else
532 mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find program module %s.mod\\n", 38, (const unsigned char *) &symName, (sizeof (symName)-1));
534 if (exitOnFailure)
536 libc_exit (1);
540 else
542 fileName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName));
544 return doOpen (n, symName, fileName, exitOnFailure);
545 /* static analysis guarentees a RETURN statement will be used before here. */
546 __builtin_unreachable ();
551 pass -
554 static void pass (unsigned int no, decl_node n, mcComp_parserFunction f, decl_isNodeF isnode, mcComp_openFunction open)
556 if (((*isnode.proc) (n)) && (! (decl_isVisited (n))))
558 decl_setVisited (n);
559 if ((*open.proc) (n, true))
561 if (! ((*f.proc) ()))
563 mcError_writeFormat0 ((const char *) "compilation failed", 18);
564 mcLexBuf_closeSource ();
565 return;
567 mcLexBuf_closeSource ();
574 doPass -
577 static void doPass (bool parseDefs, bool parseMain, unsigned int no, symbolKey_performOperation p, const char *desc_, unsigned int _desc_high)
579 DynamicStrings_String descs;
580 char desc[_desc_high+1];
582 /* make a local copy of each unbounded array. */
583 memcpy (desc, desc_, _desc_high+1);
585 setToPassNo (no);
586 descs = DynamicStrings_InitString ((const char *) desc, _desc_high);
587 mcQuiet_qprintf2 ((const char *) "Pass %d: %s\\n", 13, (const unsigned char *) &no, (sizeof (no)-1), (const unsigned char *) &descs, (sizeof (descs)-1));
588 decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) decl_unsetVisited});
589 decl_foreachModModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) decl_unsetVisited});
590 if (parseMain)
592 decl_unsetVisited (decl_getMainModule ());
593 if (parseDefs && (decl_isImp (decl_getMainModule ())))
595 /* we need to parse the definition module of a corresponding implementation module. */
596 (*p.proc) (reinterpret_cast <void *> (decl_lookupDef (decl_getSymName (decl_getMainModule ()))));
598 (*p.proc) (reinterpret_cast <void *> (decl_getMainModule ()));
600 if (parseDefs)
602 decl_foreachDefModuleDo (p);
604 mcError_flushWarnings ();
605 mcError_flushErrors ();
606 setToPassNo (0);
611 setToPassNo -
614 static void setToPassNo (unsigned int n)
616 currentPass = n;
621 init - initialise data structures for this module.
624 static void init (void)
626 setToPassNo (0);
631 compile - check, s, is non NIL before calling doCompile.
634 extern "C" void mcComp_compile (DynamicStrings_String s)
636 if (s != NULL)
638 doCompile (s);
644 getPassNo - return the pass no.
647 extern "C" unsigned int mcComp_getPassNo (void)
649 return currentPass;
650 /* static analysis guarentees a RETURN statement will be used before here. */
651 __builtin_unreachable ();
654 extern "C" void _M2_mcComp_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
656 init ();
659 extern "C" void _M2_mcComp_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])