blob: 2a56c3444c27a9e8d9bd042a2aa3be5d27045304 [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
Sean Callanan65ec7242011-05-10 19:47:39 +000012#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000013#include "lldb/Core/Module.h"
Greg Claytonf15996e2011-04-07 22:46:35 +000014#include "lldb/Interpreter/Args.h"
Greg Clayton12bec712010-06-28 21:30:43 +000015#include "lldb/Symbol/CompileUnit.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Symbol/ObjectFile.h"
17#include "lldb/Symbol/Symbol.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton12bec712010-06-28 21:30:43 +000019#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020
21using namespace lldb;
22using namespace lldb_private;
23
24SymbolContext::SymbolContext() :
25 target_sp (),
26 module_sp (),
27 comp_unit (NULL),
28 function (NULL),
29 block (NULL),
30 line_entry (),
31 symbol (NULL)
32{
33}
34
35SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
36 target_sp (),
37 module_sp (m),
38 comp_unit (cu),
39 function (f),
40 block (b),
41 line_entry (),
42 symbol (s)
43{
44 if (le)
45 line_entry = *le;
46}
47
48SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
49 target_sp (t),
50 module_sp (m),
51 comp_unit (cu),
52 function (f),
53 block (b),
54 line_entry (),
55 symbol (s)
56{
57 if (le)
58 line_entry = *le;
59}
60
61SymbolContext::SymbolContext(const SymbolContext& rhs) :
62 target_sp (rhs.target_sp),
63 module_sp (rhs.module_sp),
64 comp_unit (rhs.comp_unit),
65 function (rhs.function),
66 block (rhs.block),
67 line_entry (rhs.line_entry),
68 symbol (rhs.symbol)
69{
70}
71
72
73SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
74 target_sp (),
75 module_sp (),
76 comp_unit (NULL),
77 function (NULL),
78 block (NULL),
79 line_entry (),
80 symbol (NULL)
81{
82 sc_scope->CalculateSymbolContext (this);
83}
84
85const SymbolContext&
86SymbolContext::operator= (const SymbolContext& rhs)
87{
88 if (this != &rhs)
89 {
90 target_sp = rhs.target_sp;
91 module_sp = rhs.module_sp;
92 comp_unit = rhs.comp_unit;
93 function = rhs.function;
94 block = rhs.block;
95 line_entry = rhs.line_entry;
96 symbol = rhs.symbol;
97 }
98 return *this;
99}
100
101void
102SymbolContext::Clear()
103{
104 target_sp.reset();
105 module_sp.reset();
106 comp_unit = NULL;
107 function = NULL;
108 block = NULL;
109 line_entry.Clear();
110 symbol = NULL;
111}
112
113void
114SymbolContext::DumpStopContext
115(
116 Stream *s,
117 ExecutionContextScope *exe_scope,
118 const Address &addr,
Greg Clayton72b71582010-09-02 21:44:10 +0000119 bool show_fullpaths,
Greg Clayton33ed1702010-08-24 00:45:41 +0000120 bool show_module,
121 bool show_inlined_frames
Chris Lattner24943d22010-06-08 16:52:24 +0000122) const
123{
Chris Lattner24943d22010-06-08 16:52:24 +0000124 if (show_module && module_sp)
125 {
Greg Clayton72b71582010-09-02 21:44:10 +0000126 if (show_fullpaths)
127 *s << module_sp->GetFileSpec();
128 else
129 *s << module_sp->GetFileSpec().GetFilename();
130 s->PutChar('`');
Chris Lattner24943d22010-06-08 16:52:24 +0000131 }
132
133 if (function != NULL)
134 {
135 if (function->GetMangled().GetName())
136 function->GetMangled().GetName().Dump(s);
137
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000138 if (addr.IsValid())
139 {
140 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
141 if (function_offset)
142 s->Printf(" + %llu", function_offset);
143 }
Chris Lattner24943d22010-06-08 16:52:24 +0000144
145 if (block != NULL)
146 {
147 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000148 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000149 s->IndentLess();
150 }
151 else
152 {
153 if (line_entry.IsValid())
154 {
155 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000156 if (line_entry.DumpStopContext(s, show_fullpaths))
Chris Lattner24943d22010-06-08 16:52:24 +0000157 return;
158 }
159 }
160 }
161 else if (symbol != NULL)
162 {
163 symbol->GetMangled().GetName().Dump(s);
164
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000165 if (addr.IsValid() && symbol->GetAddressRangePtr())
Chris Lattner24943d22010-06-08 16:52:24 +0000166 {
Greg Clayton70436352010-06-30 23:03:03 +0000167 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
168 if (symbol_offset)
169 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000170 }
171 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000172 else if (addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000173 {
174 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
175 }
176}
177
178void
Greg Claytoneea26402010-09-14 23:36:40 +0000179SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000180{
181 if (module_sp)
182 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000183 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000184 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000185 *s << '"';
186 if (module_sp->GetArchitecture().IsValid())
Greg Clayton940b1032011-02-23 00:35:02 +0000187 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
Greg Clayton12bec712010-06-28 21:30:43 +0000188 s->EOL();
189 }
190
191 if (comp_unit != NULL)
192 {
193 s->Indent("CompileUnit: ");
194 comp_unit->GetDescription (s, level);
195 s->EOL();
196 }
197
198 if (function != NULL)
199 {
200 s->Indent(" Function: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000201 function->GetDescription (s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000202 s->EOL();
203
204 Type *func_type = function->GetType();
205 if (func_type)
206 {
207 s->Indent(" FuncType: ");
208 func_type->GetDescription (s, level, false);
209 s->EOL();
210 }
211 }
212
213 if (block != NULL)
214 {
215 std::vector<Block *> blocks;
216 blocks.push_back (block);
217 Block *parent_block = block->GetParent();
218
219 while (parent_block)
220 {
221 blocks.push_back (parent_block);
222 parent_block = parent_block->GetParent();
223 }
224 std::vector<Block *>::reverse_iterator pos;
225 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
226 std::vector<Block *>::reverse_iterator end = blocks.rend();
227 for (pos = begin; pos != end; ++pos)
228 {
229 if (pos == begin)
230 s->Indent(" Blocks: ");
231 else
232 s->Indent(" ");
Greg Claytoneea26402010-09-14 23:36:40 +0000233 (*pos)->GetDescription(s, function, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000234 s->EOL();
235 }
236 }
237
238 if (line_entry.IsValid())
239 {
240 s->Indent(" LineEntry: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000241 line_entry.GetDescription (s, level, comp_unit, target, false);
Greg Clayton12bec712010-06-28 21:30:43 +0000242 s->EOL();
243 }
244
245 if (symbol != NULL)
246 {
247 s->Indent(" Symbol: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000248 symbol->GetDescription(s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000249 s->EOL();
250 }
251}
252
Greg Clayton33ed1702010-08-24 00:45:41 +0000253uint32_t
254SymbolContext::GetResolvedMask () const
255{
256 uint32_t resolved_mask = 0;
257 if (target_sp) resolved_mask |= eSymbolContextTarget;
258 if (module_sp) resolved_mask |= eSymbolContextModule;
259 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
260 if (function) resolved_mask |= eSymbolContextFunction;
261 if (block) resolved_mask |= eSymbolContextBlock;
262 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
263 if (symbol) resolved_mask |= eSymbolContextSymbol;
264 return resolved_mask;
265}
Greg Clayton12bec712010-06-28 21:30:43 +0000266
267
268void
Greg Claytoneea26402010-09-14 23:36:40 +0000269SymbolContext::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000270{
271 *s << (void *)this << ": ";
272 s->Indent();
273 s->PutCString("SymbolContext");
274 s->IndentMore();
275 s->EOL();
276 s->IndentMore();
277 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000278 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000279 if (module_sp)
280 module_sp->GetFileSpec().Dump(s);
281 s->EOL();
282 s->Indent();
283 *s << "CompileUnit = " << (void *)comp_unit;
284 if (comp_unit != NULL)
Johnny Chencff44fd2010-10-29 22:18:43 +0000285 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000286 s->EOL();
287 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000288 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000289 if (function != NULL)
290 {
Greg Clayton12bec712010-06-28 21:30:43 +0000291 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000292 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Greg Clayton12bec712010-06-28 21:30:43 +0000293 s->EOL();
294 s->Indent();
295 Type* func_type = function->GetType();
296 if (func_type)
297 {
298 *s << " Type = ";
299 func_type->Dump (s, false);
300 }
Chris Lattner24943d22010-06-08 16:52:24 +0000301 }
302 s->EOL();
303 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000304 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000305 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000306 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000307 // Dump the block and pass it a negative depth to we print all the parent blocks
308 //if (block != NULL)
309 // block->Dump(s, function->GetFileAddress(), INT_MIN);
310 s->EOL();
311 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000312 *s << "LineEntry = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000313 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000314 s->EOL();
315 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000316 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000317 if (symbol != NULL && symbol->GetMangled())
318 *s << ' ' << symbol->GetMangled().GetName().AsCString();
319 s->EOL();
320 s->IndentLess();
321 s->IndentLess();
322}
323
324bool
325lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
326{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000327 return lhs.function == rhs.function
328 && lhs.symbol == rhs.symbol
329 && lhs.module_sp.get() == rhs.module_sp.get()
330 && lhs.comp_unit == rhs.comp_unit
331 && lhs.target_sp.get() == rhs.target_sp.get()
332 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000333}
334
335bool
336lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
337{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000338 return lhs.function != rhs.function
Greg Clayton889fbd02011-03-26 19:14:58 +0000339 || lhs.symbol != rhs.symbol
340 || lhs.module_sp.get() != rhs.module_sp.get()
341 || lhs.comp_unit != rhs.comp_unit
342 || lhs.target_sp.get() != rhs.target_sp.get()
343 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000344}
345
346bool
Greg Claytonff44ab42011-04-23 02:04:55 +0000347SymbolContext::GetAddressRange (uint32_t scope,
348 uint32_t range_idx,
349 bool use_inline_block_range,
350 AddressRange &range) const
Chris Lattner24943d22010-06-08 16:52:24 +0000351{
352 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
353 {
354 range = line_entry.range;
355 return true;
356 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000357
358 if ((scope & eSymbolContextBlock) && (block != NULL))
Chris Lattner24943d22010-06-08 16:52:24 +0000359 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000360 if (use_inline_block_range)
Chris Lattner24943d22010-06-08 16:52:24 +0000361 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000362 Block *inline_block = block->GetContainingInlinedBlock();
363 if (inline_block)
364 return inline_block->GetRangeAtIndex (range_idx, range);
365 }
366 else
367 {
368 return block->GetRangeAtIndex (range_idx, range);
369 }
370 }
371
372 if ((scope & eSymbolContextFunction) && (function != NULL))
373 {
374 if (range_idx == 0)
375 {
376 range = function->GetAddressRange();
377 return true;
378 }
379 }
380
381 if ((scope & eSymbolContextSymbol) && (symbol != NULL) && (symbol->GetAddressRangePtr() != NULL))
382 {
383 if (range_idx == 0)
384 {
385 range = *symbol->GetAddressRangePtr();
386
387 if (range.GetByteSize() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000388 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000389 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000390 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000391 ObjectFile *objfile = module_sp->GetObjectFile();
392 if (objfile)
393 {
394 Symtab *symtab = objfile->GetSymtab();
395 if (symtab)
396 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
397 }
Chris Lattner24943d22010-06-08 16:52:24 +0000398 }
399 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000400 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000401 }
Chris Lattner24943d22010-06-08 16:52:24 +0000402 }
403 range.Clear();
404 return false;
405}
406
Greg Clayton6916e352010-11-13 03:52:47 +0000407ClangNamespaceDecl
408SymbolContext::FindNamespace (const ConstString &name) const
409{
410 ClangNamespaceDecl namespace_decl;
411 if (module_sp)
412 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name);
413 return namespace_decl;
414}
Chris Lattner24943d22010-06-08 16:52:24 +0000415
Sean Callanan0fc73582010-07-27 00:55:47 +0000416size_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000417SymbolContext::FindFunctionsByName (const ConstString &name,
418 bool include_symbols,
419 bool append,
420 SymbolContextList &sc_list) const
Sean Callanan0fc73582010-07-27 00:55:47 +0000421{
422 if (!append)
423 sc_list.Clear();
424
Chris Lattner24943d22010-06-08 16:52:24 +0000425 if (function != NULL)
426 {
427 // FIXME: Look in the class of the current function, if it exists,
428 // for methods matching name.
429 }
430
Chris Lattner24943d22010-06-08 16:52:24 +0000431 if (module_sp != NULL)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000432 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000433
434 if (target_sp)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000435 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, 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
Greg Clayton6916e352010-11-13 03:52:47 +0000440//lldb::VariableSP
441//SymbolContext::FindVariableByName (const char *name) const
442//{
443// lldb::VariableSP return_value;
444// return return_value;
445//}
Chris Lattner24943d22010-06-08 16:52:24 +0000446
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
Sean Callanan65ec7242011-05-10 19:47:39 +0000457 SymbolContext sc_for_global_search;
458
459 sc_for_global_search.target_sp = target_sp;
460
461 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (sc_for_global_search, name, false, 1, types))
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000462 return types.GetTypeAtIndex(0);
463
Chris Lattner24943d22010-06-08 16:52:24 +0000464 return return_value;
465}
466
Jim Inghamd60d94a2011-03-11 03:53:59 +0000467//----------------------------------------------------------------------
468//
469// SymbolContextSpecifier
470//
471//----------------------------------------------------------------------
472
473bool
474SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
475{
476 bool return_value = true;
477 switch (type)
478 {
479 case eNothingSpecified:
480 Clear();
481 break;
482 case eLineStartSpecified:
483 m_start_line = line_no;
484 m_type |= eLineStartSpecified;
485 break;
486 case eLineEndSpecified:
487 m_end_line = line_no;
488 m_type |= eLineEndSpecified;
489 break;
490 default:
491 return_value = false;
492 break;
493 }
494 return return_value;
495}
496
497bool
498SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
499{
500 bool return_value = true;
501 switch (type)
502 {
503 case eNothingSpecified:
504 Clear();
505 break;
506 case eModuleSpecified:
507 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000508 // See if we can find the Module, if so stick it in the SymbolContext.
509 FileSpec module_spec(spec_string, false);
510 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000511 m_type |= eModuleSpecified;
512 if (module_sp)
513 m_module_sp = module_sp;
514 else
515 m_module_spec.assign (spec_string);
516 }
517 break;
518 case eFileSpecified:
519 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
520 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000521 m_file_spec_ap.reset (new FileSpec (spec_string, false));
Jim Inghamd60d94a2011-03-11 03:53:59 +0000522 m_type |= eFileSpecified;
523 break;
524 case eLineStartSpecified:
525 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
526 if (return_value)
527 m_type |= eLineStartSpecified;
528 break;
529 case eLineEndSpecified:
530 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
531 if (return_value)
532 m_type |= eLineEndSpecified;
533 break;
534 case eFunctionSpecified:
535 m_function_spec.assign(spec_string);
536 m_type |= eFunctionSpecified;
537 break;
538 case eClassOrNamespaceSpecified:
539 Clear();
540 m_class_name.assign (spec_string);
541 m_type = eClassOrNamespaceSpecified;
542 break;
543 case eAddressRangeSpecified:
544 // Not specified yet...
545 break;
546 }
547
548 return return_value;
549}
550
551void
552SymbolContextSpecifier::Clear()
553{
554 m_module_spec.clear();
555 m_file_spec_ap.reset();
556 m_function_spec.clear();
557 m_class_name.clear();
558 m_start_line = 0;
559 m_end_line = 0;
560 m_address_range_ap.reset();
561
562 m_type = eNothingSpecified;
563}
564
565bool
566SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
567{
568 if (m_type == eNothingSpecified)
569 return true;
570
571 if (m_target_sp.get() != sc.target_sp.get())
572 return false;
573
574 if (m_type & eModuleSpecified)
575 {
576 if (sc.module_sp)
577 {
578 if (m_module_sp.get() != NULL)
579 {
580 if (m_module_sp.get() != sc.module_sp.get())
581 return false;
582 }
583 else
584 {
585 FileSpec module_file_spec (m_module_spec.c_str(), false);
586 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
587 return false;
588 }
589 }
590 }
591 if (m_type & eFileSpecified)
592 {
593 if (m_file_spec_ap.get())
594 {
595 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
596 if (sc.block == NULL && sc.comp_unit == NULL)
597 return false;
598
599 // Check if the block is present, and if so is it inlined:
600 bool was_inlined = false;
601 if (sc.block != NULL)
602 {
603 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
604 if (inline_info != NULL)
605 {
606 was_inlined = true;
607 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
608 return false;
609 }
610 }
611
612 // Next check the comp unit, but only if the SymbolContext was not inlined.
613 if (!was_inlined && sc.comp_unit != NULL)
614 {
615 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
616 return false;
617 }
618 }
619 }
620 if (m_type & eLineStartSpecified
621 || m_type & eLineEndSpecified)
622 {
623 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
624 return false;
625 }
626
627 if (m_type & eFunctionSpecified)
628 {
629 // First check the current block, and if it is inlined, get the inlined function name:
630 bool was_inlined = false;
631 ConstString func_name(m_function_spec.c_str());
632
633 if (sc.block != NULL)
634 {
635 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
636 if (inline_info != NULL)
637 {
638 was_inlined = true;
639 const Mangled &name = inline_info->GetMangled();
640 if (!name.NameMatches (func_name))
641 return false;
642 }
643 }
644 // If it wasn't inlined, check the name in the function or symbol:
645 if (!was_inlined)
646 {
647 if (sc.function != NULL)
648 {
649 if (!sc.function->GetMangled().NameMatches(func_name))
650 return false;
651 }
652 else if (sc.symbol != NULL)
653 {
654 if (!sc.symbol->GetMangled().NameMatches(func_name))
655 return false;
656 }
657 }
658
659
660 }
661
662 return true;
663}
664
665bool
666SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
667{
668 if (m_type & eAddressRangeSpecified)
669 {
670
671 }
672 else
673 {
674 Address match_address (addr, NULL);
675 SymbolContext sc;
676 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
677 return SymbolContextMatches(sc);
678 }
679 return true;
680}
681
682void
683SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
684{
685 char path_str[PATH_MAX + 1];
686
687 if (m_type == eNothingSpecified)
688 {
689 s->Printf ("Nothing specified.\n");
690 }
691
692 if (m_type == eModuleSpecified)
693 {
694 s->Indent();
695 if (m_module_sp)
696 {
697 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
698 s->Printf ("Module: %s\n", path_str);
699 }
700 else
701 s->Printf ("Module: %s\n", m_module_spec.c_str());
702 }
703
704 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL)
705 {
706 m_file_spec_ap->GetPath (path_str, PATH_MAX);
707 s->Indent();
708 s->Printf ("File: %s", path_str);
709 if (m_type == eLineStartSpecified)
710 {
711 s->Printf (" from line %d", m_start_line);
712 if (m_type == eLineEndSpecified)
713 s->Printf ("to line %d", m_end_line);
714 else
715 s->Printf ("to end", m_end_line);
716 }
717 else if (m_type == eLineEndSpecified)
718 {
719 s->Printf (" from start to line %d", m_end_line);
720 }
721 s->Printf (".\n");
722 }
723
724 if (m_type == eLineStartSpecified)
725 {
726 s->Indent();
727 s->Printf ("From line %d", m_start_line);
728 if (m_type == eLineEndSpecified)
729 s->Printf ("to line %d", m_end_line);
730 else
731 s->Printf ("to end", m_end_line);
732 s->Printf (".\n");
733 }
734 else if (m_type == eLineEndSpecified)
735 {
736 s->Printf ("From start to line %d.\n", m_end_line);
737 }
738
739 if (m_type == eFunctionSpecified)
740 {
741 s->Indent();
742 s->Printf ("Function: %s.\n", m_function_spec.c_str());
743 }
744
745 if (m_type == eClassOrNamespaceSpecified)
746 {
747 s->Indent();
748 s->Printf ("Class name: %s.\n", m_class_name.c_str());
749 }
750
751 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
752 {
753 s->Indent();
754 s->PutCString ("Address range: ");
755 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
756 s->PutCString ("\n");
757 }
758}
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000759
Chris Lattner24943d22010-06-08 16:52:24 +0000760//----------------------------------------------------------------------
761//
762// SymbolContextList
763//
764//----------------------------------------------------------------------
765
766
767SymbolContextList::SymbolContextList() :
768 m_symbol_contexts()
769{
770}
771
772SymbolContextList::~SymbolContextList()
773{
774}
775
776void
777SymbolContextList::Append(const SymbolContext& sc)
778{
779 m_symbol_contexts.push_back(sc);
780}
781
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000782bool
Greg Clayton889fbd02011-03-26 19:14:58 +0000783SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000784{
Greg Clayton889fbd02011-03-26 19:14:58 +0000785 collection::iterator pos, end = m_symbol_contexts.end();
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000786 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
787 {
788 if (*pos == sc)
789 return false;
790 }
Greg Clayton889fbd02011-03-26 19:14:58 +0000791 if (merge_symbol_into_function
792 && sc.symbol != NULL
793 && sc.comp_unit == NULL
794 && sc.function == NULL
795 && sc.block == NULL
796 && sc.line_entry.IsValid() == false)
797 {
798 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
799 if (symbol_range)
800 {
801 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
802 {
803 if (pos->function)
804 {
805 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
806 {
807 // Do we already have a function with this symbol?
808 if (pos->symbol == sc.symbol)
809 return false;
810 if (pos->symbol == NULL)
811 {
812 pos->symbol = sc.symbol;
813 return false;
814 }
815 }
816 }
817 }
818 }
819 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000820 m_symbol_contexts.push_back(sc);
821 return true;
822}
823
Chris Lattner24943d22010-06-08 16:52:24 +0000824void
825SymbolContextList::Clear()
826{
827 m_symbol_contexts.clear();
828}
829
830void
Greg Claytoneea26402010-09-14 23:36:40 +0000831SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000832{
833
834 *s << (void *)this << ": ";
835 s->Indent();
836 s->PutCString("SymbolContextList");
837 s->EOL();
838 s->IndentMore();
839
840 collection::const_iterator pos, end = m_symbol_contexts.end();
841 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
842 {
Greg Claytoneea26402010-09-14 23:36:40 +0000843 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000844 }
845 s->IndentLess();
846}
847
848bool
849SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
850{
851 if (idx < m_symbol_contexts.size())
852 {
853 sc = m_symbol_contexts[idx];
854 return true;
855 }
856 return false;
857}
858
859bool
860SymbolContextList::RemoveContextAtIndex (uint32_t idx)
861{
862 if (idx < m_symbol_contexts.size())
863 {
864 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
865 return true;
866 }
867 return false;
868}
869
870uint32_t
871SymbolContextList::GetSize() const
872{
873 return m_symbol_contexts.size();
874}
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000875
876uint32_t
877SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
878{
879 uint32_t match_count = 0;
880 const uint32_t size = m_symbol_contexts.size();
881 for (uint32_t idx = 0; idx<size; ++idx)
882 {
883 if (m_symbol_contexts[idx].line_entry.line == line)
884 ++match_count;
885 }
886 return match_count;
887}
888