From a0ffaf56bf4db6c162d6e38c60e0c9d4148e47ba Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 16 Jun 2013 19:16:50 +0200 Subject: [PATCH] Do not codegen aggregate types from within debug info generation. This avoids problems where we would codegen children of an "inner" template instantiation (i.e. a member of a non-template aggregate in another module) because we have no way to know the outer (declare-only) entity exists in the respective mustDefineSymbol invocation. An example for this are the std.typecons.RefCounted internals of std.file.DirIterator, as used from std.datetime and other modules. This is not only inefficient, but also causes linking issues due to attribute inference for these functions not having run yet (and consequently the mangled name being different from the actual definition). --- gen/todebug.cpp | 34 ++++++++++++++++------------------ ir/iraggr.cpp | 3 +-- ir/iraggr.h | 3 --- ir/irtypeaggr.cpp | 2 +- ir/irtypeaggr.h | 6 ++++++ 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/gen/todebug.cpp b/gen/todebug.cpp index 0588c6f9..3db36789 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -23,6 +23,7 @@ #include "gen/tollvm.h" #include "gen/utils.h" #include "ir/irmodule.h" +#include "ir/irtypeaggr.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/FileSystem.h" @@ -254,9 +255,7 @@ static void add_base_fields( static llvm::DIType dwarfCompositeType(Type* type) { - LLType* T = DtoType(type); Type* t = type->toBasetype(); - assert((t->ty == Tstruct || t->ty == Tclass) && "unsupported type for dwarfCompositeType"); AggregateDeclaration* sd; @@ -272,19 +271,20 @@ static llvm::DIType dwarfCompositeType(Type* type) } assert(sd); - // make sure it's resolved - sd->codegen(Type::sir); + // Use the actual type associated with the declaration, ignoring any + // const/… wrappers. + LLType* T = DtoType(sd->type); + IrTypeAggr* ir = sd->type->irtype->isAggr(); + assert(ir); + + if (static_cast(ir->diCompositeType) != 0) + return ir->diCompositeType; // if we don't know the aggregate's size, we don't know enough about it // to provide debug info. probably a forward-declared struct? if (sd->sizeok == 0) return llvm::DICompositeType(NULL); - IrAggr* ir = sd->ir.irStruct; - assert(ir); - if (static_cast(ir->diCompositeType) != 0) - return ir->diCompositeType; - // elements std::vector elems; @@ -295,17 +295,15 @@ static llvm::DIType dwarfCompositeType(Type* type) llvm::DIType derivedFrom; // set diCompositeType to handle recursive types properly - if (!ir->diCompositeType) { - unsigned tag = (t->ty == Tstruct) ? llvm::dwarf::DW_TAG_structure_type - : llvm::dwarf::DW_TAG_class_type; - ir->diCompositeType = gIR->dibuilder.createForwardDecl(tag, name, + unsigned tag = (t->ty == Tstruct) ? llvm::dwarf::DW_TAG_structure_type + : llvm::dwarf::DW_TAG_class_type; + ir->diCompositeType = gIR->dibuilder.createForwardDecl(tag, name, #if LDC_LLVM_VER >= 302 - llvm::DIDescriptor(file), + llvm::DIDescriptor(file), #endif - file, linnum); - } + file, linnum); - if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one + if (!sd->isInterfaceDeclaration()) // plain interfaces don't have one { if (t->ty == Tstruct) { @@ -321,7 +319,7 @@ static llvm::DIType dwarfCompositeType(Type* type) } else { - ClassDeclaration *classDecl = ir->aggrdecl->isClassDeclaration(); + ClassDeclaration *classDecl = sd->isClassDeclaration(); add_base_fields(classDecl, file, elems); if (classDecl->baseClass) derivedFrom = dwarfCompositeType(classDecl->baseClass->getType()); diff --git a/ir/iraggr.cpp b/ir/iraggr.cpp index ce4bdc9d..35733b79 100644 --- a/ir/iraggr.cpp +++ b/ir/iraggr.cpp @@ -26,8 +26,7 @@ ////////////////////////////////////////////////////////////////////////////// IrAggr::IrAggr(AggregateDeclaration* aggr) -: diCompositeType(NULL), - init_type(LLStructType::create(gIR->context(), std::string(aggr->toPrettyChars()) + "_init")) +: init_type(LLStructType::create(gIR->context(), std::string(aggr->toPrettyChars()) + "_init")) { aggrdecl = aggr; diff --git a/ir/iraggr.h b/ir/iraggr.h index 033a716e..04621c28 100644 --- a/ir/iraggr.h +++ b/ir/iraggr.h @@ -45,9 +45,6 @@ struct IrAggr /// true only for: align(1) struct S { ... } bool packed; - /// Composite type debug description. - llvm::DIType diCompositeType; - ////////////////////////////////////////////////////////////////////////// /// Create the __initZ symbol lazily. diff --git a/ir/irtypeaggr.cpp b/ir/irtypeaggr.cpp index 7ed76c14..a55aca7e 100644 --- a/ir/irtypeaggr.cpp +++ b/ir/irtypeaggr.cpp @@ -24,6 +24,6 @@ IrTypeAggr::IrTypeAggr(AggregateDeclaration * ad) : IrType(ad->type, LLStructType::create(gIR->context(), ad->toPrettyChars())), - aggr(ad) + aggr(ad), diCompositeType(NULL) { } diff --git a/ir/irtypeaggr.h b/ir/irtypeaggr.h index 6dbe6b83..2c8579f4 100644 --- a/ir/irtypeaggr.h +++ b/ir/irtypeaggr.h @@ -12,6 +12,7 @@ #include "ir/irtype.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo.h" #include #include @@ -39,6 +40,11 @@ public: /// iterator def_end() { return default_fields.end(); } + + /// Composite type debug description. This is not only to cache, but also + /// used for resolving forward references. + llvm::DIType diCompositeType; + protected: /// IrTypeAggr(AggregateDeclaration* ad);