blob: 135cf3b7a3d44462b41dbdfcd83c9458d0b1e7d2 [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 Claytonf15996e2011-04-07 22:46:35 +000013#include "lldb/Interpreter/Args.h"
Greg Clayton12bec712010-06-28 21:30:43 +000014#include "lldb/Symbol/CompileUnit.h"
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Symbol/ObjectFile.h"
16#include "lldb/Symbol/Symbol.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton12bec712010-06-28 21:30:43 +000018#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019
20using namespace lldb;
21using namespace lldb_private;
22
23SymbolContext::SymbolContext() :
24 target_sp (),
25 module_sp (),
26 comp_unit (NULL),
27 function (NULL),
28 block (NULL),
29 line_entry (),
30 symbol (NULL)
31{
32}
33
34SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
35 target_sp (),
36 module_sp (m),
37 comp_unit (cu),
38 function (f),
39 block (b),
40 line_entry (),
41 symbol (s)
42{
43 if (le)
44 line_entry = *le;
45}
46
47SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
48 target_sp (t),
49 module_sp (m),
50 comp_unit (cu),
51 function (f),
52 block (b),
53 line_entry (),
54 symbol (s)
55{
56 if (le)
57 line_entry = *le;
58}
59
60SymbolContext::SymbolContext(const SymbolContext& rhs) :
61 target_sp (rhs.target_sp),
62 module_sp (rhs.module_sp),
63 comp_unit (rhs.comp_unit),
64 function (rhs.function),
65 block (rhs.block),
66 line_entry (rhs.line_entry),
67 symbol (rhs.symbol)
68{
69}
70
71
72SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
73 target_sp (),
74 module_sp (),
75 comp_unit (NULL),
76 function (NULL),
77 block (NULL),
78 line_entry (),
79 symbol (NULL)
80{
81 sc_scope->CalculateSymbolContext (this);
82}
83
84const SymbolContext&
85SymbolContext::operator= (const SymbolContext& rhs)
86{
87 if (this != &rhs)
88 {
89 target_sp = rhs.target_sp;
90 module_sp = rhs.module_sp;
91 comp_unit = rhs.comp_unit;
92 function = rhs.function;
93 block = rhs.block;
94 line_entry = rhs.line_entry;
95 symbol = rhs.symbol;
96 }
97 return *this;
98}
99
100void
101SymbolContext::Clear()
102{
103 target_sp.reset();
104 module_sp.reset();
105 comp_unit = NULL;
106 function = NULL;
107 block = NULL;
108 line_entry.Clear();
109 symbol = NULL;
110}
111
112void
113SymbolContext::DumpStopContext
114(
115 Stream *s,
116 ExecutionContextScope *exe_scope,
117 const Address &addr,
Greg Clayton72b71582010-09-02 21:44:10 +0000118 bool show_fullpaths,
Greg Clayton33ed1702010-08-24 00:45:41 +0000119 bool show_module,
120 bool show_inlined_frames
Chris Lattner24943d22010-06-08 16:52:24 +0000121) const
122{
Chris Lattner24943d22010-06-08 16:52:24 +0000123 if (show_module && module_sp)
124 {
Greg Clayton72b71582010-09-02 21:44:10 +0000125 if (show_fullpaths)
126 *s << module_sp->GetFileSpec();
127 else
128 *s << module_sp->GetFileSpec().GetFilename();
129 s->PutChar('`');
Chris Lattner24943d22010-06-08 16:52:24 +0000130 }
131
132 if (function != NULL)
133 {
134 if (function->GetMangled().GetName())
135 function->GetMangled().GetName().Dump(s);
136
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000137 if (addr.IsValid())
138 {
139 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
140 if (function_offset)
141 s->Printf(" + %llu", function_offset);
142 }
Chris Lattner24943d22010-06-08 16:52:24 +0000143
144 if (block != NULL)
145 {
146 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000147 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000148 s->IndentLess();
149 }
150 else
151 {
152 if (line_entry.IsValid())
153 {
154 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000155 if (line_entry.DumpStopContext(s, show_fullpaths))
Chris Lattner24943d22010-06-08 16:52:24 +0000156 return;
157 }
158 }
159 }
160 else if (symbol != NULL)
161 {
162 symbol->GetMangled().GetName().Dump(s);
163
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000164 if (addr.IsValid() && symbol->GetAddressRangePtr())
Chris Lattner24943d22010-06-08 16:52:24 +0000165 {
Greg Clayton70436352010-06-30 23:03:03 +0000166 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
167 if (symbol_offset)
168 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000169 }
170 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000171 else if (addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000172 {
173 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
174 }
175}
176
177void
Greg Claytoneea26402010-09-14 23:36:40 +0000178SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000179{
180 if (module_sp)
181 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000182 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000183 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000184 *s << '"';
185 if (module_sp->GetArchitecture().IsValid())
Greg Clayton940b1032011-02-23 00:35:02 +0000186 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
Greg Clayton12bec712010-06-28 21:30:43 +0000187 s->EOL();
188 }
189
190 if (comp_unit != NULL)
191 {
192 s->Indent("CompileUnit: ");
193 comp_unit->GetDescription (s, level);
194 s->EOL();
195 }
196
197 if (function != NULL)
198 {
199 s->Indent(" Function: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000200 function->GetDescription (s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000201 s->EOL();
202
203 Type *func_type = function->GetType();
204 if (func_type)
205 {
206 s->Indent(" FuncType: ");
207 func_type->GetDescription (s, level, false);
208 s->EOL();
209 }
210 }
211
212 if (block != NULL)
213 {
214 std::vector<Block *> blocks;
215 blocks.push_back (block);
216 Block *parent_block = block->GetParent();
217
218 while (parent_block)
219 {
220 blocks.push_back (parent_block);
221 parent_block = parent_block->GetParent();
222 }
223 std::vector<Block *>::reverse_iterator pos;
224 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
225 std::vector<Block *>::reverse_iterator end = blocks.rend();
226 for (pos = begin; pos != end; ++pos)
227 {
228 if (pos == begin)
229 s->Indent(" Blocks: ");
230 else
231 s->Indent(" ");
Greg Claytoneea26402010-09-14 23:36:40 +0000232 (*pos)->GetDescription(s, function, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000233 s->EOL();
234 }
235 }
236
237 if (line_entry.IsValid())
238 {
239 s->Indent(" LineEntry: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000240 line_entry.GetDescription (s, level, comp_unit, target, false);
Greg Clayton12bec712010-06-28 21:30:43 +0000241 s->EOL();
242 }
243
244 if (symbol != NULL)
245 {
246 s->Indent(" Symbol: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000247 symbol->GetDescription(s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000248 s->EOL();
249 }
250}
251
Greg Clayton33ed1702010-08-24 00:45:41 +0000252uint32_t
253SymbolContext::GetResolvedMask () const
254{
255 uint32_t resolved_mask = 0;
256 if (target_sp) resolved_mask |= eSymbolContextTarget;
257 if (module_sp) resolved_mask |= eSymbolContextModule;
258 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
259 if (function) resolved_mask |= eSymbolContextFunction;
260 if (block) resolved_mask |= eSymbolContextBlock;
261 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
262 if (symbol) resolved_mask |= eSymbolContextSymbol;
263 return resolved_mask;
264}
Greg Clayton12bec712010-06-28 21:30:43 +0000265
266
267void
Greg Claytoneea26402010-09-14 23:36:40 +0000268SymbolContext::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000269{
270 *s << (void *)this << ": ";
271 s->Indent();
272 s->PutCString("SymbolContext");
273 s->IndentMore();
274 s->EOL();
275 s->IndentMore();
276 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000277 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000278 if (module_sp)
279 module_sp->GetFileSpec().Dump(s);
280 s->EOL();
281 s->Indent();
282 *s << "CompileUnit = " << (void *)comp_unit;
283 if (comp_unit != NULL)
Johnny Chencff44fd2010-10-29 22:18:43 +0000284 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000285 s->EOL();
286 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000287 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000288 if (function != NULL)
289 {
Greg Clayton12bec712010-06-28 21:30:43 +0000290 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000291 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Greg Clayton12bec712010-06-28 21:30:43 +0000292 s->EOL();
293 s->Indent();
294 Type* func_type = function->GetType();
295 if (func_type)
296 {
297 *s << " Type = ";
298 func_type->Dump (s, false);
299 }
Chris Lattner24943d22010-06-08 16:52:24 +0000300 }
301 s->EOL();
302 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000303 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000304 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000305 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000306 // Dump the block and pass it a negative depth to we print all the parent blocks
307 //if (block != NULL)
308 // block->Dump(s, function->GetFileAddress(), INT_MIN);
309 s->EOL();
310 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000311 *s << "LineEntry = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000312 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000313 s->EOL();
314 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000315 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000316 if (symbol != NULL && symbol->GetMangled())
317 *s << ' ' << symbol->GetMangled().GetName().AsCString();
318 s->EOL();
319 s->IndentLess();
320 s->IndentLess();
321}
322
323bool
324lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
325{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000326 return lhs.function == rhs.function
327 && lhs.symbol == rhs.symbol
328 && lhs.module_sp.get() == rhs.module_sp.get()
329 && lhs.comp_unit == rhs.comp_unit
330 && lhs.target_sp.get() == rhs.target_sp.get()
331 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000332}
333
334bool
335lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
336{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000337 return lhs.function != rhs.function
Greg Clayton889fbd02011-03-26 19:14:58 +0000338 || lhs.symbol != rhs.symbol
339 || lhs.module_sp.get() != rhs.module_sp.get()
340 || lhs.comp_unit != rhs.comp_unit
341 || lhs.target_sp.get() != rhs.target_sp.get()
342 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000343}
344
345bool
Greg Claytonff44ab42011-04-23 02:04:55 +0000346SymbolContext::GetAddressRange (uint32_t scope,
347 uint32_t range_idx,
348 bool use_inline_block_range,
349 AddressRange &range) const
Chris Lattner24943d22010-06-08 16:52:24 +0000350{
351 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
352 {
353 range = line_entry.range;
354 return true;
355 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000356
357 if ((scope & eSymbolContextBlock) && (block != NULL))
Chris Lattner24943d22010-06-08 16:52:24 +0000358 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000359 if (use_inline_block_range)
Chris Lattner24943d22010-06-08 16:52:24 +0000360 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000361 Block *inline_block = block->GetContainingInlinedBlock();
362 if (inline_block)
363 return inline_block->GetRangeAtIndex (range_idx, range);
364 }
365 else
366 {
367 return block->GetRangeAtIndex (range_idx, range);
368 }
369 }
370
371 if ((scope & eSymbolContextFunction) && (function != NULL))
372 {
373 if (range_idx == 0)
374 {
375 range = function->GetAddressRange();
376 return true;
377 }
378 }
379
380 if ((scope & eSymbolContextSymbol) && (symbol != NULL) && (symbol->GetAddressRangePtr() != NULL))
381 {
382 if (range_idx == 0)
383 {
384 range = *symbol->GetAddressRangePtr();
385
386 if (range.GetByteSize() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000387 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000388 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000389 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000390 ObjectFile *objfile = module_sp->GetObjectFile();
391 if (objfile)
392 {
393 Symtab *symtab = objfile->GetSymtab();
394 if (symtab)
395 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
396 }
Chris Lattner24943d22010-06-08 16:52:24 +0000397 }
398 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000399 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000400 }
Chris Lattner24943d22010-06-08 16:52:24 +0000401 }
402 range.Clear();
403 return false;
404}
405
Greg Clayton6916e352010-11-13 03:52:47 +0000406ClangNamespaceDecl
407SymbolContext::FindNamespace (const ConstString &name) const
408{
409 ClangNamespaceDecl namespace_decl;
410 if (module_sp)
411 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name);
412 return namespace_decl;
413}
Chris Lattner24943d22010-06-08 16:52:24 +0000414
Sean Callanan0fc73582010-07-27 00:55:47 +0000415size_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000416SymbolContext::FindFunctionsByName (const ConstString &name,
417 bool include_symbols,
418 bool append,
419 SymbolContextList &sc_list) const
Sean Callanan0fc73582010-07-27 00:55:47 +0000420{
421 if (!append)
422 sc_list.Clear();
423
Chris Lattner24943d22010-06-08 16:52:24 +0000424 if (function != NULL)
425 {
426 // FIXME: Look in the class of the current function, if it exists,
427 // for methods matching name.
428 }
429
Chris Lattner24943d22010-06-08 16:52:24 +0000430 if (module_sp != NULL)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000431 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000432
433 if (target_sp)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000434 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000435
Sean Callanan0fc73582010-07-27 00:55:47 +0000436 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000437}
438
Greg Clayton6916e352010-11-13 03:52:47 +0000439//lldb::VariableSP
440//SymbolContext::FindVariableByName (const char *name) const
441//{
442// lldb::VariableSP return_value;
443// return return_value;
444//}
Chris Lattner24943d22010-06-08 16:52:24 +0000445
446lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000447SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000448{
449 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000450
451 TypeList types;
452
453 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
454 return types.GetTypeAtIndex(0);
455
456 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
457 return types.GetTypeAtIndex(0);
458
Chris Lattner24943d22010-06-08 16:52:24 +0000459 return return_value;
460}
461
Jim Inghamd60d94a2011-03-11 03:53:59 +0000462//----------------------------------------------------------------------
463//
464// SymbolContextSpecifier
465//
466//----------------------------------------------------------------------
467
468bool
469SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
470{
471 bool return_value = true;
472 switch (type)
473 {
474 case eNothingSpecified:
475 Clear();
476 break;
477 case eLineStartSpecified:
478 m_start_line = line_no;
479 m_type |= eLineStartSpecified;
480 break;
481 case eLineEndSpecified:
482 m_end_line = line_no;
483 m_type |= eLineEndSpecified;
484 break;
485 default:
486 return_value = false;
487 break;
488 }
489 return return_value;
490}
491
492bool
493SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
494{
495 bool return_value = true;
496 switch (type)
497 {
498 case eNothingSpecified:
499 Clear();
500 break;
501 case eModuleSpecified:
502 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000503 // See if we can find the Module, if so stick it in the SymbolContext.
504 FileSpec module_spec(spec_string, false);
505 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000506 m_type |= eModuleSpecified;
507 if (module_sp)
508 m_module_sp = module_sp;
509 else
510 m_module_spec.assign (spec_string);
511 }
512 break;
513 case eFileSpecified:
514 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
515 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000516 m_file_spec_ap.reset (new FileSpec (spec_string, false));
Jim Inghamd60d94a2011-03-11 03:53:59 +0000517 m_type |= eFileSpecified;
518 break;
519 case eLineStartSpecified:
520 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
521 if (return_value)
522 m_type |= eLineStartSpecified;
523 break;
524 case eLineEndSpecified:
525 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
526 if (return_value)
527 m_type |= eLineEndSpecified;
528 break;
529 case eFunctionSpecified:
530 m_function_spec.assign(spec_string);
531 m_type |= eFunctionSpecified;
532 break;
533 case eClassOrNamespaceSpecified:
534 Clear();
535 m_class_name.assign (spec_string);
536 m_type = eClassOrNamespaceSpecified;
537 break;
538 case eAddressRangeSpecified:
539 // Not specified yet...
540 break;
541 }
542
543 return return_value;
544}
545
546void
547SymbolContextSpecifier::Clear()
548{
549 m_module_spec.clear();
550 m_file_spec_ap.reset();
551 m_function_spec.clear();
552 m_class_name.clear();
553 m_start_line = 0;
554 m_end_line = 0;
555 m_address_range_ap.reset();
556
557 m_type = eNothingSpecified;
558}
559
560bool
561SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
562{
563 if (m_type == eNothingSpecified)
564 return true;
565
566 if (m_target_sp.get() != sc.target_sp.get())
567 return false;
568
569 if (m_type & eModuleSpecified)
570 {
571 if (sc.module_sp)
572 {
573 if (m_module_sp.get() != NULL)
574 {
575 if (m_module_sp.get() != sc.module_sp.get())
576 return false;
577 }
578 else
579 {
580 FileSpec module_file_spec (m_module_spec.c_str(), false);
581 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
582 return false;
583 }
584 }
585 }
586 if (m_type & eFileSpecified)
587 {
588 if (m_file_spec_ap.get())
589 {
590 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
591 if (sc.block == NULL && sc.comp_unit == NULL)
592 return false;
593
594 // Check if the block is present, and if so is it inlined:
595 bool was_inlined = false;
596 if (sc.block != NULL)
597 {
598 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
599 if (inline_info != NULL)
600 {
601 was_inlined = true;
602 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
603 return false;
604 }
605 }
606
607 // Next check the comp unit, but only if the SymbolContext was not inlined.
608 if (!was_inlined && sc.comp_unit != NULL)
609 {
610 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
611 return false;
612 }
613 }
614 }
615 if (m_type & eLineStartSpecified
616 || m_type & eLineEndSpecified)
617 {
618 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
619 return false;
620 }
621
622 if (m_type & eFunctionSpecified)
623 {
624 // First check the current block, and if it is inlined, get the inlined function name:
625 bool was_inlined = false;
626 ConstString func_name(m_function_spec.c_str());
627
628 if (sc.block != NULL)
629 {
630 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
631 if (inline_info != NULL)
632 {
633 was_inlined = true;
634 const Mangled &name = inline_info->GetMangled();
635 if (!name.NameMatches (func_name))
636 return false;
637 }
638 }
639 // If it wasn't inlined, check the name in the function or symbol:
640 if (!was_inlined)
641 {
642 if (sc.function != NULL)
643 {
644 if (!sc.function->GetMangled().NameMatches(func_name))
645 return false;
646 }
647 else if (sc.symbol != NULL)
648 {
649 if (!sc.symbol->GetMangled().NameMatches(func_name))
650 return false;
651 }
652 }
653
654
655 }
656
657 return true;
658}
659
660bool
661SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
662{
663 if (m_type & eAddressRangeSpecified)
664 {
665
666 }
667 else
668 {
669 Address match_address (addr, NULL);
670 SymbolContext sc;
671 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
672 return SymbolContextMatches(sc);
673 }
674 return true;
675}
676
677void
678SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
679{
680 char path_str[PATH_MAX + 1];
681
682 if (m_type == eNothingSpecified)
683 {
684 s->Printf ("Nothing specified.\n");
685 }
686
687 if (m_type == eModuleSpecified)
688 {
689 s->Indent();
690 if (m_module_sp)
691 {
692 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
693 s->Printf ("Module: %s\n", path_str);
694 }
695 else
696 s->Printf ("Module: %s\n", m_module_spec.c_str());
697 }
698
699 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL)
700 {
701 m_file_spec_ap->GetPath (path_str, PATH_MAX);
702 s->Indent();
703 s->Printf ("File: %s", path_str);
704 if (m_type == eLineStartSpecified)
705 {
706 s->Printf (" from line %d", m_start_line);
707 if (m_type == eLineEndSpecified)
708 s->Printf ("to line %d", m_end_line);
709 else
710 s->Printf ("to end", m_end_line);
711 }
712 else if (m_type == eLineEndSpecified)
713 {
714 s->Printf (" from start to line %d", m_end_line);
715 }
716 s->Printf (".\n");
717 }
718
719 if (m_type == eLineStartSpecified)
720 {
721 s->Indent();
722 s->Printf ("From line %d", m_start_line);
723 if (m_type == eLineEndSpecified)
724 s->Printf ("to line %d", m_end_line);
725 else
726 s->Printf ("to end", m_end_line);
727 s->Printf (".\n");
728 }
729 else if (m_type == eLineEndSpecified)
730 {
731 s->Printf ("From start to line %d.\n", m_end_line);
732 }
733
734 if (m_type == eFunctionSpecified)
735 {
736 s->Indent();
737 s->Printf ("Function: %s.\n", m_function_spec.c_str());
738 }
739
740 if (m_type == eClassOrNamespaceSpecified)
741 {
742 s->Indent();
743 s->Printf ("Class name: %s.\n", m_class_name.c_str());
744 }
745
746 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
747 {
748 s->Indent();
749 s->PutCString ("Address range: ");
750 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
751 s->PutCString ("\n");
752 }
753}
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000754
Chris Lattner24943d22010-06-08 16:52:24 +0000755//----------------------------------------------------------------------
756//
757// SymbolContextList
758//
759//----------------------------------------------------------------------
760
761
762SymbolContextList::SymbolContextList() :
763 m_symbol_contexts()
764{
765}
766
767SymbolContextList::~SymbolContextList()
768{
769}
770
771void
772SymbolContextList::Append(const SymbolContext& sc)
773{
774 m_symbol_contexts.push_back(sc);
775}
776
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000777bool
Greg Clayton889fbd02011-03-26 19:14:58 +0000778SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000779{
Greg Clayton889fbd02011-03-26 19:14:58 +0000780 collection::iterator pos, end = m_symbol_contexts.end();
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000781 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
782 {
783 if (*pos == sc)
784 return false;
785 }
Greg Clayton889fbd02011-03-26 19:14:58 +0000786 if (merge_symbol_into_function
787 && sc.symbol != NULL
788 && sc.comp_unit == NULL
789 && sc.function == NULL
790 && sc.block == NULL
791 && sc.line_entry.IsValid() == false)
792 {
793 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
794 if (symbol_range)
795 {
796 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
797 {
798 if (pos->function)
799 {
800 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
801 {
802 // Do we already have a function with this symbol?
803 if (pos->symbol == sc.symbol)
804 return false;
805 if (pos->symbol == NULL)
806 {
807 pos->symbol = sc.symbol;
808 return false;
809 }
810 }
811 }
812 }
813 }
814 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000815 m_symbol_contexts.push_back(sc);
816 return true;
817}
818
Chris Lattner24943d22010-06-08 16:52:24 +0000819void
820SymbolContextList::Clear()
821{
822 m_symbol_contexts.clear();
823}
824
825void
Greg Claytoneea26402010-09-14 23:36:40 +0000826SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000827{
828
829 *s << (void *)this << ": ";
830 s->Indent();
831 s->PutCString("SymbolContextList");
832 s->EOL();
833 s->IndentMore();
834
835 collection::const_iterator pos, end = m_symbol_contexts.end();
836 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
837 {
Greg Claytoneea26402010-09-14 23:36:40 +0000838 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000839 }
840 s->IndentLess();
841}
842
843bool
844SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
845{
846 if (idx < m_symbol_contexts.size())
847 {
848 sc = m_symbol_contexts[idx];
849 return true;
850 }
851 return false;
852}
853
854bool
855SymbolContextList::RemoveContextAtIndex (uint32_t idx)
856{
857 if (idx < m_symbol_contexts.size())
858 {
859 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
860 return true;
861 }
862 return false;
863}
864
865uint32_t
866SymbolContextList::GetSize() const
867{
868 return m_symbol_contexts.size();
869}
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000870
871uint32_t
872SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
873{
874 uint32_t match_count = 0;
875 const uint32_t size = m_symbol_contexts.size();
876 for (uint32_t idx = 0; idx<size; ++idx)
877 {
878 if (m_symbol_contexts[idx].line_entry.line == line)
879 ++match_count;
880 }
881 return match_count;
882}
883