diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 49 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.h | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 23 |
3 files changed, 78 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 1827fc980c3..19745dc2a0c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -44,6 +44,7 @@ CGDebugInfo::CGDebugInfo(CodeGenModule *m) , CompileUnitAnchor(NULL) , SubprogramAnchor(NULL) , RegionStack() +, VariableDescList() , Subprogram(NULL) { SR = new llvm::DISerializer(); @@ -72,7 +73,12 @@ CGDebugInfo::~CGDebugInfo() = RegionStack.begin(); I != RegionStack.end(); ++I) { delete *I; } - + + for (std::vector<llvm::VariableDesc *>::iterator I + = VariableDescList.begin(); I != VariableDescList.end(); ++I) { + delete *I; + } + delete CompileUnitAnchor; delete SubprogramAnchor; } @@ -519,3 +525,44 @@ void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) RegionStack.pop_back(); } +/// EmitDeclare - Emit local variable declaration debug info. +void CGDebugInfo::EmitDeclare(const VarDecl *decl, unsigned Tag, + llvm::Value *AI, + llvm::IRBuilder &Builder) +{ + // FIXME: If it is a compiler generated temporary then return. + + // Construct llvm.dbg.declare function. + if (!DeclareFn) + DeclareFn = llvm::Intrinsic::getDeclaration(&M->getModule(), + llvm::Intrinsic::dbg_declare); + + // Get type information. + llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); + llvm::TypeDesc *TyDesc = getOrCreateType(decl->getType(), Unit); + + SourceManager &SM = M->getContext().getSourceManager(); + uint64_t Loc = SM.getLogicalLineNumber(CurLoc); + + // Construct variable. + llvm::VariableDesc *Variable = new llvm::VariableDesc(Tag); + Variable->setContext(RegionStack.back()); + Variable->setName(decl->getName()); + Variable->setFile(Unit); + Variable->setLine(Loc); + Variable->setType(TyDesc); + + // Push it onto the list so that we can free it. + VariableDescList.push_back(Variable); + + // Cast the AllocA result to a {}* for the call to llvm.dbg.declare. + // These bit cast instructions will get freed when the basic block is + // deleted. So do not need to free them explicity. + const llvm::PointerType *EmpPtr = SR->getEmptyStructPtrType(); + llvm::Value *AllocACast = new llvm::BitCastInst(AI, EmpPtr, decl->getName(), + Builder.GetInsertBlock()); + + // Call llvm.dbg.declare. + Builder.CreateCall2(DeclareFn, AllocACast, getCastValueFor(Variable), ""); +} + diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 4e6626fc4d9..3e7835a2d07 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -30,11 +30,13 @@ namespace llvm { class DebugInfoDesc; class Value; class TypeDesc; + class VariableDesc; class SubprogramDesc; } namespace clang { class FunctionDecl; + class VarDecl; namespace CodeGen { class CodeGenModule; @@ -61,7 +63,8 @@ private: llvm::Function *RegionEndFn; llvm::AnchorDesc *CompileUnitAnchor; llvm::AnchorDesc *SubprogramAnchor; - std::vector<llvm::DebugInfoDesc *> RegionStack; + std::vector<llvm::DebugInfoDesc *> RegionStack; + std::vector<llvm::VariableDesc *> VariableDescList; llvm::SubprogramDesc *Subprogram; /// Helper functions for getOrCreateType. @@ -98,6 +101,10 @@ public: /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a /// block. void EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder); + + /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration. + void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI, + llvm::IRBuilder &Builder); /// getOrCreateCompileUnit - Get the compile unit from the cache or create a /// new one if necessary. diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 6e40ea05829..4541fc4caa3 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "CGDebugInfo.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "clang/AST/AST.h" @@ -18,6 +19,7 @@ #include "clang/Basic/TargetInfo.h" #include "llvm/GlobalVariable.h" #include "llvm/Type.h" +#include "llvm/Support/Dwarf.h" using namespace clang; using namespace CodeGen; @@ -143,7 +145,16 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); DMEntry = DeclPtr; - + + // Emit debug info for local var declaration. + CGDebugInfo *DI = CGM.getDebugInfo(); + if(DI) { + if(D.getLocation().isValid()) + DI->setLocation(D.getLocation()); + DI->EmitDeclare(&D, llvm::dwarf::DW_TAG_auto_variable, + DeclPtr, Builder); + } + // If this local has an initializer, emit it now. if (const Expr *Init = D.getInit()) { if (!hasAggregateLLVMType(Init->getType())) { @@ -188,5 +199,15 @@ void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) { llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); DMEntry = DeclPtr; + + // Emit debug info for param declaration. + CGDebugInfo *DI = CGM.getDebugInfo(); + if(DI) { + if(D.getLocation().isValid()) + DI->setLocation(D.getLocation()); + DI->EmitDeclare(&D, llvm::dwarf::DW_TAG_arg_variable, + DeclPtr, Builder); + } + } |