blob: 0a33d5adbf06af86af285e7af390945a4bcf2cdf [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Symbol/SymbolContext.h"
11#include "lldb/Symbol/CompileUnit.h"
12#include "lldb/Core/Module.h"
13#include "lldb/Symbol/ObjectFile.h"
14#include "lldb/Symbol/Symbol.h"
15#include "lldb/Target/Target.h"
16#include "lldb/Symbol/SymbolVendor.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21SymbolContext::SymbolContext() :
22 target_sp (),
23 module_sp (),
24 comp_unit (NULL),
25 function (NULL),
26 block (NULL),
27 line_entry (),
28 symbol (NULL)
29{
30}
31
32SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
33 target_sp (),
34 module_sp (m),
35 comp_unit (cu),
36 function (f),
37 block (b),
38 line_entry (),
39 symbol (s)
40{
41 if (le)
42 line_entry = *le;
43}
44
45SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
46 target_sp (t),
47 module_sp (m),
48 comp_unit (cu),
49 function (f),
50 block (b),
51 line_entry (),
52 symbol (s)
53{
54 if (le)
55 line_entry = *le;
56}
57
58SymbolContext::SymbolContext(const SymbolContext& rhs) :
59 target_sp (rhs.target_sp),
60 module_sp (rhs.module_sp),
61 comp_unit (rhs.comp_unit),
62 function (rhs.function),
63 block (rhs.block),
64 line_entry (rhs.line_entry),
65 symbol (rhs.symbol)
66{
67}
68
69
70SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
71 target_sp (),
72 module_sp (),
73 comp_unit (NULL),
74 function (NULL),
75 block (NULL),
76 line_entry (),
77 symbol (NULL)
78{
79 sc_scope->CalculateSymbolContext (this);
80}
81
82const SymbolContext&
83SymbolContext::operator= (const SymbolContext& rhs)
84{
85 if (this != &rhs)
86 {
87 target_sp = rhs.target_sp;
88 module_sp = rhs.module_sp;
89 comp_unit = rhs.comp_unit;
90 function = rhs.function;
91 block = rhs.block;
92 line_entry = rhs.line_entry;
93 symbol = rhs.symbol;
94 }
95 return *this;
96}
97
98void
99SymbolContext::Clear()
100{
101 target_sp.reset();
102 module_sp.reset();
103 comp_unit = NULL;
104 function = NULL;
105 block = NULL;
106 line_entry.Clear();
107 symbol = NULL;
108}
109
110void
111SymbolContext::DumpStopContext
112(
113 Stream *s,
114 ExecutionContextScope *exe_scope,
115 const Address &addr,
116 bool show_module
117) const
118{
119 Process *process = NULL;
120 if (exe_scope)
121 process = exe_scope->CalculateProcess();
122 addr_t load_addr = addr.GetLoadAddress (process);
123
124 if (show_module && module_sp)
125 {
126 *s << module_sp->GetFileSpec().GetFilename() << '`';
127 }
128
129 if (function != NULL)
130 {
131 if (function->GetMangled().GetName())
132 function->GetMangled().GetName().Dump(s);
133
134 const addr_t func_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
135 if (load_addr > func_load_addr)
136 s->Printf(" + %llu", load_addr - func_load_addr);
137
138 if (block != NULL)
139 {
140 s->IndentMore();
141 block->DumpStopContext(s, this);
142 s->IndentLess();
143 }
144 else
145 {
146 if (line_entry.IsValid())
147 {
148 s->PutCString(" at ");
149 if (line_entry.DumpStopContext(s))
150 return;
151 }
152 }
153 }
154 else if (symbol != NULL)
155 {
156 symbol->GetMangled().GetName().Dump(s);
157
158 if (symbol->GetAddressRangePtr())
159 {
160 const addr_t sym_load_addr = symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(process);
161 if (load_addr > sym_load_addr)
162 s->Printf(" + %llu", load_addr - sym_load_addr);
163 }
164 }
165 else
166 {
167 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
168 }
169}
170
171void
172SymbolContext::Dump(Stream *s, Process *process) const
173{
174 *s << (void *)this << ": ";
175 s->Indent();
176 s->PutCString("SymbolContext");
177 s->IndentMore();
178 s->EOL();
179 s->IndentMore();
180 s->Indent();
181 *s << "Module = " << (void *)module_sp.get() << ' ';
182 if (module_sp)
183 module_sp->GetFileSpec().Dump(s);
184 s->EOL();
185 s->Indent();
186 *s << "CompileUnit = " << (void *)comp_unit;
187 if (comp_unit != NULL)
188 *s << " {" << comp_unit->GetID() << "} " << *(dynamic_cast<FileSpec*> (comp_unit));
189 s->EOL();
190 s->Indent();
191 *s << "Function = " << (void *)function;
192 if (function != NULL)
193 {
194 *s << " {" << function->GetID() << "} ";/// << function->GetType()->GetName();
195// Type* func_type = function->Type();
196// if (func_type)
197// {
198// s->EOL();
199// const UserDefType* func_udt = func_type->GetUserDefinedType().get();
200// if (func_udt)
201// {
202// s->IndentMore();
203// func_udt->Dump(s, func_type);
204// s->IndentLess();
205// }
206// }
207 }
208 s->EOL();
209 s->Indent();
210 *s << "Block = " << (void *)block;
211 if (block != NULL)
212 *s << " {" << block->GetID() << '}';
213 // Dump the block and pass it a negative depth to we print all the parent blocks
214 //if (block != NULL)
215 // block->Dump(s, function->GetFileAddress(), INT_MIN);
216 s->EOL();
217 s->Indent();
218 *s << "LineEntry = ";
219 line_entry.Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
220 s->EOL();
221 s->Indent();
222 *s << "Symbol = " << (void *)symbol;
223 if (symbol != NULL && symbol->GetMangled())
224 *s << ' ' << symbol->GetMangled().GetName().AsCString();
225 s->EOL();
226 s->IndentLess();
227 s->IndentLess();
228}
229
230bool
231lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
232{
233 return lhs.target_sp.get() == rhs.target_sp.get() &&
234 lhs.module_sp.get() == rhs.module_sp.get() &&
235 lhs.comp_unit == rhs.comp_unit &&
236 lhs.function == rhs.function &&
237 LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
238 lhs.symbol == rhs.symbol;
239}
240
241bool
242lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
243{
244 return lhs.target_sp.get() != rhs.target_sp.get() ||
245 lhs.module_sp.get() != rhs.module_sp.get() ||
246 lhs.comp_unit != rhs.comp_unit ||
247 lhs.function != rhs.function ||
248 LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
249 lhs.symbol != rhs.symbol;
250}
251
252bool
253SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
254{
255 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
256 {
257 range = line_entry.range;
258 return true;
259 }
260 else if ((scope & eSymbolContextFunction) && function != NULL)
261 {
262 range = function->GetAddressRange();
263 return true;
264 }
265 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
266 {
267 range = *symbol->GetAddressRangePtr();
268
269 if (range.GetByteSize() == 0)
270 {
271 if (module_sp)
272 {
273 ObjectFile *objfile = module_sp->GetObjectFile();
274 if (objfile)
275 {
276 Symtab *symtab = objfile->GetSymtab();
277 if (symtab)
278 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
279 }
280 }
281 }
282 return true;
283 }
284 range.Clear();
285 return false;
286}
287
288
289Function *
290SymbolContext::FindFunctionByName (const char *name) const
291{
292 ConstString name_const_str (name);
293 if (function != NULL)
294 {
295 // FIXME: Look in the class of the current function, if it exists,
296 // for methods matching name.
297 }
298
299 //
300 if (comp_unit != NULL)
301 {
302 // Make sure we've read in all the functions. We should be able to check and see
303 // if there's one by this name present before we do this...
304 module_sp->GetSymbolVendor()->ParseCompileUnitFunctions(*this);
305 uint32_t func_idx;
306 lldb::FunctionSP func_sp;
307 for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
308 {
309 if (func_sp->GetMangled().GetName() == name_const_str)
310 return func_sp.get();
311 }
312 }
313 if (module_sp != NULL)
314 {
315 SymbolContextList sc_matches;
316 if (module_sp->FindFunctions (name_const_str, false, sc_matches) > 0)
317 {
318 SymbolContext sc;
319 sc_matches.GetContextAtIndex (0, sc);
320 return sc.function;
321 }
322 }
323
324 if (target_sp)
325 {
326 SymbolContextList sc_matches;
327 if (target_sp->GetImages().FindFunctions (name_const_str, sc_matches) > 0)
328 {
329 SymbolContext sc;
330 sc_matches.GetContextAtIndex (0, sc);
331 return sc.function;
332 }
333 }
334
335 return NULL;
336}
337
338lldb::VariableSP
339SymbolContext::FindVariableByName (const char *name) const
340{
341 lldb::VariableSP return_value;
342 return return_value;
343}
344
345lldb::TypeSP
346SymbolContext::FindTypeByName (const char *name) const
347{
348 lldb::TypeSP return_value;
349 return return_value;
350}
351
352//----------------------------------------------------------------------
353//
354// SymbolContextList
355//
356//----------------------------------------------------------------------
357
358
359SymbolContextList::SymbolContextList() :
360 m_symbol_contexts()
361{
362}
363
364SymbolContextList::~SymbolContextList()
365{
366}
367
368void
369SymbolContextList::Append(const SymbolContext& sc)
370{
371 m_symbol_contexts.push_back(sc);
372}
373
374void
375SymbolContextList::Clear()
376{
377 m_symbol_contexts.clear();
378}
379
380void
381SymbolContextList::Dump(Stream *s, Process *process) const
382{
383
384 *s << (void *)this << ": ";
385 s->Indent();
386 s->PutCString("SymbolContextList");
387 s->EOL();
388 s->IndentMore();
389
390 collection::const_iterator pos, end = m_symbol_contexts.end();
391 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
392 {
393 pos->Dump(s, process);
394 }
395 s->IndentLess();
396}
397
398bool
399SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
400{
401 if (idx < m_symbol_contexts.size())
402 {
403 sc = m_symbol_contexts[idx];
404 return true;
405 }
406 return false;
407}
408
409bool
410SymbolContextList::RemoveContextAtIndex (uint32_t idx)
411{
412 if (idx < m_symbol_contexts.size())
413 {
414 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
415 return true;
416 }
417 return false;
418}
419
420uint32_t
421SymbolContextList::GetSize() const
422{
423 return m_symbol_contexts.size();
424}