]> granicus.if.org Git - clang/commitdiff
Emit parameter and local variable debug information with -g.
authorSanjiv Gupta <sanjiv.gupta@microchip.com>
Fri, 30 May 2008 10:30:31 +0000 (10:30 +0000)
committerSanjiv Gupta <sanjiv.gupta@microchip.com>
Fri, 30 May 2008 10:30:31 +0000 (10:30 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51765 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
lib/CodeGen/CGDecl.cpp

index 1827fc980c3dff651b7542bef4a7db4e2faeb7d5..19745dc2a0ce213b7f17d78cabdf02f5c9f30054 100644 (file)
@@ -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), "");
+}
+
index 4e6626fc4d9269afecc40cc3d4be114113c576c1..3e7835a2d07cb64bf422115df592486842f735f4 100644 (file)
@@ -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.
index 6e40ea05829f3a5e9a561aed970102b4f2210c16..4541fc4caa349f354636aebf021e9a19b338884f 100644 (file)
@@ -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);
+  }
+
 }