Use arrays instead of constant-sized SmallVectors.
[oota-llvm.git] / lib / Analysis / DIBuilder.cpp
1 //===--- 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"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Support/Dwarf.h"
21
22 using namespace llvm;
23 using namespace llvm::dwarf;
24
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);
29 }
30 DIBuilder::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.
35 void DIBuilder::CreateCompileUnit(unsigned Lang, StringRef Filename, 
36                                   StringRef Directory, StringRef Producer, 
37                                   bool isOptimized, StringRef Flags, 
38                                   unsigned RunTimeVer) {
39   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)));
53 }
54
55 /// CreateFile - Create a file descriptor to hold debugging information
56 /// for a file.
57 DIFile DIBuilder::CreateFile(StringRef Filename, StringRef Directory) {
58   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)));
66 }
67
68 /// CreateEnumerator - Create a single enumerator value.
69 DIEnumerator DIBuilder::CreateEnumerator(StringRef Name, uint64_t Val) {
70   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)));
76 }
77
78 /// CreateBasicType - Create debugging information entry for a basic 
79 /// type, e.g 'char'.
80 DIType 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.
85   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)));
98 }
99
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.
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)));
117 }
118
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.
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)));
136 }
137
138 /// CreateReferenceType - Create debugging information entry for a reference.
139 DIType DIBuilder::CreateReferenceType(DIType RTy) {
140   // 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)));
154 }
155
156 /// CreateTypedef - Create debugging information entry for a typedef.
157 DIType DIBuilder::CreateTypedef(DIType Ty, StringRef Name, DIFile File,
158                                 unsigned LineNo) {
159   // 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)));
174 }
175
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!");
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)));
194 }
195
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.
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)));
214 }
215
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, 
221                                    DIType Ty) {
222   // 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)));
236 }
237
238 /// CreateArtificialType - Create a new DIType with "artificial" flag set.
239 DIType 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 }