Improve visibility/correctness of operand indices in "llvm.db" objects.
[oota-llvm.git] / lib / CodeGen / MachineDebugInfo.cpp
1 //===-- 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 //===----------------------------------------------------------------------===//
9
10 #include "llvm/CodeGen/MachineDebugInfo.h"
11
12 #include "llvm/Constants.h"
13 #include "llvm/DerivedTypes.h"
14 #include "llvm/Intrinsics.h"
15 #include "llvm/Instructions.h"
16 #include "llvm/Module.h"
17 #include "llvm/Support/Dwarf.h"
18
19 using namespace llvm;
20
21 // Handle the Pass registration stuff necessary to use TargetData's.
22 namespace {
23   RegisterPass<MachineDebugInfo> X("machinedebuginfo", "Debug Information");
24 }
25
26 //===----------------------------------------------------------------------===//
27
28 /// getGlobalVariablesUsing - Return all of the global variables which have the
29 /// specified value in their initializer somewhere.
30 static void
31 getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
32   // Scan though value users.
33   for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
34     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
35       // If the user is a global variable then add to result.
36       Result.push_back(GV);
37     } else if (Constant *C = dyn_cast<Constant>(*I)) {
38       // If the user is a constant variable then scan its users
39       getGlobalVariablesUsing(C, Result);
40     }
41   }
42 }
43
44 /// getGlobalVariablesUsing - Return all of the global variables that use the
45 /// named global variable.
46 static std::vector<GlobalVariable*>
47 getGlobalVariablesUsing(Module &M, const std::string &RootName) {
48   std::vector<GlobalVariable*> Result;  // Global variables matching criteria.
49
50   // Get the global variable root.
51   GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
52                                    StructType::get(std::vector<const Type*>()));
53
54   // If present and linkonce then scan for users.
55   if (UseRoot && UseRoot->hasLinkOnceLinkage()) {
56     getGlobalVariablesUsing(UseRoot, Result);
57   }
58   
59   return Result;
60 }
61   
62 /// getStringValue - Turn an LLVM constant pointer that eventually points to a
63 /// global into a string value.  Return an empty string if we can't do it.
64 ///
65 const static std::string getStringValue(Value *V, unsigned Offset = 0) {
66   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
67     if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
68       ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
69       if (Init->isString()) {
70         std::string Result = Init->getAsString();
71         if (Offset < Result.size()) {
72           // If we are pointing INTO The string, erase the beginning...
73           Result.erase(Result.begin(), Result.begin()+Offset);
74
75           // Take off the null terminator, and any string fragments after it.
76           std::string::size_type NullPos = Result.find_first_of((char)0);
77           if (NullPos != std::string::npos)
78             Result.erase(Result.begin()+NullPos, Result.end());
79           return Result;
80         }
81       }
82     }
83   } else if (Constant *C = dyn_cast<Constant>(V)) {
84     if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
85       return getStringValue(GV, Offset);
86     else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
87       if (CE->getOpcode() == Instruction::GetElementPtr) {
88         // Turn a gep into the specified offset.
89         if (CE->getNumOperands() == 3 &&
90             cast<Constant>(CE->getOperand(1))->isNullValue() &&
91             isa<ConstantInt>(CE->getOperand(2))) {
92           return getStringValue(CE->getOperand(0),
93                    Offset+cast<ConstantInt>(CE->getOperand(2))->getRawValue());
94         }
95       }
96     }
97   }
98   return "";
99 }
100
101 /// getGlobalValue - Return either a direct or cast Global value.
102 ///
103 static GlobalVariable *getGlobalValue(Value *V) {
104   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
105     return GV;
106   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
107     return CE->getOpcode() == Instruction::Cast ?  dyn_cast<GlobalVariable>(V)
108                                                 :  NULL;
109   }
110   return NULL;
111 }
112
113   
114 //===----------------------------------------------------------------------===//
115
116 DebugInfoWrapper::DebugInfoWrapper(GlobalVariable *G)
117 : GV(G)
118 , IC(dyn_cast<ConstantStruct>(GV->getInitializer())) {
119   assert(IC && "llvm.db.global is missing structured constant");
120 }
121   
122 //===----------------------------------------------------------------------===//
123
124 CompileUnitWrapper::CompileUnitWrapper(GlobalVariable *G)
125 : DebugInfoWrapper(G)
126 {
127   // FIXME - should probably ease up on the number of operands (version.)
128   assert(IC->getNumOperands() == N_op &&
129          "Compile unit does not have correct number of operands");
130 }
131
132 /// getTag - Return the compile unit's tag number.  Currently should be 
133 /// DW_TAG_variable.
134 unsigned CompileUnitWrapper::getTag() const {
135   return cast<ConstantUInt>(IC->getOperand(Tag_op))->getValue();
136 }
137
138 /// isCorrectDebugVersion - Return true if is the correct llvm debug version.
139 /// Currently the value is 0 (zero.)  If the value is is not correct then
140 /// ignore all debug information.
141 bool CompileUnitWrapper::isCorrectDebugVersion() const {
142   return cast<ConstantUInt>(IC->getOperand(Version_op))->getValue();
143 }
144
145 /// getLanguage - Return the compile unit's language number (ex. DW_LANG_C89.)
146 ///
147 unsigned CompileUnitWrapper::getLanguage() const {
148   return cast<ConstantUInt>(IC->getOperand(Language_op))->getValue();
149 }
150
151 /// getFileName - Return the compile unit's file name.
152 ///
153 const std::string CompileUnitWrapper::getFileName() const {
154   return getStringValue(IC->getOperand(FileName_op));
155 }
156
157 /// getDirectory - Return the compile unit's file directory.
158 ///
159 const std::string CompileUnitWrapper::getDirectory() const {
160   return getStringValue(IC->getOperand(Directory_op));
161 }
162   
163 /// getProducer - Return the compile unit's generator name.
164 ///
165 const std::string CompileUnitWrapper::getProducer() const {
166   return getStringValue(IC->getOperand(Producer_op));
167 }
168
169 //===----------------------------------------------------------------------===//
170
171 GlobalWrapper::GlobalWrapper(GlobalVariable *G)
172 : DebugInfoWrapper(G)
173 {
174   // FIXME - should probably ease up on the number of operands (version.)
175   assert(IC->getNumOperands() == N_op &&
176          "Global does not have correct number of operands");
177 }
178
179 /// getTag - Return the global's tag number.  Currently should be 
180 /// DW_TAG_variable or DW_TAG_subprogram.
181 unsigned GlobalWrapper::getTag() const {
182   return cast<ConstantUInt>(IC->getOperand(Tag_op))->getValue();
183 }
184
185 /// getContext - Return the "lldb.compile_unit" context global.
186 ///
187 GlobalVariable *GlobalWrapper::getContext() const {
188   return getGlobalValue(IC->getOperand(Context_op));
189 }
190
191 /// getName - Return the name of the global.
192 ///
193 const std::string GlobalWrapper::getName() const {
194   return getStringValue(IC->getOperand(Name_op));
195 }
196
197 /// getType - Return the type of the global.
198 ///
199 const GlobalVariable *GlobalWrapper::getType() const {
200   return getGlobalValue(IC->getOperand(Type_op));
201 }
202
203 /// isStatic - Return true if the global is static.
204 ///
205 bool GlobalWrapper::isStatic() const {
206   return cast<ConstantBool>(IC->getOperand(Static_op))->getValue();
207 }
208
209 /// isDefinition - Return true if the global is a definition.
210 ///
211 bool GlobalWrapper::isDefinition() const {
212   return dyn_cast<ConstantBool>(IC->getOperand(Definition_op))->getValue();
213 }
214
215 /// getGlobalVariable - Return the global variable (tag == DW_TAG_variable.)
216 ///
217 GlobalVariable *GlobalWrapper::getGlobalVariable() const {
218   return getGlobalValue(IC->getOperand(GlobalVariable_op));
219 }
220
221 //===----------------------------------------------------------------------===//
222
223
224 MachineDebugInfo::MachineDebugInfo()
225 : CompileUnits()
226 , Directories()
227 , SourceFiles()
228 , Lines()
229 {
230   
231 }
232 MachineDebugInfo::~MachineDebugInfo() {
233
234 }
235
236 /// doInitialization - Initialize the debug state for a new module.
237 ///
238 bool MachineDebugInfo::doInitialization() {
239   return false;
240 }
241
242 /// doFinalization - Tear down the debug state after completion of a module.
243 ///
244 bool MachineDebugInfo::doFinalization() {
245   return false;
246 }
247
248 /// AnalyzeModule - Scan the module for global debug information.
249 ///
250 void MachineDebugInfo::AnalyzeModule(Module &M) {
251   SetupCompileUnits(M);
252 }
253
254 /// SetupCompileUnits - Set up the unique vector of compile units.
255 ///
256 void MachineDebugInfo::SetupCompileUnits(Module &M) {
257   // Get vector of all debug compile units.
258   std::vector<GlobalVariable*> Globals =
259                        getGlobalVariablesUsing(M, "llvm.dbg.translation_units");
260   
261   // Scan all compile unit globals.
262   for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
263     // Create wrapper for compile unit.
264     CompileUnitWrapper CUI(Globals[i]);
265     // Add to result.
266     if (CUI.isCorrectDebugVersion()) CompileUnits.insert(CUI);
267   }
268   
269   // If there any bad compile units then suppress debug information
270   if (CompileUnits.size() != Globals.size()) CompileUnits.reset();
271 }
272
273 /// getCompileUnits - Return a vector of debug compile units.
274 ///
275 const UniqueVector<CompileUnitWrapper> MachineDebugInfo::getCompileUnits()const{
276   return CompileUnits;
277 }
278
279 /// getGlobalVariables - Return a vector of debug global variables.
280 ///
281 std::vector<GlobalWrapper> MachineDebugInfo::getGlobalVariables(Module &M) {
282   // Get vector of all debug global objects.
283   std::vector<GlobalVariable*> Globals =
284                                  getGlobalVariablesUsing(M, "llvm.dbg.globals");
285   
286   // Accumulation of global variables.
287   std::vector<GlobalWrapper> GlobalVariables;
288
289 // FIXME - skip until globals have new format
290 #if 0
291   // Scan all globals.
292   for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
293     // Create wrapper for global.
294     GlobalWrapper GW(Globals[i]);
295     // If the global is a variable then add to result.
296     if (GW.getTag() == DW_TAG_variable) GlobalVariables.push_back(GW);
297   }
298 #endif
299
300   return GlobalVariables;
301 }
302