https://gcc.gnu.org/g:ec99905f7b39914ddb074c13ffbe05f0216784a1

commit r15-6685-gec99905f7b39914ddb074c13ffbe05f0216784a1
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Jan 8 10:57:50 2025 +0100

    dwarf2out: Emit DWARF 6 DW_AT_language_{name,version}
    
    DWARF has voted in recently https://dwarfstd.org/issues/241209.1.html ,
    which is basically just a guarantee that the DWARF 6 draft
    DW_AT_language_{name,version} attribute codes and content of
    https://dwarfstd.org/languages-v6.html can be used as an extension
    in DWARF 5 and won't be changed.
    
    So, this patch is an alternative to the
    https://gcc.gnu.org/pipermail/gcc-patches/2024-November/669671.html
    patch, which had the major problem that it required changing all the
    DWARF consumers to be able to debug C17 or later or C++17 or later
    sources.
    This patch uses still DWARF 5 DW_LANG_C11 or DW_LANG_C_plus_plus_14,
    the latest code in DWARF 5 proper, so all DWARF 5 capable consumers
    should be able to deal with that, but additionally emits the
    DWARF 6 attributes so that newer DWARF consumers can see it isn't
    just C++14 but say C++23 or C11 but C23.  Consumers which don't know
    those DWARF 6 attributes would just ignore them.  This is like any other
    -gno-strict-dwarf extension, except that normally we emit say DWARF 5
    codes where possible only after DWARF 5 is released, while in this case
    there is a guarantee it can be used before DWARF 6 is released.
    
    2025-01-08  Jakub Jelinek  <ja...@redhat.com>
    
    include/
            * dwarf2.h (enum dwarf_source_language): Fix comment pasto.
            (enum dwarf_source_language_name): New type.
            * dwarf2.def (DW_AT_language_name, DW_AT_language_version): New
            DWARF 6 codes.
    gcc/
            * dwarf2out.cc (break_out_comdat_types): Copy over
            DW_AT_language_{name,version} if present.
            (output_skeleton_debug_sections): Remove also
            DW_AT_language_{name,version}.
            (gen_compile_unit_die): For C17, C23, C2Y, C++17, C++20, C++23
            and C++26 emit for -gdwarf-5 -gno-strict-dwarf also
            DW_AT_language_{name,version} attributes.
    gcc/testsuite/
            * g++.dg/debug/dwarf2/lang-cpp17.C: Add -gno-strict-dwarf to
            dg-options.  Check also for DW_AT_language_{name,version} values.
            * g++.dg/debug/dwarf2/lang-cpp20.C: Likewise.
            * g++.dg/debug/dwarf2/lang-cpp23.C: New test.

Diff:
---
 gcc/dwarf2out.cc                               | 76 ++++++++++++++++++++++----
 gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C |  6 +-
 gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C |  6 +-
 gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp23.C | 10 ++++
 include/dwarf2.def                             |  3 +
 include/dwarf2.h                               | 55 ++++++++++++++++++-
 6 files changed, 139 insertions(+), 17 deletions(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 1f6a6ce41825..8085b8d85d89 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -8755,6 +8755,14 @@ break_out_comdat_types (dw_die_ref die)
         unit = new_die (DW_TAG_type_unit, NULL, NULL);
         add_AT_unsigned (unit, DW_AT_language,
                          get_AT_unsigned (comp_unit_die (), DW_AT_language));
+       if (unsigned lname = get_AT_unsigned (comp_unit_die (),
+                                             DW_AT_language_name))
+         {
+           add_AT_unsigned (unit, DW_AT_language_name, lname);
+           add_AT_unsigned (unit, DW_AT_language_version,
+                            get_AT_unsigned (comp_unit_die (),
+                                             DW_AT_language_version));
+         }
 
        /* Add the new unit's type DIE into the comdat type list.  */
         type_node = ggc_cleared_alloc<comdat_type_node> ();
@@ -11404,6 +11412,8 @@ output_skeleton_debug_sections (dw_die_ref comp_unit,
   /* 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);
+  remove_AT (comp_unit, DW_AT_language_name);
+  remove_AT (comp_unit, DW_AT_language_version);
 
   switch_to_section (debug_skeleton_info_section);
   ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_info_section_label);
@@ -25318,7 +25328,7 @@ gen_compile_unit_die (const char *filename)
 {
   dw_die_ref die;
   const char *language_string = lang_hooks.name;
-  int language;
+  int language, lname, lversion;
 
   die = new_die (DW_TAG_compile_unit, NULL, NULL);
 
@@ -25366,6 +25376,8 @@ gen_compile_unit_die (const char *filename)
     }
 
   language = DW_LANG_C;
+  lname = 0;
+  lversion = 0;
   if (startswith (language_string, "GNU C")
       && ISDIGIT (language_string[5]))
     {
@@ -25376,11 +25388,28 @@ gen_compile_unit_die (const char *filename)
            language = DW_LANG_C99;
 
          if (dwarf_version >= 5 /* || !dwarf_strict */)
-           if (strcmp (language_string, "GNU C11") == 0
-               || strcmp (language_string, "GNU C17") == 0
-               || strcmp (language_string, "GNU C23") == 0
-               || strcmp (language_string, "GNU C2Y") == 0)
-             language = DW_LANG_C11;
+           {
+             if (strcmp (language_string, "GNU C11") == 0)
+               language = DW_LANG_C11;
+             else if (strcmp (language_string, "GNU C17") == 0)
+               {
+                 language = DW_LANG_C11;
+                 lname = DW_LNAME_C;
+                 lversion = 201710;
+               }
+             else if (strcmp (language_string, "GNU C23") == 0)
+               {
+                 language = DW_LANG_C11;
+                 lname = DW_LNAME_C;
+                 lversion = 202311;
+               }
+             else if (strcmp (language_string, "GNU C2Y") == 0)
+               {
+                 language = DW_LANG_C11;
+                 lname = DW_LNAME_C;
+                 lversion = 202500;
+               }
+           }
        }
     }
   else if (startswith (language_string, "GNU C++"))
