blob: 2f5ff3a2434ca63a2712e8f33ef3643b5abea43c [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 Clayton2e3d6f22010-09-10 22:05:05 +0000159 if (addr.IsValid())
160 {
161 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
162 if (function_offset)
163 s->Printf(" + %llu", function_offset);
164 }
Chris Lattner24943d22010-06-08 16:52:24 +0000165
166 if (block != NULL)
167 {
168 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000169 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000170 s->IndentLess();
171 }
172 else
173 {
174 if (line_entry.IsValid())
175 {
176 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000177 if (line_entry.DumpStopContext(s, show_fullpaths))
Chris Lattner24943d22010-06-08 16:52:24 +0000178 return;
179 }
180 }
181 }
182 else if (symbol != NULL)
183 {
184 symbol->GetMangled().GetName().Dump(s);
185
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000186 if (addr.IsValid() && symbol->GetAddressRangePtr())
Chris Lattner24943d22010-06-08 16:52:24 +0000187 {
Greg Clayton70436352010-06-30 23:03:03 +0000188 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
189 if (symbol_offset)
190 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000191 }
192 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000193 else if (addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000194 {
195 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
196 }
197}
198
199void
Greg Claytoneea26402010-09-14 23:36:40 +0000200SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000201{
202 if (module_sp)
203 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000204 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000205 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000206 *s << '"';
207 if (module_sp->GetArchitecture().IsValid())
208 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().AsCString());
Greg Clayton12bec712010-06-28 21:30:43 +0000209 s->EOL();
210 }
211
212 if (comp_unit != NULL)
213 {
214 s->Indent("CompileUnit: ");
215 comp_unit->GetDescription (s, level);
216 s->EOL();
217 }
218
219 if (function != NULL)
220 {
221 s->Indent(" Function: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000222 function->GetDescription (s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000223 s->EOL();
224
225 Type *func_type = function->GetType();
226 if (func_type)
227 {
228 s->Indent(" FuncType: ");
229 func_type->GetDescription (s, level, false);
230 s->EOL();
231 }
232 }
233
234 if (block != NULL)
235 {
236 std::vector<Block *> blocks;
237 blocks.push_back (block);
238 Block *parent_block = block->GetParent();
239
240 while (parent_block)
241 {
242 blocks.push_back (parent_block);
243 parent_block = parent_block->GetParent();
244 }
245 std::vector<Block *>::reverse_iterator pos;
246 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
247 std::vector<Block *>::reverse_iterator end = blocks.rend();
248 for (pos = begin; pos != end; ++pos)
249 {
250 if (pos == begin)
251 s->Indent(" Blocks: ");
252 else
253 s->Indent(" ");
Greg Claytoneea26402010-09-14 23:36:40 +0000254 (*pos)->GetDescription(s, function, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000255 s->EOL();
256 }
257 }
258
259 if (line_entry.IsValid())
260 {
261 s->Indent(" LineEntry: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000262 line_entry.GetDescription (s, level, comp_unit, target, false);
Greg Clayton12bec712010-06-28 21:30:43 +0000263 s->EOL();
264 }
265
266 if (symbol != NULL)
267 {
268 s->Indent(" Symbol: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000269 symbol->GetDescription(s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000270 s->EOL();
271 }
272}
273
Greg Clayton33ed1702010-08-24 00:45:41 +0000274uint32_t
275SymbolContext::GetResolvedMask () const
276{
277 uint32_t resolved_mask = 0;
278 if (target_sp) resolved_mask |= eSymbolContextTarget;
279 if (module_sp) resolved_mask |= eSymbolContextModule;
280 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
281 if (function) resolved_mask |= eSymbolContextFunction;
282 if (block) resolved_mask |= eSymbolContextBlock;
283 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
284 if (symbol) resolved_mask |= eSymbolContextSymbol;
285 return resolved_mask;
286}
Greg Clayton12bec712010-06-28 21:30:43 +0000287
288
289void
Greg Claytoneea26402010-09-14 23:36:40 +0000290SymbolContext::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000291{
292 *s << (void *)this << ": ";
293 s->Indent();
294 s->PutCString("SymbolContext");
295 s->IndentMore();
296 s->EOL();
297 s->IndentMore();
298 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000299 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000300 if (module_sp)
301 module_sp->GetFileSpec().Dump(s);
302 s->EOL();
303 s->Indent();
304 *s << "CompileUnit = " << (void *)comp_unit;
305 if (comp_unit != NULL)
Johnny Chencff44fd2010-10-29 22:18:43 +0000306 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000307 s->EOL();
308 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000309 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000310 if (function != NULL)
311 {
Greg Clayton12bec712010-06-28 21:30:43 +0000312 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000313 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Greg Clayton12bec712010-06-28 21:30:43 +0000314 s->EOL();
315 s->Indent();
316 Type* func_type = function->GetType();
317 if (func_type)
318 {
319 *s << " Type = ";
320 func_type->Dump (s, false);
321 }
Chris Lattner24943d22010-06-08 16:52:24 +0000322 }
323 s->EOL();
324 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000325 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000326 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000327 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000328 // Dump the block and pass it a negative depth to we print all the parent blocks
329 //if (block != NULL)
330 // block->Dump(s, function->GetFileAddress(), INT_MIN);
331 s->EOL();
332 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000333 *s << "LineEntry = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000334 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000335 s->EOL();
336 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000337 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000338 if (symbol != NULL && symbol->GetMangled())
339 *s << ' ' << symbol->GetMangled().GetName().AsCString();
340 s->EOL();
341 s->IndentLess();
342 s->IndentLess();
343}
344
345bool
346lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
347{
348 return lhs.target_sp.get() == rhs.target_sp.get() &&
349 lhs.module_sp.get() == rhs.module_sp.get() &&
350 lhs.comp_unit == rhs.comp_unit &&
351 lhs.function == rhs.function &&
352 LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
353 lhs.symbol == rhs.symbol;
354}
355
356bool
357lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
358{
359 return lhs.target_sp.get() != rhs.target_sp.get() ||
360 lhs.module_sp.get() != rhs.module_sp.get() ||
361 lhs.comp_unit != rhs.comp_unit ||
362 lhs.function != rhs.function ||
363 LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
364 lhs.symbol != rhs.symbol;
365}
366
367bool
368SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
369{
370 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
371 {
372 range = line_entry.range;
373 return true;
374 }
375 else if ((scope & eSymbolContextFunction) && function != NULL)
376 {
377 range = function->GetAddressRange();
378 return true;
379 }
380 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
381 {
382 range = *symbol->GetAddressRangePtr();
383
384 if (range.GetByteSize() == 0)
385 {
386 if (module_sp)
387 {
388 ObjectFile *objfile = module_sp->GetObjectFile();
389 if (objfile)
390 {
391 Symtab *symtab = objfile->GetSymtab();
392 if (symtab)
393 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
394 }
395 }
396 }
397 return true;
398 }
399 range.Clear();
400 return false;
401}
402
Greg Clayton6916e352010-11-13 03:52:47 +0000403ClangNamespaceDecl
404SymbolContext::FindNamespace (const ConstString &name) const
405{
406 ClangNamespaceDecl namespace_decl;
407 if (module_sp)
408 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name);
409 return namespace_decl;
410}
Chris Lattner24943d22010-06-08 16:52:24 +0000411
Sean Callanan0fc73582010-07-27 00:55:47 +0000412size_t
413SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const
414{
415 if (!append)
416 sc_list.Clear();
417
Chris Lattner24943d22010-06-08 16:52:24 +0000418 if (function != NULL)
419 {
420 // FIXME: Look in the class of the current function, if it exists,
421 // for methods matching name.
422 }
423
Chris Lattner24943d22010-06-08 16:52:24 +0000424 if (module_sp != NULL)
Sean Callanan0fc73582010-07-27 00:55:47 +0000425 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000426
427 if (target_sp)
Sean Callanan0fc73582010-07-27 00:55:47 +0000428 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000429
Sean Callanan0fc73582010-07-27 00:55:47 +0000430 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000431}
432
Greg Clayton6916e352010-11-13 03:52:47 +0000433//lldb::VariableSP
434//SymbolContext::FindVariableByName (const char *name) const
435//{
436// lldb::VariableSP return_value;
437// return return_value;
438//}
Chris Lattner24943d22010-06-08 16:52:24 +0000439
440lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000441SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000442{
443 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000444
445 TypeList types;
446
447 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
448 return types.GetTypeAtIndex(0);
449
450 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
451 return types.GetTypeAtIndex(0);
452
Chris Lattner24943d22010-06-08 16:52:24 +0000453 return return_value;
454}
455
456//----------------------------------------------------------------------
457//
458// SymbolContextList
459//
460//----------------------------------------------------------------------
461
462
463SymbolContextList::SymbolContextList() :
464 m_symbol_contexts()
465{
466}
467
468SymbolContextList::~SymbolContextList()
469{
470}
471
472void
473SymbolContextList::Append(const SymbolContext& sc)
474{
475 m_symbol_contexts.push_back(sc);
476}
477
478void
479SymbolContextList::Clear()
480{
481 m_symbol_contexts.clear();
482}
483
484void
Greg Claytoneea26402010-09-14 23:36:40 +0000485SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000486{
487
488 *s << (void *)this << ": ";
489 s->Indent();
490 s->PutCString("SymbolContextList");
491 s->EOL();
492 s->IndentMore();
493
494 collection::const_iterator pos, end = m_symbol_contexts.end();
495 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
496 {
Greg Claytoneea26402010-09-14 23:36:40 +0000497 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000498 }
499 s->IndentLess();
500}
501
502bool
503SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
504{
505 if (idx < m_symbol_contexts.size())
506 {
507 sc = m_symbol_contexts[idx];
508 return true;
509 }
510 return false;
511}
512
513bool
514SymbolContextList::RemoveContextAtIndex (uint32_t idx)
515{
516 if (idx < m_symbol_contexts.size())
517 {
518 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
519 return true;
520 }
521 return false;
522}
523
524uint32_t
525SymbolContextList::GetSize() const
526{
527 return m_symbol_contexts.size();
528}