blob: d70976c5cd4d954d94a70b0c6fd13df159770247 [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"
Greg Clayton12bec712010-06-28 21:30:43 +000011
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "lldb/Core/Module.h"
Greg Clayton12bec712010-06-28 21:30:43 +000013#include "lldb/Symbol/CompileUnit.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "lldb/Symbol/ObjectFile.h"
15#include "lldb/Symbol/Symbol.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton12bec712010-06-28 21:30:43 +000017#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018
19using namespace lldb;
20using namespace lldb_private;
21
22SymbolContext::SymbolContext() :
23 target_sp (),
24 module_sp (),
25 comp_unit (NULL),
26 function (NULL),
27 block (NULL),
28 line_entry (),
29 symbol (NULL)
30{
31}
32
33SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
34 target_sp (),
35 module_sp (m),
36 comp_unit (cu),
37 function (f),
38 block (b),
39 line_entry (),
40 symbol (s)
41{
42 if (le)
43 line_entry = *le;
44}
45
46SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
47 target_sp (t),
48 module_sp (m),
49 comp_unit (cu),
50 function (f),
51 block (b),
52 line_entry (),
53 symbol (s)
54{
55 if (le)
56 line_entry = *le;
57}
58
59SymbolContext::SymbolContext(const SymbolContext& rhs) :
60 target_sp (rhs.target_sp),
61 module_sp (rhs.module_sp),
62 comp_unit (rhs.comp_unit),
63 function (rhs.function),
64 block (rhs.block),
65 line_entry (rhs.line_entry),
66 symbol (rhs.symbol)
67{
68}
69
70
71SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
72 target_sp (),
73 module_sp (),
74 comp_unit (NULL),
75 function (NULL),
76 block (NULL),
77 line_entry (),
78 symbol (NULL)
79{
80 sc_scope->CalculateSymbolContext (this);
81}
82
83const SymbolContext&
84SymbolContext::operator= (const SymbolContext& rhs)
85{
86 if (this != &rhs)
87 {
88 target_sp = rhs.target_sp;
89 module_sp = rhs.module_sp;
90 comp_unit = rhs.comp_unit;
91 function = rhs.function;
92 block = rhs.block;
93 line_entry = rhs.line_entry;
94 symbol = rhs.symbol;
95 }
96 return *this;
97}
98
99void
100SymbolContext::Clear()
101{
102 target_sp.reset();
103 module_sp.reset();
104 comp_unit = NULL;
105 function = NULL;
106 block = NULL;
107 line_entry.Clear();
108 symbol = NULL;
109}
110
111void
112SymbolContext::DumpStopContext
113(
114 Stream *s,
115 ExecutionContextScope *exe_scope,
116 const Address &addr,
Greg Clayton72b71582010-09-02 21:44:10 +0000117 bool show_fullpaths,
Greg Clayton33ed1702010-08-24 00:45:41 +0000118 bool show_module,
119 bool show_inlined_frames
Chris Lattner24943d22010-06-08 16:52:24 +0000120) const
121{
Chris Lattner24943d22010-06-08 16:52:24 +0000122 if (show_module && module_sp)
123 {
Greg Clayton72b71582010-09-02 21:44:10 +0000124 if (show_fullpaths)
125 *s << module_sp->GetFileSpec();
126 else
127 *s << module_sp->GetFileSpec().GetFilename();
128 s->PutChar('`');
Chris Lattner24943d22010-06-08 16:52:24 +0000129 }
130
131 if (function != NULL)
132 {
133 if (function->GetMangled().GetName())
134 function->GetMangled().GetName().Dump(s);
135
Greg Clayton33ed1702010-08-24 00:45:41 +0000136 if (show_inlined_frames && block)
137 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000138 const InlineFunctionInfo *inline_info = block->GetInlinedFunctionInfo();
Greg Clayton33ed1702010-08-24 00:45:41 +0000139 if (inline_info == NULL)
140 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000141 const Block *parent_inline_block = block->GetInlinedParent();
Greg Clayton33ed1702010-08-24 00:45:41 +0000142 if (parent_inline_block)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000143 inline_info = parent_inline_block->GetInlinedFunctionInfo();
Greg Clayton33ed1702010-08-24 00:45:41 +0000144 }
145
146 if (inline_info)
147 {
148 s->PutCString(" [inlined] ");
149 inline_info->GetName().Dump(s);
150
151 if (line_entry.IsValid())
152 {
153 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000154 line_entry.DumpStopContext(s, show_fullpaths);
Greg Clayton33ed1702010-08-24 00:45:41 +0000155 }
156 return;
157 }
158 }
Greg Clayton70436352010-06-30 23:03:03 +0000159 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
160 if (function_offset)
161 s->Printf(" + %llu", function_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000162
163 if (block != NULL)
164 {
165 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000166 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000167 s->IndentLess();
168 }
169 else
170 {
171 if (line_entry.IsValid())
172 {
173 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000174 if (line_entry.DumpStopContext(s, show_fullpaths))
Chris Lattner24943d22010-06-08 16:52:24 +0000175 return;
176 }
177 }
178 }
179 else if (symbol != NULL)
180 {
181 symbol->GetMangled().GetName().Dump(s);
182
183 if (symbol->GetAddressRangePtr())
184 {
Greg Clayton70436352010-06-30 23:03:03 +0000185 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
186 if (symbol_offset)
187 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000188 }
189 }
190 else
191 {
192 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
193 }
194}
195
196void
Greg Clayton12bec712010-06-28 21:30:43 +0000197SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Process *process) const
198{
199 if (module_sp)
200 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000201 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000202 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000203 *s << '"';
204 if (module_sp->GetArchitecture().IsValid())
205 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().AsCString());
Greg Clayton12bec712010-06-28 21:30:43 +0000206 s->EOL();
207 }
208
209 if (comp_unit != NULL)
210 {
211 s->Indent("CompileUnit: ");
212 comp_unit->GetDescription (s, level);
213 s->EOL();
214 }
215
216 if (function != NULL)
217 {
218 s->Indent(" Function: ");
219 function->GetDescription (s, level, process);
220 s->EOL();
221
222 Type *func_type = function->GetType();
223 if (func_type)
224 {
225 s->Indent(" FuncType: ");
226 func_type->GetDescription (s, level, false);
227 s->EOL();
228 }
229 }
230
231 if (block != NULL)
232 {
233 std::vector<Block *> blocks;
234 blocks.push_back (block);
235 Block *parent_block = block->GetParent();
236
237 while (parent_block)
238 {
239 blocks.push_back (parent_block);
240 parent_block = parent_block->GetParent();
241 }
242 std::vector<Block *>::reverse_iterator pos;
243 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
244 std::vector<Block *>::reverse_iterator end = blocks.rend();
245 for (pos = begin; pos != end; ++pos)
246 {
247 if (pos == begin)
248 s->Indent(" Blocks: ");
249 else
250 s->Indent(" ");
Greg Clayton75ccf502010-08-21 02:22:51 +0000251 (*pos)->GetDescription(s, function, level, process);
Greg Clayton12bec712010-06-28 21:30:43 +0000252 s->EOL();
253 }
254 }
255
256 if (line_entry.IsValid())
257 {
258 s->Indent(" LineEntry: ");
259 line_entry.GetDescription (s, level, comp_unit, process, false);
260 s->EOL();
261 }
262
263 if (symbol != NULL)
264 {
265 s->Indent(" Symbol: ");
266 symbol->GetDescription(s, level, process);
267 s->EOL();
268 }
269}
270
Greg Clayton33ed1702010-08-24 00:45:41 +0000271uint32_t
272SymbolContext::GetResolvedMask () const
273{
274 uint32_t resolved_mask = 0;
275 if (target_sp) resolved_mask |= eSymbolContextTarget;
276 if (module_sp) resolved_mask |= eSymbolContextModule;
277 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
278 if (function) resolved_mask |= eSymbolContextFunction;
279 if (block) resolved_mask |= eSymbolContextBlock;
280 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
281 if (symbol) resolved_mask |= eSymbolContextSymbol;
282 return resolved_mask;
283}
Greg Clayton12bec712010-06-28 21:30:43 +0000284
285
286void
Chris Lattner24943d22010-06-08 16:52:24 +0000287SymbolContext::Dump(Stream *s, Process *process) const
288{
289 *s << (void *)this << ": ";
290 s->Indent();
291 s->PutCString("SymbolContext");
292 s->IndentMore();
293 s->EOL();
294 s->IndentMore();
295 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000296 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000297 if (module_sp)
298 module_sp->GetFileSpec().Dump(s);
299 s->EOL();
300 s->Indent();
301 *s << "CompileUnit = " << (void *)comp_unit;
302 if (comp_unit != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000303 *s << " {0x" << comp_unit->GetID() << "} " << *(dynamic_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000304 s->EOL();
305 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000306 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000307 if (function != NULL)
308 {
Greg Clayton12bec712010-06-28 21:30:43 +0000309 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
310 function->GetAddressRange().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
311 s->EOL();
312 s->Indent();
313 Type* func_type = function->GetType();
314 if (func_type)
315 {
316 *s << " Type = ";
317 func_type->Dump (s, false);
318 }
Chris Lattner24943d22010-06-08 16:52:24 +0000319 }
320 s->EOL();
321 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000322 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000323 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000324 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000325 // Dump the block and pass it a negative depth to we print all the parent blocks
326 //if (block != NULL)
327 // block->Dump(s, function->GetFileAddress(), INT_MIN);
328 s->EOL();
329 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000330 *s << "LineEntry = ";
Chris Lattner24943d22010-06-08 16:52:24 +0000331 line_entry.Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
332 s->EOL();
333 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000334 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000335 if (symbol != NULL && symbol->GetMangled())
336 *s << ' ' << symbol->GetMangled().GetName().AsCString();
337 s->EOL();
338 s->IndentLess();
339 s->IndentLess();
340}
341
342bool
343lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
344{
345 return lhs.target_sp.get() == rhs.target_sp.get() &&
346 lhs.module_sp.get() == rhs.module_sp.get() &&
347 lhs.comp_unit == rhs.comp_unit &&
348 lhs.function == rhs.function &&
349 LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
350 lhs.symbol == rhs.symbol;
351}
352
353bool
354lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
355{
356 return lhs.target_sp.get() != rhs.target_sp.get() ||
357 lhs.module_sp.get() != rhs.module_sp.get() ||
358 lhs.comp_unit != rhs.comp_unit ||
359 lhs.function != rhs.function ||
360 LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
361 lhs.symbol != rhs.symbol;
362}
363
364bool
365SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
366{
367 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
368 {
369 range = line_entry.range;
370 return true;
371 }
372 else if ((scope & eSymbolContextFunction) && function != NULL)
373 {
374 range = function->GetAddressRange();
375 return true;
376 }
377 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
378 {
379 range = *symbol->GetAddressRangePtr();
380
381 if (range.GetByteSize() == 0)
382 {
383 if (module_sp)
384 {
385 ObjectFile *objfile = module_sp->GetObjectFile();
386 if (objfile)
387 {
388 Symtab *symtab = objfile->GetSymtab();
389 if (symtab)
390 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
391 }
392 }
393 }
394 return true;
395 }
396 range.Clear();
397 return false;
398}
399
400
Sean Callanan0fc73582010-07-27 00:55:47 +0000401size_t
402SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const
403{
404 if (!append)
405 sc_list.Clear();
406
Chris Lattner24943d22010-06-08 16:52:24 +0000407 if (function != NULL)
408 {
409 // FIXME: Look in the class of the current function, if it exists,
410 // for methods matching name.
411 }
412
Chris Lattner24943d22010-06-08 16:52:24 +0000413 if (comp_unit != NULL)
414 {
415 // Make sure we've read in all the functions. We should be able to check and see
416 // if there's one by this name present before we do this...
417 module_sp->GetSymbolVendor()->ParseCompileUnitFunctions(*this);
418 uint32_t func_idx;
419 lldb::FunctionSP func_sp;
420 for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
421 {
Sean Callanan0fc73582010-07-27 00:55:47 +0000422 if (func_sp->GetMangled().GetName() == name)
423 {
424 SymbolContext sym_ctx(target_sp,
425 module_sp,
426 comp_unit,
427 func_sp.get());
428 sc_list.Append(sym_ctx);
429 }
Chris Lattner24943d22010-06-08 16:52:24 +0000430 }
431 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000432
Chris Lattner24943d22010-06-08 16:52:24 +0000433 if (module_sp != NULL)
Sean Callanan0fc73582010-07-27 00:55:47 +0000434 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000435
436 if (target_sp)
Sean Callanan0fc73582010-07-27 00:55:47 +0000437 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000438
Sean Callanan0fc73582010-07-27 00:55:47 +0000439 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000440}
441
442lldb::VariableSP
443SymbolContext::FindVariableByName (const char *name) const
444{
445 lldb::VariableSP return_value;
446 return return_value;
447}
448
449lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000450SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000451{
452 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000453
454 TypeList types;
455
456 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
457 return types.GetTypeAtIndex(0);
458
459 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
460 return types.GetTypeAtIndex(0);
461
Chris Lattner24943d22010-06-08 16:52:24 +0000462 return return_value;
463}
464
465//----------------------------------------------------------------------
466//
467// SymbolContextList
468//
469//----------------------------------------------------------------------
470
471
472SymbolContextList::SymbolContextList() :
473 m_symbol_contexts()
474{
475}
476
477SymbolContextList::~SymbolContextList()
478{
479}
480
481void
482SymbolContextList::Append(const SymbolContext& sc)
483{
484 m_symbol_contexts.push_back(sc);
485}
486
487void
488SymbolContextList::Clear()
489{
490 m_symbol_contexts.clear();
491}
492
493void
494SymbolContextList::Dump(Stream *s, Process *process) const
495{
496
497 *s << (void *)this << ": ";
498 s->Indent();
499 s->PutCString("SymbolContextList");
500 s->EOL();
501 s->IndentMore();
502
503 collection::const_iterator pos, end = m_symbol_contexts.end();
504 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
505 {
506 pos->Dump(s, process);
507 }
508 s->IndentLess();
509}
510
511bool
512SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
513{
514 if (idx < m_symbol_contexts.size())
515 {
516 sc = m_symbol_contexts[idx];
517 return true;
518 }
519 return false;
520}
521
522bool
523SymbolContextList::RemoveContextAtIndex (uint32_t idx)
524{
525 if (idx < m_symbol_contexts.size())
526 {
527 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
528 return true;
529 }
530 return false;
531}
532
533uint32_t
534SymbolContextList::GetSize() const
535{
536 return m_symbol_contexts.size();
537}