blob: c7b2fb266130fa8eb51fd86fa86cae281864a4ca [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
Greg Clayton23b8abb2011-09-26 07:11:27 +0000490bool
491SymbolContext::GetParentInlinedFrameInfo (const Address &curr_frame_pc,
492 bool is_concrete_frame,
493 SymbolContext &next_frame_sc,
494 Address &inlined_frame_addr) const
495{
496 next_frame_sc.Clear();
497 inlined_frame_addr.Clear();
498
499 if (block)
500 {
501 bool concrete_has_inlines = false;
502 Block *curr_inlined_block = NULL;
503 Block *next_inlined_block = NULL;
504 //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
505 if (is_concrete_frame)
506 {
507 curr_inlined_block = block->GetContainingInlinedBlock();
508 if (curr_inlined_block)
509 {
510 concrete_has_inlines = true;
511 next_inlined_block = curr_inlined_block->GetInlinedParent();
512 }
513 }
514 else
515 {
516 curr_inlined_block = block;
517 next_inlined_block = block->GetInlinedParent();
518 }
519
520 if (next_inlined_block)
521 {
522 next_inlined_block->CalculateSymbolContext (&next_frame_sc);
523
524 AddressRange range;
525 bool got_range = curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range);
526 assert (got_range);
527 const InlineFunctionInfo* inline_info = next_inlined_block->GetInlinedFunctionInfo();
528 if (inline_info)
529 {
530 inlined_frame_addr = range.GetBaseAddress();
531 next_frame_sc.line_entry.range.GetBaseAddress() = inlined_frame_addr;
532 next_frame_sc.line_entry.file = inline_info->GetCallSite().GetFile();
533 next_frame_sc.line_entry.line = inline_info->GetCallSite().GetLine();
534 next_frame_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
535 return true;
536 }
537 }
538 else if (is_concrete_frame && !concrete_has_inlines)
539 {
540 // This is the symbol context for the frame that was found using the
541 // PC value and there are no inlined blocks so there are no inlined
542 // parent frames.
543 return false;
544 }
545 else
546 {
547 // We have had inlined frames before and now we are at the function
548 // instance that called the inlined frames.
549 // The SymbolContext object should contain a previous inline symbol
550 // context which we need to use to get the file, line and column info
551 const InlineFunctionInfo* inline_info = curr_inlined_block->GetInlinedFunctionInfo();
552 if (inline_info)
553 {
554 Block *parent_block = curr_inlined_block->GetParent();
555 if (parent_block)
556 {
557 parent_block->CalculateSymbolContext (&next_frame_sc);
558
559 AddressRange range;
560 if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
561 {
562 inlined_frame_addr = range.GetBaseAddress();
563 //const addr_t range_file_file_addr = inlined_frame_addr.GetFileAddress();
564 next_frame_sc.line_entry.range.GetBaseAddress() = inlined_frame_addr;
565 next_frame_sc.line_entry.file = inline_info->GetCallSite().GetFile();
566 next_frame_sc.line_entry.line = inline_info->GetCallSite().GetLine();
567 next_frame_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
568 return true;
569 }
570 }
571 }
572 }
573 }
574
575 return false;
576}
577
578
Jim Inghamd60d94a2011-03-11 03:53:59 +0000579//----------------------------------------------------------------------
580//
581// SymbolContextSpecifier
582//
583//----------------------------------------------------------------------
584
Greg Clayton6e0101c2011-09-17 06:21:20 +0000585SymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
586 m_target_sp (target_sp),
587 m_module_spec (),
588 m_module_sp (),
589 m_file_spec_ap (),
590 m_start_line (0),
591 m_end_line (0),
592 m_function_spec (),
593 m_class_name (),
594 m_address_range_ap (),
595 m_type (eNothingSpecified)
596{
597}
598
599SymbolContextSpecifier::~SymbolContextSpecifier()
600{
601}
602
Jim Inghamd60d94a2011-03-11 03:53:59 +0000603bool
604SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
605{
606 bool return_value = true;
607 switch (type)
608 {
609 case eNothingSpecified:
610 Clear();
611 break;
612 case eLineStartSpecified:
613 m_start_line = line_no;
614 m_type |= eLineStartSpecified;
615 break;
616 case eLineEndSpecified:
617 m_end_line = line_no;
618 m_type |= eLineEndSpecified;
619 break;
620 default:
621 return_value = false;
622 break;
623 }
624 return return_value;
625}
626
627bool
628SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
629{
630 bool return_value = true;
631 switch (type)
632 {
633 case eNothingSpecified:
634 Clear();
635 break;
636 case eModuleSpecified:
637 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000638 // See if we can find the Module, if so stick it in the SymbolContext.
639 FileSpec module_spec(spec_string, false);
640 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000641 m_type |= eModuleSpecified;
642 if (module_sp)
643 m_module_sp = module_sp;
644 else
645 m_module_spec.assign (spec_string);
646 }
647 break;
648 case eFileSpecified:
649 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
650 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000651 m_file_spec_ap.reset (new FileSpec (spec_string, false));
Jim Inghamd60d94a2011-03-11 03:53:59 +0000652 m_type |= eFileSpecified;
653 break;
654 case eLineStartSpecified:
655 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
656 if (return_value)
657 m_type |= eLineStartSpecified;
658 break;
659 case eLineEndSpecified:
660 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
661 if (return_value)
662 m_type |= eLineEndSpecified;
663 break;
664 case eFunctionSpecified:
665 m_function_spec.assign(spec_string);
666 m_type |= eFunctionSpecified;
667 break;
668 case eClassOrNamespaceSpecified:
669 Clear();
670 m_class_name.assign (spec_string);
671 m_type = eClassOrNamespaceSpecified;
672 break;
673 case eAddressRangeSpecified:
674 // Not specified yet...
675 break;
676 }
677
678 return return_value;
679}
680
681void
682SymbolContextSpecifier::Clear()
683{
684 m_module_spec.clear();
685 m_file_spec_ap.reset();
686 m_function_spec.clear();
687 m_class_name.clear();
688 m_start_line = 0;
689 m_end_line = 0;
690 m_address_range_ap.reset();
691
692 m_type = eNothingSpecified;
693}
694
695bool
696SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
697{
698 if (m_type == eNothingSpecified)
699 return true;
700
701 if (m_target_sp.get() != sc.target_sp.get())
702 return false;
703
704 if (m_type & eModuleSpecified)
705 {
706 if (sc.module_sp)
707 {
708 if (m_module_sp.get() != NULL)
709 {
710 if (m_module_sp.get() != sc.module_sp.get())
711 return false;
712 }
713 else
714 {
715 FileSpec module_file_spec (m_module_spec.c_str(), false);
716 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
717 return false;
718 }
719 }
720 }
721 if (m_type & eFileSpecified)
722 {
723 if (m_file_spec_ap.get())
724 {
725 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
726 if (sc.block == NULL && sc.comp_unit == NULL)
727 return false;
728
729 // Check if the block is present, and if so is it inlined:
730 bool was_inlined = false;
731 if (sc.block != NULL)
732 {
733 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
734 if (inline_info != NULL)
735 {
736 was_inlined = true;
737 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
738 return false;
739 }
740 }
741
742 // Next check the comp unit, but only if the SymbolContext was not inlined.
743 if (!was_inlined && sc.comp_unit != NULL)
744 {
745 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
746 return false;
747 }
748 }
749 }
750 if (m_type & eLineStartSpecified
751 || m_type & eLineEndSpecified)
752 {
753 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
754 return false;
755 }
756
757 if (m_type & eFunctionSpecified)
758 {
759 // First check the current block, and if it is inlined, get the inlined function name:
760 bool was_inlined = false;
761 ConstString func_name(m_function_spec.c_str());
762
763 if (sc.block != NULL)
764 {
765 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
766 if (inline_info != NULL)
767 {
768 was_inlined = true;
769 const Mangled &name = inline_info->GetMangled();
770 if (!name.NameMatches (func_name))
771 return false;
772 }
773 }
774 // If it wasn't inlined, check the name in the function or symbol:
775 if (!was_inlined)
776 {
777 if (sc.function != NULL)
778 {
779 if (!sc.function->GetMangled().NameMatches(func_name))
780 return false;
781 }
782 else if (sc.symbol != NULL)
783 {
784 if (!sc.symbol->GetMangled().NameMatches(func_name))
785 return false;
786 }
787 }
788
789
790 }
791
792 return true;
793}
794
795bool
796SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
797{
798 if (m_type & eAddressRangeSpecified)
799 {
800
801 }
802 else
803 {
804 Address match_address (addr, NULL);
805 SymbolContext sc;
806 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
807 return SymbolContextMatches(sc);
808 }
809 return true;
810}
811
812void
813SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
814{
815 char path_str[PATH_MAX + 1];
816
817 if (m_type == eNothingSpecified)
818 {
819 s->Printf ("Nothing specified.\n");
820 }
821
822 if (m_type == eModuleSpecified)
823 {
824 s->Indent();
825 if (m_module_sp)
826 {
827 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
828 s->Printf ("Module: %s\n", path_str);
829 }
830 else
831 s->Printf ("Module: %s\n", m_module_spec.c_str());
832 }
833
834 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL)
835 {
836 m_file_spec_ap->GetPath (path_str, PATH_MAX);
837 s->Indent();
838 s->Printf ("File: %s", path_str);
839 if (m_type == eLineStartSpecified)
840 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000841 s->Printf (" from line %lu", m_start_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000842 if (m_type == eLineEndSpecified)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000843 s->Printf ("to line %lu", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000844 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000845 s->Printf ("to end");
Jim Inghamd60d94a2011-03-11 03:53:59 +0000846 }
847 else if (m_type == eLineEndSpecified)
848 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000849 s->Printf (" from start to line %ld", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000850 }
851 s->Printf (".\n");
852 }
853
854 if (m_type == eLineStartSpecified)
855 {
856 s->Indent();
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000857 s->Printf ("From line %lu", m_start_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000858 if (m_type == eLineEndSpecified)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000859 s->Printf ("to line %lu", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000860 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000861 s->Printf ("to end");
Jim Inghamd60d94a2011-03-11 03:53:59 +0000862 s->Printf (".\n");
863 }
864 else if (m_type == eLineEndSpecified)
865 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000866 s->Printf ("From start to line %ld.\n", m_end_line);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000867 }
868
869 if (m_type == eFunctionSpecified)
870 {
871 s->Indent();
872 s->Printf ("Function: %s.\n", m_function_spec.c_str());
873 }
874
875 if (m_type == eClassOrNamespaceSpecified)
876 {
877 s->Indent();
878 s->Printf ("Class name: %s.\n", m_class_name.c_str());
879 }
880
881 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
882 {
883 s->Indent();
884 s->PutCString ("Address range: ");
885 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
886 s->PutCString ("\n");
887 }
888}
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000889
Chris Lattner24943d22010-06-08 16:52:24 +0000890//----------------------------------------------------------------------
891//
892// SymbolContextList
893//
894//----------------------------------------------------------------------
895
896
897SymbolContextList::SymbolContextList() :
898 m_symbol_contexts()
899{
900}
901
902SymbolContextList::~SymbolContextList()
903{
904}
905
906void
907SymbolContextList::Append(const SymbolContext& sc)
908{
909 m_symbol_contexts.push_back(sc);
910}
911
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000912bool
Greg Clayton889fbd02011-03-26 19:14:58 +0000913SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000914{
Greg Clayton889fbd02011-03-26 19:14:58 +0000915 collection::iterator pos, end = m_symbol_contexts.end();
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000916 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
917 {
918 if (*pos == sc)
919 return false;
920 }
Greg Clayton889fbd02011-03-26 19:14:58 +0000921 if (merge_symbol_into_function
922 && sc.symbol != NULL
923 && sc.comp_unit == NULL
924 && sc.function == NULL
925 && sc.block == NULL
926 && sc.line_entry.IsValid() == false)
927 {
928 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
929 if (symbol_range)
930 {
931 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
932 {
933 if (pos->function)
934 {
935 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
936 {
937 // Do we already have a function with this symbol?
938 if (pos->symbol == sc.symbol)
939 return false;
940 if (pos->symbol == NULL)
941 {
942 pos->symbol = sc.symbol;
943 return false;
944 }
945 }
946 }
947 }
948 }
949 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000950 m_symbol_contexts.push_back(sc);
951 return true;
952}
953
Chris Lattner24943d22010-06-08 16:52:24 +0000954void
955SymbolContextList::Clear()
956{
957 m_symbol_contexts.clear();
958}
959
960void
Greg Claytoneea26402010-09-14 23:36:40 +0000961SymbolContextList::Dump(Stream *s, Target *target) const
Chris Lattner24943d22010-06-08 16:52:24 +0000962{
963
964 *s << (void *)this << ": ";
965 s->Indent();
966 s->PutCString("SymbolContextList");
967 s->EOL();
968 s->IndentMore();
969
970 collection::const_iterator pos, end = m_symbol_contexts.end();
971 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
972 {
Greg Claytoneea26402010-09-14 23:36:40 +0000973 pos->Dump(s, target);
Chris Lattner24943d22010-06-08 16:52:24 +0000974 }
975 s->IndentLess();
976}
977
978bool
979SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
980{
981 if (idx < m_symbol_contexts.size())
982 {
983 sc = m_symbol_contexts[idx];
984 return true;
985 }
986 return false;
987}
988
989bool
990SymbolContextList::RemoveContextAtIndex (uint32_t idx)
991{
992 if (idx < m_symbol_contexts.size())
993 {
994 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
995 return true;
996 }
997 return false;
998}
999
1000uint32_t
1001SymbolContextList::GetSize() const
1002{
1003 return m_symbol_contexts.size();
1004}
Greg Clayton52c8b6e2011-04-19 04:19:37 +00001005
1006uint32_t
1007SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
1008{
1009 uint32_t match_count = 0;
1010 const uint32_t size = m_symbol_contexts.size();
1011 for (uint32_t idx = 0; idx<size; ++idx)
1012 {
1013 if (m_symbol_contexts[idx].line_entry.line == line)
1014 ++match_count;
1015 }
1016 return match_count;
1017}
1018