@@ -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",
@@ -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 ()
@@ -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
@@ -54,7 +54,12 @@ CONST
VAR
Barg,
+ MDarg,
+ MMDarg,
+ MQarg,
+ CmdLineObj,
SaveTempsDir,
+ DumpDir,
GenModuleListFilename,
UselistFilename,
RuntimeModuleOverride,
@@ -132,6 +137,94 @@ BEGIN
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.
@@ -364,6 +457,25 @@ BEGIN
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.
@@ -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.
@@ -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 );
*)
@@ -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. */
@@ -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);
@@ -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
@@ -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
@@ -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},
@@ -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.