mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
Debug info: better handling of static aggregate members with DIFlagStaticMember
Once again closer to GDC and Clang's output, and attaching static variables to the module scope prevents an assert from triggering in IR/DIBuilder.cpp: checkGlobalVariableScope(): Assertion `CT->getIdentifier().empty() && "Context of a global variable should not be a type with identifier"'
This commit is contained in:
parent
2cdae62b0e
commit
9facf5ad28
2 changed files with 77 additions and 6 deletions
|
@ -29,6 +29,9 @@
|
|||
#include "module.h"
|
||||
#include "mtype.h"
|
||||
#include "nspace.h"
|
||||
#include "template.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -108,6 +111,17 @@ ldc::DIScope ldc::DIBuilder::GetSymbolScope(Dsymbol* s) {
|
|||
|
||||
auto parent = s->toParent();
|
||||
|
||||
auto vd = s->isVarDeclaration();
|
||||
if (vd && vd->isDataseg()) {
|
||||
// static variables get attached to the module scope, but their
|
||||
// parent composite types have to get declared
|
||||
while (!parent->isModule()) {
|
||||
if (parent->isAggregateDeclaration())
|
||||
CreateCompositeTypeDescription(parent->getType());
|
||||
parent = parent->toParent();
|
||||
}
|
||||
}
|
||||
|
||||
if (auto tempinst = parent->isTemplateInstance()) {
|
||||
return GetSymbolScope(tempinst->tempdecl);
|
||||
} else if (auto m = parent->isModule()) {
|
||||
|
@ -391,7 +405,8 @@ ldc::DIType ldc::DIBuilder::CreateComplexType(Type *type) {
|
|||
ldc::DIType ldc::DIBuilder::CreateMemberType(unsigned linnum, Type *type,
|
||||
ldc::DIFile file,
|
||||
const char *c_name,
|
||||
unsigned offset, Prot::Kind prot) {
|
||||
unsigned offset, Prot::Kind prot,
|
||||
bool isStatic, DIScope scope) {
|
||||
Type *t = type->toBasetype();
|
||||
|
||||
// translate functions to function pointers
|
||||
|
@ -418,7 +433,10 @@ ldc::DIType ldc::DIBuilder::CreateMemberType(unsigned linnum, Type *type,
|
|||
break;
|
||||
}
|
||||
|
||||
return DBuilder.createMemberType(GetCU(),
|
||||
if (isStatic)
|
||||
Flags |= DIFlags::FlagStaticMember;
|
||||
|
||||
return DBuilder.createMemberType(scope,
|
||||
c_name, // name
|
||||
file, // file
|
||||
linnum, // line number
|
||||
|
@ -441,6 +459,34 @@ void ldc::DIBuilder::AddFields(AggregateDeclaration *ad, ldc::DIFile file,
|
|||
}
|
||||
}
|
||||
|
||||
void ldc::DIBuilder::AddStaticMembers(AggregateDeclaration *ad, ldc::DIFile file,
|
||||
llvm::SmallVector<LLMetadata *, 16> &elems) {
|
||||
auto scope = CreateCompositeTypeDescription(ad->getType());
|
||||
|
||||
std::function<void(Dsymbols*)> visitMembers = [&] (Dsymbols* members) {
|
||||
for (auto s : *members) {
|
||||
if (auto attrib = s->isAttribDeclaration()) {
|
||||
if (Dsymbols *d = attrib->include(nullptr))
|
||||
visitMembers(d);
|
||||
} else if (auto tmixin = s->isTemplateMixin()) {
|
||||
visitMembers(tmixin->members); // FIXME: static variables inside a template mixin need to be put inside a child DICompositeType for their value to become accessible (mangling issue).
|
||||
// Also DWARF supports imported declarations, but LLVM currently does nothing with DIImportedEntity except at CU-level.
|
||||
} else if (auto vd = s->isVarDeclaration())
|
||||
if (vd->isDataseg() && !vd->aliassym /* TODO: tuples*/) {
|
||||
llvm::MDNode* elem = CreateMemberType(vd->loc.linnum, vd->type, file,
|
||||
vd->toChars(), 0,
|
||||
vd->prot().kind,
|
||||
/*isStatic = */true, scope);
|
||||
elems.push_back(elem);
|
||||
StaticDataMemberCache[vd].reset(elem);
|
||||
|
||||
}
|
||||
} /*else if (auto fd = s->isFuncDeclaration())*/ // Clang also adds static functions as declarations,
|
||||
// but they already work without adding them.
|
||||
};
|
||||
visitMembers(ad->members);
|
||||
}
|
||||
|
||||
ldc::DIType ldc::DIBuilder::CreateCompositeType(Type *type) {
|
||||
Type *t = type->toBasetype();
|
||||
assert((t->ty == Tstruct || t->ty == Tclass) &&
|
||||
|
@ -522,6 +568,7 @@ ldc::DIType ldc::DIBuilder::CreateCompositeType(Type *type) {
|
|||
}
|
||||
AddFields(ad, file, elems);
|
||||
}
|
||||
AddStaticMembers(ad, file, elems);
|
||||
|
||||
auto elemsArray = DBuilder.getOrCreateArray(elems);
|
||||
|
||||
|
@ -739,6 +786,12 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type) {
|
|||
llvm_unreachable("Unsupported type in debug info");
|
||||
}
|
||||
|
||||
ldc::DICompositeType ldc::DIBuilder::CreateCompositeTypeDescription(Type *type) {
|
||||
DIType ret = type->toBasetype()->ty == Tclass
|
||||
? CreateCompositeType(type) : CreateTypeDescription(type);
|
||||
return llvm::cast<llvm::DICompositeType>(ret);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::DICompileUnit::DebugEmissionKind getDebugEmissionKind()
|
||||
|
@ -1171,6 +1224,15 @@ void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
|
|||
assert(vd->isDataseg() ||
|
||||
(vd->storage_class & (STCconst | STCimmutable) && vd->_init));
|
||||
|
||||
DIScope scope = GetSymbolScope(vd);
|
||||
llvm::MDNode* Decl = nullptr;
|
||||
|
||||
if (vd->isDataseg() && vd->toParent()->isAggregateDeclaration()) {
|
||||
// static aggregate member
|
||||
Decl = StaticDataMemberCache[vd];
|
||||
assert(Decl && "static aggregate member not declared");
|
||||
}
|
||||
|
||||
OutBuffer mangleBuf;
|
||||
mangleToBuffer(vd, &mangleBuf);
|
||||
|
||||
|
@ -1179,7 +1241,7 @@ void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
|
|||
#else
|
||||
DBuilder.createGlobalVariable(
|
||||
#endif
|
||||
GetSymbolScope(vd), // context
|
||||
scope, // context
|
||||
vd->toChars(), // name
|
||||
mangleBuf.peekString(), // linkage name
|
||||
CreateFile(vd), // file
|
||||
|
@ -1187,10 +1249,11 @@ void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
|
|||
CreateTypeDescription(vd->type), // type
|
||||
vd->protection.kind == Prot::private_, // is local to unit
|
||||
#if LDC_LLVM_VER >= 400
|
||||
nullptr // relative location of field
|
||||
nullptr, // relative location of field
|
||||
#else
|
||||
llVar // value
|
||||
llVar, // value
|
||||
#endif
|
||||
Decl // declaration
|
||||
);
|
||||
|
||||
#if LDC_LLVM_VER >= 400
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue