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.
This commit is contained in:
Christian Kamm 2009-02-08 16:50:22 +01:00
parent fc480b7fd8
commit 7c93355672
17 changed files with 250 additions and 389 deletions

View file

@ -554,6 +554,34 @@ Module *Dsymbol::getModule()
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;
}
/*************************************
*/

View file

@ -119,7 +119,8 @@ struct Dsymbol : Object
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();

View file

@ -2982,6 +2982,11 @@ void TemplateInstance::semantic(Scope *sc)
// get the enclosing template instance from the scope tinst
tinst = sc->tinst;
// get the module of the outermost enclosing instantiation
if (tinst)
tmodule = tinst->tmodule;
else
tmodule = sc->module;
#if LOG

View file

@ -647,7 +647,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
// 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();

View file

@ -47,14 +47,14 @@ IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm:
}
//////////////////////////////////////////////////////////////////////////////////////////
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;

View file

@ -131,7 +131,7 @@ struct CallOrInvoke_Invoke : public CallOrInvoke
// represents the module
struct IRState
{
IRState();
IRState(llvm::Module* m);
// module
Module* dmodule;
@ -190,6 +190,9 @@ struct IRState
// builder helper
IRBuilderHelper ir;
// debug info helper
llvm::DIFactory difactory;
typedef std::list<Dsymbol*> DsymbolList;
// dsymbols that need to be resolved
DsymbolList resolveList;

View file

@ -14,6 +14,8 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Support/IRBuilder.h"
using llvm::IRBuilder;

View file

@ -974,7 +974,7 @@ void DtoConstInitGlobal(VarDeclaration* vd)
// 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 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s
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 mustDefineSymbol(Dsymbol* s)
bool needsTemplateLinkage(Dsymbol* s)
{
#if 1
#if 0
return DtoIsTemplateInstance(s) != NULL;
#else
Module* M = DtoIsTemplateInstance(s);

View file

@ -24,22 +24,6 @@ using namespace llvm::dwarf;
//////////////////////////////////////////////////////////////////////////////////////////////////
/**
* 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<LLConstant*> 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.
@ -56,41 +40,16 @@ static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const cha
//////////////////////////////////////////////////////////////////////////////////////////////////
/**
* 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<LLConstant*> 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 @@ static const llvm::StructType* getDwarfGlobalVariableType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type"));
}
//////////////////////////////////////////////////////////////////////////////////////////////////
static LLGlobalVariable* dwarfCompileUnit(Module* m)
{
std::vector<LLConstant*> 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<LLConstant*> 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<LLConstant*> 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<LLConstant*> 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 @@ static LLGlobalVariable* dwarfBasicType(Type* type, llvm::GlobalVariable* compil
{
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<LLConstant*> vals(10);
// tag
vals[0] = DBG_TAG(tag);
// context
vals[1] = DBG_CAST(compileUnit);
// name
vals[2] = name;
// 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
// find base type
llvm::DIType basetype;
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);
basetype = dwarfTypeDescription_impl(nt, compileUnit, NULL);
if (nt->ty == Tvoid)
basetype = llvm::DIType(NULL);
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());
// find base type
llvm::DIType basetype;
basetype = dwarfTypeDescription(t, compileUnit, NULL);
if (t->ty == Tvoid)
basetype = llvm::DIType(NULL);
std::vector<LLConstant*> 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;
// 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 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
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 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
{
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 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
// 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<LLConstant*> elems;
if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
@ -470,7 +282,7 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
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 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
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 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
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);
llvm::DICompileUnit compileUnit = DtoDwarfCompileUnit(gIR->dmodule);
std::vector<LLConstant*> 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");
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 @@ static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typ
else
tag = DW_TAG_auto_variable;
std::vector<LLConstant*> 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<LLValue*,2> 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 @@ static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable*
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 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
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 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
//////////////////////////////////////////////////////////////////////////////////////////////////
LLGlobalVariable* DtoDwarfCompileUnit(Module* m)
llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
{
Logger::println("D to dwarf compile_unit");
LOG_SCOPE;
@ -669,52 +460,89 @@ LLGlobalVariable* DtoDwarfCompileUnit(Module* m)
// 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 @@ void DtoDwarfFuncStart(FuncDeclaration* fd)
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 @@ void DtoDwarfFuncEnd(FuncDeclaration* fd)
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 @@ void DtoDwarfStopPoint(unsigned ln)
Logger::println("D to dwarf stoppoint at line %u", ln);
LOG_SCOPE;
LLSmallVector<LLValue*,3> 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()
);
}

View file

@ -8,14 +8,14 @@ void RegisterDwarfSymbols(llvm::Module* mod);
* @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 @@ llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
* 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 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd);
* @param vd
* @return
*/
LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
#endif // LDC_GEN_TODEBUG_H

View file

@ -82,9 +82,14 @@ void Module::genobjfile(int multiobj)
// 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 @@ void Module::genobjfile(int multiobj)
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 @@ llvm::Function* build_module_ctor()
// 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 @@ static llvm::Function* build_module_dtor()
// 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 @@ static llvm::Function* build_module_unittest()
// 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 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
// 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));
}

View file

@ -31,8 +31,6 @@ IrFunction::IrFunction(FuncDeclaration* fd)
_arguments = NULL;
_argptr = NULL;
dwarfSubProg = NULL;
nextUnique.push(0);
}

View file

@ -28,7 +28,7 @@ struct IrFunction : IrBase
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);

View file

@ -10,8 +10,6 @@ IrModule::IrModule(Module* module, const char* srcfilename)
LLConstant* slice = DtoConstString(srcfilename);
fileName = new llvm::GlobalVariable(
slice->getType(), true, LLGlobalValue::InternalLinkage, slice, ".modulefilename", gIR->module);
dwarfCompileUnit = NULL;
}
IrModule::~IrModule()

View file

@ -12,8 +12,8 @@ struct IrModule : IrBase
Module* M;
LLGlobalVariable* dwarfCompileUnit;
LLGlobalVariable* fileName;
llvm::DICompileUnit diCompileUnit;
};
#endif

View file

@ -33,7 +33,8 @@ IrStruct::IrStruct(AggregateDeclaration* aggr)
: 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 @@ IrStruct::IrStruct(AggregateDeclaration* aggr)
classInfoDefined = false;
packed = false;
dwarfComposite = NULL;
}
IrStruct::~IrStruct()

View file

@ -148,8 +148,8 @@ struct IrStruct : IrBase
// align(1) struct S { ... }
bool packed;
// dwarf composite global
LLGlobalVariable* dwarfComposite;
// composite type debug description
llvm::DICompositeType diCompositeType;
};
//////////////////////////////////////////////////////////////////////////////