Introduce DIBuilder. It is intended to be a front-end friendly interface to emit...
[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/Support/Dwarf.h"
20
21 using namespace llvm;
22 using namespace llvm::dwarf;
23
24 static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) {
25   assert((Tag & LLVMDebugVersionMask) == 0 &&
26          "Tag too large for debug encoding!");
27   return ConstantInt::get(Type::getInt32Ty(VMContext), Tag | LLVMDebugVersion);
28 }
29 DIBuilder::DIBuilder(Module &m)
30   : M(m), VMContext(M.getContext()), TheCU(0) {}
31
32 /// CreateCompileUnit - A CompileUnit provides an anchor for all debugging
33 /// information generated during this instance of compilation.
34 void DIBuilder::CreateCompileUnit(unsigned Lang, StringRef Filename, 
35                                   StringRef Directory, StringRef Producer, 
36                                   bool isOptimized, StringRef Flags, 
37                                   unsigned RunTimeVer) {
38   SmallVector<Value *, 16> Elts;
39   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit));
40   Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)));
41   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Lang));
42   Elts.push_back(MDString::get(VMContext, Filename));
43   Elts.push_back(MDString::get(VMContext, Directory));
44   Elts.push_back(MDString::get(VMContext, Producer));
45   // Deprecate isMain field.
46   Elts.push_back(ConstantInt::get(Type::getInt1Ty(VMContext), true)); // isMain
47   Elts.push_back(ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized));
48   Elts.push_back(MDString::get(VMContext, Flags));
49   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer));
50
51   TheCU = DICompileUnit(MDNode::get(VMContext, Elts.data(), Elts.size()));
52 }
53
54 /// CreateFile - Create a file descriptor to hold debugging information
55 /// for a file.
56 DIFile DIBuilder::CreateFile(StringRef Filename, StringRef Directory) {
57   assert (TheCU && "Unable to create DW_TAG_file_type without CompileUnit");
58   SmallVector<Value *, 4> Elts;
59   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_file_type));
60   Elts.push_back(MDString::get(VMContext, Filename));
61   Elts.push_back(MDString::get(VMContext, Directory));
62   Elts.push_back(TheCU);
63   return DIFile(MDNode::get(VMContext, Elts.data(), Elts.size()));
64 }
65
66 /// CreateEnumerator - Create a single enumerator value.
67 DIEnumerator DIBuilder::CreateEnumerator(StringRef Name, uint64_t Val) {
68   SmallVector<Value *, 4> Elts;
69   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_enumerator));
70   Elts.push_back(MDString::get(VMContext, Name));
71   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), Val));
72   return DIEnumerator(MDNode::get(VMContext, Elts.data(), Elts.size()));
73 }
74
75 /// CreateBasicType - Create debugging information entry for a basic 
76 /// type, e.g 'char'.
77 DIType DIBuilder::CreateBasicType(StringRef Name, uint64_t SizeInBits, 
78                                   uint64_t AlignInBits,
79                                   unsigned Encoding) {
80   // Basic types are encoded in DIBasicType format. Line number, filename,
81   // offset and flags are always empty here.
82   SmallVector<Value *, 12> Elts;
83   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_base_type));
84   Elts.push_back(TheCU);
85   Elts.push_back(MDString::get(VMContext, Name));
86   Elts.push_back(NULL); // Filename 
87   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line
88   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits));
89   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits));
90   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset
91   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags;
92   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Encoding));
93   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));
94 }
95
96 /// CreateQaulifiedType - Create debugging information entry for a qualified
97 /// type, e.g. 'const int'.
98 DIType DIBuilder::CreateQualifiedType(unsigned Tag, DIType FromTy) {
99   /// Qualified types are encoded in DIDerivedType format.
100   SmallVector<Value *, 12> Elts;
101   Elts.push_back(GetTagConstant(VMContext, Tag));
102   Elts.push_back(TheCU);
103   Elts.push_back(MDString::get(VMContext, StringRef())); // Empty name.
104   Elts.push_back(NULL); // Filename
105   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line
106   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size
107   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align
108   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset
109   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags
110   Elts.push_back(FromTy);
111   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
112 }
113
114 /// CreatePointerType - Create debugging information entry for a pointer.
115 DIType DIBuilder::CreatePointerType(DIType PointeeTy, uint64_t SizeInBits,
116                                     uint64_t AlignInBits, StringRef Name) {
117   /// pointer types are encoded in DIDerivedType format.
118   SmallVector<Value *, 12> Elts;
119   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type));
120   Elts.push_back(TheCU);
121   Elts.push_back(MDString::get(VMContext, Name));
122   Elts.push_back(NULL); // Filename
123   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line
124   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits));
125   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits));
126   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset
127   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags
128   Elts.push_back(PointeeTy);
129   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
130 }
131
132 /// CreateReferenceType - Create debugging information entry for a reference.
133 DIType DIBuilder::CreateReferenceType(DIType RTy) {
134   /// references are encoded in DIDerivedType format.
135   SmallVector<Value *, 12> Elts;
136   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_reference_type));
137   Elts.push_back(TheCU);
138   Elts.push_back(NULL); // Name
139   Elts.push_back(NULL); // Filename
140   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line
141   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size
142   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align
143   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset
144   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags
145   Elts.push_back(RTy);
146   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
147 }
148
149 /// CreateTypedef - Create debugging information entry for a typedef.
150 DIType DIBuilder::CreateTypedef(DIType Ty, StringRef Name, DIFile File,
151                                 unsigned LineNo) {
152   /// typedefs are encoded in DIDerivedType format.
153   assert (Ty.Verify() && "Invalid typedef type!");
154   SmallVector<Value *, 12> Elts;
155   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_typedef));
156   Elts.push_back(Ty.getContext());
157   Elts.push_back(MDString::get(VMContext, Name));
158   Elts.push_back(File);
159   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo));
160   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size
161   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align
162   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset
163   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags
164   Elts.push_back(Ty);
165   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
166 }
167
168 /// CreateFriend - Create debugging information entry for a 'friend'.
169 DIType DIBuilder::CreateFriend(DIType Ty, DIType FriendTy) {
170   /// typedefs are encoded in DIDerivedType format.
171   assert (Ty.Verify() && "Invalid type!");
172   assert (FriendTy.Verify() && "Invalid friend type!");
173   SmallVector<Value *, 12> Elts;
174   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_friend));
175   Elts.push_back(Ty);
176   Elts.push_back(NULL); // Name
177   Elts.push_back(Ty.getFile());
178   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line
179   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size
180   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align
181   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset
182   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags
183   Elts.push_back(FriendTy);
184   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
185 }
186
187 /// CreateInheritance - Create debugging information entry to establish
188 /// inheritnace relationship between two types.
189 DIType DIBuilder::CreateInheritance(DIType Ty, DIType BaseTy, 
190                                     uint64_t BaseOffset, unsigned Flags) {
191   /// TAG_inheritance is encoded in DIDerivedType format.
192   SmallVector<Value *, 12> Elts;
193   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_inheritance));
194   Elts.push_back(Ty);
195   Elts.push_back(NULL); // Name
196   Elts.push_back(NULL); // File
197   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line
198   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size
199   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align
200   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), BaseOffset));
201   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Flags));
202   Elts.push_back(BaseTy);
203   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
204 }
205
206 /// CreateMemberType - Create debugging information entry for a member.
207 DIType DIBuilder::CreateMemberType(DIDescriptor Context, StringRef Name, 
208                                    DIFile F, unsigned LineNumber, 
209                                    uint64_t SizeInBits, uint64_t AlignInBits,
210                                    uint64_t OffsetInBits, unsigned Flags, 
211                                    DIType Ty) {
212  /// TAG_member is encoded in DIDerivedType format.
213   SmallVector<Value *, 12> Elts;
214   Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_member));
215   Elts.push_back(Context);
216   Elts.push_back(MDString::get(VMContext, Name));
217   Elts.push_back(F);
218   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber));
219   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits));
220   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits));
221   Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits));
222   Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Flags));
223   Elts.push_back(Ty);
224   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));  
225 }
226
227 /// CreateArtificialType - Create a new DIType with "artificial" flag set.
228 DIType DIBuilder::CreateArtificialType(DIType Ty) {
229   if (Ty.isArtificial())
230     return Ty;
231
232   SmallVector<Value *, 9> Elts;
233   MDNode *N = Ty;
234   assert (N && "Unexpected input DIType!");
235   for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
236     if (Value *V = N->getOperand(i))
237       Elts.push_back(V);
238     else
239       Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
240   }
241
242   unsigned CurFlags = Ty.getFlags();
243   CurFlags = CurFlags | DIType::FlagArtificial;
244
245   // Flags are stored at this slot.
246   Elts[8] =  ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags);
247
248   return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));
249 }