On Fri, Nov 21, 2014 at 09:28:45AM +0100, Jakub Jelinek wrote:
> I think best would be to tweak
>       if (value < 2 || value > 4)
>         error_at (loc, "dwarf version %d is not supported", value);
>       else
>         opts->x_dwarf_version = value;
> so that we accept value 5 too, and for now, until the
> most common consumers are changed, use
>   if (dwarf_version >= 5 /* || !dwarf_strict */)
> so that
> - you can actually use it in the test with -gdwarf-5
> - you can commit it right away
> - people can start playing with what it will mean to support DWARF5
> 
> GCC 4.5 also allowed -gdwarf-4 even when DWARF4 has not been released yet.
> When there are consumers that can grok it, we can uncomment the
> || !dwarf_strict.

That makes sense and would be convenient for me.

I made the change in opts.c and added some minimal documentation.
And made sure we only emit the new DWARFv5 language values, but not yet
anything else (the table header format has changed for debug_info and
debug_line in v5, but we don't emit new style headers yet). The testcases
were updated to explicitly add -gdwarf-5.

> >    else if (strncmp (language_string, "GNU C", 5) == 0)
> >      {
> >        language = DW_LANG_C89;
> >        if (dwarf_version >= 3 || !dwarf_strict)
> > -   if (strcmp (language_string, "GNU C99") == 0)
> > -     language = DW_LANG_C99;
> > +   {
> > +     if (strcmp (language_string, "GNU C89") != 0)
> > +       language = DW_LANG_C99;
> > +
> > +     if (dwarf_version >= 5 || !dwarf_strict)
> > +       if (strcmp (language_string, "GNU C11") == 0)
> > +         language = DW_LANG_C11;
> > +   }
> 
> Shouldn't we emit at least DW_LANG_C99 for GNU C11 if
> not dwarf_version >= 5 /* || !dwarf_strict */ but
> dwarf_version >= 3 || !dwarf_strict is true?

Yes, that is the intention. If it is a versioned GNU C then it is
at least DW_LANG_C89, if we have -gdwarf-3 or higher and it isn't
GNU C89 then it is at least DW_LANG_C99 and if we have -gdwarf-5
and it is GNU C11 then we emit DW_LANG_C11.

I added an explicit testcase for this.

> BTW, noticed we don't have anything for Fortran 2003 and 2008,
> filed a DWARF Issue for that.

Thanks. I have only focussed on C and C++ because I don't know anything
about version changes in other language standards.

With the above change everything keeps working fine. You only need a
patched GDB when explicitly using -gdwarf-5.

OK to commit?

Thanks,

Mark
    PR debug/38757 continued. Handle C11, C++11 and C++14.
    
    Add experimental (minimal) DWARFv5 support.
    
    This change depends on the new DWARFv5 constants mentioned in the
    following draft: http://dwarfstd.org/doc/dwarf5.20141029.pdf
    
    gcc/ChangeLog
    
        * doc/invoke.texi (-gdwarf-@{version}): Mention experimental DWARFv5.
        * opts.c (common_handle_option): Accept -gdwarf-5.
        * dwarf2out.c (is_cxx): Add DW_LANG_C_plus_plus_11 and
        DW_LANG_C_plus_plus_14.
        (lower_bound_default): Likewise. Plus DW_LANG_C11.
        (gen_compile_unit_die): Output DW_LANG_C_plus_plus_11,
        DW_LANG_C_plus_plus_14 or DW_LANG_C11.
        (output_compilation_unit_header): Output at most a DWARFv4 header.
        (output_skeleton_debug_sections): Likewise.
        (output_line_info): Likewise.
        (output_aranges): Document header version number.
    
    gcc/testsuite/ChangeLog
    
        * gcc.dg/debug/dwarf2/lang-c11.c: New test.
        * gcc.dg/debug/dwarf2/lang-c11-d4-strict.c: Likewise.
        * g++.dg/debug/dwarf2/lang-cpp11.C: Likewise.
        * g++.dg/debug/dwarf2/lang-cpp14.C: Likewise.
        * g++.dg/debug/dwarf2/lang-cpp98.C: Likewise.
    
    include/ChangeLog
    
        * dwarf2.h: Add DW_LANG_C_plus_plus_11, DW_LANG_C11 and
        DW_LANG_C_plus_plus_14.

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 89edddb..d7bce2a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5407,8 +5407,8 @@ assembler (GAS) to fail with an error.
 @item -gdwarf-@var{version}
 @opindex gdwarf-@var{version}
 Produce debugging information in DWARF format (if that is supported).
-The value of @var{version} may be either 2, 3 or 4; the default version
-for most targets is 4.
+The value of @var{version} may be either 2, 3, 4 or 5; the default version
+for most targets is 4.  DWARF Version 5 is only experimental.
 
 Note that with DWARF Version 2, some ports require and always
 use some non-conflicting DWARF 3 extensions in the unwind tables.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3d50ac9..d0eaaf1 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4684,7 +4684,8 @@ is_cxx (void)
 {
   unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
 
-  return lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus;
+  return (lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus
+         || lang == DW_LANG_C_plus_plus_11 || lang == DW_LANG_C_plus_plus_14);
 }
 
 /* Return TRUE if the language is Java.  */
@@ -8966,7 +8967,9 @@ output_die (dw_die_ref die)
 static void
 output_compilation_unit_header (void)
 {
-  int ver = dwarf_version;
+  /* We don't support actual DWARFv5 units yet, we just use some
+     DWARFv5 draft DIE tags in DWARFv4 format.  */
+  int ver = dwarf_version < 5 ? dwarf_version : 4;
 
   if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
     dw2_asm_output_data (4, 0xffffffff,
@@ -9109,6 +9112,10 @@ add_top_level_skeleton_die_attrs (dw_die_ref die)
 static void
 output_skeleton_debug_sections (dw_die_ref comp_unit)
 {
+  /* We don't support actual DWARFv5 units yet, we just use some
+     DWARFv5 draft DIE tags in DWARFv4 format.  */
+  int ver = dwarf_version < 5 ? dwarf_version : 4;
+
   /* These attributes will be found in the full debug_info section.  */
   remove_AT (comp_unit, DW_AT_producer);
   remove_AT (comp_unit, DW_AT_language);
@@ -9128,7 +9135,7 @@ output_skeleton_debug_sections (dw_die_ref comp_unit)
                        - DWARF_INITIAL_LENGTH_SIZE
                        + size_of_die (comp_unit),
                       "Length of Compilation Unit Info");
-  dw2_asm_output_data (2, dwarf_version, "DWARF version number");
+  dw2_asm_output_data (2, ver, "DWARF version number");
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, 
debug_skeleton_abbrev_section_label,
                          debug_abbrev_section,
                          "Offset Into Abbrev. Section");
@@ -9481,7 +9488,7 @@ output_aranges (unsigned long aranges_length)
       "Initial length escape value indicating 64-bit DWARF extension");
   dw2_asm_output_data (DWARF_OFFSET_SIZE, aranges_length,
                       "Length of Address Ranges Info");
-  /* Version number for aranges is still 2, even in DWARF3.  */
+  /* Version number for aranges is still 2, even up to DWARF5.  */
   dw2_asm_output_data (2, 2, "DWARF Version");
   if (dwarf_split_debug_info)
     dw2_asm_output_offset (DWARF_OFFSET_SIZE, 
debug_skeleton_info_section_label,
@@ -10156,7 +10163,8 @@ static void
 output_line_info (bool prologue_only)
 {
   char l1[20], l2[20], p1[20], p2[20];
-  int ver = dwarf_version;
+  /* We don't support DWARFv5 line tables yet.  */
+  int ver = dwarf_version < 5 ? dwarf_version : 4;
   bool saw_one = false;
   int opc;
 
@@ -16402,7 +16410,10 @@ lower_bound_default (void)
     case DW_LANG_C:
     case DW_LANG_C89:
     case DW_LANG_C99:
+    case DW_LANG_C11:
     case DW_LANG_C_plus_plus:
+    case DW_LANG_C_plus_plus_11:
+    case DW_LANG_C_plus_plus_14:
     case DW_LANG_ObjC:
     case DW_LANG_ObjC_plus_plus:
     case DW_LANG_Java:
@@ -16746,6 +16757,7 @@ add_prototyped_attribute (dw_die_ref die, tree 
func_type)
     case DW_LANG_C:
     case DW_LANG_C89:
     case DW_LANG_C99:
+    case DW_LANG_C11:
     case DW_LANG_ObjC:
       if (prototype_p (func_type))
        add_AT_flag (die, DW_AT_prototyped, 1);
@@ -19592,15 +19604,30 @@ gen_compile_unit_die (const char *filename)
 
   language = DW_LANG_C;
   if (strncmp (language_string, "GNU C", 5) == 0
-      && (language_string[5] == 0 || ISDIGIT (language_string[5])))
+      && 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;
+       {
+         if (strcmp (language_string, "GNU C89") != 0)
+           language = DW_LANG_C99;
+
+         if (dwarf_version >= 5 /* || !dwarf_strict */)
+           if (strcmp (language_string, "GNU C11") == 0)
+             language = DW_LANG_C11;
+       }
     }
   else if (strncmp (language_string, "GNU C++", 7) == 0)
-    language = DW_LANG_C_plus_plus;
+    {
+      language = DW_LANG_C_plus_plus;
+      if (dwarf_version >= 5 /* || !dwarf_strict */)
+       {
+         if (strcmp (language_string, "GNU C++11") == 0)
+           language = DW_LANG_C_plus_plus_11;
+         else if (strcmp (language_string, "GNU C++14") == 0)
+           language = DW_LANG_C_plus_plus_14;
+       }
+    }
   else if (strcmp (language_string, "GNU F77") == 0)
     language = DW_LANG_Fortran77;
   else if (strcmp (language_string, "GNU Pascal") == 0)
diff --git a/gcc/opts.c b/gcc/opts.c
index f3deb40..3a0ed61 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1992,7 +1992,7 @@ common_handle_option (struct gcc_options *opts,
       
       /* FALLTHRU */
     case OPT_gdwarf_:
-      if (value < 2 || value > 4)
+      if (value < 2 || value > 5)
        error_at (loc, "dwarf version %d is not supported", value);
       else
        opts->x_dwarf_version = value;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp11.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp11.C
new file mode 100644
index 0000000..8079c0e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp11.C
@@ -0,0 +1,6 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++11 -gdwarf-5 -dA" }
+// DW_LANG_C_plus_plus_11 = 0x001a
+// { dg-final { scan-assembler "0x1a.*DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp14.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp14.C
new file mode 100644
index 0000000..448ec7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp14.C
@@ -0,0 +1,6 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++14 -gdwarf-5 -dA" }
+// DW_LANG_C_plus_plus_14 = 0x0021
+// { dg-final { scan-assembler "0x21.*DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp98.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp98.C
new file mode 100644
index 0000000..065cc18
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp98.C
@@ -0,0 +1,6 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++98 -g -dA" }
+// DW_LANG_C_plus_plus = 0x0004
+// { dg-final { scan-assembler "0x4.*DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c11-d4-strict.c 
b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c11-d4-strict.c
new file mode 100644
index 0000000..accc13f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c11-d4-strict.c
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-O -std=c11 -gdwarf-4 -gstrict-dwarf -dA" }
+// We cannot produce DW_LANG_C11 = 0x001d because strict-dwarf.
+// So expect DW_LANG_C99 = 0x000c
+// { dg-final { scan-assembler "0xc.*DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c11.c 
b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c11.c
new file mode 100644
index 0000000..f14c49f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c11.c
@@ -0,0 +1,6 @@
+// { dg-do compile }
+// { dg-options "-O -std=c11 -gdwarf-5 -dA" }
+// DW_LANG_C11 = 0x001d
+// { dg-final { scan-assembler "0x1d.*DW_AT_language" } } */
+
+int version;
diff --git a/include/dwarf2.h b/include/dwarf2.h
index 120e2c1..ca440dd 100644
--- a/include/dwarf2.h
+++ b/include/dwarf2.h
@@ -309,6 +309,10 @@ enum dwarf_source_language
     /* DWARF 5.  */
     DW_LANG_Go = 0x0016,
 
+    DW_LANG_C_plus_plus_11 = 0x001a, /* dwarf5.20141029.pdf DRAFT */
+    DW_LANG_C11 = 0x001d,
+    DW_LANG_C_plus_plus_14 = 0x0021,
+
     DW_LANG_lo_user = 0x8000,  /* Implementation-defined range start.  */
     DW_LANG_hi_user = 0xffff,  /* Implementation-defined range start.  */
 

Reply via email to