blob: db0bccb726e61801d8928caaa659ea0f66a2c5fb [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 Clayton33ed1702010-08-24 00:45:41 +0000117 bool show_module,
118 bool show_inlined_frames
Chris Lattner24943d22010-06-08 16:52:24 +0000119) const
120{
Chris Lattner24943d22010-06-08 16:52:24 +0000121 if (show_module && module_sp)
122 {
123 *s << module_sp->GetFileSpec().GetFilename() << '`';
124 }
125
126 if (function != NULL)
127 {
128 if (function->GetMangled().GetName())
129 function->GetMangled().GetName().Dump(s);
130
Greg Clayton33ed1702010-08-24 00:45:41 +0000131
132 if (show_inlined_frames && block)
133 {
134 InlineFunctionInfo *inline_info = block->InlinedFunctionInfo();
135 if (inline_info == NULL)
136 {
137 Block *parent_inline_block = block->GetInlinedParent();
138 if (parent_inline_block)
139 inline_info = parent_inline_block->InlinedFunctionInfo();
140 }
141
142 if (inline_info)
143 {
144 s->PutCString(" [inlined] ");
145 inline_info->GetName().Dump(s);
146
147 if (line_entry.IsValid())
148 {
149 s->PutCString(" at ");
150 line_entry.DumpStopContext(s);
151 }
152 return;
153 }
154 }
Greg Clayton70436352010-06-30 23:03:03 +0000155 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
156 if (function_offset)
157 s->Printf(" + %llu", function_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000158
159 if (block != NULL)
160 {
161 s->IndentMore();
162 block->DumpStopContext(s, this);
163 s->IndentLess();
164 }
165 else
166 {
167 if (line_entry.IsValid())
168 {
169 s->PutCString(" at ");
170 if (line_entry.DumpStopContext(s))
171 return;
172 }
173 }
174 }
175 else if (symbol != NULL)
176 {
177 symbol->GetMangled().GetName().Dump(s);
178
179 if (symbol->GetAddressRangePtr())
180 {
Greg Clayton70436352010-06-30 23:03:03 +0000181 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
182 if (symbol_offset)
183 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000184 }
185 }
186 else
187 {
188 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
189 }
190}
191
192void
Greg Clayton12bec712010-06-28 21:30:43 +0000193SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Process *process) const
194{
195 if (module_sp)
196 {
197 s->Indent(" Module: \"");
198 module_sp->GetFileSpec().Dump(s);
199 s->PutChar('"');
200 s->EOL();
201 }
202
203 if (comp_unit != NULL)
204 {
205 s->Indent("CompileUnit: ");
206 comp_unit->GetDescription (s, level);
207 s->EOL();
208 }
209
210 if (function != NULL)
211 {
212 s->Indent(" Function: ");
213 function->GetDescription (s, level, process);
214 s->EOL();
215
216 Type *func_type = function->GetType();
217 if (func_type)
218 {
219 s->Indent(" FuncType: ");
220 func_type->GetDescription (s, level, false);
221 s->EOL();
222 }
223 }
224
225 if (block != NULL)
226 {
227 std::vector<Block *> blocks;
228 blocks.push_back (block);
229 Block *parent_block = block->GetParent();
230
231 while (parent_block)
232 {
233 blocks.push_back (parent_block);
234 parent_block = parent_block->GetParent();
235 }
236 std::vector<Block *>::reverse_iterator pos;
237 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
238 std::vector<Block *>::reverse_iterator end = blocks.rend();
239 for (pos = begin; pos != end; ++pos)
240 {
241 if (pos == begin)
242 s->Indent(" Blocks: ");
243 else
244 s->Indent(" ");
Greg Clayton75ccf502010-08-21 02:22:51 +0000245 (*pos)->GetDescription(s, function, level, process);
Greg Clayton12bec712010-06-28 21:30:43 +0000246 s->EOL();
247 }
248 }
249
250 if (line_entry.IsValid())
251 {
252 s->Indent(" LineEntry: ");
253 line_entry.GetDescription (s, level, comp_unit, process, false);
254 s->EOL();
255 }
256
257 if (symbol != NULL)
258 {
259 s->Indent(" Symbol: ");
260 symbol->GetDescription(s, level, process);
261 s->EOL();
262 }
263}
264
Greg Clayton33ed1702010-08-24 00:45:41 +0000265uint32_t
266SymbolContext::GetResolvedMask () const
267{
268 uint32_t resolved_mask = 0;
269 if (target_sp) resolved_mask |= eSymbolContextTarget;
270 if (module_sp) resolved_mask |= eSymbolContextModule;
271 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
272 if (function) resolved_mask |= eSymbolContextFunction;
273 if (block) resolved_mask |= eSymbolContextBlock;
274 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
275 if (symbol) resolved_mask |= eSymbolContextSymbol;
276 return resolved_mask;
277}
Greg Clayton12bec712010-06-28 21:30:43 +0000278
279
280void
Chris Lattner24943d22010-06-08 16:52:24 +0000281SymbolContext::Dump(Stream *s, Process *process) const
282{
283 *s << (void *)this << ": ";
284 s->Indent();
285 s->PutCString("SymbolContext");
286 s->IndentMore();
287 s->EOL();
288 s->IndentMore();
289 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000290 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000291 if (module_sp)
292 module_sp->GetFileSpec().Dump(s);
293 s->EOL();
294 s->Indent();
295 *s << "CompileUnit = " << (void *)comp_unit;
296 if (comp_unit != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000297 *s << " {0x" << comp_unit->GetID() << "} " << *(dynamic_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000298 s->EOL();
299 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000300 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000301 if (function != NULL)
302 {
Greg Clayton12bec712010-06-28 21:30:43 +0000303 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
304 function->GetAddressRange().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
305 s->EOL();
306 s->Indent();
307 Type* func_type = function->GetType();
308 if (func_type)
309 {
310 *s << " Type = ";
311 func_type->Dump (s, false);
312 }
Chris Lattner24943d22010-06-08 16:52:24 +0000313 }
314 s->EOL();
315 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000316 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000317 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000318 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000319 // Dump the block and pass it a negative depth to we print all the parent blocks
320 //if (block != NULL)
321 // block->Dump(s, function->GetFileAddress(), INT_MIN);
322 s->EOL();
323 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000324 *s << "LineEntry = ";
Chris Lattner24943d22010-06-08 16:52:24 +0000325 line_entry.Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
326 s->EOL();
327 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000328 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000329 if (symbol != NULL && symbol->GetMangled())
330 *s << ' ' << symbol->GetMangled().GetName().AsCString();
331 s->EOL();
332 s->IndentLess();
333 s->IndentLess();
334}
335
336bool
337lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
338{
339 return lhs.target_sp.get() == rhs.target_sp.get() &&
340 lhs.module_sp.get() == rhs.module_sp.get() &&
341 lhs.comp_unit == rhs.comp_unit &&
342 lhs.function == rhs.function &&
343 LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
344 lhs.symbol == rhs.symbol;
345}
346
347bool
348lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
349{
350 return lhs.target_sp.get() != rhs.target_sp.get() ||
351 lhs.module_sp.get() != rhs.module_sp.get() ||
352 lhs.comp_unit != rhs.comp_unit ||
353 lhs.function != rhs.function ||
354 LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
355 lhs.symbol != rhs.symbol;
356}
357
358bool
359SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
360{
361 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
362 {
363 range = line_entry.range;
364 return true;
365 }
366 else if ((scope & eSymbolContextFunction) && function != NULL)
367 {
368 range = function->GetAddressRange();
369 return true;
370 }
371 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
372 {
373 range = *symbol->GetAddressRangePtr();
374
375 if (range.GetByteSize() == 0)
376 {
377 if (module_sp)
378 {
379 ObjectFile *objfile = module_sp->GetObjectFile();
380 if (objfile)
381 {
382 Symtab *symtab = objfile->GetSymtab();
383 if (symtab)
384 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
385 }
386 }
387 }
388 return true;
389 }
390 range.Clear();
391 return false;
392}
393
394
Sean Callanan0fc73582010-07-27 00:55:47 +0000395size_t
396SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const
397{
398 if (!append)
399 sc_list.Clear();
400
Chris Lattner24943d22010-06-08 16:52:24 +0000401 if (function != NULL)
402 {
403 // FIXME: Look in the class of the current function, if it exists,
404 // for methods matching name.
405 }
406
Chris Lattner24943d22010-06-08 16:52:24 +0000407 if (comp_unit != NULL)
408 {
409 // Make sure we've read in all the functions. We should be able to check and see
410 // if there's one by this name present before we do this...
411 module_sp->GetSymbolVendor()->ParseCompileUnitFunctions(*this);
412 uint32_t func_idx;
413 lldb::FunctionSP func_sp;
414 for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
415 {
Sean Callanan0fc73582010-07-27 00:55:47 +0000416 if (func_sp->GetMangled().GetName() == name)
417 {
418 SymbolContext sym_ctx(target_sp,
419 module_sp,
420 comp_unit,
421 func_sp.get());
422 sc_list.Append(sym_ctx);
423 }
Chris Lattner24943d22010-06-08 16:52:24 +0000424 }
425 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000426
Chris Lattner24943d22010-06-08 16:52:24 +0000427 if (module_sp != NULL)
Sean Callanan0fc73582010-07-27 00:55:47 +0000428 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000429
430 if (target_sp)
Sean Callanan0fc73582010-07-27 00:55:47 +0000431 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000432
Sean Callanan0fc73582010-07-27 00:55:47 +0000433 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000434}
435
436lldb::VariableSP
437SymbolContext::FindVariableByName (const char *name) const
438{
439 lldb::VariableSP return_value;
440 return return_value;
441}
442
443lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000444SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000445{
446 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000447
448 TypeList types;
449
450 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
451 return types.GetTypeAtIndex(0);
452
453 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
454 return types.GetTypeAtIndex(0);
455
Chris Lattner24943d22010-06-08 16:52:24 +0000456 return return_value;
457}
458
459//----------------------------------------------------------------------
460//
461// SymbolContextList
462//
463//----------------------------------------------------------------------
464
465
466SymbolContextList::SymbolContextList() :
467 m_symbol_contexts()
468{
469}
470
471SymbolContextList::~SymbolContextList()
472{
473}
474
475void
476SymbolContextList::Append(const SymbolContext& sc)
477{
478 m_symbol_contexts.push_back(sc);
479}
480
481void
482SymbolContextList::Clear()
483{
484 m_symbol_contexts.clear();
485}
486
487void
488SymbolContextList::Dump(Stream *s, Process *process) const
489{
490
491 *s << (void *)this << ": ";
492 s->Indent();
493 s->PutCString("SymbolContextList");
494 s->EOL();
495 s->IndentMore();
496
497 collection::const_iterator pos, end = m_symbol_contexts.end();
498 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
499 {
500 pos->Dump(s, process);
501 }
502 s->IndentLess();
503}
504
505bool
506SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
507{
508 if (idx < m_symbol_contexts.size())
509 {
510 sc = m_symbol_contexts[idx];
511 return true;
512 }
513 return false;
514}
515
516bool
517SymbolContextList::RemoveContextAtIndex (uint32_t idx)
518{
519 if (idx < m_symbol_contexts.size())
520 {
521 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
522 return true;
523 }
524 return false;
525}
526
527uint32_t
528SymbolContextList::GetSize() const
529{
530 return m_symbol_contexts.size();
531}