blob: e4702ed1bef63005007ea430b6b5223399352cfa [file] [log] [blame]
Jim Laskey6af56812006-01-04 13:36:38 +00001//===-- llvm/CodeGen/MachineDebugInfo.cpp -----------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by James M. Laskey and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Jim Laskey6af56812006-01-04 13:36:38 +00009
10#include "llvm/CodeGen/MachineDebugInfo.h"
11
Jim Laskeyb3e789a2006-01-26 20:21:46 +000012#include "llvm/Constants.h"
13#include "llvm/DerivedTypes.h"
Jim Laskey86cbdba2006-02-06 15:33:21 +000014#include "llvm/GlobalVariable.h"
Jim Laskeyb3e789a2006-01-26 20:21:46 +000015#include "llvm/Intrinsics.h"
16#include "llvm/Instructions.h"
17#include "llvm/Module.h"
18#include "llvm/Support/Dwarf.h"
19
Jim Laskey86cbdba2006-02-06 15:33:21 +000020#include <iostream>
21
Jim Laskey6af56812006-01-04 13:36:38 +000022using namespace llvm;
23
24// Handle the Pass registration stuff necessary to use TargetData's.
25namespace {
Jim Laskeyb2efb852006-01-04 22:28:25 +000026 RegisterPass<MachineDebugInfo> X("machinedebuginfo", "Debug Information");
27}
Jim Laskey063e7652006-01-17 17:31:53 +000028
Jim Laskeyb3e789a2006-01-26 20:21:46 +000029//===----------------------------------------------------------------------===//
30
Jim Laskey86cbdba2006-02-06 15:33:21 +000031/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
Jim Laskeyb3e789a2006-01-26 20:21:46 +000032/// specified value in their initializer somewhere.
33static void
34getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
35 // Scan though value users.
36 for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
37 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
Jim Laskey86cbdba2006-02-06 15:33:21 +000038 // If the user is a GlobalVariable then add to result.
Jim Laskeyb3e789a2006-01-26 20:21:46 +000039 Result.push_back(GV);
40 } else if (Constant *C = dyn_cast<Constant>(*I)) {
41 // If the user is a constant variable then scan its users
42 getGlobalVariablesUsing(C, Result);
43 }
44 }
45}
46
Jim Laskey86cbdba2006-02-06 15:33:21 +000047/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
48/// named GlobalVariable.
Jim Laskeyb3e789a2006-01-26 20:21:46 +000049static std::vector<GlobalVariable*>
50getGlobalVariablesUsing(Module &M, const std::string &RootName) {
Jim Laskey86cbdba2006-02-06 15:33:21 +000051 std::vector<GlobalVariable*> Result; // GlobalVariables matching criteria.
Jim Laskeyce72b172006-02-11 01:01:30 +000052
53 std::vector<const Type*> FieldTypes;
54 FieldTypes.push_back(Type::UIntTy);
55 FieldTypes.push_back(PointerType::get(Type::SByteTy));
Jim Laskeyb3e789a2006-01-26 20:21:46 +000056
Jim Laskey86cbdba2006-02-06 15:33:21 +000057 // Get the GlobalVariable root.
Jim Laskeyb3e789a2006-01-26 20:21:46 +000058 GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
Jim Laskeyce72b172006-02-11 01:01:30 +000059 StructType::get(FieldTypes));
Jim Laskeyb3e789a2006-01-26 20:21:46 +000060
61 // If present and linkonce then scan for users.
62 if (UseRoot && UseRoot->hasLinkOnceLinkage()) {
63 getGlobalVariablesUsing(UseRoot, Result);
64 }
65
66 return Result;
67}
68
69/// getStringValue - Turn an LLVM constant pointer that eventually points to a
70/// global into a string value. Return an empty string if we can't do it.
71///
Chris Lattner22760af2006-01-27 17:31:30 +000072static const std::string getStringValue(Value *V, unsigned Offset = 0) {
Jim Laskeyb3e789a2006-01-26 20:21:46 +000073 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
74 if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
75 ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
76 if (Init->isString()) {
77 std::string Result = Init->getAsString();
78 if (Offset < Result.size()) {
79 // If we are pointing INTO The string, erase the beginning...
80 Result.erase(Result.begin(), Result.begin()+Offset);
81
82 // Take off the null terminator, and any string fragments after it.
83 std::string::size_type NullPos = Result.find_first_of((char)0);
84 if (NullPos != std::string::npos)
85 Result.erase(Result.begin()+NullPos, Result.end());
86 return Result;
87 }
88 }
89 }
90 } else if (Constant *C = dyn_cast<Constant>(V)) {
91 if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
92 return getStringValue(GV, Offset);
93 else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
94 if (CE->getOpcode() == Instruction::GetElementPtr) {
95 // Turn a gep into the specified offset.
96 if (CE->getNumOperands() == 3 &&
97 cast<Constant>(CE->getOperand(1))->isNullValue() &&
98 isa<ConstantInt>(CE->getOperand(2))) {
99 return getStringValue(CE->getOperand(0),
100 Offset+cast<ConstantInt>(CE->getOperand(2))->getRawValue());
101 }
102 }
103 }
104 }
105 return "";
106}
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000107
Jim Laskey86cbdba2006-02-06 15:33:21 +0000108/// isStringValue - Return true if the given value can be coerced to a string.
109///
110static bool isStringValue(Value *V) {
111 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
112 if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
113 ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
114 return Init->isString();
115 }
116 } else if (Constant *C = dyn_cast<Constant>(V)) {
117 if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
118 return isStringValue(GV);
119 else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
120 if (CE->getOpcode() == Instruction::GetElementPtr) {
121 if (CE->getNumOperands() == 3 &&
122 cast<Constant>(CE->getOperand(1))->isNullValue() &&
123 isa<ConstantInt>(CE->getOperand(2))) {
124 return isStringValue(CE->getOperand(0));
125 }
126 }
127 }
128 }
129 return false;
130}
131
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000132/// getGlobalVariable - Return either a direct or cast Global value.
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000133///
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000134static GlobalVariable *getGlobalVariable(Value *V) {
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000135 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
136 return GV;
137 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000138 if (CE->getOpcode() == Instruction::Cast) {
139 return dyn_cast<GlobalVariable>(CE->getOperand(0));
140 }
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000141 }
142 return NULL;
143}
144
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000145/// isGlobalVariable - Return true if the given value can be coerced to a
Jim Laskey86cbdba2006-02-06 15:33:21 +0000146/// GlobalVariable.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000147static bool isGlobalVariable(Value *V) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000148 if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
149 return true;
150 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
151 if (CE->getOpcode() == Instruction::Cast) {
152 return isa<GlobalVariable>(CE->getOperand(0));
153 }
154 }
155 return false;
156}
157
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000158/// getUIntOperand - Return ith operand if it is an unsigned integer.
Jim Laskey86cbdba2006-02-06 15:33:21 +0000159///
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000160static ConstantUInt *getUIntOperand(GlobalVariable *GV, unsigned i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000161 // Make sure the GlobalVariable has an initializer.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000162 if (!GV->hasInitializer()) return NULL;
Jim Laskeyb2efb852006-01-04 22:28:25 +0000163
Jim Laskey86cbdba2006-02-06 15:33:21 +0000164 // Get the initializer constant.
165 ConstantStruct *CI = dyn_cast<ConstantStruct>(GV->getInitializer());
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000166 if (!CI) return NULL;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000167
Jim Laskey86cbdba2006-02-06 15:33:21 +0000168 // Check if there is at least i + 1 operands.
169 unsigned N = CI->getNumOperands();
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000170 if (i >= N) return NULL;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000171
Jim Laskey86cbdba2006-02-06 15:33:21 +0000172 // Check constant.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000173 return dyn_cast<ConstantUInt>(CI->getOperand(i));
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000174}
Jim Laskey86cbdba2006-02-06 15:33:21 +0000175//===----------------------------------------------------------------------===//
176
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000177/// ApplyToFields - Target the visitor to each field of the debug information
Jim Laskey86cbdba2006-02-06 15:33:21 +0000178/// descriptor.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000179void DIVisitor::ApplyToFields(DebugInfoDesc *DD) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000180 DD->ApplyToFields(this);
181}
182
183//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000184/// DICountVisitor - This DIVisitor counts all the fields in the supplied debug
185/// the supplied DebugInfoDesc.
186class DICountVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000187private:
188 unsigned Count; // Running count of fields.
189
190public:
Jim Laskeyce72b172006-02-11 01:01:30 +0000191 DICountVisitor() : DIVisitor(), Count(0) {}
Jim Laskey86cbdba2006-02-06 15:33:21 +0000192
193 // Accessors.
194 unsigned getCount() const { return Count; }
195
196 /// Apply - Count each of the fields.
197 ///
198 virtual void Apply(int &Field) { ++Count; }
199 virtual void Apply(unsigned &Field) { ++Count; }
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000200 virtual void Apply(uint64_t &Field) { ++Count; }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000201 virtual void Apply(bool &Field) { ++Count; }
202 virtual void Apply(std::string &Field) { ++Count; }
203 virtual void Apply(DebugInfoDesc *&Field) { ++Count; }
204 virtual void Apply(GlobalVariable *&Field) { ++Count; }
Jim Laskey45ccae52006-02-28 20:15:07 +0000205 virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
206 ++Count;
207 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000208};
209
210//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000211/// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the
212/// supplied DebugInfoDesc.
213class DIDeserializeVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000214private:
215 DIDeserializer &DR; // Active deserializer.
216 unsigned I; // Current operand index.
217 ConstantStruct *CI; // GlobalVariable constant initializer.
218
219public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000220 DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV)
221 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000222 , DR(D)
Jim Laskeyce72b172006-02-11 01:01:30 +0000223 , I(0)
Jim Laskey86cbdba2006-02-06 15:33:21 +0000224 , CI(cast<ConstantStruct>(GV->getInitializer()))
225 {}
226
227 /// Apply - Set the value of each of the fields.
228 ///
229 virtual void Apply(int &Field) {
230 Constant *C = CI->getOperand(I++);
231 Field = cast<ConstantSInt>(C)->getValue();
232 }
233 virtual void Apply(unsigned &Field) {
234 Constant *C = CI->getOperand(I++);
235 Field = cast<ConstantUInt>(C)->getValue();
236 }
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000237 virtual void Apply(uint64_t &Field) {
238 Constant *C = CI->getOperand(I++);
239 Field = cast<ConstantUInt>(C)->getValue();
240 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000241 virtual void Apply(bool &Field) {
242 Constant *C = CI->getOperand(I++);
243 Field = cast<ConstantBool>(C)->getValue();
244 }
245 virtual void Apply(std::string &Field) {
246 Constant *C = CI->getOperand(I++);
247 Field = getStringValue(C);
248 }
249 virtual void Apply(DebugInfoDesc *&Field) {
250 Constant *C = CI->getOperand(I++);
251 Field = DR.Deserialize(C);
252 }
253 virtual void Apply(GlobalVariable *&Field) {
254 Constant *C = CI->getOperand(I++);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000255 Field = getGlobalVariable(C);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000256 }
Jim Laskey45ccae52006-02-28 20:15:07 +0000257 virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
258 Constant *C = CI->getOperand(I++);
259 GlobalVariable *GV = getGlobalVariable(C);
260 ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
261 Field.resize(0);
262 for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) {
263 GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i));
264 DebugInfoDesc *DE = DR.Deserialize(GVE);
265 Field.push_back(DE);
266 }
267 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000268};
269
270//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000271/// DISerializeVisitor - This DIVisitor serializes all the fields in
Jim Laskey86cbdba2006-02-06 15:33:21 +0000272/// the supplied DebugInfoDesc.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000273class DISerializeVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000274private:
275 DISerializer &SR; // Active serializer.
276 std::vector<Constant*> &Elements; // Element accumulator.
277
278public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000279 DISerializeVisitor(DISerializer &S, std::vector<Constant*> &E)
280 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000281 , SR(S)
282 , Elements(E)
283 {}
284
285 /// Apply - Set the value of each of the fields.
286 ///
287 virtual void Apply(int &Field) {
Jim Laskeyce72b172006-02-11 01:01:30 +0000288 Elements.push_back(ConstantSInt::get(Type::IntTy, Field));
Jim Laskey86cbdba2006-02-06 15:33:21 +0000289 }
290 virtual void Apply(unsigned &Field) {
291 Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
292 }
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000293 virtual void Apply(uint64_t &Field) {
294 Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
295 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000296 virtual void Apply(bool &Field) {
297 Elements.push_back(ConstantBool::get(Field));
298 }
299 virtual void Apply(std::string &Field) {
300 Elements.push_back(SR.getString(Field));
301 }
302 virtual void Apply(DebugInfoDesc *&Field) {
303 GlobalVariable *GV = NULL;
304
305 // If non-NULL the convert to global.
306 if (Field) GV = SR.Serialize(Field);
307
308 // FIXME - At some point should use specific type.
309 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
310
311 if (GV) {
312 // Set to pointer to global.
313 Elements.push_back(ConstantExpr::getCast(GV, EmptyTy));
314 } else {
315 // Use NULL.
316 Elements.push_back(ConstantPointerNull::get(EmptyTy));
317 }
318 }
319 virtual void Apply(GlobalVariable *&Field) {
320 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
Jim Laskeyce72b172006-02-11 01:01:30 +0000321 if (Field) {
322 Elements.push_back(ConstantExpr::getCast(Field, EmptyTy));
323 } else {
324 Elements.push_back(ConstantPointerNull::get(EmptyTy));
325 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000326 }
Jim Laskey45ccae52006-02-28 20:15:07 +0000327 virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
328 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
329 unsigned N = Field.size();
330 ArrayType *AT = ArrayType::get(EmptyTy, N);
331 std::vector<Constant *> ArrayElements;
332
333 for (unsigned i = 0, N = Field.size(); i < N; ++i) {
334 GlobalVariable *GVE = SR.Serialize(Field[i]);
335 Constant *CE = ConstantExpr::getCast(GVE, EmptyTy);
336 ArrayElements.push_back(cast<Constant>(CE));
337 }
338
339 Constant *CA = ConstantArray::get(AT, ArrayElements);
340 Constant *CAE = ConstantExpr::getCast(CA, EmptyTy);
341 Elements.push_back(CAE);
342 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000343};
344
345//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000346/// DIGetTypesVisitor - This DIVisitor gathers all the field types in
Jim Laskey86cbdba2006-02-06 15:33:21 +0000347/// the supplied DebugInfoDesc.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000348class DIGetTypesVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000349private:
350 DISerializer &SR; // Active serializer.
351 std::vector<const Type*> &Fields; // Type accumulator.
352
353public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000354 DIGetTypesVisitor(DISerializer &S, std::vector<const Type*> &F)
355 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000356 , SR(S)
357 , Fields(F)
358 {}
359
360 /// Apply - Set the value of each of the fields.
361 ///
362 virtual void Apply(int &Field) {
363 Fields.push_back(Type::IntTy);
364 }
365 virtual void Apply(unsigned &Field) {
366 Fields.push_back(Type::UIntTy);
367 }
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000368 virtual void Apply(uint64_t &Field) {
369 Fields.push_back(Type::UIntTy);
370 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000371 virtual void Apply(bool &Field) {
372 Fields.push_back(Type::BoolTy);
373 }
374 virtual void Apply(std::string &Field) {
375 Fields.push_back(SR.getStrPtrType());
376 }
377 virtual void Apply(DebugInfoDesc *&Field) {
378 // FIXME - At some point should use specific type.
379 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
380 Fields.push_back(EmptyTy);
381 }
382 virtual void Apply(GlobalVariable *&Field) {
383 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
384 Fields.push_back(EmptyTy);
385 }
Jim Laskey45ccae52006-02-28 20:15:07 +0000386 virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
387 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
388 Fields.push_back(EmptyTy);
389 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000390};
391
392//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000393/// DIVerifyVisitor - This DIVisitor verifies all the field types against
Jim Laskey86cbdba2006-02-06 15:33:21 +0000394/// a constant initializer.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000395class DIVerifyVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000396private:
397 DIVerifier &VR; // Active verifier.
398 bool IsValid; // Validity status.
399 unsigned I; // Current operand index.
400 ConstantStruct *CI; // GlobalVariable constant initializer.
401
402public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000403 DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV)
404 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000405 , VR(V)
406 , IsValid(true)
Jim Laskeyce72b172006-02-11 01:01:30 +0000407 , I(0)
Jim Laskey86cbdba2006-02-06 15:33:21 +0000408 , CI(cast<ConstantStruct>(GV->getInitializer()))
409 {
410 }
411
412 // Accessors.
413 bool isValid() const { return IsValid; }
414
415 /// Apply - Set the value of each of the fields.
416 ///
417 virtual void Apply(int &Field) {
418 Constant *C = CI->getOperand(I++);
419 IsValid = IsValid && isa<ConstantInt>(C);
420 }
421 virtual void Apply(unsigned &Field) {
422 Constant *C = CI->getOperand(I++);
423 IsValid = IsValid && isa<ConstantInt>(C);
424 }
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000425 virtual void Apply(uint64_t &Field) {
426 Constant *C = CI->getOperand(I++);
427 IsValid = IsValid && isa<ConstantInt>(C);
428 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000429 virtual void Apply(bool &Field) {
430 Constant *C = CI->getOperand(I++);
431 IsValid = IsValid && isa<ConstantBool>(C);
432 }
433 virtual void Apply(std::string &Field) {
434 Constant *C = CI->getOperand(I++);
435 IsValid = IsValid && isStringValue(C);
436 }
437 virtual void Apply(DebugInfoDesc *&Field) {
438 // FIXME - Prepare the correct descriptor.
439 Constant *C = CI->getOperand(I++);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000440 IsValid = IsValid && isGlobalVariable(C);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000441 }
442 virtual void Apply(GlobalVariable *&Field) {
443 Constant *C = CI->getOperand(I++);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000444 IsValid = IsValid && isGlobalVariable(C);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000445 }
Jim Laskey45ccae52006-02-28 20:15:07 +0000446 virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
447 Constant *C = CI->getOperand(I++);
448 IsValid = IsValid && isGlobalVariable(C);
449 if (!IsValid) return;
450
451 GlobalVariable *GV = getGlobalVariable(C);
452 IsValid = IsValid && GV && GV->hasInitializer();
453 if (!IsValid) return;
454
455 ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
456 IsValid = IsValid && CA;
457 if (!IsValid) return;
458
459 for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) {
460 IsValid = IsValid && isGlobalVariable(CA->getOperand(i));
461 if (!IsValid) return;
462
463 GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i));
464 VR.Verify(GVE);
465 }
466 }
Jim Laskey86cbdba2006-02-06 15:33:21 +0000467};
468
Jim Laskeyce72b172006-02-11 01:01:30 +0000469
Jim Laskey86cbdba2006-02-06 15:33:21 +0000470//===----------------------------------------------------------------------===//
471
Jim Laskeyce72b172006-02-11 01:01:30 +0000472/// TagFromGlobal - Returns the Tag number from a debug info descriptor
473/// GlobalVariable.
474unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) {
475 ConstantUInt *C = getUIntOperand(GV, 0);
476 return C ? (unsigned)C->getValue() : (unsigned)DIInvalid;
477}
478
479/// DescFactory - Create an instance of debug info descriptor based on Tag.
480/// Return NULL if not a recognized Tag.
481DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) {
482 switch (Tag) {
483 case DI_TAG_anchor: return new AnchorDesc();
484 case DI_TAG_compile_unit: return new CompileUnitDesc();
485 case DI_TAG_global_variable: return new GlobalVariableDesc();
486 case DI_TAG_subprogram: return new SubprogramDesc();
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000487 case DI_TAG_basictype: return new BasicTypeDesc();
Jim Laskey45ccae52006-02-28 20:15:07 +0000488 case DI_TAG_typedef:
489 case DI_TAG_pointer:
490 case DI_TAG_reference:
491 case DI_TAG_const:
492 case DI_TAG_volatile:
493 case DI_TAG_restrict: return new DerivedTypeDesc(Tag);
Jim Laskeyce72b172006-02-11 01:01:30 +0000494 default: break;
495 }
496 return NULL;
497}
498
499/// getLinkage - get linkage appropriate for this type of descriptor.
500///
501GlobalValue::LinkageTypes DebugInfoDesc::getLinkage() const {
502 return GlobalValue::InternalLinkage;
503}
504
505/// ApplyToFields - Target the vistor to the fields of the descriptor.
506///
507void DebugInfoDesc::ApplyToFields(DIVisitor *Visitor) {
508 Visitor->Apply(Tag);
509}
510
511//===----------------------------------------------------------------------===//
512
513/// getLinkage - get linkage appropriate for this type of descriptor.
514///
515GlobalValue::LinkageTypes AnchorDesc::getLinkage() const {
516 return GlobalValue::LinkOnceLinkage;
517}
518
519/// ApplyToFields - Target the visitor to the fields of the TransUnitDesc.
520///
521void AnchorDesc::ApplyToFields(DIVisitor *Visitor) {
522 DebugInfoDesc::ApplyToFields(Visitor);
523
524 Visitor->Apply(Name);
525}
526
527/// getDescString - Return a string used to compose global names and labels.
528///
529const char *AnchorDesc::getDescString() const {
530 return Name.c_str();
531}
532
533/// getTypeString - Return a string used to label this descriptors type.
534///
535const char *AnchorDesc::getTypeString() const {
536 return "llvm.dbg.anchor.type";
537}
538
539#ifndef NDEBUG
540void AnchorDesc::dump() {
541 std::cerr << getDescString() << " "
542 << "Tag(" << getTag() << "), "
543 << "Name(" << Name << ")\n";
544}
545#endif
546
547//===----------------------------------------------------------------------===//
548
549AnchoredDesc::AnchoredDesc(unsigned T)
550: DebugInfoDesc(T)
551, Anchor(NULL)
552{}
553
554/// ApplyToFields - Target the visitor to the fields of the AnchoredDesc.
555///
556void AnchoredDesc::ApplyToFields(DIVisitor *Visitor) {
557 DebugInfoDesc::ApplyToFields(Visitor);
558
559 Visitor->Apply((DebugInfoDesc *&)Anchor);
560}
561
562//===----------------------------------------------------------------------===//
563
564CompileUnitDesc::CompileUnitDesc()
565: AnchoredDesc(DI_TAG_compile_unit)
566, DebugVersion(LLVMDebugVersion)
567, Language(0)
568, FileName("")
569, Directory("")
570, Producer("")
571{}
572
Jim Laskey86cbdba2006-02-06 15:33:21 +0000573/// DebugVersionFromGlobal - Returns the version number from a compile unit
574/// GlobalVariable.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000575unsigned CompileUnitDesc::DebugVersionFromGlobal(GlobalVariable *GV) {
Jim Laskeyce72b172006-02-11 01:01:30 +0000576 ConstantUInt *C = getUIntOperand(GV, 2);
Jim Laskeyf60c2412006-02-06 21:54:05 +0000577 return C ? (unsigned)C->getValue() : (unsigned)DIInvalid;
Jim Laskey86cbdba2006-02-06 15:33:21 +0000578}
579
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000580/// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc.
581///
582void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) {
Jim Laskeyce72b172006-02-11 01:01:30 +0000583 AnchoredDesc::ApplyToFields(Visitor);
584
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000585 Visitor->Apply(DebugVersion);
586 Visitor->Apply(Language);
587 Visitor->Apply(FileName);
588 Visitor->Apply(Directory);
589 Visitor->Apply(Producer);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000590}
591
Jim Laskeyce72b172006-02-11 01:01:30 +0000592/// getDescString - Return a string used to compose global names and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000593///
Jim Laskeyce72b172006-02-11 01:01:30 +0000594const char *CompileUnitDesc::getDescString() const {
595 return "llvm.dbg.compile_unit";
596}
597
598/// getTypeString - Return a string used to label this descriptors type.
599///
600const char *CompileUnitDesc::getTypeString() const {
601 return "llvm.dbg.compile_unit.type";
602}
603
604/// getAnchorString - Return a string used to label this descriptor's anchor.
605///
606const char *CompileUnitDesc::getAnchorString() const {
607 return "llvm.dbg.compile_units";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000608}
609
Jim Laskey86cbdba2006-02-06 15:33:21 +0000610#ifndef NDEBUG
611void CompileUnitDesc::dump() {
Jim Laskeyce72b172006-02-11 01:01:30 +0000612 std::cerr << getDescString() << " "
Jim Laskey86cbdba2006-02-06 15:33:21 +0000613 << "Tag(" << getTag() << "), "
Jim Laskeyce72b172006-02-11 01:01:30 +0000614 << "Anchor(" << getAnchor() << "), "
615 << "DebugVersion(" << DebugVersion << "), "
Jim Laskey86cbdba2006-02-06 15:33:21 +0000616 << "Language(" << Language << "), "
617 << "FileName(\"" << FileName << "\"), "
618 << "Directory(\"" << Directory << "\"), "
619 << "Producer(\"" << Producer << "\")\n";
620}
621#endif
622
623//===----------------------------------------------------------------------===//
624
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000625TypeDesc::TypeDesc(unsigned T)
626: DebugInfoDesc(T)
627, Context(NULL)
628, Name("")
Jim Laskey69906002006-02-24 16:46:40 +0000629, File(NULL)
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000630, Size(0)
631{}
632
Jim Laskey69906002006-02-24 16:46:40 +0000633/// ApplyToFields - Target the visitor to the fields of the TypeDesc.
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000634///
635void TypeDesc::ApplyToFields(DIVisitor *Visitor) {
636 DebugInfoDesc::ApplyToFields(Visitor);
637
638 Visitor->Apply(Context);
639 Visitor->Apply(Name);
Jim Laskey69906002006-02-24 16:46:40 +0000640 Visitor->Apply((DebugInfoDesc *&)File);
641 Visitor->Apply(Line);
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000642 Visitor->Apply(Size);
643}
644
645/// getDescString - Return a string used to compose global names and labels.
646///
647const char *TypeDesc::getDescString() const {
648 return "llvm.dbg.type";
649}
650
651/// getTypeString - Return a string used to label this descriptor's type.
652///
653const char *TypeDesc::getTypeString() const {
654 return "llvm.dbg.type.type";
655}
656
657#ifndef NDEBUG
658void TypeDesc::dump() {
659 std::cerr << getDescString() << " "
660 << "Tag(" << getTag() << "), "
661 << "Context(" << Context << "), "
662 << "Name(\"" << Name << "\"), "
Jim Laskey69906002006-02-24 16:46:40 +0000663 << "File(" << File << "), "
664 << "Line(" << Line << "), "
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000665 << "Size(" << Size << ")\n";
666}
667#endif
668
669//===----------------------------------------------------------------------===//
670
671BasicTypeDesc::BasicTypeDesc()
672: TypeDesc(DI_TAG_basictype)
673, Encoding(0)
674{}
675
Jim Laskey69906002006-02-24 16:46:40 +0000676/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc.
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000677///
678void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) {
679 TypeDesc::ApplyToFields(Visitor);
680
681 Visitor->Apply(Encoding);
682}
683
684#ifndef NDEBUG
685void BasicTypeDesc::dump() {
686 std::cerr << getDescString() << " "
687 << "Tag(" << getTag() << "), "
688 << "Context(" << getContext() << "), "
689 << "Name(\"" << getName() << "\"), "
690 << "Size(" << getSize() << "), "
691 << "Encoding(" << Encoding << ")\n";
692}
693#endif
Jim Laskey434b40b2006-02-23 22:37:30 +0000694//===----------------------------------------------------------------------===//
695
Jim Laskey69906002006-02-24 16:46:40 +0000696DerivedTypeDesc::DerivedTypeDesc(unsigned T)
697: TypeDesc(T)
Jim Laskey434b40b2006-02-23 22:37:30 +0000698, FromType(NULL)
Jim Laskey69906002006-02-24 16:46:40 +0000699{
Jim Laskey45ccae52006-02-28 20:15:07 +0000700 assert(classof((const DebugInfoDesc *)this) && "Unknown derived type.");
Jim Laskey69906002006-02-24 16:46:40 +0000701}
Jim Laskey434b40b2006-02-23 22:37:30 +0000702
Jim Laskey69906002006-02-24 16:46:40 +0000703/// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc.
Jim Laskey434b40b2006-02-23 22:37:30 +0000704///
Jim Laskey69906002006-02-24 16:46:40 +0000705void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) {
Jim Laskey434b40b2006-02-23 22:37:30 +0000706 TypeDesc::ApplyToFields(Visitor);
707
708 Visitor->Apply((DebugInfoDesc *&)FromType);
Jim Laskey434b40b2006-02-23 22:37:30 +0000709}
710
711#ifndef NDEBUG
Jim Laskey69906002006-02-24 16:46:40 +0000712void DerivedTypeDesc::dump() {
Jim Laskey434b40b2006-02-23 22:37:30 +0000713 std::cerr << getDescString() << " "
714 << "Tag(" << getTag() << "), "
715 << "Context(" << getContext() << "), "
716 << "Name(\"" << getName() << "\"), "
717 << "Size(" << getSize() << "), "
Jim Laskey69906002006-02-24 16:46:40 +0000718 << "File(" << getFile() << "), "
719 << "Line(" << getLine() << "), "
720 << "FromType(" << FromType << ")\n";
Jim Laskey434b40b2006-02-23 22:37:30 +0000721}
722#endif
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000723
724//===----------------------------------------------------------------------===//
725
Jim Laskeyce72b172006-02-11 01:01:30 +0000726GlobalDesc::GlobalDesc(unsigned T)
727: AnchoredDesc(T)
728, Context(0)
729, Name("")
730, TyDesc(NULL)
731, IsStatic(false)
732, IsDefinition(false)
733{}
734
735/// ApplyToFields - Target the visitor to the fields of the global.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000736///
Jim Laskeyce72b172006-02-11 01:01:30 +0000737void GlobalDesc::ApplyToFields(DIVisitor *Visitor) {
738 AnchoredDesc::ApplyToFields(Visitor);
739
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000740 Visitor->Apply(Context);
741 Visitor->Apply(Name);
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000742 Visitor->Apply((DebugInfoDesc *&)TyDesc);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000743 Visitor->Apply(IsStatic);
744 Visitor->Apply(IsDefinition);
Jim Laskeyce72b172006-02-11 01:01:30 +0000745}
746
747//===----------------------------------------------------------------------===//
748
749GlobalVariableDesc::GlobalVariableDesc()
750: GlobalDesc(DI_TAG_global_variable)
751, Global(NULL)
752{}
753
754/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc.
755///
756void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) {
757 GlobalDesc::ApplyToFields(Visitor);
758
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000759 Visitor->Apply(Global);
Jim Laskey0420f2a2006-02-22 19:02:11 +0000760 Visitor->Apply(Line);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000761}
762
Jim Laskeyce72b172006-02-11 01:01:30 +0000763/// getDescString - Return a string used to compose global names and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000764///
Jim Laskeyce72b172006-02-11 01:01:30 +0000765const char *GlobalVariableDesc::getDescString() const {
766 return "llvm.dbg.global_variable";
767}
768
769/// getTypeString - Return a string used to label this descriptors type.
770///
771const char *GlobalVariableDesc::getTypeString() const {
772 return "llvm.dbg.global_variable.type";
773}
774
775/// getAnchorString - Return a string used to label this descriptor's anchor.
776///
777const char *GlobalVariableDesc::getAnchorString() const {
778 return "llvm.dbg.global_variables";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000779}
780
Jim Laskey86cbdba2006-02-06 15:33:21 +0000781#ifndef NDEBUG
782void GlobalVariableDesc::dump() {
Jim Laskeyce72b172006-02-11 01:01:30 +0000783 std::cerr << getDescString() << " "
Jim Laskey86cbdba2006-02-06 15:33:21 +0000784 << "Tag(" << getTag() << "), "
Jim Laskeyce72b172006-02-11 01:01:30 +0000785 << "Anchor(" << getAnchor() << "), "
786 << "Name(\"" << getName() << "\"), "
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000787 << "Type(\"" << getTypeDesc() << "\"), "
Jim Laskeyce72b172006-02-11 01:01:30 +0000788 << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
789 << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), "
Jim Laskey0420f2a2006-02-22 19:02:11 +0000790 << "Global(" << Global << "), "
791 << "Line(" << Line << ")\n";
Jim Laskey86cbdba2006-02-06 15:33:21 +0000792}
793#endif
794
795//===----------------------------------------------------------------------===//
796
Jim Laskeyce72b172006-02-11 01:01:30 +0000797SubprogramDesc::SubprogramDesc()
798: GlobalDesc(DI_TAG_subprogram)
799{}
800
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000801/// ApplyToFields - Target the visitor to the fields of the
Jim Laskey86cbdba2006-02-06 15:33:21 +0000802/// SubprogramDesc.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000803void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) {
Jim Laskeyce72b172006-02-11 01:01:30 +0000804 GlobalDesc::ApplyToFields(Visitor);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000805}
806
Jim Laskeyce72b172006-02-11 01:01:30 +0000807/// getDescString - Return a string used to compose global names and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000808///
Jim Laskeyce72b172006-02-11 01:01:30 +0000809const char *SubprogramDesc::getDescString() const {
810 return "llvm.dbg.subprogram";
811}
812
813/// getTypeString - Return a string used to label this descriptors type.
814///
815const char *SubprogramDesc::getTypeString() const {
816 return "llvm.dbg.subprogram.type";
817}
818
819/// getAnchorString - Return a string used to label this descriptor's anchor.
820///
821const char *SubprogramDesc::getAnchorString() const {
822 return "llvm.dbg.subprograms";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000823}
824
Jim Laskey86cbdba2006-02-06 15:33:21 +0000825#ifndef NDEBUG
826void SubprogramDesc::dump() {
Jim Laskeyce72b172006-02-11 01:01:30 +0000827 std::cerr << getDescString() << " "
Jim Laskey86cbdba2006-02-06 15:33:21 +0000828 << "Tag(" << getTag() << "), "
Jim Laskeyce72b172006-02-11 01:01:30 +0000829 << "Anchor(" << getAnchor() << "), "
830 << "Name(\"" << getName() << "\"), "
Jim Laskeyf4afdd92006-02-23 16:58:18 +0000831 << "Type(\"" << getTypeDesc() << "\"), "
Jim Laskeyce72b172006-02-11 01:01:30 +0000832 << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
833 << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n";
Jim Laskey86cbdba2006-02-06 15:33:21 +0000834}
835#endif
836
Jim Laskey45ccae52006-02-28 20:15:07 +0000837//===----------------------------------------------------------------------===//
838
Jim Laskey86cbdba2006-02-06 15:33:21 +0000839DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
Jim Laskeyce72b172006-02-11 01:01:30 +0000840 return Deserialize(getGlobalVariable(V));
Jim Laskey86cbdba2006-02-06 15:33:21 +0000841}
842DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
Jim Laskeyce72b172006-02-11 01:01:30 +0000843 // Handle NULL.
844 if (!GV) return NULL;
845
Jim Laskey86cbdba2006-02-06 15:33:21 +0000846 // Check to see if it has been already deserialized.
847 DebugInfoDesc *&Slot = GlobalDescs[GV];
848 if (Slot) return Slot;
849
850 // Get the Tag from the global.
851 unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
852
853 // Get the debug version if a compile unit.
854 if (Tag == DI_TAG_compile_unit) {
855 DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
856 }
857
858 // Create an empty instance of the correct sort.
859 Slot = DebugInfoDesc::DescFactory(Tag);
860 assert(Slot && "Unknown Tag");
861
862 // Deserialize the fields.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000863 DIDeserializeVisitor DRAM(*this, GV);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000864 DRAM.ApplyToFields(Slot);
865
866 return Slot;
867}
868
869//===----------------------------------------------------------------------===//
870
871/// getStrPtrType - Return a "sbyte *" type.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000872///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000873const PointerType *DISerializer::getStrPtrType() {
874 // If not already defined.
875 if (!StrPtrTy) {
876 // Construct the pointer to signed bytes.
877 StrPtrTy = PointerType::get(Type::SByteTy);
878 }
879
880 return StrPtrTy;
881}
882
883/// getEmptyStructPtrType - Return a "{ }*" type.
884///
885const PointerType *DISerializer::getEmptyStructPtrType() {
886 // If not already defined.
887 if (!EmptyStructPtrTy) {
888 // Construct the empty structure type.
889 const StructType *EmptyStructTy =
890 StructType::get(std::vector<const Type*>());
891 // Construct the pointer to empty structure type.
892 EmptyStructPtrTy = PointerType::get(EmptyStructTy);
893 }
894
895 return EmptyStructPtrTy;
896}
897
898/// getTagType - Return the type describing the specified descriptor (via tag.)
899///
900const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
901 // Attempt to get the previously defined type.
902 StructType *&Ty = TagTypes[DD->getTag()];
903
904 // If not already defined.
905 if (!Ty) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000906 // Set up fields vector.
907 std::vector<const Type*> Fields;
Jim Laskeyce72b172006-02-11 01:01:30 +0000908 // Get types of fields.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000909 DIGetTypesVisitor GTAM(*this, Fields);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000910 GTAM.ApplyToFields(DD);
911
912 // Construct structured type.
913 Ty = StructType::get(Fields);
914
Jim Laskey86cbdba2006-02-06 15:33:21 +0000915 // Register type name with module.
Jim Laskeyce72b172006-02-11 01:01:30 +0000916 M->addTypeName(DD->getTypeString(), Ty);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000917 }
918
919 return Ty;
920}
921
922/// getString - Construct the string as constant string global.
923///
Jim Laskeyce72b172006-02-11 01:01:30 +0000924Constant *DISerializer::getString(const std::string &String) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000925 // Check string cache for previous edition.
Jim Laskeyce72b172006-02-11 01:01:30 +0000926 Constant *&Slot = StringCache[String];
927 // return Constant if previously defined.
Jim Laskey86cbdba2006-02-06 15:33:21 +0000928 if (Slot) return Slot;
Jim Laskeyce72b172006-02-11 01:01:30 +0000929 // Construct string as an llvm constant.
Jim Laskey86cbdba2006-02-06 15:33:21 +0000930 Constant *ConstStr = ConstantArray::get(String);
931 // Otherwise create and return a new string global.
Jim Laskeyce72b172006-02-11 01:01:30 +0000932 GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true,
933 GlobalVariable::InternalLinkage,
934 ConstStr, "str", M);
935 // Convert to generic string pointer.
936 Slot = ConstantExpr::getCast(StrGV, getStrPtrType());
937 return Slot;
938
Jim Laskey86cbdba2006-02-06 15:33:21 +0000939}
940
941/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
942/// so that it can be serialized to a .bc or .ll file.
943GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
944 // Check if the DebugInfoDesc is already in the map.
945 GlobalVariable *&Slot = DescGlobals[DD];
946
947 // See if DebugInfoDesc exists, if so return prior GlobalVariable.
948 if (Slot) return Slot;
949
Jim Laskey86cbdba2006-02-06 15:33:21 +0000950 // Get the type associated with the Tag.
951 const StructType *Ty = getTagType(DD);
952
953 // Create the GlobalVariable early to prevent infinite recursion.
Jim Laskeyce72b172006-02-11 01:01:30 +0000954 GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(),
955 NULL, DD->getDescString(), M);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000956
957 // Insert new GlobalVariable in DescGlobals map.
958 Slot = GV;
959
960 // Set up elements vector
961 std::vector<Constant*> Elements;
Jim Laskeyce72b172006-02-11 01:01:30 +0000962 // Add fields.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000963 DISerializeVisitor SRAM(*this, Elements);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000964 SRAM.ApplyToFields(DD);
965
966 // Set the globals initializer.
967 GV->setInitializer(ConstantStruct::get(Ty, Elements));
968
969 return GV;
970}
971
972//===----------------------------------------------------------------------===//
973
974/// markVisited - Return true if the GlobalVariable hase been "seen" before.
975/// Mark visited otherwise.
976bool DIVerifier::markVisited(GlobalVariable *GV) {
977 // Check if the GlobalVariable is already in the Visited set.
978 std::set<GlobalVariable *>::iterator VI = Visited.lower_bound(GV);
979
980 // See if GlobalVariable exists.
981 bool Exists = VI != Visited.end() && *VI == GV;
982
983 // Insert in set.
984 if (!Exists) Visited.insert(VI, GV);
985
986 return Exists;
987}
988
989/// Verify - Return true if the GlobalVariable appears to be a valid
990/// serialization of a DebugInfoDesc.
Jim Laskeyce72b172006-02-11 01:01:30 +0000991bool DIVerifier::Verify(Value *V) {
992 return Verify(getGlobalVariable(V));
993}
Jim Laskey86cbdba2006-02-06 15:33:21 +0000994bool DIVerifier::Verify(GlobalVariable *GV) {
995 // Check if seen before.
996 if (markVisited(GV)) return true;
997
998 // Get the Tag
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000999 unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
Jim Laskeyf60c2412006-02-06 21:54:05 +00001000 if (Tag == DIInvalid) return false;
Jim Laskey86cbdba2006-02-06 15:33:21 +00001001
1002 // If a compile unit we need the debug version.
1003 if (Tag == DI_TAG_compile_unit) {
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +00001004 DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
Jim Laskeyf60c2412006-02-06 21:54:05 +00001005 if (DebugVersion == DIInvalid) return false;
Jim Laskey86cbdba2006-02-06 15:33:21 +00001006 }
1007
1008 // Construct an empty DebugInfoDesc.
1009 DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
1010 if (!DD) return false;
1011
1012 // Get the initializer constant.
1013 ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
1014
1015 // Get the operand count.
1016 unsigned N = CI->getNumOperands();
1017
1018 // Get the field count.
1019 unsigned &Slot = Counts[Tag];
1020 if (!Slot) {
1021 // Check the operand count to the field count
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +00001022 DICountVisitor CTAM;
Jim Laskey86cbdba2006-02-06 15:33:21 +00001023 CTAM.ApplyToFields(DD);
1024 Slot = CTAM.getCount();
1025 }
1026
1027 // Field count must equal operand count.
1028 if (Slot != N) {
1029 delete DD;
1030 return false;
1031 }
1032
1033 // Check each field for valid type.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +00001034 DIVerifyVisitor VRAM(*this, GV);
Jim Laskey86cbdba2006-02-06 15:33:21 +00001035 VRAM.ApplyToFields(DD);
1036
1037 // Release empty DebugInfoDesc.
1038 delete DD;
1039
1040 // Return result of field tests.
1041 return VRAM.isValid();
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001042}
1043
1044//===----------------------------------------------------------------------===//
1045
1046
1047MachineDebugInfo::MachineDebugInfo()
Jim Laskeyce72b172006-02-11 01:01:30 +00001048: DR()
Jim Laskey86cbdba2006-02-06 15:33:21 +00001049, CompileUnits()
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001050, Directories()
1051, SourceFiles()
1052, Lines()
1053{
1054
1055}
1056MachineDebugInfo::~MachineDebugInfo() {
1057
1058}
1059
Jim Laskeyb2efb852006-01-04 22:28:25 +00001060/// doInitialization - Initialize the debug state for a new module.
1061///
1062bool MachineDebugInfo::doInitialization() {
1063 return false;
Jim Laskey6af56812006-01-04 13:36:38 +00001064}
1065
Jim Laskeyb2efb852006-01-04 22:28:25 +00001066/// doFinalization - Tear down the debug state after completion of a module.
1067///
1068bool MachineDebugInfo::doFinalization() {
1069 return false;
1070}
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001071
Jim Laskeyd96185a2006-02-13 12:50:39 +00001072/// getDescFor - Convert a Value to a debug information descriptor.
Jim Laskeyce72b172006-02-11 01:01:30 +00001073///
Jim Laskeyd96185a2006-02-13 12:50:39 +00001074// FIXME - use new Value type when available.
1075DebugInfoDesc *MachineDebugInfo::getDescFor(Value *V) {
Jim Laskeyce72b172006-02-11 01:01:30 +00001076 return DR.Deserialize(V);
1077}
1078
1079/// Verify - Verify that a Value is debug information descriptor.
1080///
1081bool MachineDebugInfo::Verify(Value *V) {
1082 DIVerifier VR;
1083 return VR.Verify(V);
1084}
1085
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001086/// AnalyzeModule - Scan the module for global debug information.
1087///
1088void MachineDebugInfo::AnalyzeModule(Module &M) {
1089 SetupCompileUnits(M);
1090}
1091
1092/// SetupCompileUnits - Set up the unique vector of compile units.
1093///
1094void MachineDebugInfo::SetupCompileUnits(Module &M) {
Jim Laskey0420f2a2006-02-22 19:02:11 +00001095 std::vector<CompileUnitDesc *>CU = getAnchoredDescriptors<CompileUnitDesc>(M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001096
Jim Laskey0420f2a2006-02-22 19:02:11 +00001097 for (unsigned i = 0, N = CU.size(); i < N; i++) {
1098 CompileUnits.insert(CU[i]);
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001099 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001100}
1101
Jim Laskey6e87c0e2006-01-26 21:22:49 +00001102/// getCompileUnits - Return a vector of debug compile units.
1103///
Jim Laskey86cbdba2006-02-06 15:33:21 +00001104const UniqueVector<CompileUnitDesc *> MachineDebugInfo::getCompileUnits()const{
Jim Laskey6e87c0e2006-01-26 21:22:49 +00001105 return CompileUnits;
1106}
1107
Jim Laskey0420f2a2006-02-22 19:02:11 +00001108/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
1109/// named GlobalVariable.
1110std::vector<GlobalVariable*>
1111MachineDebugInfo::getGlobalVariablesUsing(Module &M,
1112 const std::string &RootName) {
1113 return ::getGlobalVariablesUsing(M, RootName);
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001114}