diff --git a/dmd/declaration.h b/dmd/declaration.h index 02c60be3..bda5820d 100644 --- a/dmd/declaration.h +++ b/dmd/declaration.h @@ -19,6 +19,7 @@ #include #include #include +#include #endif #include "dsymbol.h" @@ -350,6 +351,9 @@ struct VarDeclaration : Declaration /// This var is used by a naked function. bool nakedUse; + + // debug description + llvm::DIVariable debugVariable; #endif }; diff --git a/dmd2/declaration.h b/dmd2/declaration.h index e7c8f920..2f8551b4 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -19,6 +19,7 @@ #include #include #include +#include #endif #include "dsymbol.h" @@ -347,6 +348,9 @@ struct VarDeclaration : Declaration /// This var is used by a naked function. bool nakedUse; + + // debug description + llvm::DIVariable debugVariable; #endif }; diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 40eb39f3..4993eefa 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -470,6 +470,13 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) } gIR->ir->CreateStore(r, l); } + + #ifndef DISABLE_DEBUG_INFO + DVarValue *var = lhs->isVar(); + VarDeclaration *varDecl = var ? var->var : 0; + if (global.params.symdebug && varDecl && varDecl->debugVariable) + DtoDwarfValue(rhs->getRVal(), lhs->isVar()->var); + #endif } /****************************************************************************************/ diff --git a/gen/todebug.cpp b/gen/todebug.cpp index 043bc721..cd69b861 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -114,7 +114,7 @@ static llvm::DIDerivedType dwarfDerivedType(Type* type, llvm::DICompileUnit comp return gIR->difactory.CreateDerivedType( DW_TAG_pointer_type, // tag compileUnit, // context - "", // name + type->toChars(), // name DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)), // file 0, // line number getTypeBitSize(T), // size (bits) @@ -350,11 +350,12 @@ static llvm::DIVariable dwarfVariable(VarDeclaration* vd, llvm::DIType type) return gIR->difactory.CreateVariable( tag, // tag - gIR->func()->diSubprogram, // context + gIR->func()->diLexicalBlock, // context vd->toChars(), // name DtoDwarfFile(vd->loc, DtoDwarfCompileUnit(getDefinedModule(vd))), // file vd->loc.linnum, // line num - type // type + type, // type + true // preserve ); } @@ -408,10 +409,10 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd) return; // unsupported // get variable description - llvm::DIVariable VD = dwarfVariable(vd, TD); + vd->debugVariable = dwarfVariable(vd, TD); // declare - dwarfDeclare(ll, VD); + dwarfDeclare(ll, vd->debugVariable); } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -447,7 +448,6 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) m->srcfile->name->toChars(), srcpath, "LDC (http://www.dsource.org/projects/ldc)", -//FIXME: What do these two mean? gIR->dmodule == m, // isMain, false // isOptimized ); @@ -464,6 +464,7 @@ llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd) llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); llvm::DIFile file = DtoDwarfFile(fd->loc, DtoDwarfCompileUnit(getDefinedModule(fd))); + Type *retType = ((TypeFunction*)fd->type)->next; // FIXME: duplicates ? return gIR->difactory.CreateSubprogram( @@ -473,10 +474,14 @@ llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd) fd->mangle(), // linkage name file, // file fd->loc.linnum, // line no -//FIXME: what's this type for? - llvm::DIType(NULL), // type + dwarfTypeDescription(retType, context, NULL), // type fd->protection == PROTprivate, // is local to unit - gIR->dmodule == getDefinedModule(fd) // isdefinition + gIR->dmodule == getDefinedModule(fd), // isdefinition + 0, 0, // VK, Index + llvm::DIType(), + false, // isArtificial + false, // isOptimized + fd->ir.irFunc->func ); } @@ -497,8 +502,7 @@ llvm::DISubprogram DtoDwarfSubProgramInternal(const char* prettyname, const char mangledname, // linkage name DtoDwarfFile(Loc(gIR->dmodule, 0), context), // compile unit 0, // line no -//FIXME: what's this type for? - llvm::DIType(NULL), // type + llvm::DIType(NULL), // return type. TODO: fill it up true, // is local to unit true // isdefinition ); @@ -523,8 +527,11 @@ void DtoDwarfFuncStart(FuncDeclaration* fd) LOG_SCOPE; assert((llvm::MDNode*)fd->ir.irFunc->diSubprogram != 0); - //TODO: - //gIR->difactory.InsertSubprogramStart(fd->ir.irFunc->diSubprogram, gIR->scopebb()); + fd->ir.irFunc->diLexicalBlock = gIR->difactory.CreateLexicalBlock( + fd->ir.irFunc->diSubprogram, // context + DtoDwarfFile(fd->loc, DtoDwarfCompileUnit(getDefinedModule(fd))), // file + fd->loc.linnum + ); } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -535,8 +542,6 @@ void DtoDwarfFuncEnd(FuncDeclaration* fd) LOG_SCOPE; assert((llvm::MDNode*)fd->ir.irFunc->diSubprogram != 0); - //TODO: - //gIR->difactory.InsertRegionEnd(fd->ir.irFunc->diSubprogram, gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -549,4 +554,11 @@ void DtoDwarfStopPoint(unsigned ln) gIR->ir->SetCurrentDebugLocation(loc); } +////////////////////////////////////////////////////////////////////////////////////////////////// + +void DtoDwarfValue(LLValue* var, VarDeclaration* vd) +{ + gIR->difactory.InsertDbgValueIntrinsic(var, 0, vd->debugVariable, gIR->scopebb()); +} + #endif diff --git a/gen/todebug.h b/gen/todebug.h index 1d3922a1..5a4fa757 100644 --- a/gen/todebug.h +++ b/gen/todebug.h @@ -32,6 +32,8 @@ void DtoDwarfFuncEnd(FuncDeclaration* fd); void DtoDwarfStopPoint(unsigned ln); +void DtoDwarfValue(LLValue* var, VarDeclaration* vd); + /** * Emits all things necessary for making debug info for a local variable vd. * @param ll LLVM Value of the variable. @@ -47,6 +49,7 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd); */ llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); + #endif // DISABLE_DEBUG_INFO #endif // LDC_GEN_TODEBUG_H diff --git a/ir/irfunction.h b/ir/irfunction.h index 02b79fbd..055233b2 100644 --- a/ir/irfunction.h +++ b/ir/irfunction.h @@ -98,6 +98,7 @@ struct IrFunction : IrBase llvm::Value* _argptr; llvm::DISubprogram diSubprogram; + llvm::DILexicalBlock diLexicalBlock; }; #endif