Re: [PATCH] dwarf2out: Emit DWARF 6 DW_AT_language_{name,version}

Richard Biener <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gdb.devel
Message-ID <[email protected]>
On Tue, 7 Jan 2025, Jakub Jelinek wrote:

> Hi!
> 
> 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.
> 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok with me.

Thanks,
Richard.

> 2025-01-07  Jakub Jelinek  <[email protected]>
> 
> 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.
> 
> --- include/dwarf2.h.jj	2025-01-02 11:47:47.431981968 +0100
> +++ include/dwarf2.h	2025-01-06 18:55:59.802378204 +0100
> @@ -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
>    {
> --- include/dwarf2.def.jj	2025-01-02 11:47:47.191985318 +0100
> +++ include/dwarf2.def	2025-01-06 18:39:02.642383150 +0100
> @@ -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.  */
> --- 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));
> +	  }
>  
>  	/* 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_r
>    /* 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 *filena
>  {
>    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 *filena
>      }
>  
>    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 *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;
> +		}
> +	    }
>  	}
>      }
>    else if (startswith (language_string, "GNU C++"))
> @@ -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;
> +	    }
>  	}
>      }
>    else if (strcmp (language_string, "GNU F77") == 0)
> @@ -25441,6 +25488,11 @@ gen_compile_unit_die (const char *filena
>      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)
>      {
> --- gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C.jj	2021-01-18 07:18:14.929659650 +0100
> +++ gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C	2025-01-07 10:07:46.473125326 +0100
> @@ -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;
> --- gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C.jj	2021-01-18 14:52:42.946040137 +0100
> +++ gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C	2025-01-07 10:08:28.982533366 +0100
> @@ -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;
> --- gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp23.C.jj	2025-01-07 10:07:54.926007612 +0100
> +++ gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp23.C	2025-01-07 10:08:19.206669497 +0100
> @@ -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;
> 
> 	Jakub
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.