# HG changeset patch # User Christian Kamm # Date 1234108222 -3600 # Node ID 1714836f2c0bb42c671b29f0243b1c566d078fb6 # Parent 03d7c4aac65487edb74455631b995d4db98e21fe Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h. Add getCompilationModule to Dsymbol and fix template compile unit decision code. Runtime compiles with -g again. diff -r 03d7c4aac654 -r 1714836f2c0b dmd/dsymbol.c --- a/dmd/dsymbol.c Sun Feb 08 05:26:54 2009 +0100 +++ b/dmd/dsymbol.c Sun Feb 08 16:50:22 2009 +0100 @@ -554,6 +554,34 @@ return NULL; } + +/********************************** + * Determine which Module a Dsymbol will be compiled in. + * This may be different from getModule for templates. + */ + +Module *Dsymbol::getCompilationModule() +{ + Module *m; + TemplateInstance *ti; + Dsymbol *s; + + //printf("Dsymbol::getModule()\n"); + s = this; + while (s) + { + //printf("\ts = '%s'\n", s->toChars()); + m = s->isModule(); + if (m) + return m; + ti = s->isTemplateInstance(); + if (ti && ti->tmodule) + return ti->tmodule; + s = s->parent; + } + return NULL; +} + /************************************* */ diff -r 03d7c4aac654 -r 1714836f2c0b dmd/dsymbol.h --- a/dmd/dsymbol.h Sun Feb 08 05:26:54 2009 +0100 +++ b/dmd/dsymbol.h Sun Feb 08 16:50:22 2009 +0100 @@ -119,7 +119,8 @@ void error(Loc loc, const char *format, ...); void error(const char *format, ...); void checkDeprecated(Loc loc, Scope *sc); - Module *getModule(); + Module *getModule(); // module where declared + Module *getCompilationModule(); // possibly different for templates Dsymbol *pastMixin(); Dsymbol *toParent(); Dsymbol *toParent2(); diff -r 03d7c4aac654 -r 1714836f2c0b dmd/template.c --- a/dmd/template.c Sun Feb 08 05:26:54 2009 +0100 +++ b/dmd/template.c Sun Feb 08 16:50:22 2009 +0100 @@ -2982,7 +2982,12 @@ // get the enclosing template instance from the scope tinst tinst = sc->tinst; - tmodule = sc->module; + + // get the module of the outermost enclosing instantiation + if (tinst) + tmodule = tinst->tmodule; + else + tmodule = sc->module; #if LOG printf("\tdo semantic\n"); diff -r 03d7c4aac654 -r 1714836f2c0b gen/functions.cpp --- a/gen/functions.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/functions.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -647,7 +647,7 @@ // debug info if (global.params.symdebug) { Module* mo = fd->getModule(); - fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd); + fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd); } Type* t = fd->type->toBasetype(); diff -r 03d7c4aac654 -r 1714836f2c0b gen/irstate.cpp --- a/gen/irstate.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/irstate.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -47,14 +47,14 @@ } ////////////////////////////////////////////////////////////////////////////////////////// -IRState::IRState() +IRState::IRState(llvm::Module* m) + : module(m), difactory(*m) { interfaceInfoType = NULL; mutexType = NULL; moduleRefType = NULL; dmodule = 0; - module = 0; emitMain = false; mainFunc = 0; ir.state = this; diff -r 03d7c4aac654 -r 1714836f2c0b gen/irstate.h --- a/gen/irstate.h Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/irstate.h Sun Feb 08 16:50:22 2009 +0100 @@ -131,7 +131,7 @@ // represents the module struct IRState { - IRState(); + IRState(llvm::Module* m); // module Module* dmodule; @@ -190,6 +190,9 @@ // builder helper IRBuilderHelper ir; + // debug info helper + llvm::DIFactory difactory; + typedef std::list DsymbolList; // dsymbols that need to be resolved DsymbolList resolveList; diff -r 03d7c4aac654 -r 1714836f2c0b gen/llvm.h --- a/gen/llvm.h Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/llvm.h Sun Feb 08 16:50:22 2009 +0100 @@ -14,6 +14,8 @@ #include "llvm/Target/TargetData.h" +#include "llvm/Analysis/DebugInfo.h" + #include "llvm/Support/IRBuilder.h" using llvm::IRBuilder; diff -r 03d7c4aac654 -r 1714836f2c0b gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/llvmhelpers.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -974,7 +974,7 @@ // do debug info if (global.params.symdebug) { - LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd); + LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV(); // keep a reference so GDCE doesn't delete it ! gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType())); } @@ -1557,7 +1557,7 @@ bool mustDefineSymbol(Dsymbol* s) { -#if 1 +#if 0 return s->getModule() == gIR->dmodule || DtoIsTemplateInstance(s) != NULL; #else Module* M = DtoIsTemplateInstance(s); @@ -1573,7 +1573,7 @@ bool needsTemplateLinkage(Dsymbol* s) { -#if 1 +#if 0 return DtoIsTemplateInstance(s) != NULL; #else Module* M = DtoIsTemplateInstance(s); diff -r 03d7c4aac654 -r 1714836f2c0b gen/todebug.cpp --- a/gen/todebug.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/todebug.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -25,22 +25,6 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// /** - * Emits a global variable, LLVM Dwarf style. - * @param type Type of variable. - * @param values Initializers. - * @param name Name. - * @return The global variable. - */ -static LLGlobalVariable* emitDwarfGlobal(const LLStructType* type, const std::vector values, const char* name, bool linkonce=false) -{ - LLConstant* c = llvm::ConstantStruct::get(type, values); - LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; - 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. @@ -56,41 +40,16 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Emits the Dwarf anchors that are used repeatedly by LLVM debug info. - */ -static void emitDwarfAnchors() +static llvm::DIAnchor getDwarfAnchor(dwarf_constants c) { - const llvm::StructType* anchorTy = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type")); - std::vector vals(2); - - 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) -{ - if (!gIR->dwarfCUs) - emitDwarfAnchors(); switch (c) { case DW_TAG_compile_unit: - return gIR->dwarfCUs; + return gIR->difactory.GetOrCreateCompileUnitAnchor(); case DW_TAG_variable: - return gIR->dwarfGVs; + return gIR->difactory.GetOrCreateGlobalVariableAnchor(); case DW_TAG_subprogram: - return gIR->dwarfSPs; + return gIR->difactory.GetOrCreateSubprogramAnchor(); default: assert(0); } @@ -126,123 +85,20 @@ return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type")); } -////////////////////////////////////////////////////////////////////////////////////////////////// - -static LLGlobalVariable* dwarfCompileUnit(Module* m) -{ - std::vector vals(6); - vals[0] = DBG_TAG(DW_TAG_compile_unit); - vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_compile_unit)); - - if (global.params.symdebug == 2) - vals[2] = DtoConstUint(DW_LANG_C); - else - vals[2] = DtoConstUint(DW_LANG_D); - vals[3] = DtoConstStringPtr(FileName::name(m->srcfile->name->toChars()), "llvm.metadata"); - std::string srcpath(FileName::path(m->srcfile->name->toChars())); - if (!FileName::absolute(srcpath.c_str())) { - llvm::sys::Path tmp = llvm::sys::Path::GetCurrentDirectory(); - tmp.appendComponent(srcpath); - srcpath = tmp.toString(); - if (!srcpath.empty() && *srcpath.rbegin() != '/' && *srcpath.rbegin() != '\\') - srcpath = srcpath + '/'; - } - vals[4] = DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"); - vals[5] = DtoConstStringPtr("LDC (http://www.dsource.org/projects/ldc)", "llvm.metadata"); - - LLGlobalVariable* gv = emitDwarfGlobal(getDwarfCompileUnitType(), vals, "llvm.dbg.compile_unit"); - m->ir.irModule->dwarfCompileUnit = gv; - return gv; -} ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfSubProgram(llvm::GlobalVariable* emitUnit, llvm::GlobalVariable* defineUnit, const char* prettyname, const char* mangledname, unsigned int linenum, bool isprivate) -{ - std::vector vals(11); - vals[0] = DBG_TAG(DW_TAG_subprogram); - vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_subprogram)); - - vals[2] = DBG_CAST(emitUnit); - vals[3] = DtoConstStringPtr(prettyname, "llvm.metadata"); - vals[4] = vals[3]; - vals[5] = DtoConstStringPtr(mangledname, "llvm.metadata"); - vals[6] = DBG_CAST(defineUnit); - vals[7] = DtoConstUint(linenum); - vals[8] = DBG_NULL; - vals[9] = DtoConstBool(isprivate); - vals[10] = DtoConstBool(emitUnit == defineUnit); - - Logger::println("emitting subprogram global"); - - return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram"); -} - -/* -static LLGlobalVariable* dwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) -{ - std::vector vals(11); - vals[0] = DBG_TAG(DW_TAG_subprogram); - vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_subprogram)); - - vals[2] = DBG_CAST(compileUnit); - vals[3] = DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata"); - vals[4] = vals[3]; - vals[5] = DtoConstStringPtr(fd->mangle(), "llvm.metadata"); - vals[6] = DBG_CAST( DtoDwarfCompileUnit(fd->getModule()) ); - vals[7] = DtoConstUint(fd->loc.linnum); - vals[8] = DBG_NULL; - vals[9] = DtoConstBool(fd->protection == PROTprivate); - vals[10] = DtoConstBool(fd->getModule() == gIR->dmodule); - - Logger::println("emitting subprogram global"); - - return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram"); -}*/ +static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name); +static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name); ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name); -static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name); - -////////////////////////////////////////////////////////////////////////////////////////////////// - -static LLGlobalVariable* dwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit) +static llvm::DIBasicType dwarfBasicType(Type* type, llvm::DICompileUnit compileUnit) { Type* t = type->toBasetype(); - const LLType* T = DtoType(type); - std::vector vals(10); - - // tag - vals[0] = DBG_TAG(DW_TAG_base_type); - - // context - vals[1] = DBG_CAST(compileUnit); - - // name - vals[2] = DtoConstStringPtr(type->toChars(), "llvm.metadata"); - - // compile unit where defined - vals[3] = DBG_NULL; - - // line number where defined - vals[4] = DtoConstInt(0); - - // size in bits - vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); - - // alignment in bits - vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); - - // offset in bits - vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false); - - // FIXME: dont know what this is - vals[8] = DtoConstUint(0); - - // dwarf type + // find encoding unsigned id; if (t->isintegral()) { @@ -259,131 +115,85 @@ { assert(0 && "unsupported basictype for debug info"); } - vals[9] = DtoConstUint(id); - return emitDwarfGlobal(getDwarfBasicTypeType(), vals, "llvm.dbg.basictype"); + return gIR->difactory.CreateBasicType( + compileUnit, // context + type->toChars(), // name + llvm::DICompileUnit(NULL), // compile unit + 0, // line number + getTypeBitSize(T), // size (bits) + getABITypeAlign(T)*8, // align (bits) + 0, // offset (bits) +//FIXME: need flags? + 0, // flags + id // encoding + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfDerivedType(Type* type, llvm::GlobalVariable* compileUnit) +static llvm::DIDerivedType dwarfDerivedType(Type* type, llvm::DICompileUnit compileUnit) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); - // defaults - LLConstant* name = getNullPtr(getVoidPtrType()); + assert(t->ty == Tpointer && "unsupported derivedtype for debug info, only pointers allowed"); - // find tag - unsigned tag; - if (t->ty == Tpointer) - { - tag = DW_TAG_pointer_type; - } - else - { - assert(0 && "unsupported derivedtype for debug info"); - } - - std::vector vals(10); - - // tag - vals[0] = DBG_TAG(tag); - - // context - vals[1] = DBG_CAST(compileUnit); - - // name - vals[2] = name; + // find base type + llvm::DIType basetype; + Type* nt = t->nextOf(); + basetype = dwarfTypeDescription_impl(nt, compileUnit, NULL); + if (nt->ty == Tvoid) + basetype = llvm::DIType(NULL); - // compile unit where defined - vals[3] = DBG_NULL; - - // line number where defined - vals[4] = DtoConstInt(0); - - // size in bits - vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); - - // alignment in bits - vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); - - // offset in bits - vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false); - - // FIXME: dont know what this is - vals[8] = DtoConstUint(0); - - // base type - Type* nt = t->nextOf(); - LLGlobalVariable* nTD = dwarfTypeDescription_impl(nt, compileUnit, NULL); - if (nt->ty == Tvoid || !nTD) - vals[9] = DBG_NULL; - else - vals[9] = DBG_CAST(nTD); - - return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype"); + return gIR->difactory.CreateDerivedType( + DW_TAG_pointer_type, // tag + compileUnit, // context + "", // name + llvm::DICompileUnit(NULL), // compile unit + 0, // line number + getTypeBitSize(T), // size (bits) + getABITypeAlign(T)*8, // align (bits) + 0, // offset (bits) +//FIXME: need flags? + 0, // flags + basetype // derived from + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfMemberType(unsigned linnum, Type* type, LLGlobalVariable* compileUnit, LLGlobalVariable* definedCU, const char* c_name, unsigned offset) +static llvm::DIDerivedType dwarfMemberType(unsigned linnum, Type* type, llvm::DICompileUnit compileUnit, llvm::DICompileUnit definedCU, const char* c_name, unsigned offset) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); - // defaults - LLConstant* name; - if (c_name) - name = DtoConstStringPtr(c_name, "llvm.metadata"); - else - name = getNullPtr(getVoidPtrType()); - - std::vector vals(10); - - // tag - vals[0] = DBG_TAG(DW_TAG_member); - - // context - vals[1] = DBG_CAST(compileUnit); - - // name - vals[2] = name; - - // compile unit where defined - if (definedCU) - vals[3] = DBG_CAST(definedCU); - else - vals[3] = DBG_NULL; + // find base type + llvm::DIType basetype; + basetype = dwarfTypeDescription(t, compileUnit, NULL); + if (t->ty == Tvoid) + basetype = llvm::DIType(NULL); - // line number where defined - vals[4] = DtoConstInt(linnum); - - // size in bits - vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); - - // alignment in bits - vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); - - // offset in bits - vals[7] = LLConstantInt::get(LLType::Int64Ty, offset*8, false); - - // FIXME: dont know what this is - vals[8] = DtoConstUint(0); - - // base type - LLGlobalVariable* nTD = dwarfTypeDescription(t, compileUnit, NULL); - if (t->ty == Tvoid || !nTD) - vals[9] = DBG_NULL; - else - vals[9] = DBG_CAST(nTD); - - return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype"); + return gIR->difactory.CreateDerivedType( + DW_TAG_member, // tag + compileUnit, // context + c_name, // name + definedCU, // compile unit + linnum, // line number + getTypeBitSize(T), // size (bits) + getABITypeAlign(T)*8, // align (bits) + offset*8, // offset (bits) +//FIXME: need flags? + 0, // flags + basetype // derived from + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* compileUnit) +//FIXME: This does not use llvm's DIFactory as it can't +// handle recursive types properly. +static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit compileUnit) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); @@ -392,7 +202,7 @@ LLConstant* name = getNullPtr(getVoidPtrType()); LLGlobalVariable* members = NULL; unsigned linnum = 0; - LLGlobalVariable* definedCU = NULL; + llvm::DICompileUnit definedCU; // prepare tag and members unsigned tag; @@ -405,9 +215,9 @@ { tag = DW_TAG_structure_type; - LLGlobalVariable* len = dwarfMemberType(0, Type::tsize_t, compileUnit, NULL, "length", 0); + LLGlobalVariable* len = dwarfMemberType(0, Type::tsize_t, compileUnit, llvm::DICompileUnit(NULL), "length", 0).getGV(); assert(len); - LLGlobalVariable* ptr = dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, NULL, "ptr", global.params.is64bit?8:4); + LLGlobalVariable* ptr = dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, llvm::DICompileUnit(NULL), "ptr", global.params.is64bit?8:4).getGV(); assert(ptr); const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2); @@ -442,22 +252,24 @@ // 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 NULL; + return llvm::DICompositeType(NULL); IrStruct* ir = sd->ir.irStruct; assert(ir); - if (ir->dwarfComposite) - return ir->dwarfComposite; + if (!ir->diCompositeType.isNull()) + return ir->diCompositeType; // set to handle recursive types properly gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype"); - ir->dwarfComposite = gv; + // set bogus initializer to satisfy asserts in DICompositeType constructor + gv->setInitializer(LLConstant::getNullValue(getDwarfCompositeTypeType())); + ir->diCompositeType = llvm::DICompositeType(gv); tag = DW_TAG_structure_type; name = DtoConstStringPtr(sd->toChars(), "llvm.metadata"); linnum = sd->loc.linnum; - definedCU = DtoDwarfCompileUnit(sd->getModule()); + definedCU = DtoDwarfCompileUnit(sd->getCompilationModule()); std::vector elems; if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one @@ -470,7 +282,7 @@ VarDeclaration* vd = arr[k]; assert(vd); - LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset); + LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset).getGV(); elems.push_back(DBG_CAST(ptr)); } } @@ -493,14 +305,14 @@ vals[0] = DBG_TAG(tag); // context - vals[1] = DBG_CAST(compileUnit); + vals[1] = DBG_CAST(compileUnit.getGV()); // name vals[2] = name; // compile unit where defined - if (definedCU) - vals[3] = DBG_CAST(definedCU); + if (definedCU.getGV()) + vals[3] = DBG_CAST(definedCU.getGV()); else vals[3] = DBG_NULL; @@ -534,42 +346,33 @@ LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals); gv->setInitializer(initia); - return gv; + return llvm::DICompositeType(gv); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) +static llvm::DIGlobalVariable dwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) { assert(vd->isDataseg()); - LLGlobalVariable* compileUnit = DtoDwarfCompileUnit(gIR->dmodule); - - std::vector vals(12); - vals[0] = DBG_TAG(DW_TAG_variable); - vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_variable)); - - vals[2] = DBG_CAST(compileUnit); - - vals[3] = DtoConstStringPtr(vd->mangle(), "llvm.metadata"); - vals[4] = DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata"); - vals[5] = DtoConstStringPtr(vd->toChars(), "llvm.metadata"); + llvm::DICompileUnit compileUnit = DtoDwarfCompileUnit(gIR->dmodule); - vals[6] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule())); - vals[7] = DtoConstUint(vd->loc.linnum); - - LLGlobalVariable* TY = dwarfTypeDescription_impl(vd->type, compileUnit, NULL); - vals[8] = TY ? DBG_CAST(TY) : DBG_NULL; - vals[9] = DtoConstBool(vd->protection == PROTprivate); - vals[10] = DtoConstBool(vd->getModule() == gIR->dmodule); - - vals[11] = DBG_CAST(ll); - - return emitDwarfGlobal(getDwarfGlobalVariableType(), vals, "llvm.dbg.global_variable"); + return gIR->difactory.CreateGlobalVariable( + compileUnit, // context + vd->mangle(), // name + vd->toPrettyChars(), // displayname + vd->toChars(), // linkage name + DtoDwarfCompileUnit(vd->getCompilationModule()), // compile unit + vd->loc.linnum, // line num + dwarfTypeDescription_impl(vd->type, compileUnit, NULL), // type + vd->protection == PROTprivate, // is local to unit + vd->getCompilationModule() == gIR->dmodule, // is definition + ll // value + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr) +static llvm::DIVariable dwarfVariable(VarDeclaration* vd, llvm::DIType type) { assert(!vd->isDataseg() && "static variable"); @@ -579,40 +382,30 @@ else tag = DW_TAG_auto_variable; - std::vector vals(6); - // tag - vals[0] = DBG_TAG(tag); - // context - vals[1] = DBG_CAST(gIR->func()->dwarfSubProg); - // name - vals[2] = DtoConstStringPtr(vd->toChars(), "llvm.metadata"); - // compile unit where defined - vals[3] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule())); - // line number where defined - vals[4] = DtoConstUint(vd->loc.linnum); - // type descriptor - vals[5] = DBG_CAST(typeDescr); - - return emitDwarfGlobal(getDwarfVariableType(), vals, "llvm.dbg.variable"); + return gIR->difactory.CreateVariable( + tag, // tag + gIR->func()->diSubprogram, // context + vd->toChars(), // name + DtoDwarfCompileUnit(vd->getCompilationModule()), // compile unit + vd->loc.linnum, // line num + type // type + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static void dwarfDeclare(LLValue* var, LLGlobalVariable* varDescr) +static void dwarfDeclare(LLValue* var, llvm::DIVariable divar) { - LLSmallVector args(2); - args[0] = DtoBitCast(var, DBG_TYPE); - args[1] = DBG_CAST(varDescr); - gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end()); + gIR->difactory.InsertDeclare(var, divar, gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name) +static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tvoid) - return NULL; + return llvm::DIType(NULL); else if (t->isintegral() || t->isfloating()) return dwarfBasicType(type, cu); else if (t->ty == Tpointer) @@ -620,10 +413,10 @@ else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass) return dwarfCompositeType(type, cu); - return NULL; + return llvm::DIType(NULL); } -static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name) +static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tclass) @@ -640,20 +433,18 @@ LOG_SCOPE; // get compile units - LLGlobalVariable* thisCU = DtoDwarfCompileUnit(gIR->dmodule); - LLGlobalVariable* varCU = thisCU; - if (vd->getModule() != gIR->dmodule) - varCU = DtoDwarfCompileUnit(vd->getModule()); + llvm::DICompileUnit thisCU = DtoDwarfCompileUnit(gIR->dmodule); + llvm::DICompileUnit varCU = thisCU; + if (vd->getCompilationModule() != gIR->dmodule) + varCU = DtoDwarfCompileUnit(vd->getCompilationModule()); // get type description - Type* t = vd->type->toBasetype(); - LLGlobalVariable* TD = dwarfTypeDescription(vd->type, thisCU, NULL); - if (TD == NULL) + llvm::DIType TD = dwarfTypeDescription(vd->type, thisCU, NULL); + if (TD.isNull()) return; // unsupported // get variable description - LLGlobalVariable* VD; - VD = dwarfVariable(vd, TD); + llvm::DIVariable VD = dwarfVariable(vd, TD); // declare dwarfDeclare(ll, VD); @@ -661,7 +452,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -LLGlobalVariable* DtoDwarfCompileUnit(Module* m) +llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) { Logger::println("D to dwarf compile_unit"); LOG_SCOPE; @@ -669,52 +460,89 @@ // we might be generating for an import if (!m->ir.irModule) m->ir.irModule = new IrModule(m, m->srcfile->toChars()); - else if (m->ir.irModule->dwarfCompileUnit) + else if (!m->ir.irModule->diCompileUnit.isNull()) { - if (m->ir.irModule->dwarfCompileUnit->getParent() == gIR->module) - return m->ir.irModule->dwarfCompileUnit; + assert (m->ir.irModule->diCompileUnit.getGV()->getParent() == gIR->module + && "debug info compile unit belongs to incorrect llvm module!"); + return m->ir.irModule->diCompileUnit; } - LLGlobalVariable* gv = dwarfCompileUnit(m); - m->ir.irModule->dwarfCompileUnit = gv; - return gv; + // prepare srcpath + std::string srcpath(FileName::path(m->srcfile->name->toChars())); + if (!FileName::absolute(srcpath.c_str())) { + llvm::sys::Path tmp = llvm::sys::Path::GetCurrentDirectory(); + tmp.appendComponent(srcpath); + srcpath = tmp.toString(); + if (!srcpath.empty() && *srcpath.rbegin() != '/' && *srcpath.rbegin() != '\\') + srcpath = srcpath + '/'; + } + + // make compile unit + m->ir.irModule->diCompileUnit = gIR->difactory.CreateCompileUnit( + global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D, + m->srcfile->name->toChars(), + srcpath, + "LDC (http://www.dsource.org/projects/ldc)", +//FIXME: What do these two mean? + false, // isMain, + false // isOptimized + ); + + return m->ir.irModule->diCompileUnit; } ////////////////////////////////////////////////////////////////////////////////////////////////// -LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd) +llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd) { Logger::println("D to dwarf subprogram"); LOG_SCOPE; + llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); + llvm::DICompileUnit definition = DtoDwarfCompileUnit(fd->getCompilationModule()); + // FIXME: duplicates ? - return dwarfSubProgram( - DtoDwarfCompileUnit(gIR->dmodule), - DtoDwarfCompileUnit(fd->getModule()), - fd->toPrettyChars(), fd->mangle(), - fd->loc.linnum, - fd->protection == PROTprivate); + return gIR->difactory.CreateSubprogram( + context, // context + fd->toPrettyChars(), // name + fd->toPrettyChars(), // display name + fd->mangle(), // linkage name + definition, // compile unit + fd->loc.linnum, // line no +//FIXME: what's this type for? + llvm::DIType(NULL), // type + fd->protection == PROTprivate, // is local to unit + context.getGV() == definition.getGV() // isdefinition + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -LLGlobalVariable* DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname) +llvm::DISubprogram DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname) { Logger::println("D to dwarf subprogram"); LOG_SCOPE; + llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); + // FIXME: duplicates ? - return dwarfSubProgram( - DtoDwarfCompileUnit(gIR->dmodule), - DtoDwarfCompileUnit(gIR->dmodule), - prettyname, mangledname, - 0, - true); + return gIR->difactory.CreateSubprogram( + context, // context + prettyname, // name + prettyname, // display name + mangledname, // linkage name + context, // compile unit + 0, // line no +//FIXME: what's this type for? + llvm::DIType(NULL), // type + true, // is local to unit + true // isdefinition + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) +llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) { Logger::println("D to dwarf global_variable"); LOG_SCOPE; @@ -730,8 +558,8 @@ Logger::println("D to dwarf funcstart"); LOG_SCOPE; - assert(fd->ir.irFunc->dwarfSubProg); - gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); + assert(!fd->ir.irFunc->diSubprogram.isNull()); + gIR->difactory.InsertSubprogramStart(fd->ir.irFunc->diSubprogram, gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -741,8 +569,8 @@ Logger::println("D to dwarf funcend"); LOG_SCOPE; - assert(fd->ir.irFunc->dwarfSubProg); - gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); + assert(!fd->ir.irFunc->diSubprogram.isNull()); + gIR->difactory.InsertRegionEnd(fd->ir.irFunc->diSubprogram, gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -752,10 +580,10 @@ Logger::println("D to dwarf stoppoint at line %u", ln); LOG_SCOPE; - LLSmallVector args(3); - args[0] = DtoConstUint(ln); - args[1] = DtoConstUint(0); - FuncDeclaration* fd = gIR->func()->decl; - args[2] = DBG_CAST(DtoDwarfCompileUnit(fd->getModule())); - gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end()); + gIR->difactory.InsertStopPoint( + DtoDwarfCompileUnit(gIR->func()->decl->getCompilationModule()), // compile unit + ln, // line no + 0, // col no + gIR->scopebb() + ); } diff -r 03d7c4aac654 -r 1714836f2c0b gen/todebug.h --- a/gen/todebug.h Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/todebug.h Sun Feb 08 16:50:22 2009 +0100 @@ -8,14 +8,14 @@ * @param m * @return the Dwarf compile_unit. */ -llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m); +llvm::DICompileUnit DtoDwarfCompileUnit(Module* m); /** * Emit the Dwarf subprogram global for a function declaration fd. * @param fd * @return the Dwarf subprogram global. */ -llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd); +llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd); /** * Emit the Dwarf subprogram global for a internal function. @@ -23,7 +23,7 @@ * module ctors/dtors and unittests. * @return the Dwarf subprogram global. */ -llvm::GlobalVariable* DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname); +llvm::DISubprogram DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname); void DtoDwarfFuncStart(FuncDeclaration* fd); void DtoDwarfFuncEnd(FuncDeclaration* fd); @@ -43,7 +43,7 @@ * @param vd * @return */ -LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); +llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); #endif // LDC_GEN_TODEBUG_H diff -r 03d7c4aac654 -r 1714836f2c0b gen/toobj.cpp --- a/gen/toobj.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/gen/toobj.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -82,9 +82,14 @@ // start by deleting the old object file deleteObjFile(); + // name the module + std::string mname(toChars()); + if (md != 0) + mname = md->toChars(); + // create a new ir state // TODO look at making the instance static and moving most functionality into IrModule where it belongs - IRState ir; + IRState ir(new llvm::Module(mname)); gIR = &ir; ir.dmodule = this; @@ -92,12 +97,6 @@ IrDsymbol::resetAll(); IrType::resetAll(); - // name the module - std::string mname(toChars()); - if (md != 0) - mname = md->toChars(); - ir.module = new llvm::Module(mname); - // module ir state // might already exist via import, just overwrite since // the global created for the filename must belong to the right llvm module @@ -426,7 +425,7 @@ // debug info LLGlobalVariable* subprog; if(global.params.symdebug) { - subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()); + subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); } @@ -471,7 +470,7 @@ // debug info LLGlobalVariable* subprog; if(global.params.symdebug) { - subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()); + subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); } @@ -516,7 +515,7 @@ // debug info LLGlobalVariable* subprog; if(global.params.symdebug) { - subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()); + subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); } @@ -573,7 +572,7 @@ // debug info LLGlobalVariable* subprog; if(global.params.symdebug) { - subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()); + subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV(); builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); } diff -r 03d7c4aac654 -r 1714836f2c0b ir/irfunction.cpp --- a/ir/irfunction.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/ir/irfunction.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -31,8 +31,6 @@ _arguments = NULL; _argptr = NULL; - dwarfSubProg = NULL; - nextUnique.push(0); } diff -r 03d7c4aac654 -r 1714836f2c0b ir/irfunction.h --- a/ir/irfunction.h Sun Feb 08 05:26:54 2009 +0100 +++ b/ir/irfunction.h Sun Feb 08 16:50:22 2009 +0100 @@ -28,7 +28,7 @@ llvm::Value* _arguments; llvm::Value* _argptr; - llvm::Constant* dwarfSubProg; + llvm::DISubprogram diSubprogram; // pushes a unique label scope of the given name void pushUniqueLabelScope(const char* name); diff -r 03d7c4aac654 -r 1714836f2c0b ir/irmodule.cpp --- a/ir/irmodule.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/ir/irmodule.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -10,8 +10,6 @@ LLConstant* slice = DtoConstString(srcfilename); fileName = new llvm::GlobalVariable( slice->getType(), true, LLGlobalValue::InternalLinkage, slice, ".modulefilename", gIR->module); - - dwarfCompileUnit = NULL; } IrModule::~IrModule() diff -r 03d7c4aac654 -r 1714836f2c0b ir/irmodule.h --- a/ir/irmodule.h Sun Feb 08 05:26:54 2009 +0100 +++ b/ir/irmodule.h Sun Feb 08 16:50:22 2009 +0100 @@ -12,8 +12,8 @@ Module* M; - LLGlobalVariable* dwarfCompileUnit; LLGlobalVariable* fileName; + llvm::DICompileUnit diCompileUnit; }; #endif diff -r 03d7c4aac654 -r 1714836f2c0b ir/irstruct.cpp --- a/ir/irstruct.cpp Sun Feb 08 05:26:54 2009 +0100 +++ b/ir/irstruct.cpp Sun Feb 08 16:50:22 2009 +0100 @@ -33,7 +33,8 @@ : initOpaque(llvm::OpaqueType::get()), classInfoOpaque(llvm::OpaqueType::get()), vtblTy(llvm::OpaqueType::get()), - vtblInitTy(llvm::OpaqueType::get()) + vtblInitTy(llvm::OpaqueType::get()), + diCompositeType(NULL) { aggrdecl = aggr; defaultFound = false; @@ -57,8 +58,6 @@ classInfoDefined = false; packed = false; - - dwarfComposite = NULL; } IrStruct::~IrStruct() diff -r 03d7c4aac654 -r 1714836f2c0b ir/irstruct.h --- a/ir/irstruct.h Sun Feb 08 05:26:54 2009 +0100 +++ b/ir/irstruct.h Sun Feb 08 16:50:22 2009 +0100 @@ -148,8 +148,8 @@ // align(1) struct S { ... } bool packed; - // dwarf composite global - LLGlobalVariable* dwarfComposite; + // composite type debug description + llvm::DICompositeType diCompositeType; }; //////////////////////////////////////////////////////////////////////////////