@@ -25392,12 +25421,30 @@ gen_compile_unit_die (const char *filename)
            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 C++17") == 0
-                  || strcmp (language_string, "GNU C++20") == 0
-                  || strcmp (language_string, "GNU C++23") == 0
-                  || strcmp (language_string, "GNU C++26") == 0)
-           /* For now.  */
-           language = DW_LANG_C_plus_plus_14;
+         else if (strcmp (language_string, "GNU C++17") == 0)
+           {
+             language = DW_LANG_C_plus_plus_14;
+             lname = DW_LNAME_C_plus_plus;
+             lversion = 201703;
+           }
+         else if (strcmp (language_string, "GNU C++20") == 0)
+           {
+             language = DW_LANG_C_plus_plus_14;
+             lname = DW_LNAME_C_plus_plus;
+             lversion = 202002;
+           }
+         else if (strcmp (language_string, "GNU C++23") == 0)
+           {
+             language = DW_LANG_C_plus_plus_14;
+             lname = DW_LNAME_C_plus_plus;
+             lversion = 202302;
+           }
+         else if (strcmp (language_string, "GNU C++26") == 0)
+           {
+             language = DW_LANG_C_plus_plus_14;
+             lname = DW_LNAME_C_plus_plus;
+             lversion = 202400;
+           }
        }
     }
   else if (strcmp (language_string, "GNU F77") == 0)
@@ -25441,6 +25488,11 @@ gen_compile_unit_die (const char *filename)
     language = DW_LANG_Ada83;
 
   add_AT_unsigned (die, DW_AT_language, language);
+  if (lname && dwarf_version >= 5 && !dwarf_strict)
+    {
+      add_AT_unsigned (die, DW_AT_language_name, lname);
+      add_AT_unsigned (die, DW_AT_language_version, lversion);
+    }
 
   switch (language)
     {
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C
index a1e3cccea263..18f73eed874a 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C
@@ -1,8 +1,10 @@
 // { dg-do compile }
-// { dg-options "-O -std=c++17 -gdwarf-5 -dA" }
+// { dg-options "-O -std=c++17 -gdwarf-5 -dA -gno-strict-dwarf" }
 // { dg-skip-if "AIX DWARF5" { powerpc-ibm-aix* } }
-// For -gdwarf-6 hopefully DW_LANG_C_plus_plus_17
 // DW_LANG_C_plus_plus_14 = 0x0021
+// DW_LNAME_C_plus_plus = 0x0004 201703
 // { dg-final { scan-assembler "0x21\[^\n\r]* DW_AT_language" } } */
+// { dg-final { scan-assembler "0x4\[^\n\r]* DW_AT_language_name" } } */
+// { dg-final { scan-assembler "0x313e7\[^\n\r]* DW_AT_language_version" } } */
 
 int version;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C
index 62abd6181559..28eca154441a 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C
@@ -1,8 +1,10 @@
 // { dg-do compile }
-// { dg-options "-O -std=c++20 -gdwarf-5 -dA" }
+// { dg-options "-O -std=c++20 -gdwarf-5 -dA -gno-strict-dwarf" }
 // { dg-skip-if "AIX DWARF5" { powerpc-ibm-aix* } }
-// For -gdwarf-6 hopefully DW_LANG_C_plus_plus_20
 // DW_LANG_C_plus_plus_14 = 0x0021
+// DW_LNAME_C_plus_plus = 0x0004 202002
 // { dg-final { scan-assembler "0x21\[^\n\r]* DW_AT_language" } } */
+// { dg-final { scan-assembler "0x4\[^\n\r]* DW_AT_language_name" } } */
+// { dg-final { scan-assembler "0x31512\[^\n\r]* DW_AT_language_version" } } */
 
 int version;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp23.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp23.C
new file mode 100644
index 000000000000..8bcc8f2d3894
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp23.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++23 -gdwarf-5 -dA -gno-strict-dwarf" }
+// { dg-skip-if "AIX DWARF5" { powerpc-ibm-aix* } }
+// DW_LANG_C_plus_plus_14 = 0x0021
+// DW_LNAME_C_plus_plus = 0x0004 202302
+// { dg-final { scan-assembler "0x21\[^\n\r]* DW_AT_language" } } */
+// { dg-final { scan-assembler "0x4\[^\n\r]* DW_AT_language_name" } } */
+// { dg-final { scan-assembler "0x3163e\[^\n\r]* DW_AT_language_version" } } */
+
+int version;
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 63cb35560e7c..e9acb79df9ce 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -364,6 +364,9 @@ DW_AT (DW_AT_export_symbols, 0x89)
 DW_AT (DW_AT_deleted, 0x8a)
 DW_AT (DW_AT_defaulted, 0x8b)
 DW_AT (DW_AT_loclists_base, 0x8c)
+/* DWARF 6.  */
+DW_AT (DW_AT_language_name, 0x90)
+DW_AT (DW_AT_language_version, 0x91)
 
 DW_AT_DUP (DW_AT_lo_user, 0x2000) /* Implementation-defined range start.  */
 DW_AT_DUP (DW_AT_hi_user, 0x3fff) /* Implementation-defined range end.  */
diff --git a/include/dwarf2.h b/include/dwarf2.h
index 0b193a250de1..344447fbc368 100644
--- a/include/dwarf2.h
+++ b/include/dwarf2.h
@@ -411,7 +411,7 @@ enum dwarf_source_language
     DW_LANG_Hylo = 0x0042,
 
     DW_LANG_lo_user = 0x8000,  /* Implementation-defined range start.  */
-    DW_LANG_hi_user = 0xffff,  /* Implementation-defined range start.  */
+    DW_LANG_hi_user = 0xffff,  /* Implementation-defined range end.  */
 
     /* MIPS.  */
     DW_LANG_Mips_Assembler = 0x8001,
@@ -428,6 +428,59 @@ enum dwarf_source_language
     DW_LANG_Rust_old = 0x9000
   };
 
