/* do not edit automatically generated by mc from mcComp. */ /* Copyright (C) 2015-2025 Free Software Foundation, Inc. This file is part of GNU Modula-2. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include # if !defined (PROC_D) # define PROC_D typedef void (*PROC_t) (void); typedef struct { PROC_t proc; } PROC; # endif # if !defined (TRUE) # define TRUE (1==1) # endif # if !defined (FALSE) # define FALSE (1==0) # endif # include "Gmcrts.h" #if defined(__cplusplus) # undef NULL # define NULL 0 #endif #define _mcComp_C #include "GmcComp.h" # include "GFIO.h" # include "Glibc.h" # include "Gdecl.h" # include "GsymbolKey.h" # include "GSYSTEM.h" # include "GmcReserved.h" # include "GmcSearch.h" # include "GmcLexBuf.h" # include "GmcFileName.h" # include "GmcPreprocess.h" # include "GFormatStrings.h" # include "Gmcflex.h" # include "Gmcp1.h" # include "Gmcp2.h" # include "Gmcp3.h" # include "Gmcp4.h" # include "Gmcp5.h" # include "GmcComment.h" # include "GmcError.h" # include "GnameKey.h" # include "GmcPrintf.h" # include "GmcQuiet.h" # include "GDynamicStrings.h" # include "GmcOptions.h" # define Debugging false typedef struct mcComp_parserFunction_p mcComp_parserFunction; typedef struct mcComp_openFunction_p mcComp_openFunction; typedef bool (*mcComp_parserFunction_t) (void); struct mcComp_parserFunction_p { mcComp_parserFunction_t proc; }; typedef bool (*mcComp_openFunction_t) (decl_node, bool); struct mcComp_openFunction_p { mcComp_openFunction_t proc; }; static unsigned int currentPass; /* compile - check, s, is non NIL before calling doCompile. */ extern "C" void mcComp_compile (DynamicStrings_String s); /* getPassNo - return the pass no. */ extern "C" unsigned int mcComp_getPassNo (void); /* doCompile - translate file, s, using a 6 pass technique. */ static void doCompile (DynamicStrings_String s); /* examineCompilationUnit - opens the source file to obtain the module name and kind of module. */ static decl_node examineCompilationUnit (void); /* peepInto - peeps into source, s, and initializes a definition/implementation or program module accordingly. */ static decl_node peepInto (DynamicStrings_String s); /* initParser - returns the node of the module found in the source file. */ static decl_node initParser (DynamicStrings_String s); /* p1 - wrap the pass procedure with the correct parameter values. */ static void p1 (decl_node n); /* p2 - wrap the pass procedure with the correct parameter values. */ static void p2 (decl_node n); /* p3 - wrap the pass procedure with the correct parameter values. */ static void p3 (decl_node n); /* p4 - wrap the pass procedure with the correct parameter values. */ static void p4 (decl_node n); /* p5 - wrap the pass procedure with the correct parameter values. */ static void p5 (decl_node n); /* doOpen - */ static bool doOpen (decl_node n, DynamicStrings_String symName, DynamicStrings_String fileName, bool exitOnFailure); /* openDef - try and open the definition module source file. Returns true/false if successful/unsuccessful or exitOnFailure. */ static bool openDef (decl_node n, bool exitOnFailure); /* openMod - try and open the implementation/program module source file. Returns true/false if successful/unsuccessful or exitOnFailure. */ static bool openMod (decl_node n, bool exitOnFailure); /* pass - */ static void pass (unsigned int no, decl_node n, mcComp_parserFunction f, decl_isNodeF isnode, mcComp_openFunction open); /* doPass - */ static void doPass (bool parseDefs, bool parseMain, unsigned int no, symbolKey_performOperation p, const char *desc_, unsigned int _desc_high); /* setToPassNo - */ static void setToPassNo (unsigned int n); /* init - initialise data structures for this module. */ static void init (void); /* doCompile - translate file, s, using a 6 pass technique. */ static void doCompile (DynamicStrings_String s) { decl_node n; n = initParser (s); doPass (true, true, 1, (symbolKey_performOperation) {(symbolKey_performOperation_t) p1}, (const char *) "lexical analysis, modules, root decls and C preprocessor", 56); doPass (true, true, 2, (symbolKey_performOperation) {(symbolKey_performOperation_t) p2}, (const char *) "[all modules] type equivalence and enumeration types", 52); doPass (true, true, 3, (symbolKey_performOperation) {(symbolKey_performOperation_t) p3}, (const char *) "[all modules] import lists, types, variables and procedure declarations", 71); doPass (true, true, 4, (symbolKey_performOperation) {(symbolKey_performOperation_t) p4}, (const char *) "[all modules] constant expressions", 34); if (! (decl_isDef (n))) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (decl_isImp (n)) { mcQuiet_qprintf0 ((const char *) "Parse implementation module\\n", 29); doPass (false, true, 5, (symbolKey_performOperation) {(symbolKey_performOperation_t) p5}, (const char *) "[implementation module] build code tree for all procedures and module initializations", 85); } else { mcQuiet_qprintf0 ((const char *) "Parse program module\\n", 22); doPass (false, true, 5, (symbolKey_performOperation) {(symbolKey_performOperation_t) p5}, (const char *) "[program module] build code tree for all procedures and module initializations", 78); } } mcQuiet_qprintf0 ((const char *) "walk tree converting it to C/C++\\n", 34); decl_out (); } /* examineCompilationUnit - opens the source file to obtain the module name and kind of module. */ static decl_node examineCompilationUnit (void) { /* stop if we see eof, ';' or '[' */ while (((mcLexBuf_currenttoken != mcReserved_eoftok) && (mcLexBuf_currenttoken != mcReserved_semicolontok)) && (mcLexBuf_currenttoken != mcReserved_lsbratok)) { if (mcLexBuf_currenttoken == mcReserved_definitiontok) { mcLexBuf_getToken (); if (mcLexBuf_currenttoken == mcReserved_moduletok) { /* avoid dangling else. */ mcLexBuf_getToken (); if (mcLexBuf_currenttoken == mcReserved_fortok) { mcLexBuf_getToken (); if (mcLexBuf_currenttoken == mcReserved_stringtok) { mcLexBuf_getToken (); } else { mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "expecting language string after FOR keyword", 43))); libc_exit (1); } } if (mcLexBuf_currenttoken == mcReserved_identtok) { return decl_lookupDef (nameKey_makekey (mcLexBuf_currentstring)); } } else { mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after DEFINITION keyword", 39))); } } else if (mcLexBuf_currenttoken == mcReserved_implementationtok) { /* avoid dangling else. */ mcLexBuf_getToken (); if (mcLexBuf_currenttoken == mcReserved_moduletok) { /* avoid dangling else. */ mcLexBuf_getToken (); if (mcLexBuf_currenttoken == mcReserved_identtok) { return decl_lookupImp (nameKey_makekey (mcLexBuf_currentstring)); } } else { mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after IMPLEMENTATION keyword", 43))); } } else if (mcLexBuf_currenttoken == mcReserved_moduletok) { /* avoid dangling else. */ mcLexBuf_getToken (); if (mcLexBuf_currenttoken == mcReserved_identtok) { return decl_lookupModule (nameKey_makekey (mcLexBuf_currentstring)); } } mcLexBuf_getToken (); } mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "failed to find module name", 26))); libc_exit (1); ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1); __builtin_unreachable (); } /* peepInto - peeps into source, s, and initializes a definition/implementation or program module accordingly. */ static decl_node peepInto (DynamicStrings_String s) { decl_node n; DynamicStrings_String fileName; fileName = mcPreprocess_preprocessModule (s); if (mcLexBuf_openSource (fileName)) { n = examineCompilationUnit (); decl_setSource (n, nameKey_makekey (DynamicStrings_string (fileName))); decl_setMainModule (n); mcLexBuf_closeSource (); mcLexBuf_reInitialize (); return n; } else { mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &s, (sizeof (s)-1)); libc_exit (1); } ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1); __builtin_unreachable (); } /* initParser - returns the node of the module found in the source file. */ static decl_node initParser (DynamicStrings_String s) { mcQuiet_qprintf1 ((const char *) "Compiling: %s\\n", 15, (const unsigned char *) &s, (sizeof (s)-1)); return peepInto (s); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* p1 - wrap the pass procedure with the correct parameter values. */ static void p1 (decl_node n) { if (decl_isDef (n)) { /* avoid dangling else. */ pass (1, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef}); if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ())) { 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}); } } else { pass (1, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod}); } } /* p2 - wrap the pass procedure with the correct parameter values. */ static void p2 (decl_node n) { if (decl_isDef (n)) { /* avoid dangling else. */ pass (2, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef}); if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ())) { 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}); } } else { pass (2, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod}); } } /* p3 - wrap the pass procedure with the correct parameter values. */ static void p3 (decl_node n) { if (decl_isDef (n)) { /* avoid dangling else. */ pass (3, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef}); if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ())) { 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}); } } else { pass (3, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod}); } } /* p4 - wrap the pass procedure with the correct parameter values. */ static void p4 (decl_node n) { if (decl_isDef (n)) { /* avoid dangling else. */ pass (4, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef}); if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ())) { 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}); } } else { pass (4, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod}); } } /* p5 - wrap the pass procedure with the correct parameter values. */ static void p5 (decl_node n) { pass (5, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp5_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod}); } /* doOpen - */ static bool doOpen (decl_node n, DynamicStrings_String symName, DynamicStrings_String fileName, bool exitOnFailure) { DynamicStrings_String postProcessed; mcQuiet_qprintf2 ((const char *) " Module %-20s : %s\\n", 22, (const unsigned char *) &symName, (sizeof (symName)-1), (const unsigned char *) &fileName, (sizeof (fileName)-1)); postProcessed = mcPreprocess_preprocessModule (fileName); decl_setSource (n, nameKey_makekey (DynamicStrings_string (postProcessed))); decl_setCurrentModule (n); if (mcLexBuf_openSource (postProcessed)) { return true; } mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &fileName, (sizeof (fileName)-1)); if (exitOnFailure) { libc_exit (1); } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* openDef - try and open the definition module source file. Returns true/false if successful/unsuccessful or exitOnFailure. */ static bool openDef (decl_node n, bool exitOnFailure) { nameKey_Name sourceName; DynamicStrings_String symName; DynamicStrings_String fileName; sourceName = decl_getSource (n); symName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n))); if (sourceName == nameKey_NulName) { /* avoid dangling else. */ if (! (mcSearch_findSourceDefFile (symName, &fileName))) { mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find definition module %s.def\\n", 41, (const unsigned char *) &symName, (sizeof (symName)-1)); if (exitOnFailure) { libc_exit (1); } } } else { fileName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName)); } return doOpen (n, symName, fileName, exitOnFailure); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* openMod - try and open the implementation/program module source file. Returns true/false if successful/unsuccessful or exitOnFailure. */ static bool openMod (decl_node n, bool exitOnFailure) { nameKey_Name sourceName; DynamicStrings_String symName; DynamicStrings_String fileName; sourceName = decl_getSource (n); symName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n))); if (sourceName == nameKey_NulName) { /* avoid dangling else. */ if (! (mcSearch_findSourceModFile (symName, &fileName))) { if (decl_isImp (n)) { mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find implementation module %s.mod\\n", 45, (const unsigned char *) &symName, (sizeof (symName)-1)); } else { mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find program module %s.mod\\n", 38, (const unsigned char *) &symName, (sizeof (symName)-1)); } if (exitOnFailure) { libc_exit (1); } } } else { fileName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName)); } return doOpen (n, symName, fileName, exitOnFailure); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* pass - */ static void pass (unsigned int no, decl_node n, mcComp_parserFunction f, decl_isNodeF isnode, mcComp_openFunction open) { if (((*isnode.proc) (n)) && (! (decl_isVisited (n)))) { decl_setVisited (n); if ((*open.proc) (n, true)) { if (! ((*f.proc) ())) { mcError_writeFormat0 ((const char *) "compilation failed", 18); mcLexBuf_closeSource (); return; } mcLexBuf_closeSource (); } } } /* doPass - */ static void doPass (bool parseDefs, bool parseMain, unsigned int no, symbolKey_performOperation p, const char *desc_, unsigned int _desc_high) { DynamicStrings_String descs; char desc[_desc_high+1]; /* make a local copy of each unbounded array. */ memcpy (desc, desc_, _desc_high+1); setToPassNo (no); descs = DynamicStrings_InitString ((const char *) desc, _desc_high); mcQuiet_qprintf2 ((const char *) "Pass %d: %s\\n", 13, (const unsigned char *) &no, (sizeof (no)-1), (const unsigned char *) &descs, (sizeof (descs)-1)); decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) decl_unsetVisited}); decl_foreachModModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) decl_unsetVisited}); if (parseMain) { decl_unsetVisited (decl_getMainModule ()); if (parseDefs && (decl_isImp (decl_getMainModule ()))) { /* we need to parse the definition module of a corresponding implementation module. */ (*p.proc) (reinterpret_cast (decl_lookupDef (decl_getSymName (decl_getMainModule ())))); } (*p.proc) (reinterpret_cast (decl_getMainModule ())); } if (parseDefs) { decl_foreachDefModuleDo (p); } mcError_flushWarnings (); mcError_flushErrors (); setToPassNo (0); } /* setToPassNo - */ static void setToPassNo (unsigned int n) { currentPass = n; } /* init - initialise data structures for this module. */ static void init (void) { setToPassNo (0); } /* compile - check, s, is non NIL before calling doCompile. */ extern "C" void mcComp_compile (DynamicStrings_String s) { if (s != NULL) { doCompile (s); } } /* getPassNo - return the pass no. */ extern "C" unsigned int mcComp_getPassNo (void) { return currentPass; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } extern "C" void _M2_mcComp_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) { init (); } extern "C" void _M2_mcComp_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) { }