1 //===--- DIBuilder.cpp - Debug Information Builder ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the DIBuilder.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Analysis/DIBuilder.h"
15 #include "llvm/Analysis/DebugInfo.h"
16 #include "llvm/Constants.h"
17 #include "llvm/IntrinsicInst.h"
18 #include "llvm/Module.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Support/Dwarf.h"
23 using namespace llvm::dwarf;
25 static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) {
26 assert((Tag & LLVMDebugVersionMask) == 0 &&
27 "Tag too large for debug encoding!");
28 return ConstantInt::get(Type::getInt32Ty(VMContext), Tag | LLVMDebugVersion);
30 DIBuilder::DIBuilder(Module &m)
31 : M(m), VMContext(M.getContext()), TheCU(0) {}
33 /// CreateCompileUnit - A CompileUnit provides an anchor for all debugging
34 /// information generated during this instance of compilation.
35 void DIBuilder::CreateCompileUnit(unsigned Lang, StringRef Filename,
36 StringRef Directory, StringRef Producer,
37 bool isOptimized, StringRef Flags,
38 unsigned RunTimeVer) {
40 GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit),
41 llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
42 ConstantInt::get(Type::getInt32Ty(VMContext), Lang),
43 MDString::get(VMContext, Filename),
44 MDString::get(VMContext, Directory),
45 MDString::get(VMContext, Producer),
46 // Deprecate isMain field.
47 ConstantInt::get(Type::getInt1Ty(VMContext), true), // isMain
48 ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
49 MDString::get(VMContext, Flags),
50 ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer)
52 TheCU = DICompileUnit(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
55 /// CreateFile - Create a file descriptor to hold debugging information
57 DIFile DIBuilder::CreateFile(StringRef Filename, StringRef Directory) {
58 assert(TheCU && "Unable to create DW_TAG_file_type without CompileUnit");
60 GetTagConstant(VMContext, dwarf::DW_TAG_file_type),
61 MDString::get(VMContext, Filename),
62 MDString::get(VMContext, Directory),
65 return DIFile(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
68 /// CreateEnumerator - Create a single enumerator value.
69 DIEnumerator DIBuilder::CreateEnumerator(StringRef Name, uint64_t Val) {
71 GetTagConstant(VMContext, dwarf::DW_TAG_enumerator),
72 MDString::get(VMContext, Name),
73 ConstantInt::get(Type::getInt64Ty(VMContext), Val)
75 return DIEnumerator(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
78 /// CreateBasicType - Create debugging information entry for a basic
80 DIType DIBuilder::CreateBasicType(StringRef Name, uint64_t SizeInBits,
83 // Basic types are encoded in DIBasicType format. Line number, filename,
84 // offset and flags are always empty here.
86 GetTagConstant(VMContext, dwarf::DW_TAG_base_type),
88 MDString::get(VMContext, Name),
90 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
91 ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
92 ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
93 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
94 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags;
95 ConstantInt::get(Type::getInt32Ty(VMContext), Encoding)
97 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
100 /// CreateQaulifiedType - Create debugging information entry for a qualified
101 /// type, e.g. 'const int'.
102 DIType DIBuilder::CreateQualifiedType(unsigned Tag, DIType FromTy) {
103 // Qualified types are encoded in DIDerivedType format.
105 GetTagConstant(VMContext, Tag),
107 MDString::get(VMContext, StringRef()), // Empty name.
109 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
110 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
111 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
112 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
113 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
116 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
119 /// CreatePointerType - Create debugging information entry for a pointer.
120 DIType DIBuilder::CreatePointerType(DIType PointeeTy, uint64_t SizeInBits,
121 uint64_t AlignInBits, StringRef Name) {
122 // Pointer types are encoded in DIDerivedType format.
124 GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type),
126 MDString::get(VMContext, Name),
128 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
129 ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
130 ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
131 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
132 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
135 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
138 /// CreateReferenceType - Create debugging information entry for a reference.
139 DIType DIBuilder::CreateReferenceType(DIType RTy) {
140 // References are encoded in DIDerivedType format.
142 GetTagConstant(VMContext, dwarf::DW_TAG_reference_type),
146 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
147 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
148 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
149 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
150 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
153 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
156 /// CreateTypedef - Create debugging information entry for a typedef.
157 DIType DIBuilder::CreateTypedef(DIType Ty, StringRef Name, DIFile File,
159 // typedefs are encoded in DIDerivedType format.
160 assert(Ty.Verify() && "Invalid typedef type!");
162 GetTagConstant(VMContext, dwarf::DW_TAG_typedef),
164 MDString::get(VMContext, Name),
166 ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
167 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
168 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
169 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
170 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
173 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
176 /// CreateFriend - Create debugging information entry for a 'friend'.
177 DIType DIBuilder::CreateFriend(DIType Ty, DIType FriendTy) {
178 // typedefs are encoded in DIDerivedType format.
179 assert(Ty.Verify() && "Invalid type!");
180 assert(FriendTy.Verify() && "Invalid friend type!");
182 GetTagConstant(VMContext, dwarf::DW_TAG_friend),
186 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
187 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
188 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
189 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
190 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
193 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
196 /// CreateInheritance - Create debugging information entry to establish
197 /// inheritnace relationship between two types.
198 DIType DIBuilder::CreateInheritance(DIType Ty, DIType BaseTy,
199 uint64_t BaseOffset, unsigned Flags) {
200 // TAG_inheritance is encoded in DIDerivedType format.
202 GetTagConstant(VMContext, dwarf::DW_TAG_inheritance),
206 ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
207 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
208 ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
209 ConstantInt::get(Type::getInt64Ty(VMContext), BaseOffset),
210 ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
213 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
216 /// CreateMemberType - Create debugging information entry for a member.
217 DIType DIBuilder::CreateMemberType(DIDescriptor Context, StringRef Name,
218 DIFile F, unsigned LineNumber,
219 uint64_t SizeInBits, uint64_t AlignInBits,
220 uint64_t OffsetInBits, unsigned Flags,
222 // TAG_member is encoded in DIDerivedType format.
224 GetTagConstant(VMContext, dwarf::DW_TAG_member),
226 MDString::get(VMContext, Name),
228 ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
229 ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
230 ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
231 ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits),
232 ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
235 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
238 /// CreateArtificialType - Create a new DIType with "artificial" flag set.
239 DIType DIBuilder::CreateArtificialType(DIType Ty) {
240 if (Ty.isArtificial())
243 SmallVector<Value *, 9> Elts;
245 assert (N && "Unexpected input DIType!");
246 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
247 if (Value *V = N->getOperand(i))
250 Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
253 unsigned CurFlags = Ty.getFlags();
254 CurFlags = CurFlags | DIType::FlagArtificial;
256 // Flags are stored at this slot.
257 Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags);
259 return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));