blob: e0c76d32fb6045f8038a709ac0852dd4fb99a40a [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)
39, RegionStartFn(NULL)
40, RegionEndFn(NULL)
41, RegionStack()
42{
43 SR = new llvm::DISerializer();
44 SR->setModule (&M->getModule());
45}
46
47CGDebugInfo::~CGDebugInfo()
48{
49 delete SR;
50}
51
52
53/// getCastValueFor - Return a llvm representation for a given debug information
54/// descriptor cast to an empty struct pointer.
55llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) {
56 return llvm::ConstantExpr::getBitCast(SR->Serialize(DD),
57 SR->getEmptyStructPtrType());
58}
59
60/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
61/// one if necessary.
62llvm::CompileUnitDesc
63*CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) {
64
65 // See if this compile unit has been used before.
66 llvm::CompileUnitDesc *&Slot = CompileUnitCache[Loc.getFileID()];
67 if (Slot) return Slot;
68
69 // Create new compile unit.
70 // FIXME: Where to free these?
71 // One way is to iterate over the CompileUnitCache in ~CGDebugInfo.
72 llvm::CompileUnitDesc *Unit = new llvm::CompileUnitDesc();
73
74 // Make sure we have an anchor.
75 if (!CompileUnitAnchor) {
76 CompileUnitAnchor = new llvm::AnchorDesc(Unit);
77 }
78
79 // Get source file information.
80 SourceManager &SM = M->getContext().getSourceManager();
81 const FileEntry *FE = SM.getFileEntryForLoc(Loc);
82 const char *FileName = FE->getName();
83 const char *DirName = FE->getDir()->getName();
84
85 Unit->setAnchor(CompileUnitAnchor);
86 Unit->setFileName(FileName);
87 Unit->setDirectory(DirName);
88
89 // Set up producer name.
90 // FIXME: Do not know how to get clang version yet.
91 Unit->setProducer("clang");
92
93 // Set up Language number.
94 // FIXME: Handle other languages as well.
95 Unit->setLanguage(llvm::dwarf::DW_LANG_C89);
96
97 // Update cache.
98 Slot = Unit;
99
100 return Unit;
101}
102
103
104void
105CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) {
106
107 // Don't bother if things are the same as last time.
108 SourceManager &SM = M->getContext().getSourceManager();
109 if (CurLoc == PrevLoc
110 || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc)
111 && SM.isFromSameFile(CurLoc, PrevLoc)))
112 return;
113 if (CurLoc.isInvalid()) return;
114
115 // Update last state.
116 PrevLoc = CurLoc;
117
118 // Get the appropriate compile unit.
119 llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
120
121 // Lazily construct llvm.dbg.stoppoint function.
122 if (!StopPointFn)
123 StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
124 llvm::Intrinsic::dbg_stoppoint);
125
126 uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc);
127 uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc);
128
129 // Invoke llvm.dbg.stoppoint
130 Builder.CreateCall3(StopPointFn,
131 llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo),
132 llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo),
133 getCastValueFor(Unit), "");
134}
135
136/// EmitRegionStart- Constructs the debug code for entering a declarative
137/// region - "llvm.dbg.region.start.".
138void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder)
139{
140 llvm::BlockDesc *Block = new llvm::BlockDesc();
141 if (RegionStack.size() > 0)
142 Block->setContext(RegionStack.back());
143 RegionStack.push_back(Block);
144
145 // Lazily construct llvm.dbg.region.start function.
146 if (!RegionStartFn)
147 RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
148 llvm::Intrinsic::dbg_region_start);
149
150 // Call llvm.dbg.func.start.
151 Builder.CreateCall(RegionStartFn, getCastValueFor(Block), "");
152}
153
154/// EmitRegionEnd - Constructs the debug code for exiting a declarative
155/// region - "llvm.dbg.region.end."
156void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder)
157{
158 // Lazily construct llvm.dbg.region.end function.
159 if (!RegionEndFn)
160 RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(),
161 llvm::Intrinsic::dbg_region_end);
162
163 // Provide an region stop point.
164 EmitStopPoint(Fn, Builder);
165
166 // Call llvm.dbg.func.end.
167 Builder.CreateCall(RegionEndFn, getCastValueFor(RegionStack.back()), "");
168 RegionStack.pop_back();
169 // FIXME: Free here the memory created for BlockDesc in RegionStart?
170}
171