diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-05-22 01:40:10 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-05-22 01:40:10 +0000 |
commit | 3f2af1002249c8acc9ce17f1fc50324864feb8e1 (patch) | |
tree | 78a34b5f3203319ca8fd0bbf3f2af64c085ee47e /lib/CodeGen/CGDebugInfo.cpp | |
parent | 144ac61f9005a0da4327d4e62a4c453923b7bc0c (diff) |
Make debugging information usable. This is barebones, but it makes -g
actually work (instead of crashing llc), and there's enough info emitted
to get line number information in gdb. This should hopefully be helpful
for debugging non-working programs.
I got rid of the begin/endregion calls because the implementation wasn't
working; someone who knows the debugging info a bit better might try to
add it. I really have no clue how a compiler is supposed to emit them.
This commit shouldn't have any effect without -g.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51404 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 9cceb5ce0a..abe1699fe8 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -36,9 +36,12 @@ CGDebugInfo::CGDebugInfo(CodeGenModule *m) , PrevLoc() , CompileUnitCache() , StopPointFn(NULL) +, CompileUnitAnchor(NULL) +, SubProgramAnchor(NULL) , RegionStartFn(NULL) , RegionEndFn(NULL) -, RegionStack() +, FuncStartFn(NULL) +, CurFuncDesc(NULL) { SR = new llvm::DISerializer(); SR->setModule (&M->getModule()); @@ -47,6 +50,19 @@ CGDebugInfo::CGDebugInfo(CodeGenModule *m) CGDebugInfo::~CGDebugInfo() { delete SR; + // Clean up allocated debug info; we can't do this until after the + // serializer is destroyed because it caches pointers to + // the debug info + delete CompileUnitAnchor; + delete SubProgramAnchor; + // Clean up compile unit descriptions + std::map<unsigned, llvm::CompileUnitDesc *>::iterator MI; + for (MI = CompileUnitCache.begin(); MI != CompileUnitCache.end(); ++MI) + delete MI->second; + // Clean up misc allocations + std::vector<llvm::DebugInfoDesc*>::iterator VI; + for (VI = DebugAllocationList.begin(); VI != DebugAllocationList.end(); ++VI) + delete *VI; } @@ -79,8 +95,14 @@ llvm::CompileUnitDesc // 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(); + const char *FileName, *DirName; + if (FE) { + FileName = FE->getName(); + DirName = FE->getDir()->getName(); + } else { + FileName = SM.getSourceName(Loc); + DirName = ""; + } Unit->setAnchor(CompileUnitAnchor); Unit->setFileName(FileName); @@ -103,6 +125,7 @@ llvm::CompileUnitDesc void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) { + if (CurLoc.isInvalid() || CurLoc.isMacroID()) return; // Don't bother if things are the same as last time. SourceManager &SM = M->getContext().getSourceManager(); @@ -110,7 +133,6 @@ CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) { || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc) && SM.isFromSameFile(CurLoc, PrevLoc))) return; - if (CurLoc.isInvalid()) return; // Update last state. PrevLoc = CurLoc; @@ -135,25 +157,35 @@ CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) { /// EmitRegionStart- Constructs the debug code for entering a declarative /// region - "llvm.dbg.region.start.". -void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder) +void CGDebugInfo::EmitFunctionStart(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), ""); + // Get the appropriate compile unit. + llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); + + llvm::SubprogramDesc* Block = new llvm::SubprogramDesc; + DebugAllocationList.push_back(Block); + Block->setFile(Unit); + Block->setContext(Unit); + if (!SubProgramAnchor) { + SubProgramAnchor = new llvm::AnchorDesc(Block); + SR->Serialize(SubProgramAnchor); + } + Block->setAnchor(SubProgramAnchor); + Block->setName(Fn->getName()); + Block->setFullName(Fn->getName()); + Block->setIsDefinition(true); + SourceManager &SM = M->getContext().getSourceManager(); + Block->setLine(SM.getLogicalLineNumber(CurLoc)); + CurFuncDesc = getCastValueFor(Block); + if (!FuncStartFn) + FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), + llvm::Intrinsic::dbg_func_start); + Builder.CreateCall(FuncStartFn, CurFuncDesc); } /// EmitRegionEnd - Constructs the debug code for exiting a declarative /// region - "llvm.dbg.region.end." -void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) +void CGDebugInfo::EmitFunctionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) { // Lazily construct llvm.dbg.region.end function. if (!RegionEndFn) @@ -164,8 +196,6 @@ void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) 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? + Builder.CreateCall(RegionEndFn, CurFuncDesc, ""); } |