Provide a way for spec fragments to detect which language specific driver is in use. This allows for language-specific functionality to be included during linking, like unwind constructors for C++ exception handling.
Signed-off-by: Keith Packard <[email protected]> --- gcc/algol68/a68spec.cc | 3 +++ gcc/c-family/cppspec.cc | 3 +++ gcc/c/gccspec.cc | 3 +++ gcc/cobol/gcobolspec.cc | 3 +++ gcc/cp/g++spec.cc | 3 +++ gcc/d/d-spec.cc | 2 ++ gcc/doc/invoke.texi | 17 +++++++++++++++++ gcc/fortran/gfortranspec.cc | 3 +++ gcc/gcc.cc | 28 ++++++++++++++++++++++++++++ gcc/gcc.h | 3 +++ gcc/go/gospec.cc | 3 +++ gcc/jit/jit-spec.cc | 3 +++ gcc/m2/gm2spec.cc | 3 +++ gcc/rust/rustspec.cc | 3 +++ 14 files changed, 80 insertions(+) diff --git a/gcc/algol68/a68spec.cc b/gcc/algol68/a68spec.cc index bc11abde76e..6c9dbf05a9e 100644 --- a/gcc/algol68/a68spec.cc +++ b/gcc/algol68/a68spec.cc @@ -220,3 +220,6 @@ lang_specific_pre_link (void) /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for Algol68. */ + +/* Language target for this driver */ +const char *lang_specific_language = "algol68"; diff --git a/gcc/c-family/cppspec.cc b/gcc/c-family/cppspec.cc index bee629f33df..c1f436a0bdd 100644 --- a/gcc/c-family/cppspec.cc +++ b/gcc/c-family/cppspec.cc @@ -198,3 +198,6 @@ int lang_specific_pre_link (void) /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for cpp. */ + +/* Language target for this driver */ +const char *lang_specific_language = NULL; diff --git a/gcc/c/gccspec.cc b/gcc/c/gccspec.cc index af438f26f21..b47a5abd28d 100644 --- a/gcc/c/gccspec.cc +++ b/gcc/c/gccspec.cc @@ -105,3 +105,6 @@ lang_specific_pre_link (void) /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for C. */ + +/* Language target for this driver */ +const char *lang_specific_language = "c"; diff --git a/gcc/cobol/gcobolspec.cc b/gcc/cobol/gcobolspec.cc index 500d55dc6b1..672081a6a65 100644 --- a/gcc/cobol/gcobolspec.cc +++ b/gcc/cobol/gcobolspec.cc @@ -569,3 +569,6 @@ lang_specific_pre_link (void) return 0; } + +/* Language target for this driver */ +const char *lang_specific_language = "cobol"; diff --git a/gcc/cp/g++spec.cc b/gcc/cp/g++spec.cc index ab6482d4f5d..7ddaacdf396 100644 --- a/gcc/cp/g++spec.cc +++ b/gcc/cp/g++spec.cc @@ -495,3 +495,6 @@ int lang_specific_pre_link (void) /* Not used for C++. */ /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for C++. */ + +/* Language target for this driver */ +const char *lang_specific_language = "c++"; diff --git a/gcc/d/d-spec.cc b/gcc/d/d-spec.cc index 442bc1d8820..f88d1b84ea5 100644 --- a/gcc/d/d-spec.cc +++ b/gcc/d/d-spec.cc @@ -529,3 +529,5 @@ lang_specific_pre_link (void) int lang_specific_extra_outfiles = 0; /* Not used for D. */ +/* Language target for this driver */ +const char *lang_specific_language = "d"; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 87c0470c3db..09ab6270c2b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -39566,6 +39566,23 @@ intended to be passed to the LTO linker plugin. The @code{print-asm-header} function takes no arguments and simply prints a banner like: +@item @code{if-driverlang} +The @code{if-driverlang} spec function takes at least two arguments +and an optional third one. The first argument is a language name as is +used with @option{-x}. That is compared with the target language of +the Compilation Driver, for example the target language for @file{gcc} +is @samp{c} and the target language for @file{g++} is @samp{c++}. If +they match, the function returns the second argument. If they do not +match, the function returns the third argument if there is one, or +NULL otherwise. This can be used to select general options or linker +parameters based upon which Compilation Driver was invoked. Here is a +small example of its usage: + +@smallexample +*startfile: +crt0%O%s %:if-driverlang(c++ crtbegin%O%s) +@end smallexample + @smallexample Assembler options ================= diff --git a/gcc/fortran/gfortranspec.cc b/gcc/fortran/gfortranspec.cc index d0df0ee6171..bc206bb58a0 100644 --- a/gcc/fortran/gfortranspec.cc +++ b/gcc/fortran/gfortranspec.cc @@ -448,3 +448,6 @@ lang_specific_pre_link (void) /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for F77. */ + +/* Language target for this driver */ +const char *lang_specific_language = "f77"; diff --git a/gcc/gcc.cc b/gcc/gcc.cc index 6b6f6f87c52..bc5c90880d5 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -463,6 +463,7 @@ static const char *debug_level_greater_than_spec_func (int, const char **); static const char *dwarf_version_greater_than_spec_func (int, const char **); static const char *find_fortran_preinclude_file (int, const char **); static const char *join_spec_func (int, const char **); +static const char *if_driverlang_spec_function (int, const char **); static char *convert_white_space (char *); static char *quote_spec (char *); static char *quote_spec_arg (char *); @@ -1825,6 +1826,7 @@ static const struct spec_function static_spec_functions[] = { "dwarf-version-gt", dwarf_version_greater_than_spec_func }, { "fortran-preinclude-file", find_fortran_preinclude_file}, { "join", join_spec_func}, + { "if-driverlang", if_driverlang_spec_function }, #ifdef EXTRA_SPEC_FUNCTIONS EXTRA_SPEC_FUNCTIONS #endif @@ -11252,6 +11254,32 @@ join_spec_func (int argc, const char **argv) return XOBFINISH (&obstack, const char *); } +/* if-driverlang built-in spec function. + + Checks to see if the language-specific driver has specified a + language name that matches the first arg. Returns the second arg if + so, otherwise returns the third arg if it is present. */ + +static const char * +if_driverlang_spec_function (int argc, const char **argv) +{ + const char *language; + + /* Must have two or three arguments. */ + if (argc != 2 && argc != 3) + return NULL; + + language = lang_specific_language; + + if (language && !strcmp (argv[0], language)) + return argv[1]; + + if (argc == 3) + return argv[2]; + + return NULL; +} + /* If any character in ORIG fits QUOTE_P (_, P), reallocate the string so as to precede every one of them with a backslash. Return the original string or the reallocated one. */ diff --git a/gcc/gcc.h b/gcc/gcc.h index d2884314310..e5d9428e564 100644 --- a/gcc/gcc.h +++ b/gcc/gcc.h @@ -88,6 +88,9 @@ extern int n_infiles; /* Number of extra output files that lang_specific_pre_link may generate. */ extern int lang_specific_extra_outfiles; +/* The target language of the current driver, NULL if none */ +extern const char *lang_specific_language; + /* A vector of corresponding output files is made up later. */ extern const char **outfiles; diff --git a/gcc/go/gospec.cc b/gcc/go/gospec.cc index 6e7d05197e8..0e5ec8e3b7f 100644 --- a/gcc/go/gospec.cc +++ b/gcc/go/gospec.cc @@ -463,3 +463,6 @@ int lang_specific_pre_link (void) /* Not used for Go. */ /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for Go. */ + +/* Language target for this driver */ +const char *lang_specific_language = "go"; diff --git a/gcc/jit/jit-spec.cc b/gcc/jit/jit-spec.cc index 004195b8b74..e04e800d04d 100644 --- a/gcc/jit/jit-spec.cc +++ b/gcc/jit/jit-spec.cc @@ -39,3 +39,6 @@ lang_specific_pre_link (void) /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for jit. */ + +/* Language target for this driver */ +const char *lang_specific_language = NULL; diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc index 755c60b1c88..e54c5e24158 100644 --- a/gcc/m2/gm2spec.cc +++ b/gcc/m2/gm2spec.cc @@ -966,3 +966,6 @@ lang_specific_pre_link (void) /* Not used for M2. */ /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; + +/* Language target for this driver */ +const char *lang_specific_language = "modula-2"; diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc index 509e2990df3..a18a82d7700 100644 --- a/gcc/rust/rustspec.cc +++ b/gcc/rust/rustspec.cc @@ -189,3 +189,6 @@ lang_specific_pre_link (void) /* Not used for Rust. */ /* Number of extra output files that lang_specific_pre_link may generate. */ int lang_specific_extra_outfiles = 0; /* Not used for Rust. */ + +/* Language target for this driver */ +const char *lang_specific_language = "rust"; -- 2.51.0
