blob: abe1699fe8dc8ae1925b96e5295fed016f434958 [file] [log] [blame]
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +00001//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This coordinates the debug information generation while generating code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CGDebugInfo.h"
15#include "CodeGenModule.h"
16#include "llvm/Constants.h"
17#include "llvm/DerivedTypes.h"
18#include "llvm/Instructions.h"
19#include "llvm/Intrinsics.h"
20#include "llvm/Module.h"
21#include "llvm/Support/Dwarf.h"
22#include "llvm/Support/IRBuilder.h"
23#include "llvm/Target/TargetMachine.h"
24#include "llvm/ADT/StringExtras.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/CodeGen/MachineModuleInfo.h"
27#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/FileManager.h"
29#include "clang/AST/ASTContext.h"
30using namespace clang;
31using namespace clang::CodeGen;
32
33CGDebugInfo::CGDebugInfo(CodeGenModule *m)
34: M(m)
35, CurLoc()
36, PrevLoc()
37, CompileUnitCache()
38, StopPointFn(NULL)
Eli Friedman3f2af102008-05-22 01:40:10 +000039, CompileUnitAnchor(NULL)
40, SubProgramAnchor(NULL)
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +000041, RegionStartFn(NULL)
42, RegionEndFn(NULL)
Eli Friedman3f2af102008-05-22 01:40:10 +000043, FuncStartFn(NULL)
44, CurFuncDesc(NULL)
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +000045{
46 SR = new llvm::DISerializer();
47 SR->setModule (&M->getModule());
48}
49
50CGDebugInfo::~CGDebugInfo()
51{
52 delete SR;
Eli Friedman3f2af102008-05-22 01:40:10 +000053 // Clean up allocated debug info; we can't do this until after the
54 // serializer is destroyed because it caches pointers to
55 // the debug info
56 delete CompileUnitAnchor;
57 delete SubProgramAnchor;
58 // Clean up compile unit descriptions
59 std::map<unsigned, llvm::CompileUnitDesc *>::iterator MI;
60 for (MI = CompileUnitCache.begin(); MI != CompileUnitCache.end(); ++MI)
61 delete MI->second;
62 // Clean up misc allocations
63 std::vector<llvm::DebugInfoDesc*>::iterator VI;
64 for (VI = DebugAllocationList.begin(); VI != DebugAllocationList.end(); ++VI)
65 delete *VI;
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +000066}
67
68
69/// getCastValueFor - Return a llvm representation for a given debug information
70/// descriptor cast to an empty struct pointer.
71llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) {
72 return llvm::ConstantExpr::getBitCast(SR->Serialize(DD),
Eli Friedman86eb3112008-05-13 14:40:48 +000073 SR->getEmptyStructPtrType());
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +000074}
75
76/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
77/// one if necessary.
78llvm::CompileUnitDesc
79*CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) {
80
81 // See if this compile unit has been used before.
82 llvm::CompileUnitDesc *&Slot = CompileUnitCache[Loc.getFileID()];
83 if (Slot) return Slot;
84
85 // Create new compile unit.
86 // FIXME: Where to free these?
87 // One way is to iterate over the CompileUnitCache in ~CGDebugInfo.
88 llvm::CompileUnitDesc *Unit = new llvm::CompileUnitDesc();
89
90 // Make sure we have an anchor.
91 if (!CompileUnitAnchor) {
92 CompileUnitAnchor = new llvm::AnchorDesc(Unit);
93 }
94
95 // Get source file information.
96 SourceManager &SM = M->getContext().getSourceManager();
97 const FileEntry *FE = SM.getFileEntryForLoc(Loc);
Eli Friedman3f2af102008-05-22 01:40:10 +000098 const char *FileName, *DirName;
99 if (FE) {
100 FileName = FE->getName();
101 DirName = FE->getDir()->getName();
102 } else {
103 FileName = SM.getSourceName(Loc);
104 DirName = "";
105 }
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000106
107 Unit->setAnchor(CompileUnitAnchor);
108 Unit->setFileName(FileName);
109 Unit->setDirectory(DirName);
110
111 // Set up producer name.
112 // FIXME: Do not know how to get clang version yet.
113 Unit->setProducer("clang");
114
115 // Set up Language number.
116 // FIXME: Handle other languages as well.
117 Unit->setLanguage(llvm::dwarf::DW_LANG_C89);
118
119 // Update cache.
120 Slot = Unit;
121
122 return Unit;
123}
124
125
126void
127CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) {
Eli Friedman3f2af102008-05-22 01:40:10 +0000128 if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000129
130 // Don't bother if things are the same as last time.
131 SourceManager &SM = M->getContext().getSourceManager();
132 if (CurLoc == PrevLoc
133 || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc)
134 && SM.isFromSameFile(CurLoc, PrevLoc)))
135 return;
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000136
137 // Update last state.
138 PrevLoc = CurLoc;
139
140 // Get the appropriate compile unit.
141 llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
142
143 // Lazily construct llvm.dbg.stoppoint function.
144 if (!StopPointFn)
145 StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
Eli Friedman86eb3112008-05-13 14:40:48 +0000146 llvm::Intrinsic::dbg_stoppoint);
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000147
148 uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc);
149 uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc);
150
151 // Invoke llvm.dbg.stoppoint
152 Builder.CreateCall3(StopPointFn,
Eli Friedman86eb3112008-05-13 14:40:48 +0000153 llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo),
154 llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo),
155 getCastValueFor(Unit), "");
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000156}
157
158/// EmitRegionStart- Constructs the debug code for entering a declarative
159/// region - "llvm.dbg.region.start.".
Eli Friedman3f2af102008-05-22 01:40:10 +0000160void CGDebugInfo::EmitFunctionStart(llvm::Function *Fn, llvm::IRBuilder &Builder)
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000161{
Eli Friedman3f2af102008-05-22 01:40:10 +0000162 // Get the appropriate compile unit.
163 llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000164
Eli Friedman3f2af102008-05-22 01:40:10 +0000165 llvm::SubprogramDesc* Block = new llvm::SubprogramDesc;
166 DebugAllocationList.push_back(Block);
167 Block->setFile(Unit);
168 Block->setContext(Unit);
169 if (!SubProgramAnchor) {
170 SubProgramAnchor = new llvm::AnchorDesc(Block);
171 SR->Serialize(SubProgramAnchor);
172 }
173 Block->setAnchor(SubProgramAnchor);
174 Block->setName(Fn->getName());
175 Block->setFullName(Fn->getName());
176 Block->setIsDefinition(true);
177 SourceManager &SM = M->getContext().getSourceManager();
178 Block->setLine(SM.getLogicalLineNumber(CurLoc));
179 CurFuncDesc = getCastValueFor(Block);
180 if (!FuncStartFn)
181 FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
182 llvm::Intrinsic::dbg_func_start);
183 Builder.CreateCall(FuncStartFn, CurFuncDesc);
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000184}
185
186/// EmitRegionEnd - Constructs the debug code for exiting a declarative
187/// region - "llvm.dbg.region.end."
Eli Friedman3f2af102008-05-22 01:40:10 +0000188void CGDebugInfo::EmitFunctionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder)
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000189{
190 // Lazily construct llvm.dbg.region.end function.
191 if (!RegionEndFn)
192 RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(),
Eli Friedman86eb3112008-05-13 14:40:48 +0000193 llvm::Intrinsic::dbg_region_end);
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000194
195 // Provide an region stop point.
196 EmitStopPoint(Fn, Builder);
197
198 // Call llvm.dbg.func.end.
Eli Friedman3f2af102008-05-22 01:40:10 +0000199 Builder.CreateCall(RegionEndFn, CurFuncDesc, "");
Sanjiv Guptae8b9f5b2008-05-08 08:54:20 +0000200}
201