+/* DWARF 6 source language names and codes.  */
+enum dwarf_source_language_name
+  {
+    /* https://dwarfstd.org/languages-v6.html */
+    DW_LNAME_Ada = 0x0001,
+    DW_LNAME_BLISS = 0x0002,
+    DW_LNAME_C = 0x0003,
+    DW_LNAME_C_plus_plus = 0x0004,
+    DW_LNAME_Cobol = 0x0005,
+    DW_LNAME_Crystal = 0x0006,
+    DW_LNAME_D = 0x0007,
+    DW_LNAME_Dylan = 0x0008,
+    DW_LNAME_Fortran = 0x0009,
+    DW_LNAME_Go = 0x000a,
+    DW_LNAME_Haskell = 0x000b,
+    DW_LNAME_Java = 0x000c,
+    DW_LNAME_Julia = 0x000d,
+    DW_LNAME_Kotlin = 0x000e,
+    DW_LNAME_Modula2 = 0x000f,
+    DW_LNAME_Modula3 = 0x0010,
+    DW_LNAME_ObjC = 0x0011,
+    DW_LNAME_ObjC_plus_plus = 0x0012,
+    DW_LNAME_OCaml = 0x0013,
+    DW_LNAME_OpenCL_C = 0x0014,
+    DW_LNAME_Pascal = 0x0015,
+    DW_LNAME_PLI = 0x0016,
+    DW_LNAME_Python = 0x0017,
+    DW_LNAME_RenderScript = 0x0018,
+    DW_LNAME_Rust = 0x0019,
+    DW_LNAME_Swift = 0x001a,
+    DW_LNAME_UPC = 0x001b,
+    DW_LNAME_Zig = 0x001c,
+    DW_LNAME_Assembly = 0x001d,
+    DW_LNAME_C_sharp = 0x001e,
+    DW_LNAME_Mojo = 0x001f,
+    DW_LNAME_GLSL = 0x0020,
+    DW_LNAME_GLSL_ES = 0x0021,
+    DW_LNAME_HLSL = 0x0022,
+    DW_LNAME_OpenCL_CPP = 0x0023,
+    DW_LNAME_CPP_for_OpenCL = 0x0024,
+    DW_LNAME_SYCL = 0x0025,
+    DW_LNAME_Ruby = 0x0026,
+    DW_LNAME_Move = 0x0027,
+    DW_LNAME_Hylo = 0x0028,
+    DW_LNAME_HIP = 0x0029,
+    DW_LNAME_Odin = 0x002a,
+    DW_LNAME_P4 = 0x002b,
+    DW_LNAME_Metal = 0x002c,
+
+    DW_LNAME_lo_user = 0x8000, /* Implementation-defined range start.  */
+    DW_LNAME_hi_user = 0xffff  /* Implementation-defined range end.  */
+  };
+
 /* Names and codes for macro information.  */
 enum dwarf_macinfo_record_type
   {

Reply via email to