blob: 45a5f52c3bf3f747af16debc839725077c702837 [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
Greg Clayton6e0101c2011-09-17 06:21:20 +000085SymbolContext::~SymbolContext ()
86{
87}
88
Chris Lattner24943d22010-06-08 16:52:24 +000089const SymbolContext&
90SymbolContext::operator= (const SymbolContext& rhs)
91{
92 if (this != &rhs)
93 {
94 target_sp = rhs.target_sp;
95 module_sp = rhs.module_sp;
96 comp_unit = rhs.comp_unit;
97 function = rhs.function;
98 block = rhs.block;
99 line_entry = rhs.line_entry;
100 symbol = rhs.symbol;
101 }
102 return *this;
103}
104
105void
106SymbolContext::Clear()
107{
108 target_sp.reset();
109 module_sp.reset();
110 comp_unit = NULL;
111 function = NULL;
112 block = NULL;
113 line_entry.Clear();
114 symbol = NULL;
115}
116
Greg Claytonfb816422011-07-10 19:21:23 +0000117bool
Chris Lattner24943d22010-06-08 16:52:24 +0000118SymbolContext::DumpStopContext
119(
120 Stream *s,
121 ExecutionContextScope *exe_scope,
122 const Address &addr,
Greg Clayton72b71582010-09-02 21:44:10 +0000123 bool show_fullpaths,
Greg Clayton33ed1702010-08-24 00:45:41 +0000124 bool show_module,
125 bool show_inlined_frames
Chris Lattner24943d22010-06-08 16:52:24 +0000126) const
127{
Greg Claytonfb816422011-07-10 19:21:23 +0000128 bool dumped_something = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000129 if (show_module && module_sp)
130 {
Greg Clayton72b71582010-09-02 21:44:10 +0000131 if (show_fullpaths)
132 *s << module_sp->GetFileSpec();
133 else
134 *s << module_sp->GetFileSpec().GetFilename();
135 s->PutChar('`');
Greg Claytonfb816422011-07-10 19:21:23 +0000136 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000137 }
138
139 if (function != NULL)
140 {
141 if (function->GetMangled().GetName())
Greg Claytonfb816422011-07-10 19:21:23 +0000142 {
143 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000144 function->GetMangled().GetName().Dump(s);
Greg Claytonfb816422011-07-10 19:21:23 +0000145 }
Chris Lattner24943d22010-06-08 16:52:24 +0000146
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000147 if (addr.IsValid())
148 {
149 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
150 if (function_offset)
Greg Claytonfb816422011-07-10 19:21:23 +0000151 {
152 dumped_something = true;
153 s->Printf(" + %llu", function_offset);
154 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000155 }
Chris Lattner24943d22010-06-08 16:52:24 +0000156
157 if (block != NULL)
158 {
159 s->IndentMore();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000160 block->DumpStopContext (s, this, NULL, show_fullpaths, show_inlined_frames);
Chris Lattner24943d22010-06-08 16:52:24 +0000161 s->IndentLess();
Greg Claytonfb816422011-07-10 19:21:23 +0000162 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000163 }
164 else
165 {
166 if (line_entry.IsValid())
167 {
Greg Claytonfb816422011-07-10 19:21:23 +0000168 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000169 s->PutCString(" at ");
Greg Clayton72b71582010-09-02 21:44:10 +0000170 if (line_entry.DumpStopContext(s, show_fullpaths))
Greg Clayton7dd98df2011-07-12 17:06:17 +0000171 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000172 }
173 }
174 }
175 else if (symbol != NULL)
176 {
Greg Claytonfb816422011-07-10 19:21:23 +0000177 if (symbol->GetMangled().GetName())
178 {
179 dumped_something = true;
180 symbol->GetMangled().GetName().Dump(s);
181 }
Chris Lattner24943d22010-06-08 16:52:24 +0000182
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000183 if (addr.IsValid() && symbol->GetAddressRangePtr())
Chris Lattner24943d22010-06-08 16:52:24 +0000184 {
Greg Clayton70436352010-06-30 23:03:03 +0000185 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
186 if (symbol_offset)
Greg Claytonfb816422011-07-10 19:21:23 +0000187 {
188 dumped_something = true;
189 s->Printf(" + %llu", symbol_offset);
190 }
Chris Lattner24943d22010-06-08 16:52:24 +0000191 }
192 }
Greg Clayton2e3d6f22010-09-10 22:05:05 +0000193 else if (addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000194 {
195 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
Greg Claytonfb816422011-07-10 19:21:23 +0000196 dumped_something = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000197 }
Greg Claytonfb816422011-07-10 19:21:23 +0000198 return dumped_something;
Chris Lattner24943d22010-06-08 16:52:24 +0000199}
200
201void
Greg Claytoneea26402010-09-14 23:36:40 +0000202SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000203{
204 if (module_sp)
205 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000206 s->Indent(" Module: file = \"");
Greg Clayton12bec712010-06-28 21:30:43 +0000207 module_sp->GetFileSpec().Dump(s);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000208 *s << '"';
209 if (module_sp->GetArchitecture().IsValid())
Greg Clayton940b1032011-02-23 00:35:02 +0000210 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
Greg Clayton12bec712010-06-28 21:30:43 +0000211 s->EOL();
212 }
213
214 if (comp_unit != NULL)
215 {
216 s->Indent("CompileUnit: ");
217 comp_unit->GetDescription (s, level);
218 s->EOL();
219 }
220
221 if (function != NULL)
222 {
223 s->Indent(" Function: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000224 function->GetDescription (s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000225 s->EOL();
226
227 Type *func_type = function->GetType();
228 if (func_type)
229 {
230 s->Indent(" FuncType: ");
231 func_type->GetDescription (s, level, false);
232 s->EOL();
233 }
234 }
235
236 if (block != NULL)
237 {
238 std::vector<Block *> blocks;
239 blocks.push_back (block);
240 Block *parent_block = block->GetParent();
241
242 while (parent_block)
243 {
244 blocks.push_back (parent_block);
245 parent_block = parent_block->GetParent();
246 }
247 std::vector<Block *>::reverse_iterator pos;
248 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
249 std::vector<Block *>::reverse_iterator end = blocks.rend();
250 for (pos = begin; pos != end; ++pos)
251 {
252 if (pos == begin)
253 s->Indent(" Blocks: ");
254 else
255 s->Indent(" ");
Greg Claytoneea26402010-09-14 23:36:40 +0000256 (*pos)->GetDescription(s, function, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000257 s->EOL();
258 }
259 }
260
261 if (line_entry.IsValid())
262 {
263 s->Indent(" LineEntry: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000264 line_entry.GetDescription (s, level, comp_unit, target, false);
Greg Clayton12bec712010-06-28 21:30:43 +0000265 s->EOL();
266 }
267
268 if (symbol != NULL)
269 {
270 s->Indent(" Symbol: ");
Greg Claytoneea26402010-09-14 23:36:40 +0000271 symbol->GetDescription(s, level, target);
Greg Clayton12bec712010-06-28 21:30:43 +0000272 s->EOL();
273 }
274}
275
Greg Clayton33ed1702010-08-24 00:45:41 +0000276uint32_t
277SymbolContext::GetResolvedMask () const
278{
279 uint32_t resolved_mask = 0;
280 if (target_sp) resolved_mask |= eSymbolContextTarget;
281 if (module_sp) resolved_mask |= eSymbolContextModule;
282 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
283 if (function) resolved_mask |= eSymbolContextFunction;
284 if (block) resolved_mask |= eSymbolContextBlock;
285 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
286 if (symbol) resolved_mask |= eSymbolContextSymbol;
287 return resolved_mask;
288}
Greg Clayton12bec712010-06-28 21:30:43 +0000289
290
291void
Greg Claytoneea26402010-09-14 23:36:40 +0000292SymbolContext::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000293{
294 *s << (void *)this << ": ";
295 s->Indent();
296 s->PutCString("SymbolContext");
297 s->IndentMore();
298 s->EOL();
299 s->IndentMore();
300 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000301 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000302 if (module_sp)
303 module_sp->GetFileSpec().Dump(s);
304 s->EOL();
305 s->Indent();
306 *s << "CompileUnit = " << (void *)comp_unit;
307 if (comp_unit != NULL)
Johnny Chencff44fd2010-10-29 22:18:43 +0000308 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000309 s->EOL();
310 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000311 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000312 if (function != NULL)
313 {
Greg Clayton12bec712010-06-28 21:30:43 +0000314 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000315 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Greg Clayton12bec712010-06-28 21:30:43 +0000316 s->EOL();
317 s->Indent();
318 Type* func_type = function->GetType();
319 if (func_type)
320 {
321 *s << " Type = ";
322 func_type->Dump (s, false);
323 }
Chris Lattner24943d22010-06-08 16:52:24 +0000324 }
325 s->EOL();
326 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000327 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000328 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000329 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000330 // Dump the block and pass it a negative depth to we print all the parent blocks
331 //if (block != NULL)
332 // block->Dump(s, function->GetFileAddress(), INT_MIN);
333 s->EOL();
334 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000335 *s << "LineEntry = ";
Greg Claytoneea26402010-09-14 23:36:40 +0000336 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000337 s->EOL();
338 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000339 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000340 if (symbol != NULL && symbol->GetMangled())
341 *s << ' ' << symbol->GetMangled().GetName().AsCString();
342 s->EOL();
343 s->IndentLess();
344 s->IndentLess();
345}
346
347bool
348lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
349{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000350 return lhs.function == rhs.function
351 && lhs.symbol == rhs.symbol
352 && lhs.module_sp.get() == rhs.module_sp.get()
353 && lhs.comp_unit == rhs.comp_unit
354 && lhs.target_sp.get() == rhs.target_sp.get()
355 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000356}
357
358bool
359lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
360{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000361 return lhs.function != rhs.function
Greg Clayton889fbd02011-03-26 19:14:58 +0000362 || lhs.symbol != rhs.symbol
363 || lhs.module_sp.get() != rhs.module_sp.get()
364 || lhs.comp_unit != rhs.comp_unit
365 || lhs.target_sp.get() != rhs.target_sp.get()
366 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000367}
368
369bool
Greg Claytonff44ab42011-04-23 02:04:55 +0000370SymbolContext::GetAddressRange (uint32_t scope,
371 uint32_t range_idx,
372 bool use_inline_block_range,
373 AddressRange &range) const
Chris Lattner24943d22010-06-08 16:52:24 +0000374{
375 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
376 {
377 range = line_entry.range;
378 return true;
379 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000380
381 if ((scope & eSymbolContextBlock) && (block != NULL))
Chris Lattner24943d22010-06-08 16:52:24 +0000382 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000383 if (use_inline_block_range)
Chris Lattner24943d22010-06-08 16:52:24 +0000384 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000385 Block *inline_block = block->GetContainingInlinedBlock();
386 if (inline_block)
387 return inline_block->GetRangeAtIndex (range_idx, range);
388 }
389 else
390 {
391 return block->GetRangeAtIndex (range_idx, range);
392 }
393 }
394
395 if ((scope & eSymbolContextFunction) && (function != NULL))
396 {
397 if (range_idx == 0)
398 {
399 range = function->GetAddressRange();
400 return true;
401 }
402 }
403
404 if ((scope & eSymbolContextSymbol) && (symbol != NULL) && (symbol->GetAddressRangePtr() != NULL))
405 {
406 if (range_idx == 0)
407 {
408 range = *symbol->GetAddressRangePtr();
409
410 if (range.GetByteSize() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000411 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000412 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000413 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000414 ObjectFile *objfile = module_sp->GetObjectFile();
415 if (objfile)
416 {
417 Symtab *symtab = objfile->GetSymtab();
418 if (symtab)
419 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
420 }
Chris Lattner24943d22010-06-08 16:52:24 +0000421 }
422 }
Greg Claytonff44ab42011-04-23 02:04:55 +0000423 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000424 }
Chris Lattner24943d22010-06-08 16:52:24 +0000425 }
426 range.Clear();
427 return false;
428}
429
Greg Clayton6916e352010-11-13 03:52:47 +0000430ClangNamespaceDecl
431SymbolContext::FindNamespace (const ConstString &name) const
432{
433 ClangNamespaceDecl namespace_decl;
434 if (module_sp)
435 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name);
436 return namespace_decl;
437}
Chris Lattner24943d22010-06-08 16:52:24 +0000438
Sean Callanan0fc73582010-07-27 00:55:47 +0000439size_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000440SymbolContext::FindFunctionsByName (const ConstString &name,
441 bool include_symbols,
442 bool append,
443 SymbolContextList &sc_list) const
Sean Callanan0fc73582010-07-27 00:55:47 +0000444{
445 if (!append)
446 sc_list.Clear();
447
Chris Lattner24943d22010-06-08 16:52:24 +0000448 if (function != NULL)
449 {
450 // FIXME: Look in the class of the current function, if it exists,
451 // for methods matching name.
452 }
453
Greg Clayton6e0101c2011-09-17 06:21:20 +0000454 if (module_sp)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000455 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000456
457 if (target_sp)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000458 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000459
Sean Callanan0fc73582010-07-27 00:55:47 +0000460 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000461}
462
Greg Clayton6916e352010-11-13 03:52:47 +0000463//lldb::VariableSP
464//SymbolContext::FindVariableByName (const char *name) const
465//{
466// lldb::VariableSP return_value;
467// return return_value;
468//}
Chris Lattner24943d22010-06-08 16:52:24 +0000469
470lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000471SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000472{
473 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000474
475 TypeList types;
476
477 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
478 return types.GetTypeAtIndex(0);
479
Sean Callanan65ec7242011-05-10 19:47:39 +0000480 SymbolContext sc_for_global_search;
481
482 sc_for_global_search.target_sp = target_sp;
483
484 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 +0000485 return types.GetTypeAtIndex(0);
486
Chris Lattner24943d22010-06-08 16:52:24 +0000487 return return_value;
488}
489
Jim Inghamd60d94a2011-03-11 03:53:59 +0000490//----------------------------------------------------------------------
491//
492// SymbolContextSpecifier
493//
494//----------------------------------------------------------------------
495
Greg Clayton6e0101c2011-09-17 06:21:20 +0000496SymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
497 m_target_sp (target_sp),
498 m_module_spec (),
499 m_module_sp (),
500 m_file_spec_ap (),
501 m_start_line (0),
502 m_end_line (0),
503 m_function_spec (),
504 m_class_name (),
505 m_address_range_ap (),
506 m_type (eNothingSpecified)
507{
508}
509
510SymbolContextSpecifier::~SymbolContextSpecifier()
511{
512}
513
Jim Inghamd60d94a2011-03-11 03:53:59 +0000514bool
515SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
516{
517 bool return_value = true;
518 switch (type)
519 {
520 case eNothingSpecified:
521 Clear();
522 break;
523 case eLineStartSpecified:
524 m_start_line = line_no;
525 m_type |= eLineStartSpecified;
526 break;
527 case eLineEndSpecified:
528 m_end_line = line_no;
529 m_type |= eLineEndSpecified;
530 break;
531 default:
532 return_value = false;
533 break;
534 }
535 return return_value;
536}
537
538bool
539SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
540{
541 bool return_value = true;
542 switch (type)
543 {
544 case eNothingSpecified:
545 Clear();
546 break;
547 case eModuleSpecified:
548 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000549 // See if we can find the Module, if so stick it in the SymbolContext.
550 FileSpec module_spec(spec_string, false);
551 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000552 m_type |= eModuleSpecified;
553 if (module_sp)
554 m_module_sp = module_sp;
555 else
556 m_module_spec.assign (spec_string);
557 }
558 break;
559 case eFileSpecified:
560 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
561 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000562 m_file_spec_ap.reset (new FileSpec (spec_string, false));
Jim Inghamd60d94a2011-03-11 03:53:59 +0000563 m_type |= eFileSpecified;
564 break;
565 case eLineStartSpecified:
566 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
567 if (return_value)
568 m_type |= eLineStartSpecified;
569 break;
570 case eLineEndSpecified:
571 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
572 if (return_value)
573 m_type |= eLineEndSpecified;
574 break;
575 case eFunctionSpecified:
576 m_function_spec.assign(spec_string);
577 m_type |= eFunctionSpecified;
578 break;
579 case eClassOrNamespaceSpecified:
580 Clear();
581 m_class_name.assign (spec_string);
582 m_type = eClassOrNamespaceSpecified;
583 break;
584 case eAddressRangeSpecified:
585 // Not specified yet...
586 break;
587 }
588
589 return return_value;
590}
591
592void
593SymbolContextSpecifier::Clear()
594{
595 m_module_spec.clear();
596 m_file_spec_ap.reset();
597 m_function_spec.clear();
598 m_class_name.clear();
599 m_start_line = 0;
600 m_end_line = 0;
601 m_address_range_ap.reset();
602
603 m_type = eNothingSpecified;
604}
605
606bool
607SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
608{
609 if (m_type == eNothingSpecified)
610 return true;
611
612 if (m_target_sp.get() != sc.target_sp.get())
613 return false;
614
615 if (m_type & eModuleSpecified)
616 {
617 if (sc.module_sp)
618 {
619 if (m_module_sp.get() != NULL)
620 {
621 if (m_module_sp.get() != sc.module_sp.get())
622 return false;
623 }
624 else
625 {
626 FileSpec module_file_spec (m_module_spec.c_str(), false);
627 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
628 return false;
629 }
630 }
631 }
632 if (m_type & eFileSpecified)
633 {
634 if (m_file_spec_ap.get())
635 {
636 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
637 if (sc.block == NULL && sc.comp_unit == NULL)
638 return false;
639
640 // Check if the block is present, and if so is it inlined:
641 bool was_inlined = false;
642 if (sc.block != NULL)
643 {
644 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
645 if (inline_info != NULL)
646 {
647 was_inlined = true;
648 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
649 return false;
650 }
651 }
652
653 // Next check the comp unit, but only if the SymbolContext was not inlined.
654 if (!was_inlined && sc.comp_unit != NULL)
655 {
656 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
657 return false;
658 }
659 }
660 }
661 if (m_type & eLineStartSpecified
662 || m_type & eLineEndSpecified)
663 {
664 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
665 return false;
666 }
667
668 if (m_type & eFunctionSpecified)
669 {
670 // First check the current block, and if it is inlined, get the inlined function name:
671 bool was_inlined = false;
672 ConstString func_name(m_function_spec.c_str());
673
674 if (sc.block != NULL)
675 {
676 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
677 if (inline_info != NULL)
678 {
679 was_inlined = true;
680 const Mangled &name = inline_info->GetMangled();
681 if (!name.NameMatches (func_name))
682 return false;
683 }
684 }
685 // If it wasn't inlined, check the name in the function or symbol:
686 if (!was_inlined)
687 {
688 if (sc.function != NULL)
689 {
690 if (!sc.function->GetMangled().NameMatches(func_name))
691 return false;
692 }
693 else if (sc.symbol != NULL)
694 {
695 if (!sc.symbol->GetMangled().NameMatches(func_name))
696 return false;
697 }
698 }
699
700
701 }
702
703 return true;
704}
705
706bool
707SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
708{
709 if (m_type & eAddressRangeSpecified)
710 {
711
712 }
713 else
714 {
715 Address match_address (addr, NULL);
716 SymbolContext sc;
717 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
718 return SymbolContextMatches(sc);
719 }
720 return true;
721}
722
723void
724SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
725{
726 char path_str[PATH_MAX + 1];
727
728 if (m_type == eNothingSpecified)
729 {
730 s->Printf ("Nothing specified.\n");
731 }
732
733 if (m_type == eModuleSpecified)
734 {
735 s->Indent();
736 if (m_module_sp)
737 {
738 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
739 s->Printf ("Module: %s\n", path_str);
740 }
741 else
742 s->Printf ("Module: %s\n", m_module_spec.c_str());
743 }
744
745 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL)
746 {
747 m_file_spec_ap->GetPath (path_str, PATH_MAX);
748 s->Indent();
749 s->Printf ("File: %s", path_str);
750 if (m_type == eLineStartSpecified)
751 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000752 s->Printf (" from line %lu", m_start_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000753 if (m_type == eLineEndSpecified)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000754 s->Printf ("to line %lu", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000755 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000756 s->Printf ("to end");
Jim Inghamd60d94a2011-03-11 03:53:59 +0000757 }
758 else if (m_type == eLineEndSpecified)
759 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000760 s->Printf (" from start to line %ld", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000761 }
762 s->Printf (".\n");
763 }
764
765 if (m_type == eLineStartSpecified)
766 {
767 s->Indent();
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000768 s->Printf ("From line %lu", m_start_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000769 if (m_type == eLineEndSpecified)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000770 s->Printf ("to line %lu", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000771 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000772 s->Printf ("to end");
Jim Inghamd60d94a2011-03-11 03:53:59 +0000773 s->Printf (".\n");
774 }
775 else if (m_type == eLineEndSpecified)
776 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000777 s->Printf ("From start to line %ld.\n", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000778 }
779
780 if (m_type == eFunctionSpecified)
781 {
782 s->Indent();
783 s->Printf ("Function: %s.\n", m_function_spec.c_str());
784 }
785
786 if (m_type == eClassOrNamespaceSpecified)
787 {
788 s->Indent();
789 s->Printf ("Class name: %s.\n", m_class_name.c_str());
790 }
791
792 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
793 {
794 s->Indent();
795 s->PutCString ("Address range: ");
796 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
797 s->PutCString ("\n");
798 }
799}
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000800
Chris Lattner24943d22010-06-08 16:52:24 +0000801//----------------------------------------------------------------------
802//
803// SymbolContextList
804//
805//----------------------------------------------------------------------
806
807
808SymbolContextList::SymbolContextList() :
809 m_symbol_contexts()
810{
811}
812
813SymbolContextList::~SymbolContextList()
814{
815}
816
817void
818SymbolContextList::Append(const SymbolContext& sc)
819{
820 m_symbol_contexts.push_back(sc);
821}
822
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000823bool
Greg Clayton889fbd02011-03-26 19:14:58 +0000824SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000825{
Greg Clayton889fbd02011-03-26 19:14:58 +0000826 collection::iterator pos, end = m_symbol_contexts.end();
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000827 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
828 {
829 if (*pos == sc)
830 return false;
831 }
Greg Clayton889fbd02011-03-26 19:14:58 +0000832 if (merge_symbol_into_function
833 && sc.symbol != NULL
834 && sc.comp_unit == NULL
835 && sc.function == NULL
836 && sc.block == NULL
837 && sc.line_entry.IsValid() == false)
838 {
839 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
840 if (symbol_range)
841 {
842 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
843 {
844 if (pos->function)
845 {
846 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
847 {
848 // Do we already have a function with this symbol?
849 if (pos->symbol == sc.symbol)
850 return false;
851 if (pos->symbol == NULL)
852 {
853 pos->symbol = sc.symbol;
854 return false;
855 }
856 }
857 }
858 }
859 }
860 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000861 m_symbol_contexts.push_back(sc);
862 return true;
863}
864
Chris Lattner24943d22010-06-08 16:52:24 +0000865void
866SymbolContextList::Clear()
867{
868 m_symbol_contexts.clear();
869}
870
871void
Greg Claytoneea26402010-09-14 23:36:40 +0000872SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000873{
874
875 *s << (void *)this << ": ";
876 s->Indent();
877 s->PutCString("SymbolContextList");
878 s->EOL();
879 s->IndentMore();
880
881 collection::const_iterator pos, end = m_symbol_contexts.end();
882 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
883 {
Greg Claytoneea26402010-09-14 23:36:40 +0000884 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000885 }
886 s->IndentLess();
887}
888
889bool
890SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
891{
892 if (idx < m_symbol_contexts.size())
893 {
894 sc = m_symbol_contexts[idx];
895 return true;
896 }
897 return false;
898}
899
900bool
901SymbolContextList::RemoveContextAtIndex (uint32_t idx)
902{
903 if (idx < m_symbol_contexts.size())
904 {
905 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
906 return true;
907 }
908 return false;
909}
910
911uint32_t
912SymbolContextList::GetSize() const
913{
914 return m_symbol_contexts.size();
915}
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000916
917uint32_t
918SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
919{
920 uint32_t match_count = 0;
921 const uint32_t size = m_symbol_contexts.size();
922 for (uint32_t idx = 0; idx<size; ++idx)
923 {
924 if (m_symbol_contexts[idx].line_entry.line == line)
925 ++match_count;
926 }
927 return match_count;
928}
929