blob: a5a36bb9d4e248e2ef1658e41fd96ce2ca4b589f [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 Clayton2e3d6f22010-09-10 22:05:05 +0000136 if (addr.IsValid())
137 {
138 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
139 if (function_offset)
140 s->Printf(" + %llu", function_offset);
141 }
Chris Lattner24943d22010-06-08 16:52:24 +0000142
143 if (block != NULL)
144 {
145 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000146 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000147 s->IndentLess();
148 }
149 else
150 {
151 if (line_entry.IsValid())
152 {
153 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000154 if (line_entry.DumpStopContext(s, show_fullpaths))
Chris Lattner24943d22010-06-08 16:52:24 +0000155 return;
156 }
157 }
158 }
159 else if (symbol != NULL)
160 {
161 symbol->GetMangled().GetName().Dump(s);
162
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000163 if (addr.IsValid() && symbol->GetAddressRangePtr())
Chris Lattner24943d22010-06-08 16:52:24 +0000164 {
Greg Clayton70436352010-06-30 23:03:03 +0000165 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
166 if (symbol_offset)
167 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000168 }
169 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000170 else if (addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000171 {
172 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
173 }
174}
175
176void
Greg Claytoneea26402010-09-14 23:36:40 +0000177SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000178{
179 if (module_sp)
180 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000181 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000182 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000183 *s << '"';
184 if (module_sp->GetArchitecture().IsValid())
Greg Clayton940b1032011-02-23 00:35:02 +0000185 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
Greg Clayton12bec712010-06-28 21:30:43 +0000186 s->EOL();
187 }
188
189 if (comp_unit != NULL)
190 {
191 s->Indent("CompileUnit: ");
192 comp_unit->GetDescription (s, level);
193 s->EOL();
194 }
195
196 if (function != NULL)
197 {
198 s->Indent(" Function: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000199 function->GetDescription (s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000200 s->EOL();
201
202 Type *func_type = function->GetType();
203 if (func_type)
204 {
205 s->Indent(" FuncType: ");
206 func_type->GetDescription (s, level, false);
207 s->EOL();
208 }
209 }
210
211 if (block != NULL)
212 {
213 std::vector<Block *> blocks;
214 blocks.push_back (block);
215 Block *parent_block = block->GetParent();
216
217 while (parent_block)
218 {
219 blocks.push_back (parent_block);
220 parent_block = parent_block->GetParent();
221 }
222 std::vector<Block *>::reverse_iterator pos;
223 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
224 std::vector<Block *>::reverse_iterator end = blocks.rend();
225 for (pos = begin; pos != end; ++pos)
226 {
227 if (pos == begin)
228 s->Indent(" Blocks: ");
229 else
230 s->Indent(" ");
Greg Claytoneea26402010-09-14 23:36:40 +0000231 (*pos)->GetDescription(s, function, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000232 s->EOL();
233 }
234 }
235
236 if (line_entry.IsValid())
237 {
238 s->Indent(" LineEntry: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000239 line_entry.GetDescription (s, level, comp_unit, target, false);
Greg Clayton12bec712010-06-28 21:30:43 +0000240 s->EOL();
241 }
242
243 if (symbol != NULL)
244 {
245 s->Indent(" Symbol: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000246 symbol->GetDescription(s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000247 s->EOL();
248 }
249}
250
Greg Clayton33ed1702010-08-24 00:45:41 +0000251uint32_t
252SymbolContext::GetResolvedMask () const
253{
254 uint32_t resolved_mask = 0;
255 if (target_sp) resolved_mask |= eSymbolContextTarget;
256 if (module_sp) resolved_mask |= eSymbolContextModule;
257 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
258 if (function) resolved_mask |= eSymbolContextFunction;
259 if (block) resolved_mask |= eSymbolContextBlock;
260 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
261 if (symbol) resolved_mask |= eSymbolContextSymbol;
262 return resolved_mask;
263}
Greg Clayton12bec712010-06-28 21:30:43 +0000264
265
266void
Greg Claytoneea26402010-09-14 23:36:40 +0000267SymbolContext::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000268{
269 *s << (void *)this << ": ";
270 s->Indent();
271 s->PutCString("SymbolContext");
272 s->IndentMore();
273 s->EOL();
274 s->IndentMore();
275 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000276 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000277 if (module_sp)
278 module_sp->GetFileSpec().Dump(s);
279 s->EOL();
280 s->Indent();
281 *s << "CompileUnit = " << (void *)comp_unit;
282 if (comp_unit != NULL)
Johnny Chencff44fd2010-10-29 22:18:43 +0000283 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000284 s->EOL();
285 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000286 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000287 if (function != NULL)
288 {
Greg Clayton12bec712010-06-28 21:30:43 +0000289 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000290 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Greg Clayton12bec712010-06-28 21:30:43 +0000291 s->EOL();
292 s->Indent();
293 Type* func_type = function->GetType();
294 if (func_type)
295 {
296 *s << " Type = ";
297 func_type->Dump (s, false);
298 }
Chris Lattner24943d22010-06-08 16:52:24 +0000299 }
300 s->EOL();
301 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000302 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000303 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000304 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000305 // Dump the block and pass it a negative depth to we print all the parent blocks
306 //if (block != NULL)
307 // block->Dump(s, function->GetFileAddress(), INT_MIN);
308 s->EOL();
309 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000310 *s << "LineEntry = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000311 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000312 s->EOL();
313 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000314 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000315 if (symbol != NULL && symbol->GetMangled())
316 *s << ' ' << symbol->GetMangled().GetName().AsCString();
317 s->EOL();
318 s->IndentLess();
319 s->IndentLess();
320}
321
322bool
323lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
324{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000325 return lhs.function == rhs.function
326 && lhs.symbol == rhs.symbol
327 && lhs.module_sp.get() == rhs.module_sp.get()
328 && lhs.comp_unit == rhs.comp_unit
329 && lhs.target_sp.get() == rhs.target_sp.get()
330 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000331}
332
333bool
334lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
335{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000336 return lhs.function != rhs.function
Greg Clayton889fbd02011-03-26 19:14:58 +0000337 || lhs.symbol != rhs.symbol
338 || lhs.module_sp.get() != rhs.module_sp.get()
339 || lhs.comp_unit != rhs.comp_unit
340 || lhs.target_sp.get() != rhs.target_sp.get()
341 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000342}
343
344bool
345SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
346{
347 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
348 {
349 range = line_entry.range;
350 return true;
351 }
352 else if ((scope & eSymbolContextFunction) && function != NULL)
353 {
354 range = function->GetAddressRange();
355 return true;
356 }
357 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
358 {
359 range = *symbol->GetAddressRangePtr();
360
361 if (range.GetByteSize() == 0)
362 {
363 if (module_sp)
364 {
365 ObjectFile *objfile = module_sp->GetObjectFile();
366 if (objfile)
367 {
368 Symtab *symtab = objfile->GetSymtab();
369 if (symtab)
370 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
371 }
372 }
373 }
374 return true;
375 }
376 range.Clear();
377 return false;
378}
379
Greg Clayton6916e352010-11-13 03:52:47 +0000380ClangNamespaceDecl
381SymbolContext::FindNamespace (const ConstString &name) const
382{
383 ClangNamespaceDecl namespace_decl;
384 if (module_sp)
385 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name);
386 return namespace_decl;
387}
Chris Lattner24943d22010-06-08 16:52:24 +0000388
Sean Callanan0fc73582010-07-27 00:55:47 +0000389size_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000390SymbolContext::FindFunctionsByName (const ConstString &name,
391 bool include_symbols,
392 bool append,
393 SymbolContextList &sc_list) const
Sean Callanan0fc73582010-07-27 00:55:47 +0000394{
395 if (!append)
396 sc_list.Clear();
397
Chris Lattner24943d22010-06-08 16:52:24 +0000398 if (function != NULL)
399 {
400 // FIXME: Look in the class of the current function, if it exists,
401 // for methods matching name.
402 }
403
Chris Lattner24943d22010-06-08 16:52:24 +0000404 if (module_sp != NULL)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000405 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000406
407 if (target_sp)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000408 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000409
Sean Callanan0fc73582010-07-27 00:55:47 +0000410 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000411}
412
Greg Clayton6916e352010-11-13 03:52:47 +0000413//lldb::VariableSP
414//SymbolContext::FindVariableByName (const char *name) const
415//{
416// lldb::VariableSP return_value;
417// return return_value;
418//}
Chris Lattner24943d22010-06-08 16:52:24 +0000419
420lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000421SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000422{
423 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000424
425 TypeList types;
426
427 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
428 return types.GetTypeAtIndex(0);
429
430 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
431 return types.GetTypeAtIndex(0);
432
Chris Lattner24943d22010-06-08 16:52:24 +0000433 return return_value;
434}
435
Jim Inghamd60d94a2011-03-11 03:53:59 +0000436//----------------------------------------------------------------------
437//
438// SymbolContextSpecifier
439//
440//----------------------------------------------------------------------
441
442bool
443SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
444{
445 bool return_value = true;
446 switch (type)
447 {
448 case eNothingSpecified:
449 Clear();
450 break;
451 case eLineStartSpecified:
452 m_start_line = line_no;
453 m_type |= eLineStartSpecified;
454 break;
455 case eLineEndSpecified:
456 m_end_line = line_no;
457 m_type |= eLineEndSpecified;
458 break;
459 default:
460 return_value = false;
461 break;
462 }
463 return return_value;
464}
465
466bool
467SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
468{
469 bool return_value = true;
470 switch (type)
471 {
472 case eNothingSpecified:
473 Clear();
474 break;
475 case eModuleSpecified:
476 {
477 // See if we can find the Module, if so stick it in the SymbolContext.
478 FileSpec module_spec(spec_string, true);
479 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec);
480 m_type |= eModuleSpecified;
481 if (module_sp)
482 m_module_sp = module_sp;
483 else
484 m_module_spec.assign (spec_string);
485 }
486 break;
487 case eFileSpecified:
488 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
489 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
490 m_file_spec_ap.reset (new FileSpec (spec_string, true));
491 m_type |= eFileSpecified;
492 break;
493 case eLineStartSpecified:
494 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
495 if (return_value)
496 m_type |= eLineStartSpecified;
497 break;
498 case eLineEndSpecified:
499 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
500 if (return_value)
501 m_type |= eLineEndSpecified;
502 break;
503 case eFunctionSpecified:
504 m_function_spec.assign(spec_string);
505 m_type |= eFunctionSpecified;
506 break;
507 case eClassOrNamespaceSpecified:
508 Clear();
509 m_class_name.assign (spec_string);
510 m_type = eClassOrNamespaceSpecified;
511 break;
512 case eAddressRangeSpecified:
513 // Not specified yet...
514 break;
515 }
516
517 return return_value;
518}
519
520void
521SymbolContextSpecifier::Clear()
522{
523 m_module_spec.clear();
524 m_file_spec_ap.reset();
525 m_function_spec.clear();
526 m_class_name.clear();
527 m_start_line = 0;
528 m_end_line = 0;
529 m_address_range_ap.reset();
530
531 m_type = eNothingSpecified;
532}
533
534bool
535SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
536{
537 if (m_type == eNothingSpecified)
538 return true;
539
540 if (m_target_sp.get() != sc.target_sp.get())
541 return false;
542
543 if (m_type & eModuleSpecified)
544 {
545 if (sc.module_sp)
546 {
547 if (m_module_sp.get() != NULL)
548 {
549 if (m_module_sp.get() != sc.module_sp.get())
550 return false;
551 }
552 else
553 {
554 FileSpec module_file_spec (m_module_spec.c_str(), false);
555 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
556 return false;
557 }
558 }
559 }
560 if (m_type & eFileSpecified)
561 {
562 if (m_file_spec_ap.get())
563 {
564 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
565 if (sc.block == NULL && sc.comp_unit == NULL)
566 return false;
567
568 // Check if the block is present, and if so is it inlined:
569 bool was_inlined = false;
570 if (sc.block != NULL)
571 {
572 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
573 if (inline_info != NULL)
574 {
575 was_inlined = true;
576 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
577 return false;
578 }
579 }
580
581 // Next check the comp unit, but only if the SymbolContext was not inlined.
582 if (!was_inlined && sc.comp_unit != NULL)
583 {
584 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
585 return false;
586 }
587 }
588 }
589 if (m_type & eLineStartSpecified
590 || m_type & eLineEndSpecified)
591 {
592 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
593 return false;
594 }
595
596 if (m_type & eFunctionSpecified)
597 {
598 // First check the current block, and if it is inlined, get the inlined function name:
599 bool was_inlined = false;
600 ConstString func_name(m_function_spec.c_str());
601
602 if (sc.block != NULL)
603 {
604 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
605 if (inline_info != NULL)
606 {
607 was_inlined = true;
608 const Mangled &name = inline_info->GetMangled();
609 if (!name.NameMatches (func_name))
610 return false;
611 }
612 }
613 // If it wasn't inlined, check the name in the function or symbol:
614 if (!was_inlined)
615 {
616 if (sc.function != NULL)
617 {
618 if (!sc.function->GetMangled().NameMatches(func_name))
619 return false;
620 }
621 else if (sc.symbol != NULL)
622 {
623 if (!sc.symbol->GetMangled().NameMatches(func_name))
624 return false;
625 }
626 }
627
628
629 }
630
631 return true;
632}
633
634bool
635SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
636{
637 if (m_type & eAddressRangeSpecified)
638 {
639
640 }
641 else
642 {
643 Address match_address (addr, NULL);
644 SymbolContext sc;
645 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
646 return SymbolContextMatches(sc);
647 }
648 return true;
649}
650
651void
652SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
653{
654 char path_str[PATH_MAX + 1];
655
656 if (m_type == eNothingSpecified)
657 {
658 s->Printf ("Nothing specified.\n");
659 }
660
661 if (m_type == eModuleSpecified)
662 {
663 s->Indent();
664 if (m_module_sp)
665 {
666 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
667 s->Printf ("Module: %s\n", path_str);
668 }
669 else
670 s->Printf ("Module: %s\n", m_module_spec.c_str());
671 }
672
673 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL)
674 {
675 m_file_spec_ap->GetPath (path_str, PATH_MAX);
676 s->Indent();
677 s->Printf ("File: %s", path_str);
678 if (m_type == eLineStartSpecified)
679 {
680 s->Printf (" from line %d", m_start_line);
681 if (m_type == eLineEndSpecified)
682 s->Printf ("to line %d", m_end_line);
683 else
684 s->Printf ("to end", m_end_line);
685 }
686 else if (m_type == eLineEndSpecified)
687 {
688 s->Printf (" from start to line %d", m_end_line);
689 }
690 s->Printf (".\n");
691 }
692
693 if (m_type == eLineStartSpecified)
694 {
695 s->Indent();
696 s->Printf ("From line %d", m_start_line);
697 if (m_type == eLineEndSpecified)
698 s->Printf ("to line %d", m_end_line);
699 else
700 s->Printf ("to end", m_end_line);
701 s->Printf (".\n");
702 }
703 else if (m_type == eLineEndSpecified)
704 {
705 s->Printf ("From start to line %d.\n", m_end_line);
706 }
707
708 if (m_type == eFunctionSpecified)
709 {
710 s->Indent();
711 s->Printf ("Function: %s.\n", m_function_spec.c_str());
712 }
713
714 if (m_type == eClassOrNamespaceSpecified)
715 {
716 s->Indent();
717 s->Printf ("Class name: %s.\n", m_class_name.c_str());
718 }
719
720 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
721 {
722 s->Indent();
723 s->PutCString ("Address range: ");
724 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
725 s->PutCString ("\n");
726 }
727}
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000728
Chris Lattner24943d22010-06-08 16:52:24 +0000729//----------------------------------------------------------------------
730//
731// SymbolContextList
732//
733//----------------------------------------------------------------------
734
735
736SymbolContextList::SymbolContextList() :
737 m_symbol_contexts()
738{
739}
740
741SymbolContextList::~SymbolContextList()
742{
743}
744
745void
746SymbolContextList::Append(const SymbolContext& sc)
747{
748 m_symbol_contexts.push_back(sc);
749}
750
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000751bool
Greg Clayton889fbd02011-03-26 19:14:58 +0000752SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000753{
Greg Clayton889fbd02011-03-26 19:14:58 +0000754 collection::iterator pos, end = m_symbol_contexts.end();
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000755 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
756 {
757 if (*pos == sc)
758 return false;
759 }
Greg Clayton889fbd02011-03-26 19:14:58 +0000760 if (merge_symbol_into_function
761 && sc.symbol != NULL
762 && sc.comp_unit == NULL
763 && sc.function == NULL
764 && sc.block == NULL
765 && sc.line_entry.IsValid() == false)
766 {
767 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
768 if (symbol_range)
769 {
770 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
771 {
772 if (pos->function)
773 {
774 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
775 {
776 // Do we already have a function with this symbol?
777 if (pos->symbol == sc.symbol)
778 return false;
779 if (pos->symbol == NULL)
780 {
781 pos->symbol = sc.symbol;
782 return false;
783 }
784 }
785 }
786 }
787 }
788 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000789 m_symbol_contexts.push_back(sc);
790 return true;
791}
792
Chris Lattner24943d22010-06-08 16:52:24 +0000793void
794SymbolContextList::Clear()
795{
796 m_symbol_contexts.clear();
797}
798
799void
Greg Claytoneea26402010-09-14 23:36:40 +0000800SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000801{
802
803 *s << (void *)this << ": ";
804 s->Indent();
805 s->PutCString("SymbolContextList");
806 s->EOL();
807 s->IndentMore();
808
809 collection::const_iterator pos, end = m_symbol_contexts.end();
810 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
811 {
Greg Claytoneea26402010-09-14 23:36:40 +0000812 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000813 }
814 s->IndentLess();
815}
816
817bool
818SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
819{
820 if (idx < m_symbol_contexts.size())
821 {
822 sc = m_symbol_contexts[idx];
823 return true;
824 }
825 return false;
826}
827
828bool
829SymbolContextList::RemoveContextAtIndex (uint32_t idx)
830{
831 if (idx < m_symbol_contexts.size())
832 {
833 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
834 return true;
835 }
836 return false;
837}
838
839uint32_t
840SymbolContextList::GetSize() const
841{
842 return m_symbol_contexts.size();
843}