# HG changeset patch # User lindquist # Date 1213282706 -7200 # Node ID e3355ce5444ba07564347314d573edcb16c7776b # Parent 2f2d7c843e5d9758df43679591bbdfa34f3e939a [svn r269] Fixed dwarf debug info for structs. diff -r 2f2d7c843e5d -r e3355ce5444b gen/irstate.cpp --- a/gen/irstate.cpp Wed Jun 11 21:03:55 2008 +0200 +++ b/gen/irstate.cpp Thu Jun 12 16:58:26 2008 +0200 @@ -54,6 +54,10 @@ mainFunc = 0; ir.state = this; asmBlock = NULL; + + dwarfCUs = NULL; + dwarfSPs = NULL; + dwarfGVs = NULL; } IrFunction* IRState::func() diff -r 2f2d7c843e5d -r e3355ce5444b gen/irstate.h --- a/gen/irstate.h Wed Jun 11 21:03:55 2008 +0200 +++ b/gen/irstate.h Thu Jun 12 16:58:26 2008 +0200 @@ -159,8 +159,12 @@ // for inline asm IRAsmBlock* asmBlock; - // used array solely for keeping a reference to globals + // dwarf dbg stuff + // 'used' array solely for keeping a reference to globals std::vector usedArray; + LLGlobalVariable* dwarfCUs; + LLGlobalVariable* dwarfSPs; + LLGlobalVariable* dwarfGVs; }; #endif // LLVMDC_GEN_IRSTATE_H diff -r 2f2d7c843e5d -r e3355ce5444b gen/todebug.cpp --- a/gen/todebug.cpp Wed Jun 11 21:03:55 2008 +0200 +++ b/gen/todebug.cpp Thu Jun 12 16:58:26 2008 +0200 @@ -34,17 +34,27 @@ { LLConstant* c = llvm::ConstantStruct::get(type, values); LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; - LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, linkage, c, name, gIR->module); + LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, c, name, gIR->module); + gv->setSection("llvm.metadata"); + return gv; +} + +/** + * Emits a global variable, LLVM Dwarf style, only declares. + * @param type Type of variable. + * @param name Name. + * @return The global variable. + */ +static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const char* name, bool linkonce=false) +{ + LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; + LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, NULL, name, gIR->module); gv->setSection("llvm.metadata"); return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// -static llvm::GlobalVariable* dbg_compile_units = 0; -static llvm::GlobalVariable* dbg_global_variables = 0; -static llvm::GlobalVariable* dbg_subprograms = 0; - /** * Emits the Dwarf anchors that are used repeatedly by LLVM debug info. */ @@ -53,34 +63,33 @@ const llvm::StructType* anchorTy = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type")); std::vector vals(2); - if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) { - vals[0] = DtoConstUint(llvm::LLVMDebugVersion); - vals[1] = DtoConstUint(DW_TAG_compile_unit); - dbg_compile_units = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.compile_units", true); - } - if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) { - vals[0] = DtoConstUint(llvm::LLVMDebugVersion); - vals[1] = DtoConstUint(DW_TAG_variable); - dbg_global_variables = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.global_variables", true); - } - if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) { - vals[0] = DtoConstUint(llvm::LLVMDebugVersion); - vals[1] = DtoConstUint(DW_TAG_subprogram); - dbg_subprograms = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.subprograms", true); - } + vals[0] = DtoConstUint(llvm::LLVMDebugVersion); + vals[1] = DtoConstUint(DW_TAG_compile_unit); + gIR->dwarfCUs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.compile_units", true); + + vals[0] = DtoConstUint(llvm::LLVMDebugVersion); + vals[1] = DtoConstUint(DW_TAG_variable); + gIR->dwarfGVs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.global_variables", true); + + vals[0] = DtoConstUint(llvm::LLVMDebugVersion); + vals[1] = DtoConstUint(DW_TAG_subprogram); + gIR->dwarfSPs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.subprograms", true); } +////////////////////////////////////////////////////////////////////////////////////////////////// + static LLConstant* getDwarfAnchor(dwarf_constants c) { - emitDwarfAnchors(); + if (!gIR->dwarfCUs) + emitDwarfAnchors(); switch (c) { case DW_TAG_compile_unit: - return dbg_compile_units; + return gIR->dwarfCUs; case DW_TAG_variable: - return dbg_global_variables; + return gIR->dwarfGVs; case DW_TAG_subprogram: - return dbg_subprograms; + return gIR->dwarfSPs; default: assert(0); } @@ -163,7 +172,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu, const char* c_name); +static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name); ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -226,7 +235,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfDerivedType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit) +static LLGlobalVariable* dwarfDerivedType(Type* type, llvm::GlobalVariable* compileUnit) { const LLType* T = DtoType(type); Type* t = DtoDType(type); @@ -276,7 +285,7 @@ // base type Type* nt = t->nextOf(); - LLGlobalVariable* nTD = dwarfTypeDescription(loc, nt, compileUnit, NULL); + LLGlobalVariable* nTD = dwarfTypeDescription(nt, compileUnit, NULL); if (nt->ty == Tvoid || !nTD) vals.push_back(DBG_NULL); else @@ -287,7 +296,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfMemberType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit, const char* c_name, unsigned offset) +static LLGlobalVariable* dwarfMemberType(unsigned linnum, Type* type, LLGlobalVariable* compileUnit, LLGlobalVariable* definedCU, const char* c_name, unsigned offset) { const LLType* T = DtoType(type); Type* t = DtoDType(type); @@ -311,10 +320,13 @@ vals.push_back(name); // compile unit where defined - vals.push_back(DBG_NULL); + if (definedCU) + vals.push_back(DBG_CAST(definedCU)); + else + vals.push_back(DBG_NULL); // line number where defined - vals.push_back(DtoConstInt(0)); + vals.push_back(DtoConstInt(linnum)); // size in bits vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false)); @@ -329,7 +341,7 @@ vals.push_back(DtoConstUint(0)); // base type - LLGlobalVariable* nTD = dwarfTypeDescription(loc, t, compileUnit, NULL); + LLGlobalVariable* nTD = dwarfTypeDescription(t, compileUnit, NULL); if (t->ty == Tvoid || !nTD) vals.push_back(DBG_NULL); else @@ -340,7 +352,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfCompositeType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit) +static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* compileUnit) { const LLType* T = DtoType(type); Type* t = DtoDType(type); @@ -348,16 +360,23 @@ // defaults LLConstant* name = getNullPtr(getVoidPtrType()); LLGlobalVariable* members = NULL; + unsigned linnum = 0; + LLGlobalVariable* definedCU = NULL; // prepare tag and members unsigned tag; + + // declare final global variable + LLGlobalVariable* gv = NULL; + + // dynamic array if (t->ty == Tarray) { tag = DW_TAG_structure_type; - LLGlobalVariable* len = dwarfMemberType(loc, Type::tsize_t, compileUnit, "length", 0); + LLGlobalVariable* len = dwarfMemberType(0, Type::tsize_t, compileUnit, NULL, "length", 0); assert(len); - LLGlobalVariable* ptr = dwarfMemberType(loc, t->nextOf()->pointerTo(), compileUnit, "ptr", global.params.is64bit?8:4); + LLGlobalVariable* ptr = dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, NULL, "ptr", global.params.is64bit?8:4); assert(ptr); const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2); @@ -366,14 +385,52 @@ elems.push_back(DBG_CAST(len)); elems.push_back(DBG_CAST(ptr)); -// elems[0]->dump(); -// elems[1]->dump(); -// at->dump(); + LLConstant* ca = LLConstantArray::get(at, elems); + members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module); + members->setSection("llvm.metadata"); + + name = DtoConstStringPtr(t->toChars(), "llvm.metadata"); + } + + // struct + else if (t->ty == Tstruct) + { + TypeStruct* ts = (TypeStruct*)t; + StructDeclaration* sd = ts->sym; + assert(sd); + + IrStruct* ir = sd->ir.irStruct; + assert(ir); + if (ir->dwarfComposite) + return ir->dwarfComposite; + // set to handle recursive types properly + gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype"); + ir->dwarfComposite = gv; + + tag = DW_TAG_structure_type; + + name = DtoConstStringPtr(sd->toChars(), "llvm.metadata"); + linnum = sd->loc.linnum; + definedCU = DtoDwarfCompileUnit(sd->getModule()); + + std::vector elems; + for (IrStruct::OffsetMap::iterator i=ir->offsets.begin(); i!=ir->offsets.end(); ++i) + { + unsigned offset = i->first; + IrStruct::Offset& o = i->second; + + LLGlobalVariable* ptr = dwarfMemberType(o.var->loc.linnum, o.var->type, compileUnit, definedCU, o.var->toChars(), offset); + elems.push_back(DBG_CAST(ptr)); + } + + const LLArrayType* at = LLArrayType::get(DBG_TYPE, elems.size()); LLConstant* ca = LLConstantArray::get(at, elems); members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module); members->setSection("llvm.metadata"); } + + // unsupported composite type else { assert(0 && "unsupported compositetype for debug info"); @@ -391,10 +448,13 @@ vals.push_back(name); // compile unit where defined - vals.push_back(DBG_NULL); + if (definedCU) + vals.push_back(DBG_CAST(definedCU)); + else + vals.push_back(DBG_NULL); // line number where defined - vals.push_back(DtoConstInt(0)); + vals.push_back(DtoConstInt(linnum)); // size in bits vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false)); @@ -417,7 +477,13 @@ else vals.push_back(DBG_NULL); - return emitDwarfGlobal(getDwarfCompositeTypeType(), vals, "llvm.dbg.compositetype"); + // set initializer + if (!gv) + gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype"); + LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals); + gv->setInitializer(initia); + + return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -440,7 +506,7 @@ vals.push_back(DBG_CAST(DtoDwarfCompileUnit(vd->getModule()))); vals.push_back(DtoConstUint(vd->loc.linnum)); - LLGlobalVariable* TY = dwarfTypeDescription(vd->loc, vd->type, compileUnit, NULL); + LLGlobalVariable* TY = dwarfTypeDescription(vd->type, compileUnit, NULL); vals.push_back(TY ? DBG_CAST(TY) : DBG_NULL); vals.push_back(DtoConstBool(vd->protection == PROTprivate)); vals.push_back(DtoConstBool(vd->getModule() == gIR->dmodule)); @@ -450,6 +516,8 @@ return emitDwarfGlobal(getDwarfGlobalVariableType(), vals, "llvm.dbg.global_variable"); } +////////////////////////////////////////////////////////////////////////////////////////////////// + static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr) { assert(!vd->isDataseg() && "static variable"); @@ -489,7 +557,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu, const char* c_name) +static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tvoid) @@ -497,12 +565,10 @@ else if (t->isintegral() || t->isfloating()) return dwarfBasicType(type, cu); else if (t->ty == Tpointer) - return dwarfDerivedType(loc, type, cu); - else if (t->ty == Tarray) - return dwarfCompositeType(loc, type, cu); + return dwarfDerivedType(type, cu); + else if (t->ty == Tarray || t->ty == Tstruct) + return dwarfCompositeType(type, cu); - if (global.params.warnings) - warning("%s: unsupported type for debug info: %s", loc.toChars(), type->toChars()); return NULL; } @@ -518,7 +584,7 @@ // get type description Type* t = vd->type->toBasetype(); - LLGlobalVariable* TD = dwarfTypeDescription(vd->loc, vd->type, thisCU, NULL); + LLGlobalVariable* TD = dwarfTypeDescription(vd->type, thisCU, NULL); if (TD == NULL) return; // unsupported diff -r 2f2d7c843e5d -r e3355ce5444b ir/irmodule.cpp --- a/ir/irmodule.cpp Wed Jun 11 21:03:55 2008 +0200 +++ b/ir/irmodule.cpp Thu Jun 12 16:58:26 2008 +0200 @@ -1,3 +1,4 @@ +#include "gen/llvm.h" #include "ir/irmodule.h" IrModule::IrModule(Module* module) diff -r 2f2d7c843e5d -r e3355ce5444b ir/irmodule.h --- a/ir/irmodule.h Wed Jun 11 21:03:55 2008 +0200 +++ b/ir/irmodule.h Thu Jun 12 16:58:26 2008 +0200 @@ -12,7 +12,7 @@ Module* M; - llvm::GlobalVariable* dwarfCompileUnit; + LLGlobalVariable* dwarfCompileUnit; }; #endif diff -r 2f2d7c843e5d -r e3355ce5444b ir/irstruct.cpp --- a/ir/irstruct.cpp Wed Jun 11 21:03:55 2008 +0200 +++ b/ir/irstruct.cpp Thu Jun 12 16:58:26 2008 +0200 @@ -50,6 +50,8 @@ classDeclared = false; classDefined = false; + + dwarfComposite = NULL; } IrStruct::~IrStruct() diff -r 2f2d7c843e5d -r e3355ce5444b ir/irstruct.h --- a/ir/irstruct.h Wed Jun 11 21:03:55 2008 +0200 +++ b/ir/irstruct.h Thu Jun 12 16:58:26 2008 +0200 @@ -12,24 +12,24 @@ ClassDeclaration* decl; #if OPAQUE_VTBLS - const llvm::ArrayType* vtblTy; - llvm::ConstantArray* vtblInit; + const LLArrayType* vtblTy; + LLConstantArray* vtblInit; #else - const llvm::StructType* vtblTy; - llvm::ConstantStruct* vtblInit; + const LLStructType* vtblTy; + LLConstantStruct* vtblInit; #endif - llvm::GlobalVariable* vtbl; + LLGlobalVariable* vtbl; - const llvm::StructType* infoTy; - llvm::ConstantStruct* infoInit; - llvm::Constant* info; + const LLStructType* infoTy; + LLConstantStruct* infoInit; + LLConstant* info; int index; #if OPAQUE_VTBLS - IrInterface(BaseClass* b, const llvm::ArrayType* vt); + IrInterface(BaseClass* b, const LLArrayType* vt); #else - IrInterface(BaseClass* b, const llvm::StructType* vt); + IrInterface(BaseClass* b, const LLStructType* vt); #endif ~IrInterface(); }; @@ -45,7 +45,7 @@ { VarDeclaration* var; const LLType* type; - llvm::Constant* init; + LLConstant* init; Offset(VarDeclaration* v, const LLType* ty) : var(v), type(ty), init(NULL) {} @@ -70,25 +70,27 @@ InterfaceMap interfaceMap; InterfaceVector interfaceVec; const llvm::ArrayType* interfaceInfosTy; - llvm::GlobalVariable* interfaceInfos; + LLGlobalVariable* interfaceInfos; bool defined; bool constinited; - llvm::GlobalVariable* vtbl; + LLGlobalVariable* vtbl; #if OPAQUE_VTBLS - llvm::Constant* constVtbl; + LLConstant* constVtbl; #else - llvm::ConstantStruct* constVtbl; + LLConstantStruct* constVtbl; #endif - llvm::GlobalVariable* init; - llvm::Constant* constInit; - llvm::GlobalVariable* classInfo; - llvm::Constant* constClassInfo; + LLGlobalVariable* init; + LLConstant* constInit; + LLGlobalVariable* classInfo; + LLConstant* constClassInfo; bool hasUnions; DUnion* dunion; bool classDeclared; bool classDefined; + + LLGlobalVariable* dwarfComposite; }; #endif diff -r 2f2d7c843e5d -r e3355ce5444b llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Wed Jun 11 21:03:55 2008 +0200 +++ b/llvmdc.kdevelop.filelist Thu Jun 12 16:58:26 2008 +0200 @@ -771,6 +771,7 @@ tangotests/debug5.d tangotests/debug6.d tangotests/debug7.d +tangotests/debug8.d tangotests/e.d tangotests/f.d tangotests/files1.d