blob: e3b24ab03b59cce418f1831bf7b72d6c67323ab9 [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 Laskeyb3e789a2006-01-26 20:21:46 +000052
Jim Laskey86cbdba2006-02-06 15:33:21 +000053 // Get the GlobalVariable root.
Jim Laskeyb3e789a2006-01-26 20:21:46 +000054 GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
55 StructType::get(std::vector<const Type*>()));
56
57 // If present and linkonce then scan for users.
58 if (UseRoot && UseRoot->hasLinkOnceLinkage()) {
59 getGlobalVariablesUsing(UseRoot, Result);
60 }
61
62 return Result;
63}
64
65/// getStringValue - Turn an LLVM constant pointer that eventually points to a
66/// global into a string value. Return an empty string if we can't do it.
67///
Chris Lattner22760af2006-01-27 17:31:30 +000068static const std::string getStringValue(Value *V, unsigned Offset = 0) {
Jim Laskeyb3e789a2006-01-26 20:21:46 +000069 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
70 if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
71 ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
72 if (Init->isString()) {
73 std::string Result = Init->getAsString();
74 if (Offset < Result.size()) {
75 // If we are pointing INTO The string, erase the beginning...
76 Result.erase(Result.begin(), Result.begin()+Offset);
77
78 // Take off the null terminator, and any string fragments after it.
79 std::string::size_type NullPos = Result.find_first_of((char)0);
80 if (NullPos != std::string::npos)
81 Result.erase(Result.begin()+NullPos, Result.end());
82 return Result;
83 }
84 }
85 }
86 } else if (Constant *C = dyn_cast<Constant>(V)) {
87 if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
88 return getStringValue(GV, Offset);
89 else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
90 if (CE->getOpcode() == Instruction::GetElementPtr) {
91 // Turn a gep into the specified offset.
92 if (CE->getNumOperands() == 3 &&
93 cast<Constant>(CE->getOperand(1))->isNullValue() &&
94 isa<ConstantInt>(CE->getOperand(2))) {
95 return getStringValue(CE->getOperand(0),
96 Offset+cast<ConstantInt>(CE->getOperand(2))->getRawValue());
97 }
98 }
99 }
100 }
101 return "";
102}
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000103
Jim Laskey86cbdba2006-02-06 15:33:21 +0000104/// isStringValue - Return true if the given value can be coerced to a string.
105///
106static bool isStringValue(Value *V) {
107 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
108 if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
109 ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
110 return Init->isString();
111 }
112 } else if (Constant *C = dyn_cast<Constant>(V)) {
113 if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
114 return isStringValue(GV);
115 else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
116 if (CE->getOpcode() == Instruction::GetElementPtr) {
117 if (CE->getNumOperands() == 3 &&
118 cast<Constant>(CE->getOperand(1))->isNullValue() &&
119 isa<ConstantInt>(CE->getOperand(2))) {
120 return isStringValue(CE->getOperand(0));
121 }
122 }
123 }
124 }
125 return false;
126}
127
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000128/// getGlobalValue - Return either a direct or cast Global value.
129///
130static GlobalVariable *getGlobalValue(Value *V) {
131 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
132 return GV;
133 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000134 if (CE->getOpcode() == Instruction::Cast) {
135 return dyn_cast<GlobalVariable>(CE->getOperand(0));
136 }
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000137 }
138 return NULL;
139}
140
Jim Laskey86cbdba2006-02-06 15:33:21 +0000141/// isGlobalValue - Return true if the given value can be coerced to a
142/// GlobalVariable.
143static bool isGlobalValue(Value *V) {
144 if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
145 return true;
146 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
147 if (CE->getOpcode() == Instruction::Cast) {
148 return isa<GlobalVariable>(CE->getOperand(0));
149 }
150 }
151 return false;
152}
153
154/// isUIntOperand - Return true if the ith operand is an unsigned integer.
155///
156static bool isUIntOperand(GlobalVariable *GV, unsigned i) {
157 // Make sure the GlobalVariable has an initializer.
158 if (!GV->hasInitializer()) return false;
Jim Laskeyb2efb852006-01-04 22:28:25 +0000159
Jim Laskey86cbdba2006-02-06 15:33:21 +0000160 // Get the initializer constant.
161 ConstantStruct *CI = dyn_cast<ConstantStruct>(GV->getInitializer());
162 if (!CI) return false;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000163
Jim Laskey86cbdba2006-02-06 15:33:21 +0000164 // Check if there is at least i + 1 operands.
165 unsigned N = CI->getNumOperands();
166 if (i >= N) return false;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000167
Jim Laskey86cbdba2006-02-06 15:33:21 +0000168 // Check constant.
169 return isa<ConstantUInt>(CI->getOperand(i));
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000170}
171
172//===----------------------------------------------------------------------===//
173
Jim Laskey86cbdba2006-02-06 15:33:21 +0000174/// TagFromGlobal - Returns the Tag number from a debug info descriptor
175/// GlobalVariable.
176unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV, bool Checking) {
177 if (Checking && !isUIntOperand(GV, 0)) return DIInvalid;
178 ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
179 Constant *C = CI->getOperand(0);
180 return cast<ConstantUInt>(C)->getValue();
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000181}
182
Jim Laskey86cbdba2006-02-06 15:33:21 +0000183/// DescFactory - Create an instance of debug info descriptor based on Tag.
184/// Return NULL if not a recognized Tag.
185DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) {
186 switch (Tag) {
187 case DI_TAG_compile_unit: return new CompileUnitDesc();
188 case DI_TAG_global_variable: return new GlobalVariableDesc();
189 case DI_TAG_subprogram: return new SubprogramDesc();
190 default: break;
191 }
192 return NULL;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000193}
194
Jim Laskey86cbdba2006-02-06 15:33:21 +0000195//===----------------------------------------------------------------------===//
196
197/// ApplyToFields - Target the manager to each field of the debug information
198/// descriptor.
199void DIApplyManager::ApplyToFields(DebugInfoDesc *DD) {
200 DD->ApplyToFields(this);
201}
202
203//===----------------------------------------------------------------------===//
204/// DICountAppMgr - This DIApplyManager counts all the fields in the supplied
205/// debug the supplied DebugInfoDesc.
206class DICountAppMgr : public DIApplyManager {
207private:
208 unsigned Count; // Running count of fields.
209
210public:
211 DICountAppMgr() : DIApplyManager(), Count(1) {}
212
213 // Accessors.
214 unsigned getCount() const { return Count; }
215
216 /// Apply - Count each of the fields.
217 ///
218 virtual void Apply(int &Field) { ++Count; }
219 virtual void Apply(unsigned &Field) { ++Count; }
220 virtual void Apply(bool &Field) { ++Count; }
221 virtual void Apply(std::string &Field) { ++Count; }
222 virtual void Apply(DebugInfoDesc *&Field) { ++Count; }
223 virtual void Apply(GlobalVariable *&Field) { ++Count; }
224};
225
226//===----------------------------------------------------------------------===//
227/// DIDeserializeAppMgr - This DIApplyManager deserializes all the fields in
228/// the supplied DebugInfoDesc.
229class DIDeserializeAppMgr : public DIApplyManager {
230private:
231 DIDeserializer &DR; // Active deserializer.
232 unsigned I; // Current operand index.
233 ConstantStruct *CI; // GlobalVariable constant initializer.
234
235public:
236 DIDeserializeAppMgr(DIDeserializer &D, GlobalVariable *GV)
237 : DIApplyManager()
238 , DR(D)
239 , I(1)
240 , CI(cast<ConstantStruct>(GV->getInitializer()))
241 {}
242
243 /// Apply - Set the value of each of the fields.
244 ///
245 virtual void Apply(int &Field) {
246 Constant *C = CI->getOperand(I++);
247 Field = cast<ConstantSInt>(C)->getValue();
248 }
249 virtual void Apply(unsigned &Field) {
250 Constant *C = CI->getOperand(I++);
251 Field = cast<ConstantUInt>(C)->getValue();
252 }
253 virtual void Apply(bool &Field) {
254 Constant *C = CI->getOperand(I++);
255 Field = cast<ConstantBool>(C)->getValue();
256 }
257 virtual void Apply(std::string &Field) {
258 Constant *C = CI->getOperand(I++);
259 Field = getStringValue(C);
260 }
261 virtual void Apply(DebugInfoDesc *&Field) {
262 Constant *C = CI->getOperand(I++);
263 Field = DR.Deserialize(C);
264 }
265 virtual void Apply(GlobalVariable *&Field) {
266 Constant *C = CI->getOperand(I++);
267 Field = getGlobalValue(C);
268 }
269};
270
271//===----------------------------------------------------------------------===//
272/// DISerializeAppMgr - This DIApplyManager serializes all the fields in
273/// the supplied DebugInfoDesc.
274class DISerializeAppMgr : public DIApplyManager {
275private:
276 DISerializer &SR; // Active serializer.
277 std::vector<Constant*> &Elements; // Element accumulator.
278
279public:
280 DISerializeAppMgr(DISerializer &S, std::vector<Constant*> &E)
281 : DIApplyManager()
282 , SR(S)
283 , Elements(E)
284 {}
285
286 /// Apply - Set the value of each of the fields.
287 ///
288 virtual void Apply(int &Field) {
289 Elements.push_back(ConstantUInt::get(Type::IntTy, Field));
290 }
291 virtual void Apply(unsigned &Field) {
292 Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
293 }
294 virtual void Apply(bool &Field) {
295 Elements.push_back(ConstantBool::get(Field));
296 }
297 virtual void Apply(std::string &Field) {
298 Elements.push_back(SR.getString(Field));
299 }
300 virtual void Apply(DebugInfoDesc *&Field) {
301 GlobalVariable *GV = NULL;
302
303 // If non-NULL the convert to global.
304 if (Field) GV = SR.Serialize(Field);
305
306 // FIXME - At some point should use specific type.
307 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
308
309 if (GV) {
310 // Set to pointer to global.
311 Elements.push_back(ConstantExpr::getCast(GV, EmptyTy));
312 } else {
313 // Use NULL.
314 Elements.push_back(ConstantPointerNull::get(EmptyTy));
315 }
316 }
317 virtual void Apply(GlobalVariable *&Field) {
318 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
319 Elements.push_back(ConstantExpr::getCast(Field, EmptyTy));
320 }
321};
322
323//===----------------------------------------------------------------------===//
324/// DIGetTypesAppMgr - This DIApplyManager gathers all the field types in
325/// the supplied DebugInfoDesc.
326class DIGetTypesAppMgr : public DIApplyManager {
327private:
328 DISerializer &SR; // Active serializer.
329 std::vector<const Type*> &Fields; // Type accumulator.
330
331public:
332 DIGetTypesAppMgr(DISerializer &S, std::vector<const Type*> &F)
333 : DIApplyManager()
334 , SR(S)
335 , Fields(F)
336 {}
337
338 /// Apply - Set the value of each of the fields.
339 ///
340 virtual void Apply(int &Field) {
341 Fields.push_back(Type::IntTy);
342 }
343 virtual void Apply(unsigned &Field) {
344 Fields.push_back(Type::UIntTy);
345 }
346 virtual void Apply(bool &Field) {
347 Fields.push_back(Type::BoolTy);
348 }
349 virtual void Apply(std::string &Field) {
350 Fields.push_back(SR.getStrPtrType());
351 }
352 virtual void Apply(DebugInfoDesc *&Field) {
353 // FIXME - At some point should use specific type.
354 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
355 Fields.push_back(EmptyTy);
356 }
357 virtual void Apply(GlobalVariable *&Field) {
358 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
359 Fields.push_back(EmptyTy);
360 }
361};
362
363//===----------------------------------------------------------------------===//
364/// DIVerifyAppMgr - This DIApplyManager verifies all the field types against
365/// a constant initializer.
366class DIVerifyAppMgr : public DIApplyManager {
367private:
368 DIVerifier &VR; // Active verifier.
369 bool IsValid; // Validity status.
370 unsigned I; // Current operand index.
371 ConstantStruct *CI; // GlobalVariable constant initializer.
372
373public:
374 DIVerifyAppMgr(DIVerifier &V, GlobalVariable *GV)
375 : DIApplyManager()
376 , VR(V)
377 , IsValid(true)
378 , I(1)
379 , CI(cast<ConstantStruct>(GV->getInitializer()))
380 {
381 }
382
383 // Accessors.
384 bool isValid() const { return IsValid; }
385
386 /// Apply - Set the value of each of the fields.
387 ///
388 virtual void Apply(int &Field) {
389 Constant *C = CI->getOperand(I++);
390 IsValid = IsValid && isa<ConstantInt>(C);
391 }
392 virtual void Apply(unsigned &Field) {
393 Constant *C = CI->getOperand(I++);
394 IsValid = IsValid && isa<ConstantInt>(C);
395 }
396 virtual void Apply(bool &Field) {
397 Constant *C = CI->getOperand(I++);
398 IsValid = IsValid && isa<ConstantBool>(C);
399 }
400 virtual void Apply(std::string &Field) {
401 Constant *C = CI->getOperand(I++);
402 IsValid = IsValid && isStringValue(C);
403 }
404 virtual void Apply(DebugInfoDesc *&Field) {
405 // FIXME - Prepare the correct descriptor.
406 Constant *C = CI->getOperand(I++);
407 IsValid = IsValid && isGlobalValue(C);
408 }
409 virtual void Apply(GlobalVariable *&Field) {
410 Constant *C = CI->getOperand(I++);
411 IsValid = IsValid && isGlobalValue(C);
412 }
413};
414
415//===----------------------------------------------------------------------===//
416
417/// DebugVersionFromGlobal - Returns the version number from a compile unit
418/// GlobalVariable.
419unsigned CompileUnitDesc::DebugVersionFromGlobal(GlobalVariable *GV,
420 bool Checking) {
421 if (Checking && !isUIntOperand(GV, 1)) return DIInvalid;
422 ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
423 Constant *C = CI->getOperand(1);
424 return cast<ConstantUInt>(C)->getValue();
425}
426
427/// ApplyToFields - Target the apply manager to the fields of the
428/// CompileUnitDesc.
429void CompileUnitDesc::ApplyToFields(DIApplyManager *Mgr) {
430 Mgr->Apply(DebugVersion);
431 Mgr->Apply(Language);
432 Mgr->Apply(FileName);
433 Mgr->Apply(Directory);
434 Mgr->Apply(Producer);
435 Mgr->Apply(TransUnit);
436}
437
438/// TypeString - Return a string used to compose globalnames and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000439///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000440const char *CompileUnitDesc::TypeString() const {
441 return "compile_unit";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000442}
443
Jim Laskey86cbdba2006-02-06 15:33:21 +0000444#ifndef NDEBUG
445void CompileUnitDesc::dump() {
446 std::cerr << TypeString() << " "
447 << "Tag(" << getTag() << "), "
448 << "Language(" << Language << "), "
449 << "FileName(\"" << FileName << "\"), "
450 << "Directory(\"" << Directory << "\"), "
451 << "Producer(\"" << Producer << "\")\n";
452}
453#endif
454
455//===----------------------------------------------------------------------===//
456
457/// ApplyToFields - Target the apply manager to the fields of the
458/// GlobalVariableDesc.
459void GlobalVariableDesc::ApplyToFields(DIApplyManager *Mgr) {
460 Mgr->Apply(Context);
461 Mgr->Apply(Name);
462 Mgr->Apply(TransUnit);
463 Mgr->Apply(TyDesc);
464 Mgr->Apply(IsStatic);
465 Mgr->Apply(IsDefinition);
466 Mgr->Apply(Global);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000467}
468
Jim Laskey86cbdba2006-02-06 15:33:21 +0000469/// TypeString - Return a string used to compose globalnames and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000470///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000471const char *GlobalVariableDesc::TypeString() const {
472 return "global_variable";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000473}
474
Jim Laskey86cbdba2006-02-06 15:33:21 +0000475#ifndef NDEBUG
476void GlobalVariableDesc::dump() {
477 std::cerr << TypeString() << " "
478 << "Tag(" << getTag() << "), "
479 << "Name(\"" << Name << "\"), "
480 << "Type(" << TyDesc << "), "
481 << "IsStatic(" << (IsStatic ? "true" : "false") << "), "
482 << "IsDefinition(" << (IsDefinition ? "true" : "false") << "), "
483 << "Global(" << Global << ")\n";
484}
485#endif
486
487//===----------------------------------------------------------------------===//
488
489/// ApplyToFields - Target the apply manager to the fields of the
490/// SubprogramDesc.
491void SubprogramDesc::ApplyToFields(DIApplyManager *Mgr) {
492 Mgr->Apply(Context);
493 Mgr->Apply(Name);
494 Mgr->Apply(TransUnit);
495 Mgr->Apply(TyDesc);
496 Mgr->Apply(IsStatic);
497 Mgr->Apply(IsDefinition);
498
499 // FIXME - Temp variable until restructured.
500 GlobalVariable *Tmp;
501 Mgr->Apply(Tmp);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000502}
503
Jim Laskey86cbdba2006-02-06 15:33:21 +0000504/// TypeString - Return a string used to compose globalnames and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000505///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000506const char *SubprogramDesc::TypeString() const {
507 return "subprogram";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000508}
509
Jim Laskey86cbdba2006-02-06 15:33:21 +0000510#ifndef NDEBUG
511void SubprogramDesc::dump() {
512 std::cerr << TypeString() << " "
513 << "Tag(" << getTag() << "), "
514 << "Name(\"" << Name << "\"), "
515 << "Type(" << TyDesc << "), "
516 << "IsStatic(" << (IsStatic ? "true" : "false") << "), "
517 << "IsDefinition(" << (IsDefinition ? "true" : "false") << ")\n";
518}
519#endif
520
521//===----------------------------------------------------------------------===//
522
523DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
524 return Deserialize(cast<GlobalVariable>(V));
525}
526DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
527 // Check to see if it has been already deserialized.
528 DebugInfoDesc *&Slot = GlobalDescs[GV];
529 if (Slot) return Slot;
530
531 // Get the Tag from the global.
532 unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
533
534 // Get the debug version if a compile unit.
535 if (Tag == DI_TAG_compile_unit) {
536 DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
537 }
538
539 // Create an empty instance of the correct sort.
540 Slot = DebugInfoDesc::DescFactory(Tag);
541 assert(Slot && "Unknown Tag");
542
543 // Deserialize the fields.
544 DIDeserializeAppMgr DRAM(*this, GV);
545 DRAM.ApplyToFields(Slot);
546
547 return Slot;
548}
549
550//===----------------------------------------------------------------------===//
551
552/// getStrPtrType - Return a "sbyte *" type.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000553///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000554const PointerType *DISerializer::getStrPtrType() {
555 // If not already defined.
556 if (!StrPtrTy) {
557 // Construct the pointer to signed bytes.
558 StrPtrTy = PointerType::get(Type::SByteTy);
559 }
560
561 return StrPtrTy;
562}
563
564/// getEmptyStructPtrType - Return a "{ }*" type.
565///
566const PointerType *DISerializer::getEmptyStructPtrType() {
567 // If not already defined.
568 if (!EmptyStructPtrTy) {
569 // Construct the empty structure type.
570 const StructType *EmptyStructTy =
571 StructType::get(std::vector<const Type*>());
572 // Construct the pointer to empty structure type.
573 EmptyStructPtrTy = PointerType::get(EmptyStructTy);
574 }
575
576 return EmptyStructPtrTy;
577}
578
579/// getTagType - Return the type describing the specified descriptor (via tag.)
580///
581const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
582 // Attempt to get the previously defined type.
583 StructType *&Ty = TagTypes[DD->getTag()];
584
585 // If not already defined.
586 if (!Ty) {
587 // Get descriptor type name.
588 const char *TS = DD->TypeString();
589
590 // Set up fields vector.
591 std::vector<const Type*> Fields;
592 // Add tag field.
593 Fields.push_back(Type::UIntTy);
594 // Get types of remaining fields.
595 DIGetTypesAppMgr GTAM(*this, Fields);
596 GTAM.ApplyToFields(DD);
597
598 // Construct structured type.
599 Ty = StructType::get(Fields);
600
601 // Construct a name for the type.
602 const std::string Name = std::string("lldb.") + DD->TypeString() + ".type";
603
604 // Register type name with module.
605 M->addTypeName(Name, Ty);
606 }
607
608 return Ty;
609}
610
611/// getString - Construct the string as constant string global.
612///
613GlobalVariable *DISerializer::getString(const std::string &String) {
614 // Check string cache for previous edition.
615 GlobalVariable *&Slot = StringCache[String];
616 // return GlobalVariable if previously defined.
617 if (Slot) return Slot;
618 // Construct strings as an llvm constant.
619 Constant *ConstStr = ConstantArray::get(String);
620 // Otherwise create and return a new string global.
621 return Slot = new GlobalVariable(ConstStr->getType(), true,
622 GlobalVariable::InternalLinkage,
623 ConstStr, "str", M);
624}
625
626/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
627/// so that it can be serialized to a .bc or .ll file.
628GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
629 // Check if the DebugInfoDesc is already in the map.
630 GlobalVariable *&Slot = DescGlobals[DD];
631
632 // See if DebugInfoDesc exists, if so return prior GlobalVariable.
633 if (Slot) return Slot;
634
635 // Get DebugInfoDesc type Tag.
636 unsigned Tag = DD->getTag();
637
638 // Construct name.
639 const std::string Name = std::string("lldb.") +
640 DD->TypeString();
641
642 // Get the type associated with the Tag.
643 const StructType *Ty = getTagType(DD);
644
645 // Create the GlobalVariable early to prevent infinite recursion.
646 GlobalVariable *GV = new GlobalVariable(Ty, true,
647 GlobalValue::InternalLinkage,
648 NULL, Name, M);
649
650 // Insert new GlobalVariable in DescGlobals map.
651 Slot = GV;
652
653 // Set up elements vector
654 std::vector<Constant*> Elements;
655 // Add Tag value.
656 Elements.push_back(ConstantUInt::get(Type::UIntTy, Tag));
657 // Add remaining fields.
658 DISerializeAppMgr SRAM(*this, Elements);
659 SRAM.ApplyToFields(DD);
660
661 // Set the globals initializer.
662 GV->setInitializer(ConstantStruct::get(Ty, Elements));
663
664 return GV;
665}
666
667//===----------------------------------------------------------------------===//
668
669/// markVisited - Return true if the GlobalVariable hase been "seen" before.
670/// Mark visited otherwise.
671bool DIVerifier::markVisited(GlobalVariable *GV) {
672 // Check if the GlobalVariable is already in the Visited set.
673 std::set<GlobalVariable *>::iterator VI = Visited.lower_bound(GV);
674
675 // See if GlobalVariable exists.
676 bool Exists = VI != Visited.end() && *VI == GV;
677
678 // Insert in set.
679 if (!Exists) Visited.insert(VI, GV);
680
681 return Exists;
682}
683
684/// Verify - Return true if the GlobalVariable appears to be a valid
685/// serialization of a DebugInfoDesc.
686bool DIVerifier::Verify(GlobalVariable *GV) {
687 // Check if seen before.
688 if (markVisited(GV)) return true;
689
690 // Get the Tag
691 unsigned Tag = DebugInfoDesc::TagFromGlobal(GV, true);
692 if (Tag == DIInvalid) return false;
693
694 // If a compile unit we need the debug version.
695 if (Tag == DI_TAG_compile_unit) {
696 DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV, true);
697 if (DebugVersion == DIInvalid) return false;
698 }
699
700 // Construct an empty DebugInfoDesc.
701 DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
702 if (!DD) return false;
703
704 // Get the initializer constant.
705 ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
706
707 // Get the operand count.
708 unsigned N = CI->getNumOperands();
709
710 // Get the field count.
711 unsigned &Slot = Counts[Tag];
712 if (!Slot) {
713 // Check the operand count to the field count
714 DICountAppMgr CTAM;
715 CTAM.ApplyToFields(DD);
716 Slot = CTAM.getCount();
717 }
718
719 // Field count must equal operand count.
720 if (Slot != N) {
721 delete DD;
722 return false;
723 }
724
725 // Check each field for valid type.
726 DIVerifyAppMgr VRAM(*this, GV);
727 VRAM.ApplyToFields(DD);
728
729 // Release empty DebugInfoDesc.
730 delete DD;
731
732 // Return result of field tests.
733 return VRAM.isValid();
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000734}
735
736//===----------------------------------------------------------------------===//
737
738
739MachineDebugInfo::MachineDebugInfo()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000740: SR()
741, DR()
742, VR()
743, CompileUnits()
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000744, Directories()
745, SourceFiles()
746, Lines()
747{
748
749}
750MachineDebugInfo::~MachineDebugInfo() {
751
752}
753
Jim Laskeyb2efb852006-01-04 22:28:25 +0000754/// doInitialization - Initialize the debug state for a new module.
755///
756bool MachineDebugInfo::doInitialization() {
757 return false;
Jim Laskey6af56812006-01-04 13:36:38 +0000758}
759
Jim Laskeyb2efb852006-01-04 22:28:25 +0000760/// doFinalization - Tear down the debug state after completion of a module.
761///
762bool MachineDebugInfo::doFinalization() {
763 return false;
764}
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000765
766/// AnalyzeModule - Scan the module for global debug information.
767///
768void MachineDebugInfo::AnalyzeModule(Module &M) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000769 SR.setModule(&M);
770 DR.setModule(&M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000771 SetupCompileUnits(M);
772}
773
774/// SetupCompileUnits - Set up the unique vector of compile units.
775///
776void MachineDebugInfo::SetupCompileUnits(Module &M) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000777 SR.setModule(&M);
778 DR.setModule(&M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000779 // Get vector of all debug compile units.
780 std::vector<GlobalVariable*> Globals =
781 getGlobalVariablesUsing(M, "llvm.dbg.translation_units");
782
783 // Scan all compile unit globals.
784 for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000785 // Add compile unit to result.
786 CompileUnits.insert(
787 static_cast<CompileUnitDesc *>(DR.Deserialize(Globals[i])));
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000788 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000789}
790
Jim Laskey6e87c0e2006-01-26 21:22:49 +0000791/// getCompileUnits - Return a vector of debug compile units.
792///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000793const UniqueVector<CompileUnitDesc *> MachineDebugInfo::getCompileUnits()const{
Jim Laskey6e87c0e2006-01-26 21:22:49 +0000794 return CompileUnits;
795}
796
Jim Laskey86cbdba2006-02-06 15:33:21 +0000797/// getGlobalVariables - Return a vector of debug GlobalVariables.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000798///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000799std::vector<GlobalVariableDesc *>
800MachineDebugInfo::getGlobalVariables(Module &M) {
801 SR.setModule(&M);
802 DR.setModule(&M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000803 // Get vector of all debug global objects.
804 std::vector<GlobalVariable*> Globals =
805 getGlobalVariablesUsing(M, "llvm.dbg.globals");
806
Jim Laskey86cbdba2006-02-06 15:33:21 +0000807 // Accumulation of GlobalVariables.
808 std::vector<GlobalVariableDesc *> GlobalVariables;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000809
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000810 // Scan all globals.
811 for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000812 GlobalVariable *GV = Globals[i];
813 if (DebugInfoDesc::TagFromGlobal(GV, true) == DI_TAG_global_variable) {
814 GlobalVariableDesc *GVD =
815 static_cast<GlobalVariableDesc *>(DR.Deserialize(GV));
816 GlobalVariables.push_back(GVD);
817 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000818 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000819
820 return GlobalVariables;
821}
822