From cc9b16394fe6c9245dc4f8661a63d0c3937b62f0 Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Fri, 30 May 2008 10:30:31 +0000 Subject: [PATCH] Emit parameter and local variable debug information with -g. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51765 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 49 ++++++++++++++++++++++++++++++++++++- lib/CodeGen/CGDebugInfo.h | 9 ++++++- lib/CodeGen/CGDecl.cpp | 23 ++++++++++++++++- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 1827fc980c..19745dc2a0 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/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::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/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 4e6626fc4d..3e7835a2d0 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/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 RegionStack; + std::vector RegionStack; + std::vector 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/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 6e40ea0582..4541fc4caa 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/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); + } + } -- 2.40.0