blob: 1f24f1339bd8296f94f03b65bf6401d2e8413d8c [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
Greg Claytonfb816422011-07-10 19:21:23 +0000113bool
Chris Lattner24943d22010-06-08 16:52:24 +0000114SymbolContext::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{
Greg Claytonfb816422011-07-10 19:21:23 +0000124 bool dumped_something = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000125 if (show_module && module_sp)
126 {
Greg Clayton72b71582010-09-02 21:44:10 +0000127 if (show_fullpaths)
128 *s << module_sp->GetFileSpec();
129 else
130 *s << module_sp->GetFileSpec().GetFilename();
131 s->PutChar('`');
Greg Claytonfb816422011-07-10 19:21:23 +0000132 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000133 }
134
135 if (function != NULL)
136 {
137 if (function->GetMangled().GetName())
Greg Claytonfb816422011-07-10 19:21:23 +0000138 {
139 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000140 function->GetMangled().GetName().Dump(s);
Greg Claytonfb816422011-07-10 19:21:23 +0000141 }
Chris Lattner24943d22010-06-08 16:52:24 +0000142
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000143 if (addr.IsValid())
144 {
145 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
146 if (function_offset)
Greg Claytonfb816422011-07-10 19:21:23 +0000147 {
148 dumped_something = true;
149 s->Printf(" + %llu", function_offset);
150 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000151 }
Chris Lattner24943d22010-06-08 16:52:24 +0000152
153 if (block != NULL)
154 {
155 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000156 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000157 s->IndentLess();
Greg Claytonfb816422011-07-10 19:21:23 +0000158 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000159 }
160 else
161 {
162 if (line_entry.IsValid())
163 {
Greg Claytonfb816422011-07-10 19:21:23 +0000164 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000165 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000166 if (line_entry.DumpStopContext(s, show_fullpaths))
Chris Lattner24943d22010-06-08 16:52:24 +0000167 return;
168 }
169 }
170 }
171 else if (symbol != NULL)
172 {
Greg Claytonfb816422011-07-10 19:21:23 +0000173 if (symbol->GetMangled().GetName())
174 {
175 dumped_something = true;
176 symbol->GetMangled().GetName().Dump(s);
177 }
Chris Lattner24943d22010-06-08 16:52:24 +0000178
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000179 if (addr.IsValid() && symbol->GetAddressRangePtr())
Chris Lattner24943d22010-06-08 16:52:24 +0000180 {
Greg Clayton70436352010-06-30 23:03:03 +0000181 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
182 if (symbol_offset)
Greg Claytonfb816422011-07-10 19:21:23 +0000183 {
184 dumped_something = true;
185 s->Printf(" + %llu", symbol_offset);
186 }
Chris Lattner24943d22010-06-08 16:52:24 +0000187 }
188 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000189 else if (addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000190 {
191 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
Greg Claytonfb816422011-07-10 19:21:23 +0000192 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000193 }
Greg Claytonfb816422011-07-10 19:21:23 +0000194 return dumped_something;
Chris Lattner24943d22010-06-08 16:52:24 +0000195}
196
197void
Greg Claytoneea26402010-09-14 23:36:40 +0000198SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000199{
200 if (module_sp)
201 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000202 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000203 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000204 *s << '"';
205 if (module_sp->GetArchitecture().IsValid())
Greg Clayton940b1032011-02-23 00:35:02 +0000206 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
Greg Clayton12bec712010-06-28 21:30:43 +0000207 s->EOL();
208 }
209
210 if (comp_unit != NULL)
211 {
212 s->Indent("CompileUnit: ");
213 comp_unit->GetDescription (s, level);
214 s->EOL();
215 }
216
217 if (function != NULL)
218 {
219 s->Indent(" Function: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000220 function->GetDescription (s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000221 s->EOL();
222
223 Type *func_type = function->GetType();
224 if (func_type)
225 {
226 s->Indent(" FuncType: ");
227 func_type->GetDescription (s, level, false);
228 s->EOL();
229 }
230 }
231
232 if (block != NULL)
233 {
234 std::vector<Block *> blocks;
235 blocks.push_back (block);
236 Block *parent_block = block->GetParent();
237
238 while (parent_block)
239 {
240 blocks.push_back (parent_block);
241 parent_block = parent_block->GetParent();
242 }
243 std::vector<Block *>::reverse_iterator pos;
244 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
245 std::vector<Block *>::reverse_iterator end = blocks.rend();
246 for (pos = begin; pos != end; ++pos)
247 {
248 if (pos == begin)
249 s->Indent(" Blocks: ");
250 else
251 s->Indent(" ");
Greg Claytoneea26402010-09-14 23:36:40 +0000252 (*pos)->GetDescription(s, function, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000253 s->EOL();
254 }
255 }
256
257 if (line_entry.IsValid())
258 {
259 s->Indent(" LineEntry: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000260 line_entry.GetDescription (s, level, comp_unit, target, false);
Greg Clayton12bec712010-06-28 21:30:43 +0000261 s->EOL();
262 }
263
264 if (symbol != NULL)
265 {
266 s->Indent(" Symbol: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000267 symbol->GetDescription(s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000268 s->EOL();
269 }
270}
271
Greg Clayton33ed1702010-08-24 00:45:41 +0000272uint32_t
273SymbolContext::GetResolvedMask () const
274{
275 uint32_t resolved_mask = 0;
276 if (target_sp) resolved_mask |= eSymbolContextTarget;
277 if (module_sp) resolved_mask |= eSymbolContextModule;
278 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
279 if (function) resolved_mask |= eSymbolContextFunction;
280 if (block) resolved_mask |= eSymbolContextBlock;
281 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
282 if (symbol) resolved_mask |= eSymbolContextSymbol;
283 return resolved_mask;
284}
Greg Clayton12bec712010-06-28 21:30:43 +0000285
286
287void
Greg Claytoneea26402010-09-14 23:36:40 +0000288SymbolContext::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000289{
290 *s << (void *)this << ": ";
291 s->Indent();
292 s->PutCString("SymbolContext");
293 s->IndentMore();
294 s->EOL();
295 s->IndentMore();
296 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000297 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000298 if (module_sp)
299 module_sp->GetFileSpec().Dump(s);
300 s->EOL();
301 s->Indent();
302 *s << "CompileUnit = " << (void *)comp_unit;
303 if (comp_unit != NULL)
Johnny Chencff44fd2010-10-29 22:18:43 +0000304 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000305 s->EOL();
306 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000307 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000308 if (function != NULL)
309 {
Greg Clayton12bec712010-06-28 21:30:43 +0000310 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000311 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Greg Clayton12bec712010-06-28 21:30:43 +0000312 s->EOL();
313 s->Indent();
314 Type* func_type = function->GetType();
315 if (func_type)
316 {
317 *s << " Type = ";
318 func_type->Dump (s, false);
319 }
Chris Lattner24943d22010-06-08 16:52:24 +0000320 }
321 s->EOL();
322 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000323 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000324 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000325 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000326 // Dump the block and pass it a negative depth to we print all the parent blocks
327 //if (block != NULL)
328 // block->Dump(s, function->GetFileAddress(), INT_MIN);
329 s->EOL();
330 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000331 *s << "LineEntry = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000332 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 s->EOL();
334 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000335 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000336 if (symbol != NULL && symbol->GetMangled())
337 *s << ' ' << symbol->GetMangled().GetName().AsCString();
338 s->EOL();
339 s->IndentLess();
340 s->IndentLess();
341}
342
343bool
344lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
345{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000346 return lhs.function == rhs.function
347 && lhs.symbol == rhs.symbol
348 && lhs.module_sp.get() == rhs.module_sp.get()
349 && lhs.comp_unit == rhs.comp_unit
350 && lhs.target_sp.get() == rhs.target_sp.get()
351 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000352}
353
354bool
355lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
356{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000357 return lhs.function != rhs.function
Greg Clayton889fbd02011-03-26 19:14:58 +0000358 || lhs.symbol != rhs.symbol
359 || lhs.module_sp.get() != rhs.module_sp.get()
360 || lhs.comp_unit != rhs.comp_unit
361 || lhs.target_sp.get() != rhs.target_sp.get()
362 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000363}
364
365bool
Greg Claytonff44ab42011-04-23 02:04:55 +0000366SymbolContext::GetAddressRange (uint32_t scope,
367 uint32_t range_idx,
368 bool use_inline_block_range,
369 AddressRange &range) const
Chris Lattner24943d22010-06-08 16:52:24 +0000370{
371 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
372 {
373 range = line_entry.range;
374 return true;
375 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000376
377 if ((scope & eSymbolContextBlock) && (block != NULL))
Chris Lattner24943d22010-06-08 16:52:24 +0000378 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000379 if (use_inline_block_range)
Chris Lattner24943d22010-06-08 16:52:24 +0000380 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000381 Block *inline_block = block->GetContainingInlinedBlock();
382 if (inline_block)
383 return inline_block->GetRangeAtIndex (range_idx, range);
384 }
385 else
386 {
387 return block->GetRangeAtIndex (range_idx, range);
388 }
389 }
390
391 if ((scope & eSymbolContextFunction) && (function != NULL))
392 {
393 if (range_idx == 0)
394 {
395 range = function->GetAddressRange();
396 return true;
397 }
398 }
399
400 if ((scope & eSymbolContextSymbol) && (symbol != NULL) && (symbol->GetAddressRangePtr() != NULL))
401 {
402 if (range_idx == 0)
403 {
404 range = *symbol->GetAddressRangePtr();
405
406 if (range.GetByteSize() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000407 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000408 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000409 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000410 ObjectFile *objfile = module_sp->GetObjectFile();
411 if (objfile)
412 {
413 Symtab *symtab = objfile->GetSymtab();
414 if (symtab)
415 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
416 }
Chris Lattner24943d22010-06-08 16:52:24 +0000417 }
418 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000419 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000420 }
Chris Lattner24943d22010-06-08 16:52:24 +0000421 }
422 range.Clear();
423 return false;
424}
425
Greg Clayton6916e352010-11-13 03:52:47 +0000426ClangNamespaceDecl
427SymbolContext::FindNamespace (const ConstString &name) const
428{
429 ClangNamespaceDecl namespace_decl;
430 if (module_sp)
431 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name);
432 return namespace_decl;
433}
Chris Lattner24943d22010-06-08 16:52:24 +0000434
Sean Callanan0fc73582010-07-27 00:55:47 +0000435size_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000436SymbolContext::FindFunctionsByName (const ConstString &name,
437 bool include_symbols,
438 bool append,
439 SymbolContextList &sc_list) const
Sean Callanan0fc73582010-07-27 00:55:47 +0000440{
441 if (!append)
442 sc_list.Clear();
443
Chris Lattner24943d22010-06-08 16:52:24 +0000444 if (function != NULL)
445 {
446 // FIXME: Look in the class of the current function, if it exists,
447 // for methods matching name.
448 }
449
Chris Lattner24943d22010-06-08 16:52:24 +0000450 if (module_sp != NULL)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000451 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000452
453 if (target_sp)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000454 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000455
Sean Callanan0fc73582010-07-27 00:55:47 +0000456 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000457}
458
Greg Clayton6916e352010-11-13 03:52:47 +0000459//lldb::VariableSP
460//SymbolContext::FindVariableByName (const char *name) const
461//{
462// lldb::VariableSP return_value;
463// return return_value;
464//}
Chris Lattner24943d22010-06-08 16:52:24 +0000465
466lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000467SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000468{
469 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000470
471 TypeList types;
472
473 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
474 return types.GetTypeAtIndex(0);
475
Sean Callanan65ec7242011-05-10 19:47:39 +0000476 SymbolContext sc_for_global_search;
477
478 sc_for_global_search.target_sp = target_sp;
479
480 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 +0000481 return types.GetTypeAtIndex(0);
482
Chris Lattner24943d22010-06-08 16:52:24 +0000483 return return_value;
484}
485
Jim Inghamd60d94a2011-03-11 03:53:59 +0000486//----------------------------------------------------------------------
487//
488// SymbolContextSpecifier
489//
490//----------------------------------------------------------------------
491
492bool
493SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
494{
495 bool return_value = true;
496 switch (type)
497 {
498 case eNothingSpecified:
499 Clear();
500 break;
501 case eLineStartSpecified:
502 m_start_line = line_no;
503 m_type |= eLineStartSpecified;
504 break;
505 case eLineEndSpecified:
506 m_end_line = line_no;
507 m_type |= eLineEndSpecified;
508 break;
509 default:
510 return_value = false;
511 break;
512 }
513 return return_value;
514}
515
516bool
517SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
518{
519 bool return_value = true;
520 switch (type)
521 {
522 case eNothingSpecified:
523 Clear();
524 break;
525 case eModuleSpecified:
526 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000527 // See if we can find the Module, if so stick it in the SymbolContext.
528 FileSpec module_spec(spec_string, false);
529 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000530 m_type |= eModuleSpecified;
531 if (module_sp)
532 m_module_sp = module_sp;
533 else
534 m_module_spec.assign (spec_string);
535 }
536 break;
537 case eFileSpecified:
538 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
539 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000540 m_file_spec_ap.reset (new FileSpec (spec_string, false));
Jim Inghamd60d94a2011-03-11 03:53:59 +0000541 m_type |= eFileSpecified;
542 break;
543 case eLineStartSpecified:
544 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
545 if (return_value)
546 m_type |= eLineStartSpecified;
547 break;
548 case eLineEndSpecified:
549 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
550 if (return_value)
551 m_type |= eLineEndSpecified;
552 break;
553 case eFunctionSpecified:
554 m_function_spec.assign(spec_string);
555 m_type |= eFunctionSpecified;
556 break;
557 case eClassOrNamespaceSpecified:
558 Clear();
559 m_class_name.assign (spec_string);
560 m_type = eClassOrNamespaceSpecified;
561 break;
562 case eAddressRangeSpecified:
563 // Not specified yet...
564 break;
565 }
566
567 return return_value;
568}
569
570void
571SymbolContextSpecifier::Clear()
572{
573 m_module_spec.clear();
574 m_file_spec_ap.reset();
575 m_function_spec.clear();
576 m_class_name.clear();
577 m_start_line = 0;
578 m_end_line = 0;
579 m_address_range_ap.reset();
580
581 m_type = eNothingSpecified;
582}
583
584bool
585SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
586{
587 if (m_type == eNothingSpecified)
588 return true;
589
590 if (m_target_sp.get() != sc.target_sp.get())
591 return false;
592
593 if (m_type & eModuleSpecified)
594 {
595 if (sc.module_sp)
596 {
597 if (m_module_sp.get() != NULL)
598 {
599 if (m_module_sp.get() != sc.module_sp.get())
600 return false;
601 }
602 else
603 {
604 FileSpec module_file_spec (m_module_spec.c_str(), false);
605 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
606 return false;
607 }
608 }
609 }
610 if (m_type & eFileSpecified)
611 {
612 if (m_file_spec_ap.get())
613 {
614 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
615 if (sc.block == NULL && sc.comp_unit == NULL)
616 return false;
617
618 // Check if the block is present, and if so is it inlined:
619 bool was_inlined = false;
620 if (sc.block != NULL)
621 {
622 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
623 if (inline_info != NULL)
624 {
625 was_inlined = true;
626 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
627 return false;
628 }
629 }
630
631 // Next check the comp unit, but only if the SymbolContext was not inlined.
632 if (!was_inlined && sc.comp_unit != NULL)
633 {
634 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
635 return false;
636 }
637 }
638 }
639 if (m_type & eLineStartSpecified
640 || m_type & eLineEndSpecified)
641 {
642 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
643 return false;
644 }
645
646 if (m_type & eFunctionSpecified)
647 {
648 // First check the current block, and if it is inlined, get the inlined function name:
649 bool was_inlined = false;
650 ConstString func_name(m_function_spec.c_str());
651
652 if (sc.block != NULL)
653 {
654 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
655 if (inline_info != NULL)
656 {
657 was_inlined = true;
658 const Mangled &name = inline_info->GetMangled();
659 if (!name.NameMatches (func_name))
660 return false;
661 }
662 }
663 // If it wasn't inlined, check the name in the function or symbol:
664 if (!was_inlined)
665 {
666 if (sc.function != NULL)
667 {
668 if (!sc.function->GetMangled().NameMatches(func_name))
669 return false;
670 }
671 else if (sc.symbol != NULL)
672 {
673 if (!sc.symbol->GetMangled().NameMatches(func_name))
674 return false;
675 }
676 }
677
678
679 }
680
681 return true;
682}
683
684bool
685SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
686{
687 if (m_type & eAddressRangeSpecified)
688 {
689
690 }
691 else
692 {
693 Address match_address (addr, NULL);
694 SymbolContext sc;
695 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
696 return SymbolContextMatches(sc);
697 }
698 return true;
699}
700
701void
702SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
703{
704 char path_str[PATH_MAX + 1];
705
706 if (m_type == eNothingSpecified)
707 {
708 s->Printf ("Nothing specified.\n");
709 }
710
711 if (m_type == eModuleSpecified)
712 {
713 s->Indent();
714 if (m_module_sp)
715 {
716 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
717 s->Printf ("Module: %s\n", path_str);
718 }
719 else
720 s->Printf ("Module: %s\n", m_module_spec.c_str());
721 }
722
723 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL)
724 {
725 m_file_spec_ap->GetPath (path_str, PATH_MAX);
726 s->Indent();
727 s->Printf ("File: %s", path_str);
728 if (m_type == eLineStartSpecified)
729 {
730 s->Printf (" from line %d", m_start_line);
731 if (m_type == eLineEndSpecified)
732 s->Printf ("to line %d", m_end_line);
733 else
734 s->Printf ("to end", m_end_line);
735 }
736 else if (m_type == eLineEndSpecified)
737 {
738 s->Printf (" from start to line %d", m_end_line);
739 }
740 s->Printf (".\n");
741 }
742
743 if (m_type == eLineStartSpecified)
744 {
745 s->Indent();
746 s->Printf ("From line %d", m_start_line);
747 if (m_type == eLineEndSpecified)
748 s->Printf ("to line %d", m_end_line);
749 else
750 s->Printf ("to end", m_end_line);
751 s->Printf (".\n");
752 }
753 else if (m_type == eLineEndSpecified)
754 {
755 s->Printf ("From start to line %d.\n", m_end_line);
756 }
757
758 if (m_type == eFunctionSpecified)
759 {
760 s->Indent();
761 s->Printf ("Function: %s.\n", m_function_spec.c_str());
762 }
763
764 if (m_type == eClassOrNamespaceSpecified)
765 {
766 s->Indent();
767 s->Printf ("Class name: %s.\n", m_class_name.c_str());
768 }
769
770 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
771 {
772 s->Indent();
773 s->PutCString ("Address range: ");
774 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
775 s->PutCString ("\n");
776 }
777}
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000778
Chris Lattner24943d22010-06-08 16:52:24 +0000779//----------------------------------------------------------------------
780//
781// SymbolContextList
782//
783//----------------------------------------------------------------------
784
785
786SymbolContextList::SymbolContextList() :
787 m_symbol_contexts()
788{
789}
790
791SymbolContextList::~SymbolContextList()
792{
793}
794
795void
796SymbolContextList::Append(const SymbolContext& sc)
797{
798 m_symbol_contexts.push_back(sc);
799}
800
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000801bool
Greg Clayton889fbd02011-03-26 19:14:58 +0000802SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000803{
Greg Clayton889fbd02011-03-26 19:14:58 +0000804 collection::iterator pos, end = m_symbol_contexts.end();
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000805 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
806 {
807 if (*pos == sc)
808 return false;
809 }
Greg Clayton889fbd02011-03-26 19:14:58 +0000810 if (merge_symbol_into_function
811 && sc.symbol != NULL
812 && sc.comp_unit == NULL
813 && sc.function == NULL
814 && sc.block == NULL
815 && sc.line_entry.IsValid() == false)
816 {
817 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
818 if (symbol_range)
819 {
820 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
821 {
822 if (pos->function)
823 {
824 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
825 {
826 // Do we already have a function with this symbol?
827 if (pos->symbol == sc.symbol)
828 return false;
829 if (pos->symbol == NULL)
830 {
831 pos->symbol = sc.symbol;
832 return false;
833 }
834 }
835 }
836 }
837 }
838 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000839 m_symbol_contexts.push_back(sc);
840 return true;
841}
842
Chris Lattner24943d22010-06-08 16:52:24 +0000843void
844SymbolContextList::Clear()
845{
846 m_symbol_contexts.clear();
847}
848
849void
Greg Claytoneea26402010-09-14 23:36:40 +0000850SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000851{
852
853 *s << (void *)this << ": ";
854 s->Indent();
855 s->PutCString("SymbolContextList");
856 s->EOL();
857 s->IndentMore();
858
859 collection::const_iterator pos, end = m_symbol_contexts.end();
860 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
861 {
Greg Claytoneea26402010-09-14 23:36:40 +0000862 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000863 }
864 s->IndentLess();
865}
866
867bool
868SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
869{
870 if (idx < m_symbol_contexts.size())
871 {
872 sc = m_symbol_contexts[idx];
873 return true;
874 }
875 return false;
876}
877
878bool
879SymbolContextList::RemoveContextAtIndex (uint32_t idx)
880{
881 if (idx < m_symbol_contexts.size())
882 {
883 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
884 return true;
885 }
886 return false;
887}
888
889uint32_t
890SymbolContextList::GetSize() const
891{
892 return m_symbol_contexts.size();
893}
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000894
895uint32_t
896SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
897{
898 uint32_t match_count = 0;
899 const uint32_t size = m_symbol_contexts.size();
900 for (uint32_t idx = 0; idx<size; ++idx)
901 {
902 if (m_symbol_contexts[idx].line_entry.line == line)
903 ++match_count;
904 }
905 return match_count;
906}
907