diff options
-rw-r--r-- | gcc/gcc.cc | 1 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Comp.mod | 38 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Options.def | 90 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Options.mod | 139 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Preprocess.def | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Preprocess.mod | 130 | ||||
-rw-r--r-- | gcc/m2/gm2-gcc/m2options.h | 11 | ||||
-rw-r--r-- | gcc/m2/gm2-gcc/m2type.cc | 4 | ||||
-rw-r--r-- | gcc/m2/gm2-lang.cc | 237 | ||||
-rw-r--r-- | gcc/m2/gm2spec.cc | 33 | ||||
-rw-r--r-- | gcc/m2/lang-specs.h | 40 | ||||
-rw-r--r-- | gcc/m2/lang.opt | 119 |
12 files changed, 619 insertions, 225 deletions
@@ -1423,6 +1423,7 @@ static const struct compiler default_compilers[] = {".r", "#Ratfor", 0, 0, 0}, {".go", "#Go", 0, 1, 0}, {".d", "#D", 0, 1, 0}, {".dd", "#D", 0, 1, 0}, {".di", "#D", 0, 1, 0}, + {".mod", "#Modula-2", 0, 0, 0}, {".m2i", "#Modula-2", 0, 0, 0}, /* Next come the entries for C. */ {".c", "@c", 0, 0, 1}, {"@c", diff --git a/gcc/m2/gm2-compiler/M2Comp.mod b/gcc/m2/gm2-compiler/M2Comp.mod index fd5ea1b..05eaacc 100644 --- a/gcc/m2/gm2-compiler/M2Comp.mod +++ b/gcc/m2/gm2-compiler/M2Comp.mod @@ -22,7 +22,8 @@ along with GNU Modula-2; see the file COPYING3. If not see IMPLEMENTATION MODULE M2Comp ; -FROM M2Options IMPORT Statistics, Quiet, WholeProgram, ExtendedOpaque, GenModuleList ; +FROM M2Options IMPORT PPonly, Statistics, Quiet, WholeProgram, + ExtendedOpaque, GenModuleList ; FROM M2Pass IMPORT SetPassToPass0, SetPassToPass1, SetPassToPass2, SetPassToPassC, SetPassToPass3, SetPassToNoPass, SetPassToPassHidden ; @@ -60,11 +61,12 @@ FROM SymbolTable IMPORT GetSymName, IsDefImp, NulSym, ResolveConstructorTypes, SanityCheckConstants, IsDefinitionForC, IsBuiltinInModule, PutModLink, IsDefLink, IsModLink ; -FROM FIO IMPORT StdErr ; +FROM FIO IMPORT StdErr, StdOut ; FROM NameKey IMPORT Name, GetKey, KeyToCharStar, makekey ; FROM M2Printf IMPORT fprintf1 ; FROM M2Quiet IMPORT qprintf0, qprintf1, qprintf2 ; FROM DynamicStrings IMPORT String, InitString, KillString, InitStringCharStar, Dup, Mark, string ; +FROM M2Options IMPORT Verbose ; CONST Debugging = FALSE ; @@ -126,6 +128,10 @@ PROCEDURE Compile (s: String) ; BEGIN DoPass0(s) ; FlushWarnings ; FlushErrors ; + IF PPonly + THEN + RETURN + END; ResetForNewPass ; ResetErrorScope ; qprintf0('Pass 1: scopes, enumerated types, imports and exports\n') ; DoPass1 ; @@ -198,7 +204,7 @@ VAR name : ADDRESS ; isdefimp: BOOLEAN ; BEGIN - IF OpenSource(PreprocessModule(s)) + IF OpenSource(s) THEN ExamineCompilationUnit(name, isdefimp) ; IF isdefimp @@ -226,15 +232,26 @@ VAR Sym : CARDINAL ; i : CARDINAL ; SymName, - FileName: String ; + FileName, + PPSource: String ; BEGIN P0Init ; SetPassToPass0 ; - PeepInto(s) ; + (* Maybe preprocess the main file. *) + PPSource := PreprocessModule(s, TRUE); + IF PPonly + THEN + RETURN + END; + PeepInto (PPSource) ; Main := GetMainModule() ; i := 1 ; Sym := GetModuleNo(i) ; - qprintf1('Compiling: %s\n', s) ; + qprintf1('Compiling: %s\n', PPSource) ; + IF Verbose + THEN + fprintf1(StdOut, 'Compiling: %s\n', PPSource) ; + END ; qprintf0('Pass 0: lexical analysis, parsing, modules and associated filenames\n') ; WHILE Sym#NulSym DO SymName := InitStringCharStar(KeyToCharStar(GetSymName(Sym))) ; @@ -243,7 +260,7 @@ BEGIN IF FindSourceDefFile(SymName, FileName) THEN ModuleType := Definition ; - IF OpenSource(AssociateDefinition(PreprocessModule(FileName), Sym)) + IF OpenSource(AssociateDefinition(PreprocessModule(FileName, FALSE), Sym)) THEN IF NOT P0SyntaxCheck.CompilationUnit() THEN @@ -280,15 +297,16 @@ BEGIN (* only need to read implementation module if hidden types are declared or it is the main module *) IF Main=Sym THEN - FileName := Dup(s) + FileName := Dup (PPSource) ELSE IF FindSourceModFile (SymName, FileName) THEN + FileName := PreprocessModule (FileName, FALSE) END END ; IF FileName#NIL THEN - IF OpenSource (AssociateModule (PreprocessModule (FileName), Sym)) + IF OpenSource (AssociateModule (Dup (FileName), Sym)) THEN IF NOT P0SyntaxCheck.CompilationUnit() THEN @@ -325,7 +343,7 @@ BEGIN IF FindSourceModFile (SymName, FileName) THEN qprintf2 (' Module %-20s : %s (linking)\n', SymName, FileName) ; - IF OpenSource (AssociateModule (PreprocessModule (FileName), Sym)) + IF OpenSource (AssociateModule (PreprocessModule (FileName, FALSE), Sym)) THEN PutModLink (Sym, TRUE) ; (* This source is only used to determine link time info. *) IF NOT P0SyntaxCheck.CompilationUnit () diff --git a/gcc/m2/gm2-compiler/M2Options.def b/gcc/m2/gm2-compiler/M2Options.def index e7b34cf..df42a4a 100644 --- a/gcc/m2/gm2-compiler/M2Options.def +++ b/gcc/m2/gm2-compiler/M2Options.def @@ -52,11 +52,12 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck, SetWholeValueCheck, GetWholeValueCheck, SetLowerCaseKeywords, SetIndex, SetRange, SetWholeDiv, SetStrictTypeChecking, - Setc, Getc, SetUselist, GetUselist, GetUselistFilename, - SetShared, SetB, + Setc, Getc, SetPPOnly, GetPPOnly, + SetUselist, GetUselist, GetUselistFilename, + SetShared, Iso, Pim, Pim2, Pim3, Pim4, - cflag, + PPonly, cflag, PositiveModFloorDiv, Pedantic, Verbose, Statistics, UnboundedByReference, VerboseUnbounded, @@ -83,7 +84,7 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck, DebugBuiltins, setdefextension, setmodextension, SetStatistics, SetWall, SetSaveTemps, SetSaveTempsDir, SaveTemps, GetSaveTempsDir, - GenModuleList, + SetDumpDir, GetDumpDir, GenModuleList, CppArg, CppCommandLine, CppRemember, SetDebugFunctionLineNumbers, DebugFunctionLineNumbers, SetGenerateStatementNote, GenerateStatementNote, @@ -92,10 +93,11 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck, SetScaffoldMain, ScaffoldMain, SetRuntimeModuleOverride, GetRuntimeModuleOverride, SetGenModuleList, GetGenModuleFilename, SharedFlag, - GetB ; + SetB, GetB, SetMD, GetMD, SetMMD, GetMMD, SetObj, GetObj ; VAR + PPonly, (* -E/M/MM present? - preprocessing only *) cflag, (* -c flag present? *) Iso, (* -fiso use ISO SYSTEM.def *) Pim, (* -fpim use PIM [234] SYSTEM.def *) @@ -174,6 +176,18 @@ VAR Coding, Profiling : BOOLEAN ; +(* + SetPPOnly - set the PPonly to value (on E, M, MM). +*) + +PROCEDURE SetPPOnly (value: BOOLEAN) ; + + +(* + GetPPOnly - get the PPonly (Preprocess only). +*) + +PROCEDURE GetPPOnly () : BOOLEAN ; (* Setc - set the cflag (compile only flag -c) to value. @@ -195,13 +209,64 @@ PROCEDURE Getc () : BOOLEAN ; PROCEDURE SetB (arg: ADDRESS) ; - (* GetB - returns argument to the -B option as a string or NIL if it were never set. *) PROCEDURE GetB () : ADDRESS ; +(* + SetMD - assigns MD file to arg. +*) + +PROCEDURE SetMD (arg: ADDRESS) ; + +(* + GetMD - returns the filename set for MD or NIL if it was never set. +*) + +PROCEDURE GetMD () : ADDRESS ; + + +(* + SetMMD - assigns MMD file to arg. +*) + +PROCEDURE SetMMD (arg: ADDRESS) ; + +(* + GetMMD - returns the filename set for MMD or NIL if it was never set. +*) + +PROCEDURE GetMMD () : ADDRESS ; + +(* + SetMQ - assigns MQ file to arg. +*) + +PROCEDURE SetMQ (arg: ADDRESS) ; + +(* + GetMQ - returns the filename set for MQ or NIL if it was never set. +*) + +PROCEDURE GetMQ () : ADDRESS ; + +(* + SetScaffoldDynamic - set the -fscaffold-dynamic flag. +*) + +(* + SetObj - assigns given object file to arg. +*) + +PROCEDURE SetObj (arg: ADDRESS) ; + +(* + GetObj - returns the filename set for Object or NIL if it was never set. +*) + +PROCEDURE GetObj () : ADDRESS ; (* SetScaffoldDynamic - set the -fscaffold-dynamic flag. @@ -784,6 +849,19 @@ PROCEDURE SetSaveTempsDir (arg: ADDRESS) ; PROCEDURE GetSaveTempsDir () : String ; +(* + SetDumpDir - Specify dump dir. +*) + +PROCEDURE SetDumpDir (arg: ADDRESS) ; + + +(* + GetDumpDir - return DumpDir or NIL. +*) + +PROCEDURE GetDumpDir () : String ; + (* SetGenModuleList - set the GenModuleList flag to value and pass diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod index 14e978a..865b857 100644 --- a/gcc/m2/gm2-compiler/M2Options.mod +++ b/gcc/m2/gm2-compiler/M2Options.mod @@ -54,7 +54,12 @@ CONST VAR Barg, + MDarg, + MMDarg, + MQarg, + CmdLineObj, SaveTempsDir, + DumpDir, GenModuleListFilename, UselistFilename, RuntimeModuleOverride, @@ -133,6 +138,94 @@ END GetB ; (* + SetMD - assigns MDarg to the filename from arg. + This overrides any previous MMD. +*) + +PROCEDURE SetMD (arg: ADDRESS) ; +BEGIN + MMDarg := KillString (MMDarg) ; + MDarg := KillString (MDarg) ; + MDarg := InitStringCharStar (arg) +END SetMD ; + + +(* + GetMD - returns MDarg filename as a c-string or NIL if it was never set. +*) + +PROCEDURE GetMD () : ADDRESS ; +BEGIN + RETURN string (MDarg) +END GetMD ; + + +(* + SetMMD - assigns MMDarg to the filename from arg. + This overrides any previous MD. +*) + +PROCEDURE SetMMD (arg: ADDRESS) ; +BEGIN + MDarg := KillString (MDarg) ; + MMDarg := KillString (MMDarg) ; + MMDarg := InitStringCharStar (arg) +END SetMMD ; + + +(* + GetMMD - returns MMDarg filename as a c-string or NIL if it was never set. +*) + +PROCEDURE GetMMD () : ADDRESS ; +BEGIN + RETURN string (MMDarg) +END GetMMD ; + + +(* + SetMQ - assigns MQarg to the filename from arg. +*) + +PROCEDURE SetMQ (arg: ADDRESS) ; +BEGIN + MQarg := KillString (MQarg) ; + MQarg := InitStringCharStar (arg) +END SetMQ ; + + +(* + GetMMD - returns MQarg filename as a c-string or NIL if it was never set. +*) + +PROCEDURE GetMQ () : ADDRESS ; +BEGIN + RETURN string (MQarg) +END GetMQ ; + + +(* + SetObj - assigns CmdLineObj to the filename from arg. +*) + +PROCEDURE SetObj (arg: ADDRESS) ; +BEGIN + CmdLineObj := KillString (CmdLineObj) ; + CmdLineObj := InitStringCharStar (arg) +END SetObj ; + + +(* + GetObj - returns CmdLineObj filename as a c-string or NIL if it was never set. +*) + +PROCEDURE GetObj () : ADDRESS ; +BEGIN + RETURN string (CmdLineObj) +END GetObj ; + + +(* CppCommandLine - returns the Cpp command line and all arguments. NIL is returned if the -fcpp is absent. *) @@ -365,6 +458,25 @@ END GetCpp ; (* + SetPPOnly - set the PPonly (preprocess only) to value. +*) + +PROCEDURE SetPPOnly (value: BOOLEAN) ; +BEGIN + PPonly := value +END SetPPOnly ; + +(* + GetPPOnly - get the PPonly (preprocess only). +*) + +PROCEDURE GetPPOnly () : BOOLEAN ; +BEGIN + RETURN PPonly +END GetPPOnly ; + + +(* Setc - set the cflag (compile only flag -c) to value. *) @@ -1050,7 +1162,8 @@ END SetSaveTemps ; PROCEDURE SetSaveTempsDir (arg: ADDRESS) ; BEGIN - SaveTempsDir := InitStringCharStar (arg) + SaveTempsDir := InitStringCharStar (arg) ; + SaveTemps := TRUE END SetSaveTempsDir ; @@ -1063,6 +1176,24 @@ BEGIN RETURN SaveTempsDir END GetSaveTempsDir ; +(* + SetDumpDir - Set the dump dir. +*) + +PROCEDURE SetDumpDir (arg: ADDRESS) ; +BEGIN + DumpDir := InitStringCharStar (arg) +END SetDumpDir ; + + +(* + GetDumpDir - return DumpDir or NIL. +*) + +PROCEDURE GetDumpDir () : String ; +BEGIN + RETURN DumpDir +END GetDumpDir ; (* SetScaffoldDynamic - set the -fscaffold-dynamic flag. @@ -1247,5 +1378,9 @@ BEGIN GenModuleListFilename := NIL ; SharedFlag := FALSE ; Barg := NIL ; - SaveTempsDir := NIL + MDarg := NIL ; + MMDarg := NIL ; + MQarg := NIL ; + SaveTempsDir := NIL ; + DumpDir := NIL END M2Options. diff --git a/gcc/m2/gm2-compiler/M2Preprocess.def b/gcc/m2/gm2-compiler/M2Preprocess.def index 08fe192..0258580 100644 --- a/gcc/m2/gm2-compiler/M2Preprocess.def +++ b/gcc/m2/gm2-compiler/M2Preprocess.def @@ -45,7 +45,7 @@ EXPORT QUALIFIED PreprocessModule ; All temporary files will be deleted when the compiler exits. *) -PROCEDURE PreprocessModule (filename: String) : String ; +PROCEDURE PreprocessModule (filename: String; isMain: BOOLEAN) : String ; END M2Preprocess. diff --git a/gcc/m2/gm2-compiler/M2Preprocess.mod b/gcc/m2/gm2-compiler/M2Preprocess.mod index eb08015..ebd9cb9 100644 --- a/gcc/m2/gm2-compiler/M2Preprocess.mod +++ b/gcc/m2/gm2-compiler/M2Preprocess.mod @@ -25,7 +25,7 @@ IMPLEMENTATION MODULE M2Preprocess ; FROM SYSTEM IMPORT WORD ; FROM DynamicStrings IMPORT string, InitString, Mark, KillString, EqualArray, InitStringCharStar, - Dup, ConCat, ConCatChar, RIndex, Slice ; + Dup, ConCat, ConCatChar, RIndex, Slice, Length ; FROM choosetemp IMPORT make_temp_file ; FROM pexecute IMPORT pexecute ; @@ -33,7 +33,8 @@ FROM libc IMPORT system, exit, unlink, printf, atexit ; FROM Lists IMPORT List, InitList, KillList, IncludeItemIntoList, ForeachItemInListDo ; FROM FIO IMPORT StdErr, StdOut ; FROM M2Printf IMPORT fprintf1 ; -FROM M2Options IMPORT Verbose, CppCommandLine, SaveTemps ; +FROM M2Options IMPORT Verbose, PPonly, GetObj, GetMD, GetMMD, GetMQ, + CppCommandLine, SaveTemps, GetSaveTempsDir, GetDumpDir ; FROM NameKey IMPORT Name, MakeKey, KeyToCharStar, makekey ; @@ -77,14 +78,80 @@ BEGIN RETURN 0 END RemoveFiles ; +(* + Return the filename with no path. +*) + +PROCEDURE GetFileName (Path: String) : String ; +VAR + fstart: INTEGER ; +BEGIN + fstart := RIndex(Path, '/', 0) ; + IF fstart=-1 + THEN + fstart := 0 + ELSE + fstart := fstart + 1 + END ; + RETURN Dup (Slice(Path, fstart, Length (Path))) +END GetFileName ; + + +(* + Return basename. +*) + +PROCEDURE BaseName (Path: String) : String ; +VAR + ext, + basename: INTEGER ; +BEGIN + basename := RIndex(Path, '/', 0) ; + IF basename=-1 + THEN + basename := 0 + ELSE + basename := basename + 1 + END ; + ext := RIndex(Path, '.', 0) ; + IF ext=-1 + THEN + ext := 0 + END ; + RETURN Dup (Slice(Path, basename, ext)) +END BaseName ; (* - MakeSaveTempsFileName - return a temporary file "filename.i". + MakeSaveTempsFileName - return a temporary file like + "./filename.{def,mod}.m2i" in the CWD unless SaveTempsDir = obj, + when we put it in the dumpdir if that is specified (or fallback to '.' + if not). + We have to keep the original extension because that disambiguates .def + and .mod files (otherwise, we'd need two 'preprocessed' extensions). *) PROCEDURE MakeSaveTempsFileName (filename: String) : String ; +VAR + NewName, + DumpDir, + NewDir: String ; BEGIN - RETURN ConCat (Dup (filename), InitString ('.i')) + NewName := ConCat (GetFileName (filename), InitString ('.m2i')) ; + NewDir := GetSaveTempsDir () ; + DumpDir := GetDumpDir () ; +(* IF Verbose + THEN + fprintf1 (StdOut, "newname: %s", NewName) ; + fprintf1 (StdOut, " NewDir: %s", NewDir) ; + fprintf1 (StdOut, " DumpDir: %s\n", DumpDir) + END ; +*) + IF (NewDir AND EqualArray (NewDir, 'obj')) AND DumpDir + THEN + RETURN Dup (ConCat (DumpDir, NewName)) + ELSE + RETURN Dup (ConCat (InitString ('./'), NewName)) + END ; END MakeSaveTempsFileName ; @@ -98,7 +165,7 @@ END MakeSaveTempsFileName ; All temporary files will be deleted when the compiler exits. *) -PROCEDURE PreprocessModule (filename: String) : String ; +PROCEDURE PreprocessModule (filename: String; isMain: BOOLEAN) : String ; VAR tempfile, command, @@ -107,18 +174,55 @@ BEGIN command := CppCommandLine () ; IF (command = NIL) OR EqualArray (command, '') THEN - RETURN filename + RETURN Dup (filename) ELSE - IF SaveTemps + commandLine := Dup (command) ; + tempfile := NIL ; + (* We support MD and MMD for the main file only, at present. *) + IF isMain OR PPonly + THEN + IF GetMD () + THEN + tempfile := ConCat( Mark (InitString(' -MD ')), + InitStringCharStar (GetMD ())) + ELSIF GetMMD () + THEN + tempfile := ConCat( Mark (InitString(' -MMD ')), + InitStringCharStar (GetMMD ())) + END ; + IF tempfile + THEN + commandLine := ConCat (Dup (commandLine), Dup (tempfile)) ; + (* We can only add MQ if we already have an MD/MMD. *) + IF GetMQ () + THEN + tempfile := ConCat( Mark (InitString(' -MQ ')), + InitStringCharStar (GetMQ ())) ; + commandLine := ConCat (Dup (commandLine), Dup (tempfile)) + END ; + END ; + END ; + (* The output file depends on whether we are in stand-alone PP mode, and + if an output file is specified. *) + tempfile := NIL ; + IF PPonly + THEN + IF GetObj() + THEN + tempfile := InitStringCharStar (GetObj ()) + END ; + ELSIF SaveTemps THEN - tempfile := InitStringCharStar (MakeSaveTempsFileName (filename)) + tempfile := MakeSaveTempsFileName (filename) ELSE - tempfile := InitStringCharStar (make_temp_file (KeyToCharStar (MakeKey('i')))) + tempfile := InitStringCharStar (make_temp_file (KeyToCharStar (MakeKey('.m2i')))) + END ; + commandLine := ConCat (ConCatChar (Dup (commandLine), ' '), filename) ; + IF tempfile + THEN + commandLine := ConCat (ConCat (Dup (commandLine), + Mark (InitString(' -o '))), tempfile) ; END ; - commandLine := Dup (command) ; - commandLine := ConCat (ConCat (ConCat (ConCatChar (Dup (commandLine), ' '), filename), - Mark (InitString(' -o '))), - tempfile) ; (* use pexecute in the future res := pexecute(string(Slice(commandLine, 0, Index(commandLine, ' ', 0))), etc etc ); *) diff --git a/gcc/m2/gm2-gcc/m2options.h b/gcc/m2/gm2-gcc/m2options.h index 9cccb37..92b4fd5 100644 --- a/gcc/m2/gm2-gcc/m2options.h +++ b/gcc/m2/gm2-gcc/m2options.h @@ -61,6 +61,8 @@ EXTERN int M2Options_GetWholeValueCheck (void); EXTERN void M2Options_Setc (int value); EXTERN int M2Options_Getc (void); +EXTERN void M2Options_SetPPOnly (int value); +EXTERN int M2Options_GetPPOnly (void); EXTERN void M2Options_SetUselist (int value, const char *filename); EXTERN void M2Options_SetAutoInit (int value); @@ -112,6 +114,7 @@ EXTERN void M2Options_SetStrictTypeChecking (int value); EXTERN void M2Options_SetWall (int value); EXTERN void M2Options_SetSaveTemps (int value); EXTERN void M2Options_SetSaveTempsDir (const char *arg); +EXTERN void M2Options_SetDumpDir (const char *arg); EXTERN int M2Options_GetSaveTemps (void); EXTERN void M2Options_SetScaffoldStatic (int value); EXTERN void M2Options_SetScaffoldDynamic (int value); @@ -121,6 +124,14 @@ EXTERN void M2Options_SetGenModuleList (int value, const char *filename); EXTERN void M2Options_SetShared (int value); EXTERN void M2Options_SetB (const char *arg); EXTERN char *M2Options_GetB (void); +EXTERN void M2Options_SetMD (const char *arg); +EXTERN char *M2Options_GetMD (void); +EXTERN void M2Options_SetMMD (const char *arg); +EXTERN char *M2Options_GetMMD (void); +EXTERN void M2Options_SetMQ (const char *arg); +EXTERN char *M2Options_GetMQ (void); +EXTERN void M2Options_SetObj (const char *arg); +EXTERN char *M2Options_GetObj (void); #undef EXTERN #endif /* m2options_h. */ diff --git a/gcc/m2/gm2-gcc/m2type.cc b/gcc/m2/gm2-gcc/m2type.cc index ad5064f..634fad8 100644 --- a/gcc/m2/gm2-gcc/m2type.cc +++ b/gcc/m2/gm2-gcc/m2type.cc @@ -36,6 +36,7 @@ along with GNU Modula-2; see the file COPYING3. If not see #include "m2tree.h" #include "m2treelib.h" #include "m2type.h" +#include "m2options.h" #undef USE_BOOLEAN static int broken_set_debugging_info = TRUE; @@ -1782,6 +1783,9 @@ m2type_InitBaseTypes (location_t location) m2_packed_boolean_type_node = build_nonstandard_integer_type (1, TRUE); + if (M2Options_GetPPOnly ()) + return; + m2builtins_init (location); m2except_InitExceptions (location); m2expr_init (location); diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc index 9870743..4d9cae2 100644 --- a/gcc/m2/gm2-lang.cc +++ b/gcc/m2/gm2-lang.cc @@ -107,6 +107,8 @@ struct GTY (()) language_function /* Language hooks. */ +static void gm2_langhook_parse_file (void); + bool gm2_langhook_init (void) { @@ -120,6 +122,13 @@ gm2_langhook_init (void) /* GNU Modula-2 uses exceptions. */ using_eh_for_cleanups (); + + if (M2Options_GetPPOnly ()) + { + /* preprocess the file here. */ + gm2_langhook_parse_file (); + return false; /* Finish now, no further compilation. */ + } return true; } @@ -128,7 +137,9 @@ gm2_langhook_init (void) static unsigned int gm2_langhook_option_lang_mask (void) { - return CL_ModulaX2; + /* We need to process some driver options and pass through some C + ones to build our preprocessing lines. */ + return CL_ModulaX2 | CL_C | CL_DRIVER; } /* Initialize the options structure. */ @@ -155,27 +166,146 @@ gm2_langhook_init_options_struct (struct gcc_options *opts) static vec<bool> filename_cpp; +/* Build the C preprocessor command line here, since we need to include + options that are not passed to the handle_option function. */ + void gm2_langhook_init_options (unsigned int decoded_options_count, struct cl_decoded_option *decoded_options) { unsigned int i; bool in_cpp_args = false; + bool building_cpp_command = false; for (i = 1; i < decoded_options_count; i++) { - switch (decoded_options[i].opt_index) - { - case OPT_fcpp_begin: - in_cpp_args = true; - break; - case OPT_fcpp_end: - in_cpp_args = false; - break; - case OPT_SPECIAL_input_file: - case OPT_SPECIAL_program_name: - filename_cpp.safe_push (in_cpp_args); - } + enum opt_code code = (enum opt_code)decoded_options[i].opt_index; + const struct cl_option *option = &cl_options[code]; + const char *opt = (const char *)option->opt_text; + const char *arg = decoded_options[i].arg; + HOST_WIDE_INT value = decoded_options[i].value; + switch (code) + { + case OPT_fcpp: + gcc_checking_assert (building_cpp_command); + break; + case OPT_fcpp_begin: + in_cpp_args = true; + building_cpp_command = true; + break; + case OPT_fcpp_end: + in_cpp_args = false; + break; + case OPT_SPECIAL_input_file: + filename_cpp.safe_push (in_cpp_args); + break; + + /* C and driver opts that are not passed to the preprocessor for + modula-2, but that we use internally for building preprocesor + command lines. */ + case OPT_B: + M2Options_SetB (arg); + break; + case OPT_c: + M2Options_Setc (value); + break; + case OPT_dumpdir: + if (building_cpp_command) + M2Options_SetDumpDir (arg); + break; + case OPT_save_temps: + if (building_cpp_command) + M2Options_SetSaveTemps (value); + break; + case OPT_save_temps_: + if (building_cpp_command) + /* Also sets SaveTemps. */ + M2Options_SetSaveTempsDir (arg); + break; + + case OPT_E: + if (!in_cpp_args) + { + M2Options_SetPPOnly (value); + building_cpp_command = true; + } + M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) + && !(option->flags & CL_SEPARATE)); + break; + case OPT_M: + case OPT_MM: + gcc_checking_assert (building_cpp_command); + M2Options_SetPPOnly (value); + /* This is a preprocessor command. */ + M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) + && !(option->flags & CL_SEPARATE)); + break; + + /* We can only use MQ when the command line is either PP-only, or + when there is a MD/MMD on it. */ + case OPT_MQ: + M2Options_SetMQ (arg); + break; + + case OPT_o: + M2Options_SetObj (arg); + break; + + /* C and driver options that we ignore for the preprocessor lines. */ + case OPT_fpch_deps: + case OPT_fpch_preprocess: + break; + + case OPT_fplugin_: + /* FIXME: We might need to handle this specially, since the modula-2 + plugin is not usable here, but others might be. + For now skip all plugins to avoid fails with the m2 one. */ + break; + + /* Preprocessor arguments with a following filename. */ + case OPT_MD: + case OPT_MMD: + /* Save the filename associated with the MD/MMD which will also + mark the option as used. FIXME: maybe we should diagnose a + missing filename here, rather than assert. */ + gcc_checking_assert (i+1 < decoded_options_count); + gcc_checking_assert (decoded_options[i+1].opt_index + == OPT_SPECIAL_input_file); + /* Pick up the following filename. */ + arg = decoded_options[i+1].arg; + if (code == OPT_MD) + M2Options_SetMD (arg); + else + M2Options_SetMMD (arg); + break; + + /* Options we act on and also pass to the preprocessor. */ + case OPT_O: + M2Options_SetOptimizing (value); + if (building_cpp_command) + M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) + && !(option->flags & CL_SEPARATE)); + break; + case OPT_v: + M2Options_SetVerbose (value); + /* FALLTHROUGH */ + default: + if (code >= N_OPTS) + { + // FIXME remove debug. + fprintf(stderr, "%s : %s\n", opt, (arg ? arg : "")); + break; + } + /* Do not pass Modula-2 args to the preprocessor, any that we care + about here should already have been handled above. */ + if (option->flags & CL_ModulaX2) + break; + /* Otherwise, add this to the CPP command line. */ + if (building_cpp_command) + M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) + && !(option->flags & CL_SEPARATE)); + break; + } } filename_cpp.safe_push (false); } @@ -197,28 +327,16 @@ gm2_langhook_handle_option ( { enum opt_code code = (enum opt_code)scode; + const struct cl_option *option = &cl_options[scode]; + const char *opt = (const char *)option->opt_text; /* ignore file names. */ if (code == N_OPTS) return 1; switch (code) { - case OPT_B: - M2Options_SetB (arg); - return 1; - case OPT_c: - M2Options_Setc (value); - return 1; case OPT_I: - if (insideCppArgs) - { - const struct cl_option *option = &cl_options[scode]; - const char *opt = (const char *)option->opt_text; - M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) - && !(option->flags & CL_SEPARATE)); - } - else - Ipaths.push_back (arg); + Ipaths.push_back (arg); return 1; case OPT_fiso: M2Options_SetISO (value); @@ -358,6 +476,9 @@ gm2_langhook_handle_option ( case OPT_fcpp: M2Options_SetCpp (value); return 1; + case OPT_fpreprocessed: + /* Provided for compatibility; ignore for now. */ + return 1; case OPT_fcpp_begin: insideCppArgs = TRUE; return 1; @@ -396,31 +517,25 @@ gm2_langhook_handle_option ( return 1; break; case OPT_iprefix: + iprefix = arg; + return 1; + break; case OPT_imultilib: + imultilib = arg; + return 1; + break; case OPT_isystem: + isystem.push_back (arg); + return 1; + break; case OPT_iquote: + iquote.push_back (arg); + return 1; + break; case OPT_isysroot: - if (insideCppArgs) - { - const struct cl_option *option = &cl_options[scode]; - const char *opt = (const char *)option->opt_text; - M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) - && !(option->flags & CL_SEPARATE)); - } - if (code == OPT_iprefix) - iprefix = arg; - else if (code == OPT_imultilib) - imultilib = arg; - else if (code == OPT_iquote) - iquote.push_back (arg); - else if (code == OPT_isystem) - isystem.push_back (arg); /* Otherwise, ignored, at least for now. */ return 1; break; - case OPT_O: - M2Options_SetOptimizing (value); - return 1; case OPT_quiet: M2Options_SetQuiet (value); return 1; @@ -445,24 +560,19 @@ gm2_langhook_handle_option ( } else return 0; - case OPT_save_temps: - M2Options_SetSaveTemps (value); - return 1; - case OPT_save_temps_: - M2Options_SetSaveTempsDir (arg); - return 1; - case OPT_v: - M2Options_SetVerbose (value); + case OPT_o: + /* Options we ignore, always. */ return 1; default: if (insideCppArgs) - { - const struct cl_option *option = &cl_options[scode]; - const char *opt = (const char *)option->opt_text; - M2Options_CppArg (opt, arg, (option->flags & CL_JOINED) - && !(option->flags & CL_SEPARATE)); - return 1; - } + /* Already handled. */ + return 1; + else if (option->flags & CL_DRIVER) + /* Ignore driver options we do not specifically use. */ + return 1; + else if (option->flags & CL_C) + /* Ignore C options we do not specifically use. */ + return 1; return 0; } return 0; @@ -574,7 +684,7 @@ gm2_langhook_post_options (const char **pfilename) add_m2_import_paths (flibs); /* Returning false means that the backend should be used. */ - return false; + return M2Options_GetPPOnly (); } /* Call the compiler for every source filename on the command line. */ @@ -597,7 +707,8 @@ static void gm2_langhook_parse_file (void) { gm2_parse_input_files (in_fnames, num_in_fnames); - write_globals (); + if (!M2Options_GetPPOnly ()) + write_globals (); } static tree diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc index c248d1b..bc93133 100644 --- a/gcc/m2/gm2spec.cc +++ b/gcc/m2/gm2spec.cc @@ -133,8 +133,10 @@ static const char *add_include (const char *libpath, const char *library); static bool seen_scaffold_static = false; static bool seen_scaffold_dynamic = false; -static bool scaffold_dynamic = true; // Default uses -fscaffold-dynamic. +static bool seen_scaffold_main = false; static bool scaffold_static = false; +static bool scaffold_dynamic = true; // Default uses -fscaffold-dynamic. +static bool scaffold_main = false; static bool seen_gen_module_list = false; static bool seen_uselist = false; static bool uselist = false; @@ -525,17 +527,20 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, scaffold_static = decoded_options[i].value; args[i] |= SKIPOPT; /* We will add the option if it is needed. */ break; + case OPT_fscaffold_main: + seen_scaffold_main = true; + scaffold_main = decoded_options[i].value; + args[i] |= SKIPOPT; /* We will add the option if it is needed. */ + break; case OPT_fgen_module_list_: seen_gen_module_list = true; gen_module_list = decoded_options[i].value; if (gen_module_list) gen_module_filename = decoded_options[i].arg; - args[i] |= SKIPOPT; /* We will add the option if it is needed. */ break; case OPT_fuse_list_: seen_uselist = true; uselist = decoded_options[i].value; - args[i] |= SKIPOPT; /* We will add the option if it is needed. */ break; case OPT_nostdlib: @@ -592,6 +597,14 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, library = -1; break; + /* PCH makes no sense here, we do not catch -output-pch on purpose, + that should flag an error. */ + case OPT_fpch_deps: + case OPT_fpch_preprocess: + case OPT_Winvalid_pch: + args[i] |= SKIPOPT; + break; + case OPT_static: static_link = 1; break; @@ -694,8 +707,10 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, We also add default scaffold linking options. */ /* If we have not seen either uselist or gen_module_list and we need - to link then we turn on -fgen_module_list=- as the default. */ - if ((! (seen_uselist || seen_gen_module_list)) && linking) + to link or compile a module list then we turn on -fgen_module_list=- + as the default. */ + if (!seen_uselist && !seen_gen_module_list + && (linking || scaffold_main)) append_option (OPT_fgen_module_list_, "-", 1); /* We checked that they were not both enabled above, if there was a set @@ -705,6 +720,14 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, if (seen_scaffold_static) append_option (OPT_fscaffold_static, NULL, scaffold_static); + /* If the user has set fscaffold-main specifically, use that. Otherwise, if + we are linking then set it so that we generate the relevant code for the + main module. */ + if (seen_scaffold_main) + append_option (OPT_fscaffold_main, NULL, scaffold_main); + else if (linking) + append_option (OPT_fscaffold_main, NULL, true); + if (allow_libraries) { /* If the libraries have not been specified by the user, select the diff --git a/gcc/m2/lang-specs.h b/gcc/m2/lang-specs.h index bf88264..6228c3c 100644 --- a/gcc/m2/lang-specs.h +++ b/gcc/m2/lang-specs.h @@ -21,19 +21,35 @@ along with GCC; see the file COPYING3. If not see /* This is the contribution to the `default_compilers' array in gcc.c for GNU Modula-2. */ -/* Pass the preprocessor options on the command line together with - the exec prefix. */ - +/* A spec for the 'integrated' preprocessor implementation for Modula-2. */ #define M2CPP \ - "%{fcpp:-fcpp-begin " \ - " -E -lang-asm -traditional-cpp " \ - " %(cpp_unique_options) -fcpp-end; \ - : %I } " + "%{E|M|MM|fcpp: %{E} -fcpp-begin " \ + " %{!E:-E} %(cpp_unique_options) -traditional-cpp -ansi " \ + " -fcpp-end %{B*} %{save-temps*} ; \ + : %{v} %I } " + +/* We have three modes: + 1. When the preprocessing step is explict and there is no following + compilation. Here we do a similar process to cc1 -E where most of + the compilation is short-circuited. + 2. When we are mimicking an integrated preprocessor. Here we use the + modula-2 'fcpp' to construct a command line for the preprocessor and + snarf save-temps and dumpdir inputs to try and be consistent. + 3. We can consume a pre-processed modula-2 source. */ {".mod", "@modula-2", 0, 0, 0}, {"@modula-2", - "cc1gm2 " M2CPP - " %(cc1_options) %{B*} %{c*} %{+e*} %{I*} " - " %{i*} %{save-temps*} %{v} " - " %i %{!fsyntax-only:%(invoke_as)}", - 0, 0, 0}, + /* For preprocessing we use cc1 but wrap it in cc1gm2. */ + "%{E|M|MM:\ + cc1gm2 " M2CPP " %{!fcpp:-fcpp;:%{fcpp}} %{I*} %i } \ + %{!E:%{!M:%{!MM:\ + cc1gm2 " M2CPP " %(cc1_options) %{I*} %i %{c} \ + %{MF*:%eto generate dependencies you must specify either '-M' or '-MM'} \ + %{!fsyntax-only:%(invoke_as)} \ + }}}", 0, 0, 0}, + {".m2i", "@modula-2-cpp-output", 0, 0, 0}, + {"@modula-2-cpp-output", + "%{!M:%{!MM:%{!E: \ + cc1gm2 %<fcpp %(cc1_options) %{v} %I -fmod=.mod.m2i -fdef=.def.m2i %{I*} \ + -fpreprocessed %i %{c} \ + %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0}, diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt index 7a19adc..43d6ba5 100644 --- a/gcc/m2/lang.opt +++ b/gcc/m2/lang.opt @@ -26,78 +26,6 @@ Language Modula-2 -B -Modula-2 -; Documented in c.opt - -D -Modula-2 -; Documented in c.opt - -E -Modula-2 -; Documented in c.opt (passed to the preprocessor if -fcpp is used) - -I -Modula-2 Joined Separate -; Documented in c.opt - -L -Modula-2 Joined Separate -; Not documented - -M -Modula-2 -; Documented in c.opt - -MD -Modula-2 -; Documented in c.opt - -MF -Modula-2 -; Documented in c.opt - -MG -Modula-2 -; Documented in c.opt - -MM -Modula-2 -; Documented in c.opt - -MMD -Modula-2 -; Documented in c.opt - -Mmodules -Modula-2 -; Documented in c.opt - -Mno-modules -Modula-2 -; Documented in c.opt - -MP -Modula-2 -; Documented in c.opt - -MQ -Modula-2 -; Documented in c.opt - -MT -Modula-2 -; Documented in c.opt - -P -Modula-2 -; Documented in c.opt - -O -Modula-2 -; Documented in c.opt - Wall Modula-2 ; Documented in c.opt @@ -274,6 +202,10 @@ fpositive-mod-floor-div Modula-2 force positive result from MOD and DIV result floor +fpreprocessed +Modula-2 +; Documented in c.opt + fpthread Modula-2 link against the pthread library (default on) @@ -350,53 +282,14 @@ fwholevalue Modula-2 turns on runtime checking to check whether a whole number is about to exceed range -iprefix -Modula-2 -; Documented in c.opt - -iquote -Modula-2 -; Documented in c.opt - -isystem -Modula-2 -; Documented in c.opt - -idirafter -Modula-2 -; Documented in c.opt - -imultilib -Modula-2 +;fworking-directory +;Modula-2 ; Documented in c.opt lang-asm Modula-2 ; Documented in c.opt --save-temps -Modula-2 Alias(save-temps) - -save-temps -Modula-2 -save temporary preprocessed files - -save-temps= -Modula-2 Joined -save temporary preprocessed files - -traditional-cpp -Modula-2 -; Documented in c.opt - -v -Modula-2 -; Documented in c.opt - -x -Modula-2 Joined -specify the language from the compiler driver - static-libgm2 Driver Link the standard Modula-2 libraries statically in the compilation. |