[svn r262] Fixed debug info for normal function parameters.

Fixed debug info for pointers to basic types.
This commit is contained in:
Tomas Lindquist Olsen 2008-06-09 12:43:16 +02:00
parent 8b83eda2a2
commit 1e87ae15ef
12 changed files with 217 additions and 28 deletions

View file

@ -573,6 +573,8 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
sv->storage_class = storage_class;
// LLVMDC
sv->needsStorage = needsStorage;
}
#ifdef _DH
// Syntax copy for header file

View file

@ -781,6 +781,11 @@ void FuncDeclaration::semantic3(Scope *sc)
if (v->storage_class & STClazy)
v->storage_class |= STCin;
v->semantic(sc2);
#if IN_LLVM
// LLVMDC: the argument needs an addres if we want to attach debug info to it.
if (global.params.symdebug)
v->needsStorage = true;
#endif
if (!sc2->insert(v))
error("parameter %s.%s is already defined", toChars(), v->toChars());
else

View file

@ -607,6 +607,10 @@ void DtoDefineFunc(FuncDeclaration* fd)
s.append("_storage");
LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
if (global.params.symdebug)
DtoDwarfLocalVariable(v, vd);
gIR->ir->CreateStore(a,v);
vd->ir.irLocal->value = v;
}

View file

@ -100,17 +100,29 @@ LLConstant* GetDwarfAnchor(llvm::dwarf::dwarf_constants c)
//////////////////////////////////////////////////////////////////////////////////////////////////
const llvm::StructType* GetDwarfCompileUnitType() {
static const llvm::StructType* GetDwarfCompileUnitType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.compile_unit.type"));
}
const llvm::StructType* GetDwarfSubProgramType() {
static const llvm::StructType* GetDwarfSubProgramType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.subprogram.type"));
}
static const llvm::StructType* GetDwarfVariableType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.variable.type"));
}
static const llvm::StructType* GetDwarfDerivedTypeType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.derivedtype.type"));
}
static const llvm::StructType* GetDwarfBasicTypeType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.basictype.type"));
}
//////////////////////////////////////////////////////////////////////////////////////////////////
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m)
LLGlobalVariable* DtoDwarfCompileUnit(Module* m)
{
if (!m->ir.irModule)
m->ir.irModule = new IrModule(m);
@ -204,14 +216,15 @@ void DtoDwarfStopPoint(unsigned ln)
//////////////////////////////////////////////////////////////////////////////////////////////////
const llvm::StructType* GetDwarfBasicTypeType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.basictype.type"));
}
static LLGlobalVariable* DtoDwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu);
//////////////////////////////////////////////////////////////////////////////////////////////////
LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit)
static LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit)
{
Type* t = type->toBasetype();
const LLType* T = DtoType(type);
std::vector<LLConstant*> vals;
@ -237,14 +250,14 @@ LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUni
vals.push_back(DtoConstUint(0));
// dwarf type
unsigned id;
if (type->isintegral())
if (t->isintegral())
{
if (type->isunsigned())
id = llvm::dwarf::DW_ATE_unsigned;
else
id = llvm::dwarf::DW_ATE_signed;
}
else if (type->isfloating())
else if (t->isfloating())
{
id = llvm::dwarf::DW_ATE_float;
}
@ -262,13 +275,63 @@ LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUni
//////////////////////////////////////////////////////////////////////////////////////////////////
const llvm::StructType* GetDwarfVariableType() {
return isaStruct(gIR->module->getTypeByName("llvm.dbg.variable.type"));
static LLGlobalVariable* DtoDwarfDerivedType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit)
{
const LLType* T = DtoType(type);
Type* t = DtoDType(type);
// defaults
LLConstant* name = getNullPtr(getVoidPtrType());
// find tag
unsigned tag;
if (t->ty == Tpointer)
{
tag = llvm::dwarf::DW_TAG_pointer_type;
}
else
{
assert(0 && "unsupported derivedtype for debug info");
}
std::vector<LLConstant*> vals;
// tag
vals.push_back(llvm::ConstantExpr::getAdd(
DtoConstUint(tag),
DtoConstUint(llvm::LLVMDebugVersion)));
// context
vals.push_back(dbgToArrTy(compileUnit));
// name
vals.push_back(name);
// compile unit where defined
vals.push_back(getNullPtr(dbgArrTy()));
// line number where defined
vals.push_back(DtoConstInt(0));
// size in bits
vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
// alignment in bits
vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
// offset in bits
vals.push_back(LLConstantInt::get(LLType::Int64Ty, 0, false));
// FIXME: dont know what this is
vals.push_back(DtoConstUint(0));
// base type
Type* nt = t->nextOf();
LLGlobalVariable* nTD = DtoDwarfTypeDescription(loc, nt, compileUnit);
if (nt->ty == Tvoid || !nTD)
vals.push_back(getNullPtr(dbgArrTy()));
else
vals.push_back(dbgToArrTy(nTD));
LLConstant* c = llvm::ConstantStruct::get(GetDwarfDerivedTypeType(), vals);
LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.derivedtype", gIR->module);
gv->setSection("llvm.metadata");
return gv;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr)
static LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr)
{
unsigned tag;
if (vd->isParameter())
@ -302,10 +365,60 @@ LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDes
//////////////////////////////////////////////////////////////////////////////////////////////////
void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr)
static void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr)
{
LLSmallVector<LLValue*,2> args;
args.push_back(DtoBitCast(var, dbgArrTy()));
args.push_back(dbgToArrTy(varDescr));
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end());
}
//////////////////////////////////////////////////////////////////////////////////////////////////
static LLGlobalVariable* DtoDwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu)
{
Type* t = type->toBasetype();
if (t->isintegral() || t->isfloating())
return DtoDwarfBasicType(type, cu);
else if (t->ty == Tpointer)
return DtoDwarfDerivedType(loc, type, cu);
Logger::attention(loc, "unsupport type for debug info: %s", type->toChars());
return NULL;
}
void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
{
// get compile units
LLGlobalVariable* thisCU = DtoDwarfCompileUnit(gIR->dmodule);
LLGlobalVariable* varCU = thisCU;
if (vd->getModule() != gIR->dmodule)
varCU = DtoDwarfCompileUnit(vd->getModule());
// get type description
Type* t = vd->type->toBasetype();
LLGlobalVariable* TD = DtoDwarfTypeDescription(vd->loc, vd->type, thisCU);
if (TD == NULL)
return; // unsupported
// get variable description
LLGlobalVariable* VD;
VD = DtoDwarfVariable(vd, TD);
// declare
DtoDwarfDeclare(ll, VD);
}

