, CompileUnitAnchor(NULL)
, SubprogramAnchor(NULL)
, RegionStack()
+, VariableDescList()
, Subprogram(NULL)
{
SR = new llvm::DISerializer();
= 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;
}
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), "");
+}
+
class DebugInfoDesc;
class Value;
class TypeDesc;
+ class VariableDesc;
class SubprogramDesc;
}
namespace clang {
class FunctionDecl;
+ class VarDecl;
namespace CodeGen {
class CodeGenModule;
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.
/// 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.
//
//===----------------------------------------------------------------------===//
+#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/AST.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Type.h"
+#include "llvm/Support/Dwarf.h"
using namespace clang;
using namespace CodeGen;
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())) {
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);
+ }
+
}