mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-01 07:30:43 +03:00
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:
parent
fc480b7fd8
commit
7c93355672
17 changed files with 250 additions and 389 deletions
|
@ -554,6 +554,34 @@ Module *Dsymbol::getModule()
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,8 @@ struct Dsymbol : Object
|
||||||
void error(Loc loc, const char *format, ...);
|
void error(Loc loc, const char *format, ...);
|
||||||
void error(const char *format, ...);
|
void error(const char *format, ...);
|
||||||
void checkDeprecated(Loc loc, Scope *sc);
|
void checkDeprecated(Loc loc, Scope *sc);
|
||||||
Module *getModule();
|
Module *getModule(); // module where declared
|
||||||
|
Module *getCompilationModule(); // possibly different for templates
|
||||||
Dsymbol *pastMixin();
|
Dsymbol *pastMixin();
|
||||||
Dsymbol *toParent();
|
Dsymbol *toParent();
|
||||||
Dsymbol *toParent2();
|
Dsymbol *toParent2();
|
||||||
|
|
|
@ -2982,7 +2982,12 @@ void TemplateInstance::semantic(Scope *sc)
|
||||||
|
|
||||||
// get the enclosing template instance from the scope tinst
|
// get the enclosing template instance from the scope tinst
|
||||||
tinst = sc->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
|
#if LOG
|
||||||
printf("\tdo semantic\n");
|
printf("\tdo semantic\n");
|
||||||
|
|
|
@ -647,7 +647,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
// debug info
|
// debug info
|
||||||
if (global.params.symdebug) {
|
if (global.params.symdebug) {
|
||||||
Module* mo = fd->getModule();
|
Module* mo = fd->getModule();
|
||||||
fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd);
|
fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* t = fd->type->toBasetype();
|
Type* t = fd->type->toBasetype();
|
||||||
|
|
|
@ -47,14 +47,14 @@ IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm:
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
IRState::IRState()
|
IRState::IRState(llvm::Module* m)
|
||||||
|
: module(m), difactory(*m)
|
||||||
{
|
{
|
||||||
interfaceInfoType = NULL;
|
interfaceInfoType = NULL;
|
||||||
mutexType = NULL;
|
mutexType = NULL;
|
||||||
moduleRefType = NULL;
|
moduleRefType = NULL;
|
||||||
|
|
||||||
dmodule = 0;
|
dmodule = 0;
|
||||||
module = 0;
|
|
||||||
emitMain = false;
|
emitMain = false;
|
||||||
mainFunc = 0;
|
mainFunc = 0;
|
||||||
ir.state = this;
|
ir.state = this;
|
||||||
|
|
|
@ -131,7 +131,7 @@ struct CallOrInvoke_Invoke : public CallOrInvoke
|
||||||
// represents the module
|
// represents the module
|
||||||
struct IRState
|
struct IRState
|
||||||
{
|
{
|
||||||
IRState();
|
IRState(llvm::Module* m);
|
||||||
|
|
||||||
// module
|
// module
|
||||||
Module* dmodule;
|
Module* dmodule;
|
||||||
|
@ -190,6 +190,9 @@ struct IRState
|
||||||
// builder helper
|
// builder helper
|
||||||
IRBuilderHelper ir;
|
IRBuilderHelper ir;
|
||||||
|
|
||||||
|
// debug info helper
|
||||||
|
llvm::DIFactory difactory;
|
||||||
|
|
||||||
typedef std::list<Dsymbol*> DsymbolList;
|
typedef std::list<Dsymbol*> DsymbolList;
|
||||||
// dsymbols that need to be resolved
|
// dsymbols that need to be resolved
|
||||||
DsymbolList resolveList;
|
DsymbolList resolveList;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
|
|
||||||
|
#include "llvm/Analysis/DebugInfo.h"
|
||||||
|
|
||||||
#include "llvm/Support/IRBuilder.h"
|
#include "llvm/Support/IRBuilder.h"
|
||||||
using llvm::IRBuilder;
|
using llvm::IRBuilder;
|
||||||
|
|
||||||
|
|
|
@ -974,7 +974,7 @@ void DtoConstInitGlobal(VarDeclaration* vd)
|
||||||
// do debug info
|
// do debug info
|
||||||
if (global.params.symdebug)
|
if (global.params.symdebug)
|
||||||
{
|
{
|
||||||
LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd);
|
LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV();
|
||||||
// keep a reference so GDCE doesn't delete it !
|
// keep a reference so GDCE doesn't delete it !
|
||||||
gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType()));
|
gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType()));
|
||||||
}
|
}
|
||||||
|
@ -1557,7 +1557,7 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s
|
||||||
|
|
||||||
bool mustDefineSymbol(Dsymbol* s)
|
bool mustDefineSymbol(Dsymbol* s)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 0
|
||||||
return s->getModule() == gIR->dmodule || DtoIsTemplateInstance(s) != NULL;
|
return s->getModule() == gIR->dmodule || DtoIsTemplateInstance(s) != NULL;
|
||||||
#else
|
#else
|
||||||
Module* M = DtoIsTemplateInstance(s);
|
Module* M = DtoIsTemplateInstance(s);
|
||||||
|
@ -1573,7 +1573,7 @@ bool mustDefineSymbol(Dsymbol* s)
|
||||||
|
|
||||||
bool needsTemplateLinkage(Dsymbol* s)
|
bool needsTemplateLinkage(Dsymbol* s)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 0
|
||||||
return DtoIsTemplateInstance(s) != NULL;
|
return DtoIsTemplateInstance(s) != NULL;
|
||||||
#else
|
#else
|
||||||
Module* M = DtoIsTemplateInstance(s);
|
Module* M = DtoIsTemplateInstance(s);
|
||||||
|
|
536
gen/todebug.cpp
536
gen/todebug.cpp
|
@ -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.
|
* Emits a global variable, LLVM Dwarf style, only declares.
|
||||||
* @param type Type of variable.
|
* @param type Type of variable.
|
||||||
|
@ -56,41 +40,16 @@ static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const cha
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
static llvm::DIAnchor getDwarfAnchor(dwarf_constants c)
|
||||||
* Emits the Dwarf anchors that are used repeatedly by LLVM debug info.
|
|
||||||
*/
|
|
||||||
static void emitDwarfAnchors()
|
|
||||||
{
|
{
|
||||||
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)
|
switch (c)
|
||||||
{
|
{
|
||||||
case DW_TAG_compile_unit:
|
case DW_TAG_compile_unit:
|
||||||
return gIR->dwarfCUs;
|
return gIR->difactory.GetOrCreateCompileUnitAnchor();
|
||||||
case DW_TAG_variable:
|
case DW_TAG_variable:
|
||||||
return gIR->dwarfGVs;
|
return gIR->difactory.GetOrCreateGlobalVariableAnchor();
|
||||||
case DW_TAG_subprogram:
|
case DW_TAG_subprogram:
|
||||||
return gIR->dwarfSPs;
|
return gIR->difactory.GetOrCreateSubprogramAnchor();
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -126,123 +85,20 @@ static const llvm::StructType* getDwarfGlobalVariableType() {
|
||||||
return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type"));
|
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)
|
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);
|
||||||
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 LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name);
|
static llvm::DIBasicType dwarfBasicType(Type* type, llvm::DICompileUnit compileUnit)
|
||||||
static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static LLGlobalVariable* dwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit)
|
|
||||||
{
|
{
|
||||||
Type* t = type->toBasetype();
|
Type* t = type->toBasetype();
|
||||||
|
|
||||||
const LLType* T = DtoType(type);
|
const LLType* T = DtoType(type);
|
||||||
|
|
||||||
std::vector<LLConstant*> vals(10);
|
// find encoding
|
||||||
|
|
||||||
// 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
|
|
||||||
unsigned id;
|
unsigned id;
|
||||||
if (t->isintegral())
|
if (t->isintegral())
|
||||||
{
|
{
|
||||||
|
@ -259,131 +115,85 @@ static LLGlobalVariable* dwarfBasicType(Type* type, llvm::GlobalVariable* compil
|
||||||
{
|
{
|
||||||
assert(0 && "unsupported basictype for debug info");
|
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);
|
const LLType* T = DtoType(type);
|
||||||
Type* t = type->toBasetype();
|
Type* t = type->toBasetype();
|
||||||
|
|
||||||
// defaults
|
assert(t->ty == Tpointer && "unsupported derivedtype for debug info, only pointers allowed");
|
||||||
LLConstant* name = getNullPtr(getVoidPtrType());
|
|
||||||
|
|
||||||
// find tag
|
// find base type
|
||||||
unsigned tag;
|
llvm::DIType basetype;
|
||||||
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
|
|
||||||
Type* nt = t->nextOf();
|
Type* nt = t->nextOf();
|
||||||
LLGlobalVariable* nTD = dwarfTypeDescription_impl(nt, compileUnit, NULL);
|
basetype = dwarfTypeDescription_impl(nt, compileUnit, NULL);
|
||||||
if (nt->ty == Tvoid || !nTD)
|
if (nt->ty == Tvoid)
|
||||||
vals[9] = DBG_NULL;
|
basetype = llvm::DIType(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);
|
const LLType* T = DtoType(type);
|
||||||
Type* t = type->toBasetype();
|
Type* t = type->toBasetype();
|
||||||
|
|
||||||
// defaults
|
// find base type
|
||||||
LLConstant* name;
|
llvm::DIType basetype;
|
||||||
if (c_name)
|
basetype = dwarfTypeDescription(t, compileUnit, NULL);
|
||||||
name = DtoConstStringPtr(c_name, "llvm.metadata");
|
if (t->ty == Tvoid)
|
||||||
else
|
basetype = llvm::DIType(NULL);
|
||||||
name = getNullPtr(getVoidPtrType());
|
|
||||||
|
|
||||||
std::vector<LLConstant*> vals(10);
|
return gIR->difactory.CreateDerivedType(
|
||||||
|
DW_TAG_member, // tag
|
||||||
// tag
|
compileUnit, // context
|
||||||
vals[0] = DBG_TAG(DW_TAG_member);
|
c_name, // name
|
||||||
|
definedCU, // compile unit
|
||||||
// context
|
linnum, // line number
|
||||||
vals[1] = DBG_CAST(compileUnit);
|
getTypeBitSize(T), // size (bits)
|
||||||
|
getABITypeAlign(T)*8, // align (bits)
|
||||||
// name
|
offset*8, // offset (bits)
|
||||||
vals[2] = name;
|
//FIXME: need flags?
|
||||||
|
0, // flags
|
||||||
// compile unit where defined
|
basetype // derived from
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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);
|
const LLType* T = DtoType(type);
|
||||||
Type* t = type->toBasetype();
|
Type* t = type->toBasetype();
|
||||||
|
@ -392,7 +202,7 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
|
||||||
LLConstant* name = getNullPtr(getVoidPtrType());
|
LLConstant* name = getNullPtr(getVoidPtrType());
|
||||||
LLGlobalVariable* members = NULL;
|
LLGlobalVariable* members = NULL;
|
||||||
unsigned linnum = 0;
|
unsigned linnum = 0;
|
||||||
LLGlobalVariable* definedCU = NULL;
|
llvm::DICompileUnit definedCU;
|
||||||
|
|
||||||
// prepare tag and members
|
// prepare tag and members
|
||||||
unsigned tag;
|
unsigned tag;
|
||||||
|
@ -405,9 +215,9 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
|
||||||
{
|
{
|
||||||
tag = DW_TAG_structure_type;
|
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);
|
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);
|
assert(ptr);
|
||||||
|
|
||||||
const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2);
|
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
|
// 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?
|
// to provide debug info. probably a forward-declared struct?
|
||||||
if (sd->sizeok == 0)
|
if (sd->sizeok == 0)
|
||||||
return NULL;
|
return llvm::DICompositeType(NULL);
|
||||||
|
|
||||||
IrStruct* ir = sd->ir.irStruct;
|
IrStruct* ir = sd->ir.irStruct;
|
||||||
assert(ir);
|
assert(ir);
|
||||||
if (ir->dwarfComposite)
|
if (!ir->diCompositeType.isNull())
|
||||||
return ir->dwarfComposite;
|
return ir->diCompositeType;
|
||||||
|
|
||||||
// set to handle recursive types properly
|
// set to handle recursive types properly
|
||||||
gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype");
|
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;
|
tag = DW_TAG_structure_type;
|
||||||
|
|
||||||
name = DtoConstStringPtr(sd->toChars(), "llvm.metadata");
|
name = DtoConstStringPtr(sd->toChars(), "llvm.metadata");
|
||||||
linnum = sd->loc.linnum;
|
linnum = sd->loc.linnum;
|
||||||
definedCU = DtoDwarfCompileUnit(sd->getModule());
|
definedCU = DtoDwarfCompileUnit(sd->getCompilationModule());
|
||||||
|
|
||||||
std::vector<LLConstant*> elems;
|
std::vector<LLConstant*> elems;
|
||||||
if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
|
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];
|
VarDeclaration* vd = arr[k];
|
||||||
assert(vd);
|
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));
|
elems.push_back(DBG_CAST(ptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -493,14 +305,14 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
|
||||||
vals[0] = DBG_TAG(tag);
|
vals[0] = DBG_TAG(tag);
|
||||||
|
|
||||||
// context
|
// context
|
||||||
vals[1] = DBG_CAST(compileUnit);
|
vals[1] = DBG_CAST(compileUnit.getGV());
|
||||||
|
|
||||||
// name
|
// name
|
||||||
vals[2] = name;
|
vals[2] = name;
|
||||||
|
|
||||||
// compile unit where defined
|
// compile unit where defined
|
||||||
if (definedCU)
|
if (definedCU.getGV())
|
||||||
vals[3] = DBG_CAST(definedCU);
|
vals[3] = DBG_CAST(definedCU.getGV());
|
||||||
else
|
else
|
||||||
vals[3] = DBG_NULL;
|
vals[3] = DBG_NULL;
|
||||||
|
|
||||||
|
@ -534,42 +346,33 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
|
||||||
LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals);
|
LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals);
|
||||||
gv->setInitializer(initia);
|
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());
|
assert(vd->isDataseg());
|
||||||
LLGlobalVariable* compileUnit = DtoDwarfCompileUnit(gIR->dmodule);
|
llvm::DICompileUnit compileUnit = DtoDwarfCompileUnit(gIR->dmodule);
|
||||||
|
|
||||||
std::vector<LLConstant*> vals(12);
|
return gIR->difactory.CreateGlobalVariable(
|
||||||
vals[0] = DBG_TAG(DW_TAG_variable);
|
compileUnit, // context
|
||||||
vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_variable));
|
vd->mangle(), // name
|
||||||
|
vd->toPrettyChars(), // displayname
|
||||||
vals[2] = DBG_CAST(compileUnit);
|
vd->toChars(), // linkage name
|
||||||
|
DtoDwarfCompileUnit(vd->getCompilationModule()), // compile unit
|
||||||
vals[3] = DtoConstStringPtr(vd->mangle(), "llvm.metadata");
|
vd->loc.linnum, // line num
|
||||||
vals[4] = DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata");
|
dwarfTypeDescription_impl(vd->type, compileUnit, NULL), // type
|
||||||
vals[5] = DtoConstStringPtr(vd->toChars(), "llvm.metadata");
|
vd->protection == PROTprivate, // is local to unit
|
||||||
|
vd->getCompilationModule() == gIR->dmodule, // is definition
|
||||||
vals[6] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule()));
|
ll // value
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr)
|
static llvm::DIVariable dwarfVariable(VarDeclaration* vd, llvm::DIType type)
|
||||||
{
|
{
|
||||||
assert(!vd->isDataseg() && "static variable");
|
assert(!vd->isDataseg() && "static variable");
|
||||||
|
|
||||||
|
@ -579,40 +382,30 @@ static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typ
|
||||||
else
|
else
|
||||||
tag = DW_TAG_auto_variable;
|
tag = DW_TAG_auto_variable;
|
||||||
|
|
||||||
std::vector<LLConstant*> vals(6);
|
return gIR->difactory.CreateVariable(
|
||||||
// tag
|
tag, // tag
|
||||||
vals[0] = DBG_TAG(tag);
|
gIR->func()->diSubprogram, // context
|
||||||
// context
|
vd->toChars(), // name
|
||||||
vals[1] = DBG_CAST(gIR->func()->dwarfSubProg);
|
DtoDwarfCompileUnit(vd->getCompilationModule()), // compile unit
|
||||||
// name
|
vd->loc.linnum, // line num
|
||||||
vals[2] = DtoConstStringPtr(vd->toChars(), "llvm.metadata");
|
type // type
|
||||||
// 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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void dwarfDeclare(LLValue* var, LLGlobalVariable* varDescr)
|
static void dwarfDeclare(LLValue* var, llvm::DIVariable divar)
|
||||||
{
|
{
|
||||||
LLSmallVector<LLValue*,2> args(2);
|
gIR->difactory.InsertDeclare(var, divar, gIR->scopebb());
|
||||||
args[0] = DtoBitCast(var, DBG_TYPE);
|
|
||||||
args[1] = DBG_CAST(varDescr);
|
|
||||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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();
|
Type* t = type->toBasetype();
|
||||||
if (t->ty == Tvoid)
|
if (t->ty == Tvoid)
|
||||||
return NULL;
|
return llvm::DIType(NULL);
|
||||||
else if (t->isintegral() || t->isfloating())
|
else if (t->isintegral() || t->isfloating())
|
||||||
return dwarfBasicType(type, cu);
|
return dwarfBasicType(type, cu);
|
||||||
else if (t->ty == Tpointer)
|
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)
|
else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass)
|
||||||
return dwarfCompositeType(type, cu);
|
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();
|
Type* t = type->toBasetype();
|
||||||
if (t->ty == Tclass)
|
if (t->ty == Tclass)
|
||||||
|
@ -640,20 +433,18 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
// get compile units
|
// get compile units
|
||||||
LLGlobalVariable* thisCU = DtoDwarfCompileUnit(gIR->dmodule);
|
llvm::DICompileUnit thisCU = DtoDwarfCompileUnit(gIR->dmodule);
|
||||||
LLGlobalVariable* varCU = thisCU;
|
llvm::DICompileUnit varCU = thisCU;
|
||||||
if (vd->getModule() != gIR->dmodule)
|
if (vd->getCompilationModule() != gIR->dmodule)
|
||||||
varCU = DtoDwarfCompileUnit(vd->getModule());
|
varCU = DtoDwarfCompileUnit(vd->getCompilationModule());
|
||||||
|
|
||||||
// get type description
|
// get type description
|
||||||
Type* t = vd->type->toBasetype();
|
llvm::DIType TD = dwarfTypeDescription(vd->type, thisCU, NULL);
|
||||||
LLGlobalVariable* TD = dwarfTypeDescription(vd->type, thisCU, NULL);
|
if (TD.isNull())
|
||||||
if (TD == NULL)
|
|
||||||
return; // unsupported
|
return; // unsupported
|
||||||
|
|
||||||
// get variable description
|
// get variable description
|
||||||
LLGlobalVariable* VD;
|
llvm::DIVariable VD = dwarfVariable(vd, TD);
|
||||||
VD = dwarfVariable(vd, TD);
|
|
||||||
|
|
||||||
// declare
|
// declare
|
||||||
dwarfDeclare(ll, VD);
|
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");
|
Logger::println("D to dwarf compile_unit");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
@ -669,52 +460,89 @@ LLGlobalVariable* DtoDwarfCompileUnit(Module* m)
|
||||||
// we might be generating for an import
|
// we might be generating for an import
|
||||||
if (!m->ir.irModule)
|
if (!m->ir.irModule)
|
||||||
m->ir.irModule = new IrModule(m, m->srcfile->toChars());
|
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)
|
assert (m->ir.irModule->diCompileUnit.getGV()->getParent() == gIR->module
|
||||||
return m->ir.irModule->dwarfCompileUnit;
|
&& "debug info compile unit belongs to incorrect llvm module!");
|
||||||
|
return m->ir.irModule->diCompileUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLGlobalVariable* gv = dwarfCompileUnit(m);
|
// prepare srcpath
|
||||||
m->ir.irModule->dwarfCompileUnit = gv;
|
std::string srcpath(FileName::path(m->srcfile->name->toChars()));
|
||||||
return gv;
|
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");
|
Logger::println("D to dwarf subprogram");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
|
llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule);
|
||||||
|
llvm::DICompileUnit definition = DtoDwarfCompileUnit(fd->getCompilationModule());
|
||||||
|
|
||||||
// FIXME: duplicates ?
|
// FIXME: duplicates ?
|
||||||
return dwarfSubProgram(
|
return gIR->difactory.CreateSubprogram(
|
||||||
DtoDwarfCompileUnit(gIR->dmodule),
|
context, // context
|
||||||
DtoDwarfCompileUnit(fd->getModule()),
|
fd->toPrettyChars(), // name
|
||||||
fd->toPrettyChars(), fd->mangle(),
|
fd->toPrettyChars(), // display name
|
||||||
fd->loc.linnum,
|
fd->mangle(), // linkage name
|
||||||
fd->protection == PROTprivate);
|
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");
|
Logger::println("D to dwarf subprogram");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
|
llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule);
|
||||||
|
|
||||||
// FIXME: duplicates ?
|
// FIXME: duplicates ?
|
||||||
return dwarfSubProgram(
|
return gIR->difactory.CreateSubprogram(
|
||||||
DtoDwarfCompileUnit(gIR->dmodule),
|
context, // context
|
||||||
DtoDwarfCompileUnit(gIR->dmodule),
|
prettyname, // name
|
||||||
prettyname, mangledname,
|
prettyname, // display name
|
||||||
0,
|
mangledname, // linkage name
|
||||||
true);
|
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");
|
Logger::println("D to dwarf global_variable");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
@ -730,8 +558,8 @@ void DtoDwarfFuncStart(FuncDeclaration* fd)
|
||||||
Logger::println("D to dwarf funcstart");
|
Logger::println("D to dwarf funcstart");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(fd->ir.irFunc->dwarfSubProg);
|
assert(!fd->ir.irFunc->diSubprogram.isNull());
|
||||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(fd->ir.irFunc->dwarfSubProg));
|
gIR->difactory.InsertSubprogramStart(fd->ir.irFunc->diSubprogram, gIR->scopebb());
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -741,8 +569,8 @@ void DtoDwarfFuncEnd(FuncDeclaration* fd)
|
||||||
Logger::println("D to dwarf funcend");
|
Logger::println("D to dwarf funcend");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(fd->ir.irFunc->dwarfSubProg);
|
assert(!fd->ir.irFunc->diSubprogram.isNull());
|
||||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(fd->ir.irFunc->dwarfSubProg));
|
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);
|
Logger::println("D to dwarf stoppoint at line %u", ln);
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
LLSmallVector<LLValue*,3> args(3);
|
gIR->difactory.InsertStopPoint(
|
||||||
args[0] = DtoConstUint(ln);
|
DtoDwarfCompileUnit(gIR->func()->decl->getCompilationModule()), // compile unit
|
||||||
args[1] = DtoConstUint(0);
|
ln, // line no
|
||||||
FuncDeclaration* fd = gIR->func()->decl;
|
0, // col no
|
||||||
args[2] = DBG_CAST(DtoDwarfCompileUnit(fd->getModule()));
|
gIR->scopebb()
|
||||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,14 @@ void RegisterDwarfSymbols(llvm::Module* mod);
|
||||||
* @param m
|
* @param m
|
||||||
* @return the Dwarf compile_unit.
|
* @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.
|
* Emit the Dwarf subprogram global for a function declaration fd.
|
||||||
* @param fd
|
* @param fd
|
||||||
* @return the Dwarf subprogram global.
|
* @return the Dwarf subprogram global.
|
||||||
*/
|
*/
|
||||||
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
|
llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emit the Dwarf subprogram global for a internal function.
|
* Emit the Dwarf subprogram global for a internal function.
|
||||||
|
@ -23,7 +23,7 @@ llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
|
||||||
* module ctors/dtors and unittests.
|
* module ctors/dtors and unittests.
|
||||||
* @return the Dwarf subprogram global.
|
* @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 DtoDwarfFuncStart(FuncDeclaration* fd);
|
||||||
void DtoDwarfFuncEnd(FuncDeclaration* fd);
|
void DtoDwarfFuncEnd(FuncDeclaration* fd);
|
||||||
|
@ -43,7 +43,7 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd);
|
||||||
* @param vd
|
* @param vd
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
|
llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd);
|
||||||
|
|
||||||
#endif // LDC_GEN_TODEBUG_H
|
#endif // LDC_GEN_TODEBUG_H
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,14 @@ void Module::genobjfile(int multiobj)
|
||||||
// start by deleting the old object file
|
// start by deleting the old object file
|
||||||
deleteObjFile();
|
deleteObjFile();
|
||||||
|
|
||||||
|
// name the module
|
||||||
|
std::string mname(toChars());
|
||||||
|
if (md != 0)
|
||||||
|
mname = md->toChars();
|
||||||
|
|
||||||
// create a new ir state
|
// create a new ir state
|
||||||
// TODO look at making the instance static and moving most functionality into IrModule where it belongs
|
// 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;
|
gIR = &ir;
|
||||||
ir.dmodule = this;
|
ir.dmodule = this;
|
||||||
|
|
||||||
|
@ -92,12 +97,6 @@ void Module::genobjfile(int multiobj)
|
||||||
IrDsymbol::resetAll();
|
IrDsymbol::resetAll();
|
||||||
IrType::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
|
// module ir state
|
||||||
// might already exist via import, just overwrite since
|
// might already exist via import, just overwrite since
|
||||||
// the global created for the filename must belong to the right llvm module
|
// the global created for the filename must belong to the right llvm module
|
||||||
|
@ -426,7 +425,7 @@ llvm::Function* build_module_ctor()
|
||||||
// debug info
|
// debug info
|
||||||
LLGlobalVariable* subprog;
|
LLGlobalVariable* subprog;
|
||||||
if(global.params.symdebug) {
|
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));
|
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +470,7 @@ static llvm::Function* build_module_dtor()
|
||||||
// debug info
|
// debug info
|
||||||
LLGlobalVariable* subprog;
|
LLGlobalVariable* subprog;
|
||||||
if(global.params.symdebug) {
|
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));
|
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +515,7 @@ static llvm::Function* build_module_unittest()
|
||||||
// debug info
|
// debug info
|
||||||
LLGlobalVariable* subprog;
|
LLGlobalVariable* subprog;
|
||||||
if(global.params.symdebug) {
|
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));
|
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
|
// debug info
|
||||||
LLGlobalVariable* subprog;
|
LLGlobalVariable* subprog;
|
||||||
if(global.params.symdebug) {
|
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));
|
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ IrFunction::IrFunction(FuncDeclaration* fd)
|
||||||
_arguments = NULL;
|
_arguments = NULL;
|
||||||
_argptr = NULL;
|
_argptr = NULL;
|
||||||
|
|
||||||
dwarfSubProg = NULL;
|
|
||||||
|
|
||||||
nextUnique.push(0);
|
nextUnique.push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct IrFunction : IrBase
|
||||||
llvm::Value* _arguments;
|
llvm::Value* _arguments;
|
||||||
llvm::Value* _argptr;
|
llvm::Value* _argptr;
|
||||||
|
|
||||||
llvm::Constant* dwarfSubProg;
|
llvm::DISubprogram diSubprogram;
|
||||||
|
|
||||||
// pushes a unique label scope of the given name
|
// pushes a unique label scope of the given name
|
||||||
void pushUniqueLabelScope(const char* name);
|
void pushUniqueLabelScope(const char* name);
|
||||||
|
|
|
@ -10,8 +10,6 @@ IrModule::IrModule(Module* module, const char* srcfilename)
|
||||||
LLConstant* slice = DtoConstString(srcfilename);
|
LLConstant* slice = DtoConstString(srcfilename);
|
||||||
fileName = new llvm::GlobalVariable(
|
fileName = new llvm::GlobalVariable(
|
||||||
slice->getType(), true, LLGlobalValue::InternalLinkage, slice, ".modulefilename", gIR->module);
|
slice->getType(), true, LLGlobalValue::InternalLinkage, slice, ".modulefilename", gIR->module);
|
||||||
|
|
||||||
dwarfCompileUnit = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IrModule::~IrModule()
|
IrModule::~IrModule()
|
||||||
|
|
|
@ -12,8 +12,8 @@ struct IrModule : IrBase
|
||||||
|
|
||||||
Module* M;
|
Module* M;
|
||||||
|
|
||||||
LLGlobalVariable* dwarfCompileUnit;
|
|
||||||
LLGlobalVariable* fileName;
|
LLGlobalVariable* fileName;
|
||||||
|
llvm::DICompileUnit diCompileUnit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,8 @@ IrStruct::IrStruct(AggregateDeclaration* aggr)
|
||||||
: initOpaque(llvm::OpaqueType::get()),
|
: initOpaque(llvm::OpaqueType::get()),
|
||||||
classInfoOpaque(llvm::OpaqueType::get()),
|
classInfoOpaque(llvm::OpaqueType::get()),
|
||||||
vtblTy(llvm::OpaqueType::get()),
|
vtblTy(llvm::OpaqueType::get()),
|
||||||
vtblInitTy(llvm::OpaqueType::get())
|
vtblInitTy(llvm::OpaqueType::get()),
|
||||||
|
diCompositeType(NULL)
|
||||||
{
|
{
|
||||||
aggrdecl = aggr;
|
aggrdecl = aggr;
|
||||||
defaultFound = false;
|
defaultFound = false;
|
||||||
|
@ -57,8 +58,6 @@ IrStruct::IrStruct(AggregateDeclaration* aggr)
|
||||||
classInfoDefined = false;
|
classInfoDefined = false;
|
||||||
|
|
||||||
packed = false;
|
packed = false;
|
||||||
|
|
||||||
dwarfComposite = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IrStruct::~IrStruct()
|
IrStruct::~IrStruct()
|
||||||
|
|
|
@ -148,8 +148,8 @@ struct IrStruct : IrBase
|
||||||
// align(1) struct S { ... }
|
// align(1) struct S { ... }
|
||||||
bool packed;
|
bool packed;
|
||||||
|
|
||||||
// dwarf composite global
|
// composite type debug description
|
||||||
LLGlobalVariable* dwarfComposite;
|
llvm::DICompositeType diCompositeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue