diff mbox

[1/2] PR debug/38757 gcc does not emit DW_LANG_C99.

Message ID 1416574915.5073.5.camel@bordewijk.wildebeest.org
State New
Headers show

Commit Message

Mark Wielaard Nov. 21, 2014, 1:01 p.m. UTC
On Fri, 2014-11-21 at 12:48 +0100, Richard Biener wrote:
> On Fri, Nov 21, 2014 at 8:56 AM, Jakub Jelinek <jakub@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.

Comments

Jakub Jelinek Nov. 21, 2014, 1:05 p.m. UTC | #1
On Fri, Nov 21, 2014 at 02:01:55PM +0100, Mark Wielaard wrote:
>     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.

Ok, thanks.

	Jakub
diff mbox

Patch

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;