blob: 1b2049b1e56dd7e70eb044452e4f529bbb955f3d [file] [log] [blame]
Devang Patel35fcd652010-11-04 15:01:38 +00001//===--- DIBuilder.cpp - Debug Information Builder ------------------------===//
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 file implements the DIBuilder.
11//
12//===----------------------------------------------------------------------===//
13
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"
Benjamin Kramer42c9b252010-11-04 18:45:27 +000019#include "llvm/ADT/STLExtras.h"
Devang Patel35fcd652010-11-04 15:01:38 +000020#include "llvm/Support/Dwarf.h"
21
22using namespace llvm;
23using namespace llvm::dwarf;
24
25static 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);
29}
30DIBuilder::DIBuilder(Module &m)
31 : M(m), VMContext(M.getContext()), TheCU(0) {}
32
33/// CreateCompileUnit - A CompileUnit provides an anchor for all debugging
34/// information generated during this instance of compilation.
35void DIBuilder::CreateCompileUnit(unsigned Lang, StringRef Filename,
36 StringRef Directory, StringRef Producer,
37 bool isOptimized, StringRef Flags,
38 unsigned RunTimeVer) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +000039 Value *Elts[] = {
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)
51 };
52 TheCU = DICompileUnit(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +000053}
54
55/// CreateFile - Create a file descriptor to hold debugging information
56/// for a file.
57DIFile DIBuilder::CreateFile(StringRef Filename, StringRef Directory) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +000058 assert(TheCU && "Unable to create DW_TAG_file_type without CompileUnit");
59 Value *Elts[] = {
60 GetTagConstant(VMContext, dwarf::DW_TAG_file_type),
61 MDString::get(VMContext, Filename),
62 MDString::get(VMContext, Directory),
63 TheCU
64 };
65 return DIFile(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +000066}
67
68/// CreateEnumerator - Create a single enumerator value.
69DIEnumerator DIBuilder::CreateEnumerator(StringRef Name, uint64_t Val) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +000070 Value *Elts[] = {
71 GetTagConstant(VMContext, dwarf::DW_TAG_enumerator),
72 MDString::get(VMContext, Name),
73 ConstantInt::get(Type::getInt64Ty(VMContext), Val)
74 };
75 return DIEnumerator(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +000076}
77
78/// CreateBasicType - Create debugging information entry for a basic
79/// type, e.g 'char'.
80DIType DIBuilder::CreateBasicType(StringRef Name, uint64_t SizeInBits,
81 uint64_t AlignInBits,
82 unsigned Encoding) {
83 // Basic types are encoded in DIBasicType format. Line number, filename,
84 // offset and flags are always empty here.
Benjamin Kramer42c9b252010-11-04 18:45:27 +000085 Value *Elts[] = {
86 GetTagConstant(VMContext, dwarf::DW_TAG_base_type),
87 TheCU,
88 MDString::get(VMContext, Name),
89 NULL, // Filename
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)
96 };
97 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +000098}
99
100/// CreateQaulifiedType - Create debugging information entry for a qualified
101/// type, e.g. 'const int'.
102DIType DIBuilder::CreateQualifiedType(unsigned Tag, DIType FromTy) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000103 // Qualified types are encoded in DIDerivedType format.
104 Value *Elts[] = {
105 GetTagConstant(VMContext, Tag),
106 TheCU,
107 MDString::get(VMContext, StringRef()), // Empty name.
108 NULL, // Filename
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
114 FromTy
115 };
116 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000117}
118
119/// CreatePointerType - Create debugging information entry for a pointer.
120DIType DIBuilder::CreatePointerType(DIType PointeeTy, uint64_t SizeInBits,
121 uint64_t AlignInBits, StringRef Name) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000122 // Pointer types are encoded in DIDerivedType format.
123 Value *Elts[] = {
124 GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type),
125 TheCU,
126 MDString::get(VMContext, Name),
127 NULL, // Filename
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
133 PointeeTy
134 };
135 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000136}
137
138/// CreateReferenceType - Create debugging information entry for a reference.
139DIType DIBuilder::CreateReferenceType(DIType RTy) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000140 // References are encoded in DIDerivedType format.
141 Value *Elts[] = {
142 GetTagConstant(VMContext, dwarf::DW_TAG_reference_type),
143 TheCU,
144 NULL, // Name
145 NULL, // Filename
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
151 RTy
152 };
153 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000154}
155
156/// CreateTypedef - Create debugging information entry for a typedef.
157DIType DIBuilder::CreateTypedef(DIType Ty, StringRef Name, DIFile File,
158 unsigned LineNo) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000159 // typedefs are encoded in DIDerivedType format.
160 assert(Ty.Verify() && "Invalid typedef type!");
161 Value *Elts[] = {
162 GetTagConstant(VMContext, dwarf::DW_TAG_typedef),
163 Ty.getContext(),
164 MDString::get(VMContext, Name),
165 File,
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
171 Ty
172 };
173 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000174}
175
176/// CreateFriend - Create debugging information entry for a 'friend'.
177DIType DIBuilder::CreateFriend(DIType Ty, DIType FriendTy) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000178 // typedefs are encoded in DIDerivedType format.
179 assert(Ty.Verify() && "Invalid type!");
180 assert(FriendTy.Verify() && "Invalid friend type!");
181 Value *Elts[] = {
182 GetTagConstant(VMContext, dwarf::DW_TAG_friend),
183 Ty,
184 NULL, // Name
185 Ty.getFile(),
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
191 FriendTy
192 };
193 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000194}
195
196/// CreateInheritance - Create debugging information entry to establish
197/// inheritnace relationship between two types.
198DIType DIBuilder::CreateInheritance(DIType Ty, DIType BaseTy,
199 uint64_t BaseOffset, unsigned Flags) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000200 // TAG_inheritance is encoded in DIDerivedType format.
201 Value *Elts[] = {
202 GetTagConstant(VMContext, dwarf::DW_TAG_inheritance),
203 Ty,
204 NULL, // Name
205 NULL, // File
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),
211 BaseTy
212 };
213 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000214}
215
216/// CreateMemberType - Create debugging information entry for a member.
217DIType DIBuilder::CreateMemberType(DIDescriptor Context, StringRef Name,
218 DIFile F, unsigned LineNumber,
219 uint64_t SizeInBits, uint64_t AlignInBits,
220 uint64_t OffsetInBits, unsigned Flags,
221 DIType Ty) {
Benjamin Kramer42c9b252010-11-04 18:45:27 +0000222 // TAG_member is encoded in DIDerivedType format.
223 Value *Elts[] = {
224 GetTagConstant(VMContext, dwarf::DW_TAG_member),
225 Context,
226 MDString::get(VMContext, Name),
227 F,
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),
233 Ty
234 };
235 return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts)));
Devang Patel35fcd652010-11-04 15:01:38 +0000236}
237
238/// CreateArtificialType - Create a new DIType with "artificial" flag set.
239DIType DIBuilder::CreateArtificialType(DIType Ty) {
240 if (Ty.isArtificial())
241 return Ty;
242
243 SmallVector<Value *, 9> Elts;
244 MDNode *N = Ty;
245 assert (N && "Unexpected input DIType!");
246 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
247 if (Value *V = N->getOperand(i))
248 Elts.push_back(V);
249 else
250 Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
251 }
252
253 unsigned CurFlags = Ty.getFlags();
254 CurFlags = CurFlags | DIType::FlagArtificial;
255
256 // Flags are stored at this slot.
257 Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags);
258
259 return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));
260}