blob: f54d85681e3e3c5951cbd206bfe7d6b0d0f50a10 [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 Claytonb04e7a82010-08-24 21:05:24 +0000138 const InlineFunctionInfo *inline_info = block->InlinedFunctionInfo();
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)
143 inline_info = parent_inline_block->InlinedFunctionInfo();
144 }
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 Clayton72b71582010-09-02 21:44:10 +0000166 block->DumpStopContext(s, this, show_fullpaths);
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 {
201 s->Indent(" Module: \"");
202 module_sp->GetFileSpec().Dump(s);
203 s->PutChar('"');
204 s->EOL();
205 }
206
207 if (comp_unit != NULL)
208 {
209 s->Indent("CompileUnit: ");
210 comp_unit->GetDescription (s, level);
211 s->EOL();
212 }
213
214 if (function != NULL)
215 {
216 s->Indent(" Function: ");
217 function->GetDescription (s, level, process);
218 s->EOL();
219
220 Type *func_type = function->GetType();
221 if (func_type)
222 {
223 s->Indent(" FuncType: ");
224 func_type->GetDescription (s, level, false);
225 s->EOL();
226 }
227 }
228
229 if (block != NULL)
230 {
231 std::vector<Block *> blocks;
232 blocks.push_back (block);
233 Block *parent_block = block->GetParent();
234
235 while (parent_block)
236 {
237 blocks.push_back (parent_block);
238 parent_block = parent_block->GetParent();
239 }
240 std::vector<Block *>::reverse_iterator pos;
241 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
242 std::vector<Block *>::reverse_iterator end = blocks.rend();
243 for (pos = begin; pos != end; ++pos)
244 {
245 if (pos == begin)
246 s->Indent(" Blocks: ");
247 else
248 s->Indent(" ");
Greg Clayton75ccf502010-08-21 02:22:51 +0000249 (*pos)->GetDescription(s, function, level, process);
Greg Clayton12bec712010-06-28 21:30:43 +0000250 s->EOL();
251 }
252 }
253
254 if (line_entry.IsValid())
255 {
256 s->Indent(" LineEntry: ");
257 line_entry.GetDescription (s, level, comp_unit, process, false);
258 s->EOL();
259 }
260
261 if (symbol != NULL)
262 {
263 s->Indent(" Symbol: ");
264 symbol->GetDescription(s, level, process);
265 s->EOL();
266 }
267}
268
Greg Clayton33ed1702010-08-24 00:45:41 +0000269uint32_t
270SymbolContext::GetResolvedMask () const
271{
272 uint32_t resolved_mask = 0;
273 if (target_sp) resolved_mask |= eSymbolContextTarget;
274 if (module_sp) resolved_mask |= eSymbolContextModule;
275 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
276 if (function) resolved_mask |= eSymbolContextFunction;
277 if (block) resolved_mask |= eSymbolContextBlock;
278 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
279 if (symbol) resolved_mask |= eSymbolContextSymbol;
280 return resolved_mask;
281}
Greg Clayton12bec712010-06-28 21:30:43 +0000282
283
284void
Chris Lattner24943d22010-06-08 16:52:24 +0000285SymbolContext::Dump(Stream *s, Process *process) const
286{
287 *s << (void *)this << ": ";
288 s->Indent();
289 s->PutCString("SymbolContext");
290 s->IndentMore();
291 s->EOL();
292 s->IndentMore();
293 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000294 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000295 if (module_sp)
296 module_sp->GetFileSpec().Dump(s);
297 s->EOL();
298 s->Indent();
299 *s << "CompileUnit = " << (void *)comp_unit;
300 if (comp_unit != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000301 *s << " {0x" << comp_unit->GetID() << "} " << *(dynamic_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000302 s->EOL();
303 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000304 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000305 if (function != NULL)
306 {
Greg Clayton12bec712010-06-28 21:30:43 +0000307 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
308 function->GetAddressRange().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
309 s->EOL();
310 s->Indent();
311 Type* func_type = function->GetType();
312 if (func_type)
313 {
314 *s << " Type = ";
315 func_type->Dump (s, false);
316 }
Chris Lattner24943d22010-06-08 16:52:24 +0000317 }
318 s->EOL();
319 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000320 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000321 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000322 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000323 // Dump the block and pass it a negative depth to we print all the parent blocks
324 //if (block != NULL)
325 // block->Dump(s, function->GetFileAddress(), INT_MIN);
326 s->EOL();
327 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000328 *s << "LineEntry = ";
Chris Lattner24943d22010-06-08 16:52:24 +0000329 line_entry.Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
330 s->EOL();
331 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000332 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000333 if (symbol != NULL && symbol->GetMangled())
334 *s << ' ' << symbol->GetMangled().GetName().AsCString();
335 s->EOL();
336 s->IndentLess();
337 s->IndentLess();
338}
339
340bool
341lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
342{
343 return lhs.target_sp.get() == rhs.target_sp.get() &&
344 lhs.module_sp.get() == rhs.module_sp.get() &&
345 lhs.comp_unit == rhs.comp_unit &&
346 lhs.function == rhs.function &&
347 LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
348 lhs.symbol == rhs.symbol;
349}
350
351bool
352lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
353{
354 return lhs.target_sp.get() != rhs.target_sp.get() ||
355 lhs.module_sp.get() != rhs.module_sp.get() ||
356 lhs.comp_unit != rhs.comp_unit ||
357 lhs.function != rhs.function ||
358 LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
359 lhs.symbol != rhs.symbol;
360}
361
362bool
363SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
364{
365 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
366 {
367 range = line_entry.range;
368 return true;
369 }
370 else if ((scope & eSymbolContextFunction) && function != NULL)
371 {
372 range = function->GetAddressRange();
373 return true;
374 }
375 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
376 {
377 range = *symbol->GetAddressRangePtr();
378
379 if (range.GetByteSize() == 0)
380 {
381 if (module_sp)
382 {
383 ObjectFile *objfile = module_sp->GetObjectFile();
384 if (objfile)
385 {
386 Symtab *symtab = objfile->GetSymtab();
387 if (symtab)
388 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
389 }
390 }
391 }
392 return true;
393 }
394 range.Clear();
395 return false;
396}
397
398
Sean Callanan0fc73582010-07-27 00:55:47 +0000399size_t
400SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const
401{
402 if (!append)
403 sc_list.Clear();
404
Chris Lattner24943d22010-06-08 16:52:24 +0000405 if (function != NULL)
406 {
407 // FIXME: Look in the class of the current function, if it exists,
408 // for methods matching name.
409 }
410
Chris Lattner24943d22010-06-08 16:52:24 +0000411 if (comp_unit != NULL)
412 {
413 // Make sure we've read in all the functions. We should be able to check and see
414 // if there's one by this name present before we do this...
415 module_sp->GetSymbolVendor()->ParseCompileUnitFunctions(*this);
416 uint32_t func_idx;
417 lldb::FunctionSP func_sp;
418 for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
419 {
Sean Callanan0fc73582010-07-27 00:55:47 +0000420 if (func_sp->GetMangled().GetName() == name)
421 {
422 SymbolContext sym_ctx(target_sp,
423 module_sp,
424 comp_unit,
425 func_sp.get());
426 sc_list.Append(sym_ctx);
427 }
Chris Lattner24943d22010-06-08 16:52:24 +0000428 }
429 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000430
Chris Lattner24943d22010-06-08 16:52:24 +0000431 if (module_sp != NULL)
Sean Callanan0fc73582010-07-27 00:55:47 +0000432 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000433
434 if (target_sp)
Sean Callanan0fc73582010-07-27 00:55:47 +0000435 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000436
Sean Callanan0fc73582010-07-27 00:55:47 +0000437 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000438}
439
440lldb::VariableSP
441SymbolContext::FindVariableByName (const char *name) const
442{
443 lldb::VariableSP return_value;
444 return return_value;
445}
446
447lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000448SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000449{
450 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000451
452 TypeList types;
453
454 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
455 return types.GetTypeAtIndex(0);
456
457 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
458 return types.GetTypeAtIndex(0);
459
Chris Lattner24943d22010-06-08 16:52:24 +0000460 return return_value;
461}
462
463//----------------------------------------------------------------------
464//
465// SymbolContextList
466//
467//----------------------------------------------------------------------
468
469
470SymbolContextList::SymbolContextList() :
471 m_symbol_contexts()
472{
473}
474
475SymbolContextList::~SymbolContextList()
476{
477}
478
479void
480SymbolContextList::Append(const SymbolContext& sc)
481{
482 m_symbol_contexts.push_back(sc);
483}
484
485void
486SymbolContextList::Clear()
487{
488 m_symbol_contexts.clear();
489}
490
491void
492SymbolContextList::Dump(Stream *s, Process *process) const
493{
494
495 *s << (void *)this << ": ";
496 s->Indent();
497 s->PutCString("SymbolContextList");
498 s->EOL();
499 s->IndentMore();
500
501 collection::const_iterator pos, end = m_symbol_contexts.end();
502 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
503 {
504 pos->Dump(s, process);
505 }
506 s->IndentLess();
507}
508
509bool
510SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
511{
512 if (idx < m_symbol_contexts.size())
513 {
514 sc = m_symbol_contexts[idx];
515 return true;
516 }
517 return false;
518}
519
520bool
521SymbolContextList::RemoveContextAtIndex (uint32_t idx)
522{
523 if (idx < m_symbol_contexts.size())
524 {
525 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
526 return true;
527 }
528 return false;
529}
530
531uint32_t
532SymbolContextList::GetSize() const
533{
534 return m_symbol_contexts.size();
535}