Hi Jakub, On Tue, 2025-01-07 at 20:22 +0100, Jakub Jelinek wrote: > DWARF has voted in yesterday 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.
Note that most consumers (binutils, gdb, systemtap, valgrind, elfutils) have already been updated to use the new DW_LANG constants. We can easily backport that to the last stable releases before gcc 15 is released. > 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. Code looks ok to me, it is only for C and C++, would be nice to at least get it for Fortran and Ada too. > --- gcc/dwarf2out.cc.jj 2025-01-02 11:23:35.541251268 +0100 > +++ gcc/dwarf2out.cc 2025-01-07 10:09:16.866866563 +0100 > @@ -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)); > + } This relies on language_name and language_version always being set together. Which is the case in the code at this time. Should we assert that? > @@ -25376,11 +25388,28 @@ gen_compile_unit_die (const char *filena > 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; > + } > + } The use of language_string (lang_hooks.name) is a little clumsy, but already part of the current code. In the future it would be nice to have separate language and version hooks for this. Personally I would just go with the new DW_LANG_C17/C23 language code, they will be supported by consumers when gcc 15 is released. The 00 for the month in C2Y is clever. Does that match the __STDC_VERSION__ defined? > @@ -25392,12 +25421,30 @@ gen_compile_unit_die (const char *filena > 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; > + } Why 202400 and not 202600? Cheers, Mark