blob: 28fc9c306f8da7790f848312b36722e7520e1a29 [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 Laskeyc2f0c8d2006-02-06 19:12:02 +0000128/// getGlobalVariable - Return either a direct or cast Global value.
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000129///
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000130static GlobalVariable *getGlobalVariable(Value *V) {
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000131 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 Laskeyc2f0c8d2006-02-06 19:12:02 +0000141/// isGlobalVariable - Return true if the given value can be coerced to a
Jim Laskey86cbdba2006-02-06 15:33:21 +0000142/// GlobalVariable.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000143static bool isGlobalVariable(Value *V) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000144 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
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000154/// getUIntOperand - Return ith operand if it is an unsigned integer.
Jim Laskey86cbdba2006-02-06 15:33:21 +0000155///
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000156static ConstantUInt *getUIntOperand(GlobalVariable *GV, unsigned i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000157 // Make sure the GlobalVariable has an initializer.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000158 if (!GV->hasInitializer()) return NULL;
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());
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000162 if (!CI) return NULL;
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();
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000166 if (i >= N) return NULL;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000167
Jim Laskey86cbdba2006-02-06 15:33:21 +0000168 // Check constant.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000169 return dyn_cast<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.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000176unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) {
177 ConstantUInt *C = getUIntOperand(GV, 0);
Jim Laskeyf60c2412006-02-06 21:54:05 +0000178 return C ? (unsigned)C->getValue() : (unsigned)DIInvalid;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000179}
180
Jim Laskey86cbdba2006-02-06 15:33:21 +0000181/// DescFactory - Create an instance of debug info descriptor based on Tag.
182/// Return NULL if not a recognized Tag.
183DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) {
184 switch (Tag) {
185 case DI_TAG_compile_unit: return new CompileUnitDesc();
186 case DI_TAG_global_variable: return new GlobalVariableDesc();
187 case DI_TAG_subprogram: return new SubprogramDesc();
188 default: break;
189 }
190 return NULL;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000191}
192
Jim Laskey86cbdba2006-02-06 15:33:21 +0000193//===----------------------------------------------------------------------===//
194
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000195/// ApplyToFields - Target the visitor to each field of the debug information
Jim Laskey86cbdba2006-02-06 15:33:21 +0000196/// descriptor.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000197void DIVisitor::ApplyToFields(DebugInfoDesc *DD) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000198 DD->ApplyToFields(this);
199}
200
201//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000202/// DICountVisitor - This DIVisitor counts all the fields in the supplied debug
203/// the supplied DebugInfoDesc.
204class DICountVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000205private:
206 unsigned Count; // Running count of fields.
207
208public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000209 DICountVisitor() : DIVisitor(), Count(1) {}
Jim Laskey86cbdba2006-02-06 15:33:21 +0000210
211 // Accessors.
212 unsigned getCount() const { return Count; }
213
214 /// Apply - Count each of the fields.
215 ///
216 virtual void Apply(int &Field) { ++Count; }
217 virtual void Apply(unsigned &Field) { ++Count; }
218 virtual void Apply(bool &Field) { ++Count; }
219 virtual void Apply(std::string &Field) { ++Count; }
220 virtual void Apply(DebugInfoDesc *&Field) { ++Count; }
221 virtual void Apply(GlobalVariable *&Field) { ++Count; }
222};
223
224//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000225/// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the
226/// supplied DebugInfoDesc.
227class DIDeserializeVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000228private:
229 DIDeserializer &DR; // Active deserializer.
230 unsigned I; // Current operand index.
231 ConstantStruct *CI; // GlobalVariable constant initializer.
232
233public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000234 DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV)
235 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000236 , DR(D)
237 , I(1)
238 , CI(cast<ConstantStruct>(GV->getInitializer()))
239 {}
240
241 /// Apply - Set the value of each of the fields.
242 ///
243 virtual void Apply(int &Field) {
244 Constant *C = CI->getOperand(I++);
245 Field = cast<ConstantSInt>(C)->getValue();
246 }
247 virtual void Apply(unsigned &Field) {
248 Constant *C = CI->getOperand(I++);
249 Field = cast<ConstantUInt>(C)->getValue();
250 }
251 virtual void Apply(bool &Field) {
252 Constant *C = CI->getOperand(I++);
253 Field = cast<ConstantBool>(C)->getValue();
254 }
255 virtual void Apply(std::string &Field) {
256 Constant *C = CI->getOperand(I++);
257 Field = getStringValue(C);
258 }
259 virtual void Apply(DebugInfoDesc *&Field) {
260 Constant *C = CI->getOperand(I++);
261 Field = DR.Deserialize(C);
262 }
263 virtual void Apply(GlobalVariable *&Field) {
264 Constant *C = CI->getOperand(I++);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000265 Field = getGlobalVariable(C);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000266 }
267};
268
269//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000270/// DISerializeVisitor - This DIVisitor serializes all the fields in
Jim Laskey86cbdba2006-02-06 15:33:21 +0000271/// the supplied DebugInfoDesc.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000272class DISerializeVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000273private:
274 DISerializer &SR; // Active serializer.
275 std::vector<Constant*> &Elements; // Element accumulator.
276
277public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000278 DISerializeVisitor(DISerializer &S, std::vector<Constant*> &E)
279 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000280 , SR(S)
281 , Elements(E)
282 {}
283
284 /// Apply - Set the value of each of the fields.
285 ///
286 virtual void Apply(int &Field) {
287 Elements.push_back(ConstantUInt::get(Type::IntTy, Field));
288 }
289 virtual void Apply(unsigned &Field) {
290 Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
291 }
292 virtual void Apply(bool &Field) {
293 Elements.push_back(ConstantBool::get(Field));
294 }
295 virtual void Apply(std::string &Field) {
296 Elements.push_back(SR.getString(Field));
297 }
298 virtual void Apply(DebugInfoDesc *&Field) {
299 GlobalVariable *GV = NULL;
300
301 // If non-NULL the convert to global.
302 if (Field) GV = SR.Serialize(Field);
303
304 // FIXME - At some point should use specific type.
305 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
306
307 if (GV) {
308 // Set to pointer to global.
309 Elements.push_back(ConstantExpr::getCast(GV, EmptyTy));
310 } else {
311 // Use NULL.
312 Elements.push_back(ConstantPointerNull::get(EmptyTy));
313 }
314 }
315 virtual void Apply(GlobalVariable *&Field) {
316 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
317 Elements.push_back(ConstantExpr::getCast(Field, EmptyTy));
318 }
319};
320
321//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000322/// DIGetTypesVisitor - This DIVisitor gathers all the field types in
Jim Laskey86cbdba2006-02-06 15:33:21 +0000323/// the supplied DebugInfoDesc.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000324class DIGetTypesVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000325private:
326 DISerializer &SR; // Active serializer.
327 std::vector<const Type*> &Fields; // Type accumulator.
328
329public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000330 DIGetTypesVisitor(DISerializer &S, std::vector<const Type*> &F)
331 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000332 , SR(S)
333 , Fields(F)
334 {}
335
336 /// Apply - Set the value of each of the fields.
337 ///
338 virtual void Apply(int &Field) {
339 Fields.push_back(Type::IntTy);
340 }
341 virtual void Apply(unsigned &Field) {
342 Fields.push_back(Type::UIntTy);
343 }
344 virtual void Apply(bool &Field) {
345 Fields.push_back(Type::BoolTy);
346 }
347 virtual void Apply(std::string &Field) {
348 Fields.push_back(SR.getStrPtrType());
349 }
350 virtual void Apply(DebugInfoDesc *&Field) {
351 // FIXME - At some point should use specific type.
352 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
353 Fields.push_back(EmptyTy);
354 }
355 virtual void Apply(GlobalVariable *&Field) {
356 const PointerType *EmptyTy = SR.getEmptyStructPtrType();
357 Fields.push_back(EmptyTy);
358 }
359};
360
361//===----------------------------------------------------------------------===//
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000362/// DIVerifyVisitor - This DIVisitor verifies all the field types against
Jim Laskey86cbdba2006-02-06 15:33:21 +0000363/// a constant initializer.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000364class DIVerifyVisitor : public DIVisitor {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000365private:
366 DIVerifier &VR; // Active verifier.
367 bool IsValid; // Validity status.
368 unsigned I; // Current operand index.
369 ConstantStruct *CI; // GlobalVariable constant initializer.
370
371public:
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000372 DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV)
373 : DIVisitor()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000374 , VR(V)
375 , IsValid(true)
376 , I(1)
377 , CI(cast<ConstantStruct>(GV->getInitializer()))
378 {
379 }
380
381 // Accessors.
382 bool isValid() const { return IsValid; }
383
384 /// Apply - Set the value of each of the fields.
385 ///
386 virtual void Apply(int &Field) {
387 Constant *C = CI->getOperand(I++);
388 IsValid = IsValid && isa<ConstantInt>(C);
389 }
390 virtual void Apply(unsigned &Field) {
391 Constant *C = CI->getOperand(I++);
392 IsValid = IsValid && isa<ConstantInt>(C);
393 }
394 virtual void Apply(bool &Field) {
395 Constant *C = CI->getOperand(I++);
396 IsValid = IsValid && isa<ConstantBool>(C);
397 }
398 virtual void Apply(std::string &Field) {
399 Constant *C = CI->getOperand(I++);
400 IsValid = IsValid && isStringValue(C);
401 }
402 virtual void Apply(DebugInfoDesc *&Field) {
403 // FIXME - Prepare the correct descriptor.
404 Constant *C = CI->getOperand(I++);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000405 IsValid = IsValid && isGlobalVariable(C);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000406 }
407 virtual void Apply(GlobalVariable *&Field) {
408 Constant *C = CI->getOperand(I++);
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000409 IsValid = IsValid && isGlobalVariable(C);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000410 }
411};
412
413//===----------------------------------------------------------------------===//
414
415/// DebugVersionFromGlobal - Returns the version number from a compile unit
416/// GlobalVariable.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000417unsigned CompileUnitDesc::DebugVersionFromGlobal(GlobalVariable *GV) {
418 ConstantUInt *C = getUIntOperand(GV, 1);
Jim Laskeyf60c2412006-02-06 21:54:05 +0000419 return C ? (unsigned)C->getValue() : (unsigned)DIInvalid;
Jim Laskey86cbdba2006-02-06 15:33:21 +0000420}
421
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000422/// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc.
423///
424void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) {
425 Visitor->Apply(DebugVersion);
426 Visitor->Apply(Language);
427 Visitor->Apply(FileName);
428 Visitor->Apply(Directory);
429 Visitor->Apply(Producer);
430 Visitor->Apply(TransUnit);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000431}
432
433/// TypeString - Return a string used to compose globalnames and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000434///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000435const char *CompileUnitDesc::TypeString() const {
436 return "compile_unit";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000437}
438
Jim Laskey86cbdba2006-02-06 15:33:21 +0000439#ifndef NDEBUG
440void CompileUnitDesc::dump() {
441 std::cerr << TypeString() << " "
442 << "Tag(" << getTag() << "), "
443 << "Language(" << Language << "), "
444 << "FileName(\"" << FileName << "\"), "
445 << "Directory(\"" << Directory << "\"), "
446 << "Producer(\"" << Producer << "\")\n";
447}
448#endif
449
450//===----------------------------------------------------------------------===//
451
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000452/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc.
453///
454void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) {
455 Visitor->Apply(Context);
456 Visitor->Apply(Name);
457 Visitor->Apply(TransUnit);
458 Visitor->Apply(TyDesc);
459 Visitor->Apply(IsStatic);
460 Visitor->Apply(IsDefinition);
461 Visitor->Apply(Global);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000462}
463
Jim Laskey86cbdba2006-02-06 15:33:21 +0000464/// TypeString - Return a string used to compose globalnames and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000465///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000466const char *GlobalVariableDesc::TypeString() const {
467 return "global_variable";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000468}
469
Jim Laskey86cbdba2006-02-06 15:33:21 +0000470#ifndef NDEBUG
471void GlobalVariableDesc::dump() {
472 std::cerr << TypeString() << " "
473 << "Tag(" << getTag() << "), "
474 << "Name(\"" << Name << "\"), "
475 << "Type(" << TyDesc << "), "
476 << "IsStatic(" << (IsStatic ? "true" : "false") << "), "
477 << "IsDefinition(" << (IsDefinition ? "true" : "false") << "), "
478 << "Global(" << Global << ")\n";
479}
480#endif
481
482//===----------------------------------------------------------------------===//
483
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000484/// ApplyToFields - Target the visitor to the fields of the
Jim Laskey86cbdba2006-02-06 15:33:21 +0000485/// SubprogramDesc.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000486void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) {
487 Visitor->Apply(Context);
488 Visitor->Apply(Name);
489 Visitor->Apply(TransUnit);
490 Visitor->Apply(TyDesc);
491 Visitor->Apply(IsStatic);
492 Visitor->Apply(IsDefinition);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000493
494 // FIXME - Temp variable until restructured.
495 GlobalVariable *Tmp;
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000496 Visitor->Apply(Tmp);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000497}
498
Jim Laskey86cbdba2006-02-06 15:33:21 +0000499/// TypeString - Return a string used to compose globalnames and labels.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000500///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000501const char *SubprogramDesc::TypeString() const {
502 return "subprogram";
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000503}
504
Jim Laskey86cbdba2006-02-06 15:33:21 +0000505#ifndef NDEBUG
506void SubprogramDesc::dump() {
507 std::cerr << TypeString() << " "
508 << "Tag(" << getTag() << "), "
509 << "Name(\"" << Name << "\"), "
510 << "Type(" << TyDesc << "), "
511 << "IsStatic(" << (IsStatic ? "true" : "false") << "), "
512 << "IsDefinition(" << (IsDefinition ? "true" : "false") << ")\n";
513}
514#endif
515
516//===----------------------------------------------------------------------===//
517
518DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
519 return Deserialize(cast<GlobalVariable>(V));
520}
521DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
522 // Check to see if it has been already deserialized.
523 DebugInfoDesc *&Slot = GlobalDescs[GV];
524 if (Slot) return Slot;
525
526 // Get the Tag from the global.
527 unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
528
529 // Get the debug version if a compile unit.
530 if (Tag == DI_TAG_compile_unit) {
531 DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
532 }
533
534 // Create an empty instance of the correct sort.
535 Slot = DebugInfoDesc::DescFactory(Tag);
536 assert(Slot && "Unknown Tag");
537
538 // Deserialize the fields.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000539 DIDeserializeVisitor DRAM(*this, GV);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000540 DRAM.ApplyToFields(Slot);
541
542 return Slot;
543}
544
545//===----------------------------------------------------------------------===//
546
547/// getStrPtrType - Return a "sbyte *" type.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000548///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000549const PointerType *DISerializer::getStrPtrType() {
550 // If not already defined.
551 if (!StrPtrTy) {
552 // Construct the pointer to signed bytes.
553 StrPtrTy = PointerType::get(Type::SByteTy);
554 }
555
556 return StrPtrTy;
557}
558
559/// getEmptyStructPtrType - Return a "{ }*" type.
560///
561const PointerType *DISerializer::getEmptyStructPtrType() {
562 // If not already defined.
563 if (!EmptyStructPtrTy) {
564 // Construct the empty structure type.
565 const StructType *EmptyStructTy =
566 StructType::get(std::vector<const Type*>());
567 // Construct the pointer to empty structure type.
568 EmptyStructPtrTy = PointerType::get(EmptyStructTy);
569 }
570
571 return EmptyStructPtrTy;
572}
573
574/// getTagType - Return the type describing the specified descriptor (via tag.)
575///
576const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
577 // Attempt to get the previously defined type.
578 StructType *&Ty = TagTypes[DD->getTag()];
579
580 // If not already defined.
581 if (!Ty) {
582 // Get descriptor type name.
583 const char *TS = DD->TypeString();
584
585 // Set up fields vector.
586 std::vector<const Type*> Fields;
587 // Add tag field.
588 Fields.push_back(Type::UIntTy);
589 // Get types of remaining fields.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000590 DIGetTypesVisitor GTAM(*this, Fields);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000591 GTAM.ApplyToFields(DD);
592
593 // Construct structured type.
594 Ty = StructType::get(Fields);
595
596 // Construct a name for the type.
597 const std::string Name = std::string("lldb.") + DD->TypeString() + ".type";
598
599 // Register type name with module.
600 M->addTypeName(Name, Ty);
601 }
602
603 return Ty;
604}
605
606/// getString - Construct the string as constant string global.
607///
608GlobalVariable *DISerializer::getString(const std::string &String) {
609 // Check string cache for previous edition.
610 GlobalVariable *&Slot = StringCache[String];
611 // return GlobalVariable if previously defined.
612 if (Slot) return Slot;
613 // Construct strings as an llvm constant.
614 Constant *ConstStr = ConstantArray::get(String);
615 // Otherwise create and return a new string global.
616 return Slot = new GlobalVariable(ConstStr->getType(), true,
617 GlobalVariable::InternalLinkage,
618 ConstStr, "str", M);
619}
620
621/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
622/// so that it can be serialized to a .bc or .ll file.
623GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
624 // Check if the DebugInfoDesc is already in the map.
625 GlobalVariable *&Slot = DescGlobals[DD];
626
627 // See if DebugInfoDesc exists, if so return prior GlobalVariable.
628 if (Slot) return Slot;
629
630 // Get DebugInfoDesc type Tag.
631 unsigned Tag = DD->getTag();
632
633 // Construct name.
634 const std::string Name = std::string("lldb.") +
635 DD->TypeString();
636
637 // Get the type associated with the Tag.
638 const StructType *Ty = getTagType(DD);
639
640 // Create the GlobalVariable early to prevent infinite recursion.
641 GlobalVariable *GV = new GlobalVariable(Ty, true,
642 GlobalValue::InternalLinkage,
643 NULL, Name, M);
644
645 // Insert new GlobalVariable in DescGlobals map.
646 Slot = GV;
647
648 // Set up elements vector
649 std::vector<Constant*> Elements;
650 // Add Tag value.
651 Elements.push_back(ConstantUInt::get(Type::UIntTy, Tag));
652 // Add remaining fields.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000653 DISerializeVisitor SRAM(*this, Elements);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000654 SRAM.ApplyToFields(DD);
655
656 // Set the globals initializer.
657 GV->setInitializer(ConstantStruct::get(Ty, Elements));
658
659 return GV;
660}
661
662//===----------------------------------------------------------------------===//
663
664/// markVisited - Return true if the GlobalVariable hase been "seen" before.
665/// Mark visited otherwise.
666bool DIVerifier::markVisited(GlobalVariable *GV) {
667 // Check if the GlobalVariable is already in the Visited set.
668 std::set<GlobalVariable *>::iterator VI = Visited.lower_bound(GV);
669
670 // See if GlobalVariable exists.
671 bool Exists = VI != Visited.end() && *VI == GV;
672
673 // Insert in set.
674 if (!Exists) Visited.insert(VI, GV);
675
676 return Exists;
677}
678
679/// Verify - Return true if the GlobalVariable appears to be a valid
680/// serialization of a DebugInfoDesc.
681bool DIVerifier::Verify(GlobalVariable *GV) {
682 // Check if seen before.
683 if (markVisited(GV)) return true;
684
685 // Get the Tag
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000686 unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
Jim Laskeyf60c2412006-02-06 21:54:05 +0000687 if (Tag == DIInvalid) return false;
Jim Laskey86cbdba2006-02-06 15:33:21 +0000688
689 // If a compile unit we need the debug version.
690 if (Tag == DI_TAG_compile_unit) {
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000691 DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
Jim Laskeyf60c2412006-02-06 21:54:05 +0000692 if (DebugVersion == DIInvalid) return false;
Jim Laskey86cbdba2006-02-06 15:33:21 +0000693 }
694
695 // Construct an empty DebugInfoDesc.
696 DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
697 if (!DD) return false;
698
699 // Get the initializer constant.
700 ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
701
702 // Get the operand count.
703 unsigned N = CI->getNumOperands();
704
705 // Get the field count.
706 unsigned &Slot = Counts[Tag];
707 if (!Slot) {
708 // Check the operand count to the field count
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000709 DICountVisitor CTAM;
Jim Laskey86cbdba2006-02-06 15:33:21 +0000710 CTAM.ApplyToFields(DD);
711 Slot = CTAM.getCount();
712 }
713
714 // Field count must equal operand count.
715 if (Slot != N) {
716 delete DD;
717 return false;
718 }
719
720 // Check each field for valid type.
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000721 DIVerifyVisitor VRAM(*this, GV);
Jim Laskey86cbdba2006-02-06 15:33:21 +0000722 VRAM.ApplyToFields(DD);
723
724 // Release empty DebugInfoDesc.
725 delete DD;
726
727 // Return result of field tests.
728 return VRAM.isValid();
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000729}
730
731//===----------------------------------------------------------------------===//
732
733
734MachineDebugInfo::MachineDebugInfo()
Jim Laskey86cbdba2006-02-06 15:33:21 +0000735: SR()
736, DR()
737, VR()
738, CompileUnits()
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000739, Directories()
740, SourceFiles()
741, Lines()
742{
743
744}
745MachineDebugInfo::~MachineDebugInfo() {
746
747}
748
Jim Laskeyb2efb852006-01-04 22:28:25 +0000749/// doInitialization - Initialize the debug state for a new module.
750///
751bool MachineDebugInfo::doInitialization() {
752 return false;
Jim Laskey6af56812006-01-04 13:36:38 +0000753}
754
Jim Laskeyb2efb852006-01-04 22:28:25 +0000755/// doFinalization - Tear down the debug state after completion of a module.
756///
757bool MachineDebugInfo::doFinalization() {
758 return false;
759}
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000760
761/// AnalyzeModule - Scan the module for global debug information.
762///
763void MachineDebugInfo::AnalyzeModule(Module &M) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000764 SR.setModule(&M);
765 DR.setModule(&M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000766 SetupCompileUnits(M);
767}
768
769/// SetupCompileUnits - Set up the unique vector of compile units.
770///
771void MachineDebugInfo::SetupCompileUnits(Module &M) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000772 SR.setModule(&M);
773 DR.setModule(&M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000774 // Get vector of all debug compile units.
775 std::vector<GlobalVariable*> Globals =
776 getGlobalVariablesUsing(M, "llvm.dbg.translation_units");
777
778 // Scan all compile unit globals.
779 for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000780 // Add compile unit to result.
781 CompileUnits.insert(
782 static_cast<CompileUnitDesc *>(DR.Deserialize(Globals[i])));
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000783 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000784}
785
Jim Laskey6e87c0e2006-01-26 21:22:49 +0000786/// getCompileUnits - Return a vector of debug compile units.
787///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000788const UniqueVector<CompileUnitDesc *> MachineDebugInfo::getCompileUnits()const{
Jim Laskey6e87c0e2006-01-26 21:22:49 +0000789 return CompileUnits;
790}
791
Jim Laskey86cbdba2006-02-06 15:33:21 +0000792/// getGlobalVariables - Return a vector of debug GlobalVariables.
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000793///
Jim Laskey86cbdba2006-02-06 15:33:21 +0000794std::vector<GlobalVariableDesc *>
795MachineDebugInfo::getGlobalVariables(Module &M) {
796 SR.setModule(&M);
797 DR.setModule(&M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000798 // Get vector of all debug global objects.
799 std::vector<GlobalVariable*> Globals =
800 getGlobalVariablesUsing(M, "llvm.dbg.globals");
801
Jim Laskey86cbdba2006-02-06 15:33:21 +0000802 // Accumulation of GlobalVariables.
803 std::vector<GlobalVariableDesc *> GlobalVariables;
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000804
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000805 // Scan all globals.
806 for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000807 GlobalVariable *GV = Globals[i];
Jim Laskeyc2f0c8d2006-02-06 19:12:02 +0000808 if (DebugInfoDesc::TagFromGlobal(GV) == DI_TAG_global_variable) {
Jim Laskey86cbdba2006-02-06 15:33:21 +0000809 GlobalVariableDesc *GVD =
810 static_cast<GlobalVariableDesc *>(DR.Deserialize(GV));
811 GlobalVariables.push_back(GVD);
812 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000813 }
Jim Laskeyb3e789a2006-01-26 20:21:46 +0000814
815 return GlobalVariables;
816}
817