View file

@ -3,10 +3,6 @@
void RegisterDwarfSymbols(llvm::Module* mod);
const llvm::StructType* GetDwarfAnchorType();
const llvm::StructType* GetDwarfCompileUnitType();
const llvm::StructType* GetDwarfSubProgramType();
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m);
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit);
@ -15,12 +11,12 @@ void DtoDwarfFuncEnd(FuncDeclaration* fd);
void DtoDwarfStopPoint(unsigned ln);
const llvm::StructType* GetDwarfBasicTypeType();
LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit);
const llvm::StructType* GetDwarfVariableType();
LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr);
void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr);
/**
* Emits all things necessary for making debug info for a local variable vd.
* @param ll LLVM Value of the variable.
* @param vd Variable declaration to emit debug info for.
*/
void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd);
#endif // LLVMDC_GEN_TODEBUG_H

View file

@ -78,12 +78,9 @@ DValue* DeclarationExp::toElem(IRState* p)
vd->ir.irLocal = new IrLocal(vd);
vd->ir.irLocal->value = allocainst;
if (global.params.symdebug && (vd->type->isintegral() || vd->type->isfloating()))
if (global.params.symdebug)
{
LLGlobalVariable* cu = DtoDwarfCompileUnit(vd->getModule());
LLGlobalVariable* bt = DtoDwarfBasicType(vd->type, cu);
LLGlobalVariable* vdesc = DtoDwarfVariable(vd, bt);
DtoDwarfDeclare(allocainst, vdesc);
DtoDwarfLocalVariable(allocainst, vd);
}
}

View file

@ -765,6 +765,10 @@ tangotests/c.d
tangotests/classes1.d
tangotests/constructors.d
tangotests/debug1.d
tangotests/debug2.d
tangotests/debug3.d
tangotests/debug4.d
tangotests/debug5.d
tangotests/e.d
tangotests/f.d
tangotests/files1.d

17
tangotests/debug1.d Normal file
View file

@ -0,0 +1,17 @@
module tangotests.debug1;
void main()
{
int* ptr;
// all these should be inspectable
int i = 1;
int j = 2;
long k = 3;
float l = 4.521;
ubyte m = 5;
*ptr = 0;//cast(int)(i+j+k+l+m);
}
extern(C) int printf(char*, ...);

15
tangotests/debug2.d Normal file
View file

@ -0,0 +1,15 @@
module tangotests.debug2;
import tango.stdc.stdlib : rand;
void main()
{
size_t iter;
while (iter < 25)
{
if (rand() % 20 == 10)
*cast(int*)null = 0;
++iter;
}
assert(0);
}

10
tangotests/debug3.d Normal file
View file

@ -0,0 +1,10 @@
module tangotests.debug3;
void main()
{
int i = 42;
int* ip = &i;
int* fail;
*fail = 0;
}

11
tangotests/debug4.d Normal file
View file

@ -0,0 +1,11 @@
module tangotests.debug4;
void main()
{
char c = 'c';
wchar wc = 'w';
dchar dc = 'd';
int* fail;
*fail = 32;
}

15
tangotests/debug5.d Normal file
View file

@ -0,0 +1,15 @@
module tangotests.debug5;
void main()
{
int i = 32;
real r = 3.1415;
real* p = &r;
func(i,r,p);
}
void func(int i, real r, real* p)
{
int* fail;
*fail = 666;
}