On Fri, 2014-11-21 at 12:48 +0100, Richard Biener wrote: > On Fri, Nov 21, 2014 at 8:56 AM, Jakub Jelinek <ja...@redhat.com> wrote: > > On Thu, Nov 20, 2014 at 11:30:11PM +0100, Mark Wielaard wrote: > >> --- a/gcc/config/avr/avr-c.c > >> +++ b/gcc/config/avr/avr-c.c > >> @@ -386,7 +386,8 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) > >> (as mentioned in ISO/IEC DTR 18037; Annex F.2) which is not > >> implemented in GCC up to now. */ > >> > >> - if (!strcmp (lang_hooks.name, "GNU C")) > >> + if (strncmp (lang_hooks.name, "GNU C", 5) == 0 > >> + && strncmp (lang_hooks.name, "GNU C++", 7) != 0) > > > > I wonder if the tests for C language shouldn't be better done > > as (strncmp (lang_hooks.name, "GNU C", 5) == 0 > > && strchr ("0123456789", lang_hooks.name[5]) != NULL) > > or (strncmp (lang_hooks.name, "GNU C", 5) == 0 > > && (ISDIGIT (lang_hooks.name[5]) || lang_hooks.name[5] == '\0')) > > to make it explicit what we are looking for, not what we aren't. > > Or even make that a helper function in langhooks.[ch] > > lang_GNU_C (), lang_GNU_CXX ()
Nice idea. I added those. It also fixes the formatting issues and makes the diff smaller. > >> --- a/gcc/langhooks.h > >> +++ b/gcc/langhooks.h > >> @@ -261,7 +261,8 @@ struct lang_hooks_for_lto > >> > >> struct lang_hooks > >> { > >> - /* String identifying the front end. e.g. "GNU C++". */ > >> + /* String identifying the front end. e.g. "GNU C++". > >> + Might include language version being used. */ > > > > As we no longer have GNU C++ as any name, using it as an example > > is weird. So, > > /* String identifying the front end and optionally language standard > > version, e.g. "GNU C++98" or "GNU Java". */ > > ? Used Jakub's example text. OK to push? Thanks, Mark PR debug/38757 gcc does not emit DW_LANG_C99. For C and C++ add the language standard version in use to lang_hooks.name. Change users of lang_hook.name to check with new functions lang_GNU_C or lang_GNU_CXX. In dwarf2out.c output the DW_LANG_C version from the lang_hooks.name and merge any LTO TRANSLATION_UNIT_LANGUAGE found. Adds two testcases to dwarf2.exp to check the right DWARF DW_AT_language is set on the compile_unit depending on the -std=c89 or -std=c99 setting. gcc/c-family/ChangeLog PR debug/38757 * c-opts.c (set_std_c89): Set lang_hooks.name. (set_std_c99): Likewise. (set_std_c11): Likewise. (set_std_cxx98): Likewise. (set_std_cxx11): Likewise. (set_std_cxx14): Likewise. (set_std_cxx1z): Likewise. gcc/ChangeLog PR debug/38757 * config/avr/avr-c.c (avr_cpu_cpp_builtins): Use lang_GNU_C. * config/darwin.c (darwin_file_end): Use lang_GNU_CXX. (darwin_override_options): Likewise. * config/ia64/ia64.c (ia64_struct_retval_addr_is_first_parm_p): Likewise. * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Likewise. * dbxout.c (get_lang_number): Likewise. (dbxout_type): Likewise. (dbxout_symbol_location): Likewise. * dwarf2out.c (add_prototyped_attribute): Add DW_AT_prototype also for DW_LANG_{C,C99,ObjC}. (highest_c_language): New function. (gen_compile_unit_die): Call highest_c_language to merge LTO TRANSLATION_UNIT_LANGUAGE. Use strncmp language_string to determine if DW_LANG_C99 or DW_LANG_C89 should be returned. * fold-const.c (fold_cond_expr_with_comparison): Use lang_GNU_CXX. * langhooks.h (struct lang_hooks): Add version comment to name. (lang_GNU_C): New function declaration. (lang_GNU_CXX): Likewise. * langhooks.c (lang_GNU_C): New function. (lang_GNU_CXX): Likewise. * vmsdbgout.c (vmsdbgout_init): Use lang_GNU_C and lang_GNU_CXX. gcc/testsuite/ChangeLog PR debug/38757 * gcc.dg/debug/dwarf2/lang-c89.c: New test. * gcc.dg/debug/dwarf2/lang-c99.c: Likewise. diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 000fdd2..08a36f0 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -1450,6 +1450,7 @@ set_std_c89 (int c94, int iso) flag_isoc94 = c94; flag_isoc99 = 0; flag_isoc11 = 0; + lang_hooks.name = "GNU C89"; } /* Set the C 99 standard (without GNU extensions if ISO). */ @@ -1463,6 +1464,7 @@ set_std_c99 (int iso) flag_isoc11 = 0; flag_isoc99 = 1; flag_isoc94 = 1; + lang_hooks.name = "GNU C99"; } /* Set the C 11 standard (without GNU extensions if ISO). */ @@ -1476,6 +1478,7 @@ set_std_c11 (int iso) flag_isoc11 = 1; flag_isoc99 = 1; flag_isoc94 = 1; + lang_hooks.name = "GNU C11"; } /* Set the C++ 98 standard (without GNU extensions if ISO). */ @@ -1487,6 +1490,7 @@ set_std_cxx98 (int iso) flag_no_nonansi_builtin = iso; flag_iso = iso; cxx_dialect = cxx98; + lang_hooks.name = "GNU C++98"; } /* Set the C++ 2011 standard (without GNU extensions if ISO). */ @@ -1501,6 +1505,7 @@ set_std_cxx11 (int iso) flag_isoc94 = 1; flag_isoc99 = 1; cxx_dialect = cxx11; + lang_hooks.name = "GNU C++11"; } /* Set the C++ 2014 draft standard (without GNU extensions if ISO). */ @@ -1515,6 +1520,7 @@ set_std_cxx14 (int iso) flag_isoc94 = 1; flag_isoc99 = 1; cxx_dialect = cxx14; + lang_hooks.name = "GNU C++14"; } /* Set the C++ 201z draft standard (without GNU extensions if ISO). */ @@ -1530,6 +1536,7 @@ set_std_cxx1z (int iso) flag_isoc99 = 1; flag_isoc11 = 1; cxx_dialect = cxx1z; + lang_hooks.name = "GNU C++14"; /* Pretend C++14 till standarization. */ } /* Args to -d specify what to dump. Silently ignore diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c index 13ece98..324afb3 100644 --- a/gcc/config/avr/avr-c.c +++ b/gcc/config/avr/avr-c.c @@ -386,7 +386,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) (as mentioned in ISO/IEC DTR 18037; Annex F.2) which is not implemented in GCC up to now. */ - if (!strcmp (lang_hooks.name, "GNU C")) + if (lang_GNU_C ()) { for (i = 0; i < ADDR_SPACE_COUNT; i++) if (!ADDR_SPACE_GENERIC_P (i) diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index a201a74..1785e85 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -2909,7 +2909,7 @@ darwin_file_end (void) } machopic_finish (asm_out_file); - if (strcmp (lang_hooks.name, "GNU C++") == 0) + if (lang_GNU_CXX ()) { switch_to_section (darwin_sections[constructor_section]); switch_to_section (darwin_sections[destructor_section]); @@ -3162,7 +3162,7 @@ darwin_override_options (void) if (flag_mkernel || flag_apple_kext) { /* -mkernel implies -fapple-kext for C++ */ - if (strcmp (lang_hooks.name, "GNU C++") == 0) + if (lang_GNU_CXX ()) flag_apple_kext = 1; flag_no_common = 1; diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index f896e10..021b56e 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -10753,7 +10753,7 @@ ia64_struct_retval_addr_is_first_parm_p (tree fntype) && ret_type && TYPE_MODE (ret_type) == BLKmode && TREE_ADDRESSABLE (ret_type) - && strcmp (lang_hooks.name, "GNU C++") == 0); + && lang_GNU_CXX ()); } /* Output the assembler code for a thunk function. THUNK_DECL is the diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 336dd43..01e24c3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -25175,7 +25175,7 @@ rs6000_output_function_epilogue (FILE *file, Java is 13. Objective-C is 14. Objective-C++ isn't assigned a number, so for now use 9. LTO and Go aren't assigned numbers either, so for now use 0. */ - if (! strcmp (language_string, "GNU C") + if (lang_GNU_C () || ! strcmp (language_string, "GNU GIMPLE") || ! strcmp (language_string, "GNU Go")) i = 0; @@ -25186,7 +25186,7 @@ rs6000_output_function_epilogue (FILE *file, i = 2; else if (! strcmp (language_string, "GNU Ada")) i = 3; - else if (! strcmp (language_string, "GNU C++") + else if (lang_GNU_CXX () || ! strcmp (language_string, "GNU Objective-C++")) i = 9; else if (! strcmp (language_string, "GNU Java")) diff --git a/gcc/dbxout.c b/gcc/dbxout.c index aa15a39..1f04f72 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -946,10 +946,9 @@ static unsigned int ATTRIBUTE_UNUSED get_lang_number (void) { const char *language_string = lang_hooks.name; - - if (strcmp (language_string, "GNU C") == 0) + if (lang_GNU_C ()) return N_SO_C; - else if (strcmp (language_string, "GNU C++") == 0) + else if (lang_GNU_CXX ()) return N_SO_CC; else if (strcmp (language_string, "GNU F77") == 0) return N_SO_FORTRAN; @@ -2167,7 +2166,7 @@ dbxout_type (tree type, int full) access == access_protected_node ? '1' :'0'); if (BINFO_VIRTUAL_P (child) - && (strcmp (lang_hooks.name, "GNU C++") == 0 + && (lang_GNU_CXX () || strcmp (lang_hooks.name, "GNU Objective-C++") == 0)) /* For a virtual base, print the (negative) offset within the vtable where we must look @@ -3028,7 +3027,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home) we rely on the fact that error_mark_node initializers always end up in bss for C++ and never end up in bss for C. */ if (DECL_INITIAL (decl) == 0 - || (!strcmp (lang_hooks.name, "GNU C++") + || (lang_GNU_CXX () && DECL_INITIAL (decl) == error_mark_node)) { int offs; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b16883f..2fac09b 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -16741,9 +16741,18 @@ add_bit_size_attribute (dw_die_ref die, tree decl) static inline void add_prototyped_attribute (dw_die_ref die, tree func_type) { - if (get_AT_unsigned (comp_unit_die (), DW_AT_language) == DW_LANG_C89 - && prototype_p (func_type)) - add_AT_flag (die, DW_AT_prototyped, 1); + switch (get_AT_unsigned (comp_unit_die (), DW_AT_language)) + { + case DW_LANG_C: + case DW_LANG_C89: + case DW_LANG_C99: + case DW_LANG_ObjC: + if (prototype_p (func_type)) + add_AT_flag (die, DW_AT_prototyped, 1); + break; + default: + break; + } } /* Add an 'abstract_origin' attribute below a given DIE. The DIE is found @@ -19503,6 +19512,30 @@ gen_producer_string (void) return producer; } +/* Given a C and/or C++ language/version string return the "highest". + C++ is assumed to be "higher" than C in this case. Used for merging + LTO translation unit languages. */ +static const char * +highest_c_language (const char *lang1, const char *lang2) +{ + if (strcmp ("GNU C++14", lang1) == 0 || strcmp ("GNU C++14", lang2) == 0) + return "GNU C++14"; + if (strcmp ("GNU C++11", lang1) == 0 || strcmp ("GNU C++11", lang2) == 0) + return "GNU C++11"; + if (strcmp ("GNU C++98", lang1) == 0 || strcmp ("GNU C++98", lang2) == 0) + return "GNU C++98"; + + if (strcmp ("GNU C11", lang1) == 0 || strcmp ("GNU C11", lang2) == 0) + return "GNU C11"; + if (strcmp ("GNU C99", lang1) == 0 || strcmp ("GNU C99", lang2) == 0) + return "GNU C99"; + if (strcmp ("GNU C89", lang1) == 0 || strcmp ("GNU C89", lang2) == 0) + return "GNU C89"; + + gcc_unreachable (); +} + + /* Generate the DIE for the compilation unit. */ static dw_die_ref @@ -19543,7 +19576,8 @@ gen_compile_unit_die (const char *filename) else if (strncmp (common_lang, "GNU C", 5) == 0 && strncmp (TRANSLATION_UNIT_LANGUAGE (t), "GNU C", 5) == 0) /* Mixing C and C++ is ok, use C++ in that case. */ - common_lang = "GNU C++"; + common_lang = highest_c_language (common_lang, + TRANSLATION_UNIT_LANGUAGE (t)); else { /* Fall back to C. */ @@ -19556,8 +19590,16 @@ gen_compile_unit_die (const char *filename) language_string = common_lang; } - language = DW_LANG_C89; - if (strcmp (language_string, "GNU C++") == 0) + language = DW_LANG_C; + if (strncmp (language_string, "GNU C", 5) == 0 + && (language_string[5] == 0 || ISDIGIT (language_string[5]))) + { + language = DW_LANG_C89; + if (dwarf_version >= 3 || !dwarf_strict) + if (strcmp (language_string, "GNU C99") == 0) + language = DW_LANG_C99; + } + else if (strncmp (language_string, "GNU C++", 7) == 0) language = DW_LANG_C_plus_plus; else if (strcmp (language_string, "GNU F77") == 0) language = DW_LANG_Fortran77; diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4321b1e..58f6c7a 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4727,7 +4727,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, as an lvalue in the C++ front-end. PR c++/19199. */ && (in_gimple_form || VECTOR_TYPE_P (type) - || (strcmp (lang_hooks.name, "GNU C++") != 0 + || (! lang_GNU_CXX () && strcmp (lang_hooks.name, "GNU Objective-C++") != 0) || ! maybe_lvalue_p (arg1) || ! maybe_lvalue_p (arg2))) diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 2461fc5..e24dabb 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -709,3 +709,20 @@ lhd_enum_underlying_base_type (const_tree enum_type) return lang_hooks.types.type_for_size (TYPE_PRECISION (enum_type), TYPE_UNSIGNED (enum_type)); } + +/* Returns true if the current lang_hooks represents the GNU C frontend. */ + +bool +lang_GNU_C (void) +{ + return (strncmp (lang_hooks.name, "GNU C", 5) == 0 + && (lang_hooks.name[5] == '\0' || ISDIGIT (lang_hooks.name[5]))); +} + +/* Returns true if the current lang_hooks represents the GNU C++ frontend. */ + +bool +lang_GNU_CXX (void) +{ + return strncmp (lang_hooks.name, "GNU C++", 7) == 0; +} diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 84449bf..6ab8b0f 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -261,7 +261,8 @@ struct lang_hooks_for_lto struct lang_hooks { - /* String identifying the front end. e.g. "GNU C++". */ + /* String identifying the front end and optionally language standard + version, e.g. "GNU C++98" or "GNU Java". */ const char *name; /* sizeof (struct lang_identifier), so make_node () creates @@ -503,5 +504,10 @@ extern tree add_builtin_function_ext_scope (const char *name, tree type, const char *library_name, tree attrs); extern tree add_builtin_type (const char *name, tree type); + +/* Language helper functions. */ + +extern bool lang_GNU_C (void); +extern bool lang_GNU_CXX (void); #endif /* GCC_LANG_HOOKS_H */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c new file mode 100644 index 0000000..6292cf8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O -std=c89 -g -dA" } */ +/* DW_LANG_C89 = 0x0001 */ +/* { dg-final { scan-assembler "0x1.*DW_AT_language" } } */ + +int version; diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c new file mode 100644 index 0000000..d09d316 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c @@ -0,0 +1,6 @@ +// { dg-do compile } +// { dg-options "-O -std=c99 -gdwarf-3 -dA" } +// DW_LANG_C99 = 0x000c +// { dg-final { scan-assembler "0xc.*DW_AT_language" } } */ + +int version; diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c index f2734ca..6cf33e4 100644 --- a/gcc/vmsdbgout.c +++ b/gcc/vmsdbgout.c @@ -1460,9 +1460,9 @@ vmsdbgout_init (const char *filename) lookup_filename (primary_filename); - if (!strcmp (language_string, "GNU C")) + if (lang_GNU_C ()) module_language = DST_K_C; - else if (!strcmp (language_string, "GNU C++")) + else if (lang_GNU_CXX ()) module_language = DST_K_CXX; else if (!strcmp (language_string, "GNU Ada")) module_language = DST_K_ADA;