[cfe-commits] r50848 - in /cfe/trunk: Driver/Makefile Driver/clang.cpp include/clang/CodeGen/ModuleBuilder.h lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGStmt.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/ModuleBuilder.cpp
Sanjiv Gupta
sanjiv.gupta at microchip.com
Thu May 8 01:54:20 PDT 2008
Author: sgupta
Date: Thu May 8 03:54:20 2008
New Revision: 50848
URL: http://llvm.org/viewvc/llvm-project?rev=50848&view=rev
Log:
Added -g command line options to clang for generating source level debug information. This patch currently enables generation of line number debug information (stoppoints) and region begin/end debug information. The new files CGDebugInfo.h and CGDebugInfo.cpp implements the debug info manager class CGDebugInfo.
Added:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
Modified:
cfe/trunk/Driver/Makefile
cfe/trunk/Driver/clang.cpp
cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
Modified: cfe/trunk/Driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Makefile?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/Driver/Makefile (original)
+++ cfe/trunk/Driver/Makefile Thu May 8 03:54:20 2008
@@ -6,7 +6,7 @@
USEDLIBS = clangCodeGen.a clangAnalysis.a clangRewrite.a clangSEMA.a \
clangAST.a clangParse.a clangLex.a clangBasic.a \
LLVMCore.a LLVMSupport.a LLVMSystem.a \
- LLVMBitWriter.a LLVMBitReader.a LLVMTarget.a
+ LLVMBitWriter.a LLVMBitReader.a LLVMCodeGen.a LLVMTarget.a
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Thu May 8 03:54:20 2008
@@ -149,6 +149,13 @@
llvm::cl::desc("Specify output file (for --serialize, this is a directory)"));
//===----------------------------------------------------------------------===//
+// Code Generator Options
+//===----------------------------------------------------------------------===//
+static llvm::cl::opt<bool>
+GenerateDebugInfo("g",
+ llvm::cl::desc("Generate source level debug information"));
+
+//===----------------------------------------------------------------------===//
// Diagnostic Options
//===----------------------------------------------------------------------===//
@@ -1161,7 +1168,7 @@
case EmitLLVM:
case EmitBC:
DestModule = new llvm::Module(InFile);
- return CreateLLVMCodeGen(Diag, LangOpts, DestModule);
+ return CreateLLVMCodeGen(Diag, LangOpts, DestModule, GenerateDebugInfo);
case SerializeAST:
// FIXME: Allow user to tailor where the file is written.
Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
+++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Thu May 8 03:54:20 2008
@@ -24,7 +24,8 @@
class ASTConsumer;
ASTConsumer *CreateLLVMCodeGen(Diagnostic &Diags, const LangOptions &Features,
- llvm::Module *&DestModule);
+ llvm::Module *&DestModule,
+ bool GenerateDebugInfo);
}
#endif
Added: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=50848&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (added)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu May 8 03:54:20 2008
@@ -0,0 +1,171 @@
+//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This coordinates the debug information generation while generating code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGDebugInfo.h"
+#include "CodeGenModule.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/AST/ASTContext.h"
+using namespace clang;
+using namespace clang::CodeGen;
+
+CGDebugInfo::CGDebugInfo(CodeGenModule *m)
+: M(m)
+, CurLoc()
+, PrevLoc()
+, CompileUnitCache()
+, StopPointFn(NULL)
+, RegionStartFn(NULL)
+, RegionEndFn(NULL)
+, RegionStack()
+{
+ SR = new llvm::DISerializer();
+ SR->setModule (&M->getModule());
+}
+
+CGDebugInfo::~CGDebugInfo()
+{
+ delete SR;
+}
+
+
+/// getCastValueFor - Return a llvm representation for a given debug information
+/// descriptor cast to an empty struct pointer.
+llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) {
+ return llvm::ConstantExpr::getBitCast(SR->Serialize(DD),
+ SR->getEmptyStructPtrType());
+}
+
+/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
+/// one if necessary.
+llvm::CompileUnitDesc
+*CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) {
+
+ // See if this compile unit has been used before.
+ llvm::CompileUnitDesc *&Slot = CompileUnitCache[Loc.getFileID()];
+ if (Slot) return Slot;
+
+ // Create new compile unit.
+ // FIXME: Where to free these?
+ // One way is to iterate over the CompileUnitCache in ~CGDebugInfo.
+ llvm::CompileUnitDesc *Unit = new llvm::CompileUnitDesc();
+
+ // Make sure we have an anchor.
+ if (!CompileUnitAnchor) {
+ CompileUnitAnchor = new llvm::AnchorDesc(Unit);
+ }
+
+ // Get source file information.
+ SourceManager &SM = M->getContext().getSourceManager();
+ const FileEntry *FE = SM.getFileEntryForLoc(Loc);
+ const char *FileName = FE->getName();
+ const char *DirName = FE->getDir()->getName();
+
+ Unit->setAnchor(CompileUnitAnchor);
+ Unit->setFileName(FileName);
+ Unit->setDirectory(DirName);
+
+ // Set up producer name.
+ // FIXME: Do not know how to get clang version yet.
+ Unit->setProducer("clang");
+
+ // Set up Language number.
+ // FIXME: Handle other languages as well.
+ Unit->setLanguage(llvm::dwarf::DW_LANG_C89);
+
+ // Update cache.
+ Slot = Unit;
+
+ return Unit;
+}
+
+
+void
+CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) {
+
+ // Don't bother if things are the same as last time.
+ SourceManager &SM = M->getContext().getSourceManager();
+ if (CurLoc == PrevLoc
+ || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc)
+ && SM.isFromSameFile(CurLoc, PrevLoc)))
+ return;
+ if (CurLoc.isInvalid()) return;
+
+ // Update last state.
+ PrevLoc = CurLoc;
+
+ // Get the appropriate compile unit.
+ llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
+
+ // Lazily construct llvm.dbg.stoppoint function.
+ if (!StopPointFn)
+ StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
+ llvm::Intrinsic::dbg_stoppoint);
+
+ uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc);
+ uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc);
+
+ // Invoke llvm.dbg.stoppoint
+ Builder.CreateCall3(StopPointFn,
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo),
+ getCastValueFor(Unit), "");
+}
+
+/// EmitRegionStart- Constructs the debug code for entering a declarative
+/// region - "llvm.dbg.region.start.".
+void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder)
+{
+ llvm::BlockDesc *Block = new llvm::BlockDesc();
+ if (RegionStack.size() > 0)
+ Block->setContext(RegionStack.back());
+ RegionStack.push_back(Block);
+
+ // Lazily construct llvm.dbg.region.start function.
+ if (!RegionStartFn)
+ RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
+ llvm::Intrinsic::dbg_region_start);
+
+ // Call llvm.dbg.func.start.
+ Builder.CreateCall(RegionStartFn, getCastValueFor(Block), "");
+}
+
+/// EmitRegionEnd - Constructs the debug code for exiting a declarative
+/// region - "llvm.dbg.region.end."
+void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder)
+{
+ // Lazily construct llvm.dbg.region.end function.
+ if (!RegionEndFn)
+ RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(),
+ llvm::Intrinsic::dbg_region_end);
+
+ // Provide an region stop point.
+ EmitStopPoint(Fn, Builder);
+
+ // Call llvm.dbg.func.end.
+ Builder.CreateCall(RegionEndFn, getCastValueFor(RegionStack.back()), "");
+ RegionStack.pop_back();
+ // FIXME: Free here the memory created for BlockDesc in RegionStart?
+}
+
Added: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=50848&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (added)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Thu May 8 03:54:20 2008
@@ -0,0 +1,84 @@
+//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the source level debug info generator for llvm translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGDEBUGINFO_H
+#define CLANG_CODEGEN_CGDEBUGINFO_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <map>
+#include <vector>
+
+
+namespace llvm {
+ class Function;
+ class IRBuilder;
+ class DISerializer;
+ class CompileUnitDesc;
+ class BasicBlock;
+ class AnchorDesc;
+ class DebugInfoDesc;
+ class Value;
+}
+
+namespace clang {
+namespace CodeGen {
+ class CodeGenModule;
+
+/// DebugInfo - This class gathers all debug information during compilation and
+/// is responsible for emitting to llvm globals or pass directly to the backend.
+class CGDebugInfo {
+private:
+ CodeGenModule *M;
+ llvm::DISerializer *SR;
+ SourceLocation CurLoc;
+ SourceLocation PrevLoc;
+
+ /// CompileUnitCache - Cache of previously constructed CompileUnits.
+ std::map<unsigned, llvm::CompileUnitDesc *> CompileUnitCache;
+
+ llvm::Function *StopPointFn;
+ llvm::AnchorDesc *CompileUnitAnchor;
+ llvm::Function *RegionStartFn;
+ llvm::Function *RegionEndFn;
+ std::vector<llvm::DebugInfoDesc *> RegionStack;
+
+public:
+ CGDebugInfo(CodeGenModule *m);
+ ~CGDebugInfo();
+
+ void setLocation(SourceLocation loc) { CurLoc = loc; };
+
+ /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
+ /// source line.
+ void EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder);
+
+ /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start
+ /// of a new block.
+ void EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder);
+
+ /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a
+ /// block.
+ void EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder);
+
+ /// getOrCreateCompileUnit - Get the compile unit from the cache or create a
+ /// new one if necessary.
+ llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc);
+
+ /// getCastValueFor - Return a llvm representation for a given debug
+ /// information descriptor cast to an empty struct pointer.
+ llvm::Value *getCastValueFor(llvm::DebugInfoDesc *DD);
+};
+} // namespace CodeGen
+} // namespace clang
+
+#endif
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu May 8 03:54:20 2008
@@ -11,6 +11,8 @@
//
//===----------------------------------------------------------------------===//
+#include "CGDebugInfo.h"
+#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "clang/AST/AST.h"
#include "clang/Basic/TargetInfo.h"
@@ -29,6 +31,18 @@
void CodeGenFunction::EmitStmt(const Stmt *S) {
assert(S && "Null statement?");
+ // Generate stoppoints if we are emitting debug info.
+ // Beginning of a Compound Statement (e.g. an opening '{') does not produce
+ // executable code. So do not generate a stoppoint for that.
+ CGDebugInfo *DI = CGM.getDebugInfo();
+ if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) {
+ if (S->getLocStart().isValid()) {
+ DI->setLocation(S->getLocStart());
+ }
+
+ DI->EmitStopPoint(CurFn, Builder);
+ }
+
switch (S->getStmtClass()) {
default:
// Must be an expression in a stmt context. Emit the value (to get
@@ -74,11 +88,25 @@
// FIXME: handle vla's etc.
if (S.body_empty() || !isa<Expr>(S.body_back())) GetLast = false;
+ CGDebugInfo *DI = CGM.getDebugInfo();
+ if (DI) {
+ if (S.getLBracLoc().isValid()) {
+ DI->setLocation(S.getLBracLoc());
+ }
+ DI->EmitRegionStart(CurFn, Builder);
+ }
+
for (CompoundStmt::const_body_iterator I = S.body_begin(),
E = S.body_end()-GetLast; I != E; ++I)
EmitStmt(*I);
-
-
+
+ if (DI) {
+ if (S.getRBracLoc().isValid()) {
+ DI->setLocation(S.getRBracLoc());
+ }
+ DI->EmitRegionEnd(CurFn, Builder);
+ }
+
if (!GetLast)
return RValue::get(0);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu May 8 03:54:20 2008
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "CGDebugInfo.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "clang/AST/ASTContext.h"
@@ -32,13 +33,19 @@
CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
llvm::Module &M, const llvm::TargetData &TD,
- Diagnostic &diags)
+ Diagnostic &diags, bool GenerateDebugInfo)
: Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
Types(C, M, TD), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
//TODO: Make this selectable at runtime
Runtime = CreateObjCRuntime(M,
getTypes().ConvertType(getContext().IntTy),
getTypes().ConvertType(getContext().LongTy));
+
+ // If debug info generation is enabled, create the CGDebugInfo object.
+ if (GenerateDebugInfo)
+ DebugInfo = new CGDebugInfo(this);
+ else
+ DebugInfo = NULL;
}
CodeGenModule::~CodeGenModule() {
@@ -49,7 +56,7 @@
EmitGlobalCtors();
EmitAnnotations();
delete Runtime;
-
+ delete DebugInfo;
// Run the verifier to check that the generated code is consistent.
assert(!verifyModule(TheModule));
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu May 8 03:54:20 2008
@@ -43,7 +43,8 @@
namespace CodeGen {
class CodeGenFunction;
-
+ class CGDebugInfo;
+
/// CodeGenModule - This class organizes the cross-module state that is used
/// while generating LLVM code.
class CodeGenModule {
@@ -54,6 +55,7 @@
Diagnostic &Diags;
CodeGenTypes Types;
CGObjCRuntime *Runtime;
+ CGDebugInfo *DebugInfo;
llvm::Function *MemCpyFn;
llvm::Function *MemSetFn;
@@ -70,10 +72,12 @@
std::vector<llvm::Function *> BuiltinFunctions;
public:
CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M,
- const llvm::TargetData &TD, Diagnostic &Diags);
+ const llvm::TargetData &TD, Diagnostic &Diags,
+ bool GenerateDebugInfo);
~CodeGenModule();
CGObjCRuntime *getObjCRuntime() { return Runtime; }
+ CGDebugInfo *getDebugInfo() { return DebugInfo; }
ASTContext &getContext() const { return Context; }
const LangOptions &getLangOptions() const { return Features; }
llvm::Module &getModule() const { return TheModule; }
Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=50848&r1=50847&r2=50848&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Thu May 8 03:54:20 2008
@@ -34,13 +34,15 @@
const llvm::TargetData *TD;
ASTContext *Ctx;
const LangOptions &Features;
+ bool GenerateDebugInfo;
protected:
llvm::Module *&M;
CodeGen::CodeGenModule *Builder;
public:
CodeGenerator(Diagnostic &diags, const LangOptions &LO,
- llvm::Module *&DestModule)
- : Diags(diags), Features(LO), M(DestModule) {}
+ llvm::Module *&DestModule, bool DebugInfoFlag)
+ : Diags(diags), Features(LO), GenerateDebugInfo(DebugInfoFlag),
+ M(DestModule) {}
~CodeGenerator() {
delete Builder;
@@ -52,7 +54,8 @@
M->setTargetTriple(Ctx->Target.getTargetTriple());
M->setDataLayout(Ctx->Target.getTargetDescription());
TD = new llvm::TargetData(Ctx->Target.getTargetDescription());
- Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags);
+ Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags,
+ GenerateDebugInfo);
}
virtual void HandleTopLevelDecl(Decl *D) {
@@ -103,7 +106,8 @@
ASTConsumer *clang::CreateLLVMCodeGen(Diagnostic &Diags,
const LangOptions &Features,
- llvm::Module *&DestModule) {
- return new CodeGenerator(Diags, Features, DestModule);
+ llvm::Module *&DestModule,
+ bool GenerateDebugInfo) {
+ return new CodeGenerator(Diags, Features, DestModule, GenerateDebugInfo);
}
More information about the cfe-commits
mailing list