d: Fix forward referenced enums missing type names in debug info [PR118309]

Calling `rest_of_type_compilation' as the D types were built meant that
debug info was being emitted before all forward references were
resolved, resulting in DW_AT_name's to be missing.

Instead, defer outputting type debug information until all modules have
been parsed and generated in `d_finish_compilation'.

	PR d/118309

gcc/d/ChangeLog:

	* modules.cc: Include debug.h
	(d_finish_compilation): Call debug_hooks->type_decl on all TYPE_DECLs.
	* types.cc: Remove toplev.h include.
	(finish_aggregate_type): Don't call rest_of_type_compilation or
	rest_of_decl_compilation on type.
	(TypeVisitor::visit (TypeEnum *)): Likewise.

gcc/testsuite/ChangeLog:

	* gdc.dg/debug/dwarf2/pr118309.d: New test.
This commit is contained in:
Iain Buclaw 2025-04-09 20:02:02 +02:00
parent 8df0de92a0
commit cee353c265
3 changed files with 47 additions and 13 deletions

View file

@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "debug.h"
#include "toplev.h"
#include "target.h"
#include "common/common-target.h"
@ -927,6 +928,14 @@ d_finish_compilation (tree *vec, int len)
/* Complete all generated thunks. */
symtab->process_same_body_aliases ();
/* Output debug information for all type declarations in this unit. */
for (int i = 0; i < len; i++)
{
tree decl = vec[i];
if (TREE_CODE (decl) == TYPE_DECL)
debug_hooks->type_decl (decl, false);
}
/* Process all file scopes in this compilation, and the external_scope,
through wrapup_global_declarations. */
for (int i = 0; i < len; i++)

View file

@ -33,7 +33,6 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "tm.h"
#include "function.h"
#include "toplev.h"
#include "target.h"
#include "stringpool.h"
#include "stor-layout.h"
@ -709,13 +708,8 @@ finish_aggregate_type (unsigned structsize, unsigned alignsize, tree type)
TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type);
}
/* Finish debugging output for this type. */
rest_of_type_compilation (type, TYPE_FILE_SCOPE_P (type));
/* Complete any other forward-referenced fields of this aggregate type. */
finish_incomplete_fields (type);
/* Finish processing of TYPE_DECL. */
rest_of_decl_compilation (TYPE_NAME (type),
DECL_FILE_SCOPE_P (TYPE_NAME (type)), 0);
}
/* Returns true if the class or struct type TYPE has already been layed out by
@ -1185,13 +1179,8 @@ public:
layout_type (t->ctype);
/* Finish debugging output for this type. */
rest_of_type_compilation (t->ctype, TYPE_FILE_SCOPE_P (t->ctype));
/* Complete forward-referenced fields of this enum type. */
finish_incomplete_fields (t->ctype);
/* Finish processing of TYPE_DECL. */
rest_of_decl_compilation (TYPE_NAME (t->ctype),
DECL_FILE_SCOPE_P (TYPE_NAME (t->ctype)), 0);
}
}

View file

@ -0,0 +1,36 @@
// { dg-do compile }
// { dg-options "-fno-druntime -gdwarf-4 -dA -fno-merge-debug-strings" }
// { dg-final { scan-assembler-times "DIE\[^\n\r\]*DW_TAG_enumeration_type" 1 } }
// { dg-final { scan-assembler-times " DW_AT_enum_class" 1 } }
// { dg-final { scan-assembler-times "\"E..\"\[^\n\]*DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "\"E1..\"\[^\n\]*DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "\"C1..\"\[^\n\]*DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "\"C2..\"\[^\n\]*DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "\"C3..\"\[^\n\]*DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "\"C4..\"\[^\n\]*DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "\"S1..\"\[^\n\]*DW_AT_name" 1 } }
module expression;
extern (C++):
class C1
{
bool bfn() { return true; }
}
class C2 : C1
{
C4 cfn() { return null; }
}
class C3 : C2
{
S1.E s;
}
class C4 : C3
{
S1 s;
}
struct S1
{
enum E : ubyte { E1 }
E e;
C3 c;
}