LLDB  mainline
SymbolContext.cpp
Go to the documentation of this file.
1 //===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/ModuleSpec.h"
13 #include "lldb/Host/Host.h"
15 #include "lldb/Symbol/Block.h"
18 #include "lldb/Symbol/ObjectFile.h"
19 #include "lldb/Symbol/Symbol.h"
20 #include "lldb/Symbol/SymbolFile.h"
22 #include "lldb/Symbol/Variable.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Utility/Log.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 SymbolContext::SymbolContext()
30  : target_sp(), module_sp(), comp_unit(nullptr), function(nullptr),
31  block(nullptr), line_entry(), symbol(nullptr), variable(nullptr) {}
32 
33 SymbolContext::SymbolContext(const ModuleSP &m, CompileUnit *cu, Function *f,
34  Block *b, LineEntry *le, Symbol *s)
35  : target_sp(), module_sp(m), comp_unit(cu), function(f), block(b),
36  line_entry(), symbol(s), variable(nullptr) {
37  if (le)
38  line_entry = *le;
39 }
40 
41 SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP &m,
42  CompileUnit *cu, Function *f, Block *b,
43  LineEntry *le, Symbol *s)
44  : target_sp(t), module_sp(m), comp_unit(cu), function(f), block(b),
45  line_entry(), symbol(s), variable(nullptr) {
46  if (le)
47  line_entry = *le;
48 }
49 
54 
56  : target_sp(), module_sp(), comp_unit(nullptr), function(nullptr),
57  block(nullptr), line_entry(), symbol(nullptr), variable(nullptr) {
58  sc_scope->CalculateSymbolContext(this);
59 }
60 
62 
64  if (this != &rhs) {
65  target_sp = rhs.target_sp;
66  module_sp = rhs.module_sp;
67  comp_unit = rhs.comp_unit;
68  function = rhs.function;
69  block = rhs.block;
70  line_entry = rhs.line_entry;
71  symbol = rhs.symbol;
72  variable = rhs.variable;
73  }
74  return *this;
75 }
76 
77 void SymbolContext::Clear(bool clear_target) {
78  if (clear_target)
79  target_sp.reset();
80  module_sp.reset();
81  comp_unit = nullptr;
82  function = nullptr;
83  block = nullptr;
84  line_entry.Clear();
85  symbol = nullptr;
86  variable = nullptr;
87 }
88 
90  const Address &addr, bool show_fullpaths,
91  bool show_module, bool show_inlined_frames,
92  bool show_function_arguments,
93  bool show_function_name) const {
94  bool dumped_something = false;
95  if (show_module && module_sp) {
96  if (show_fullpaths)
97  *s << module_sp->GetFileSpec();
98  else
99  *s << module_sp->GetFileSpec().GetFilename();
100  s->PutChar('`');
101  dumped_something = true;
102  }
103 
104  if (function != nullptr) {
105  SymbolContext inline_parent_sc;
106  Address inline_parent_addr;
107  if (!show_function_name) {
108  s->Printf("<");
109  dumped_something = true;
110  } else {
111  ConstString name;
112  if (!show_function_arguments)
113  name = function->GetNameNoArguments();
114  if (!name)
115  name = function->GetName();
116  if (name)
117  name.Dump(s);
118  }
119 
120  if (addr.IsValid()) {
121  const addr_t function_offset =
122  addr.GetOffset() -
123  function->GetAddressRange().GetBaseAddress().GetOffset();
124  if (!show_function_name) {
125  // Print +offset even if offset is 0
126  dumped_something = true;
127  s->Printf("+%" PRIu64 ">", function_offset);
128  } else if (function_offset) {
129  dumped_something = true;
130  s->Printf(" + %" PRIu64, function_offset);
131  }
132  }
133 
134  if (GetParentOfInlinedScope(addr, inline_parent_sc, inline_parent_addr)) {
135  dumped_something = true;
136  Block *inlined_block = block->GetContainingInlinedBlock();
137  const InlineFunctionInfo *inlined_block_info =
138  inlined_block->GetInlinedFunctionInfo();
139  s->Printf(
140  " [inlined] %s",
141  inlined_block_info->GetName(function->GetLanguage()).GetCString());
142 
143  lldb_private::AddressRange block_range;
144  if (inlined_block->GetRangeContainingAddress(addr, block_range)) {
145  const addr_t inlined_function_offset =
146  addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
147  if (inlined_function_offset) {
148  s->Printf(" + %" PRIu64, inlined_function_offset);
149  }
150  }
151  const Declaration &call_site = inlined_block_info->GetCallSite();
152  if (call_site.IsValid()) {
153  s->PutCString(" at ");
154  call_site.DumpStopContext(s, show_fullpaths);
155  }
156  if (show_inlined_frames) {
157  s->EOL();
158  s->Indent();
159  const bool show_function_name = true;
160  return inline_parent_sc.DumpStopContext(
161  s, exe_scope, inline_parent_addr, show_fullpaths, show_module,
162  show_inlined_frames, show_function_arguments, show_function_name);
163  }
164  } else {
165  if (line_entry.IsValid()) {
166  dumped_something = true;
167  s->PutCString(" at ");
168  if (line_entry.DumpStopContext(s, show_fullpaths))
169  dumped_something = true;
170  }
171  }
172  } else if (symbol != nullptr) {
173  if (!show_function_name) {
174  s->Printf("<");
175  dumped_something = true;
176  } else if (symbol->GetName()) {
177  dumped_something = true;
179  s->PutCString("symbol stub for: ");
180  symbol->GetName().Dump(s);
181  }
182 
183  if (addr.IsValid() && symbol->ValueIsAddress()) {
184  const addr_t symbol_offset =
185  addr.GetOffset() - symbol->GetAddressRef().GetOffset();
186  if (!show_function_name) {
187  // Print +offset even if offset is 0
188  dumped_something = true;
189  s->Printf("+%" PRIu64 ">", symbol_offset);
190  } else if (symbol_offset) {
191  dumped_something = true;
192  s->Printf(" + %" PRIu64, symbol_offset);
193  }
194  }
195  } else if (addr.IsValid()) {
196  addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
197  dumped_something = true;
198  }
199  return dumped_something;
200 }
201 
203  Target *target) const {
204  if (module_sp) {
205  s->Indent(" Module: file = \"");
206  module_sp->GetFileSpec().Dump(s);
207  *s << '"';
208  if (module_sp->GetArchitecture().IsValid())
209  s->Printf(", arch = \"%s\"",
210  module_sp->GetArchitecture().GetArchitectureName());
211  s->EOL();
212  }
213 
214  if (comp_unit != nullptr) {
215  s->Indent("CompileUnit: ");
216  comp_unit->GetDescription(s, level);
217  s->EOL();
218  }
219 
220  if (function != nullptr) {
221  s->Indent(" Function: ");
222  function->GetDescription(s, level, target);
223  s->EOL();
224 
225  Type *func_type = function->GetType();
226  if (func_type) {
227  s->Indent(" FuncType: ");
228  func_type->GetDescription(s, level, false);
229  s->EOL();
230  }
231  }
232 
233  if (block != nullptr) {
234  std::vector<Block *> blocks;
235  blocks.push_back(block);
236  Block *parent_block = block->GetParent();
237 
238  while (parent_block) {
239  blocks.push_back(parent_block);
240  parent_block = parent_block->GetParent();
241  }
242  std::vector<Block *>::reverse_iterator pos;
243  std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
244  std::vector<Block *>::reverse_iterator end = blocks.rend();
245  for (pos = begin; pos != end; ++pos) {
246  if (pos == begin)
247  s->Indent(" Blocks: ");
248  else
249  s->Indent(" ");
250  (*pos)->GetDescription(s, function, level, target);
251  s->EOL();
252  }
253  }
254 
255  if (line_entry.IsValid()) {
256  s->Indent(" LineEntry: ");
257  line_entry.GetDescription(s, level, comp_unit, target, false);
258  s->EOL();
259  }
260 
261  if (symbol != nullptr) {
262  s->Indent(" Symbol: ");
263  symbol->GetDescription(s, level, target);
264  s->EOL();
265  }
266 
267  if (variable != nullptr) {
268  s->Indent(" Variable: ");
269 
270  s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
271 
272  switch (variable->GetScope()) {
274  s->PutCString("kind = global, ");
275  break;
276 
278  s->PutCString("kind = static, ");
279  break;
280 
282  s->PutCString("kind = argument, ");
283  break;
284 
286  s->PutCString("kind = local, ");
287  break;
288 
290  s->PutCString("kind = thread local, ");
291  break;
292 
293  default:
294  break;
295  }
296 
297  s->Printf("name = \"%s\"\n", variable->GetName().GetCString());
298  }
299 }
300 
302  uint32_t resolved_mask = 0;
303  if (target_sp)
304  resolved_mask |= eSymbolContextTarget;
305  if (module_sp)
306  resolved_mask |= eSymbolContextModule;
307  if (comp_unit)
308  resolved_mask |= eSymbolContextCompUnit;
309  if (function)
310  resolved_mask |= eSymbolContextFunction;
311  if (block)
312  resolved_mask |= eSymbolContextBlock;
313  if (line_entry.IsValid())
314  resolved_mask |= eSymbolContextLineEntry;
315  if (symbol)
316  resolved_mask |= eSymbolContextSymbol;
317  if (variable)
318  resolved_mask |= eSymbolContextVariable;
319  return resolved_mask;
320 }
321 
322 void SymbolContext::Dump(Stream *s, Target *target) const {
323  *s << this << ": ";
324  s->Indent();
325  s->PutCString("SymbolContext");
326  s->IndentMore();
327  s->EOL();
328  s->IndentMore();
329  s->Indent();
330  *s << "Module = " << module_sp.get() << ' ';
331  if (module_sp)
332  module_sp->GetFileSpec().Dump(s);
333  s->EOL();
334  s->Indent();
335  *s << "CompileUnit = " << comp_unit;
336  if (comp_unit != nullptr)
337  *s << " {0x" << comp_unit->GetID() << "} "
338  << *(static_cast<FileSpec *>(comp_unit));
339  s->EOL();
340  s->Indent();
341  *s << "Function = " << function;
342  if (function != nullptr) {
343  *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName()
344  << ", address-range = ";
345  function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress,
347  s->EOL();
348  s->Indent();
349  Type *func_type = function->GetType();
350  if (func_type) {
351  *s << " Type = ";
352  func_type->Dump(s, false);
353  }
354  }
355  s->EOL();
356  s->Indent();
357  *s << "Block = " << block;
358  if (block != nullptr)
359  *s << " {0x" << block->GetID() << '}';
360  // Dump the block and pass it a negative depth to we print all the parent
361  // blocks if (block != NULL)
362  // block->Dump(s, function->GetFileAddress(), INT_MIN);
363  s->EOL();
364  s->Indent();
365  *s << "LineEntry = ";
368  s->EOL();
369  s->Indent();
370  *s << "Symbol = " << symbol;
371  if (symbol != nullptr && symbol->GetMangled())
372  *s << ' ' << symbol->GetName().AsCString();
373  s->EOL();
374  *s << "Variable = " << variable;
375  if (variable != nullptr) {
376  *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName();
377  s->EOL();
378  }
379  s->IndentLess();
380  s->IndentLess();
381 }
382 
384  const SymbolContext &rhs) {
385  return lhs.function == rhs.function && lhs.symbol == rhs.symbol &&
386  lhs.module_sp.get() == rhs.module_sp.get() &&
387  lhs.comp_unit == rhs.comp_unit &&
388  lhs.target_sp.get() == rhs.target_sp.get() &&
389  LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
390  lhs.variable == rhs.variable;
391 }
392 
394  const SymbolContext &rhs) {
395  return !(lhs == rhs);
396 }
397 
399  bool use_inline_block_range,
400  AddressRange &range) const {
401  if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) {
402  range = line_entry.range;
403  return true;
404  }
405 
406  if ((scope & eSymbolContextBlock) && (block != nullptr)) {
407  if (use_inline_block_range) {
408  Block *inline_block = block->GetContainingInlinedBlock();
409  if (inline_block)
410  return inline_block->GetRangeAtIndex(range_idx, range);
411  } else {
412  return block->GetRangeAtIndex(range_idx, range);
413  }
414  }
415 
416  if ((scope & eSymbolContextFunction) && (function != nullptr)) {
417  if (range_idx == 0) {
418  range = function->GetAddressRange();
419  return true;
420  }
421  }
422 
423  if ((scope & eSymbolContextSymbol) && (symbol != nullptr)) {
424  if (range_idx == 0) {
425  if (symbol->ValueIsAddress()) {
426  range.GetBaseAddress() = symbol->GetAddressRef();
427  range.SetByteSize(symbol->GetByteSize());
428  return true;
429  }
430  }
431  }
432  range.Clear();
433  return false;
434 }
435 
437  LanguageType lang;
438  if (function && (lang = function->GetLanguage()) != eLanguageTypeUnknown) {
439  return lang;
440  } else if (variable &&
441  (lang = variable->GetLanguage()) != eLanguageTypeUnknown) {
442  return lang;
443  } else if (symbol && (lang = symbol->GetLanguage()) != eLanguageTypeUnknown) {
444  return lang;
445  } else if (comp_unit &&
446  (lang = comp_unit->GetLanguage()) != eLanguageTypeUnknown) {
447  return lang;
448  } else if (symbol) {
449  // If all else fails, try to guess the language from the name.
450  return symbol->GetMangled().GuessLanguage();
451  }
452  return eLanguageTypeUnknown;
453 }
454 
456  SymbolContext &next_frame_sc,
457  Address &next_frame_pc) const {
458  next_frame_sc.Clear(false);
459  next_frame_pc.Clear();
460 
461  if (block) {
462  // const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
463 
464  // In order to get the parent of an inlined function we first need to see
465  // if we are in an inlined block as "this->block" could be an inlined
466  // block, or a parent of "block" could be. So lets check if this block or
467  // one of this blocks parents is an inlined function.
468  Block *curr_inlined_block = block->GetContainingInlinedBlock();
469  if (curr_inlined_block) {
470  // "this->block" is contained in an inline function block, so to get the
471  // scope above the inlined block, we get the parent of the inlined block
472  // itself
473  Block *next_frame_block = curr_inlined_block->GetParent();
474  // Now calculate the symbol context of the containing block
475  next_frame_block->CalculateSymbolContext(&next_frame_sc);
476 
477  // If we get here we weren't able to find the return line entry using the
478  // nesting of the blocks and the line table. So just use the call site
479  // info from our inlined block.
480 
481  AddressRange range;
482  if (curr_inlined_block->GetRangeContainingAddress(curr_frame_pc, range)) {
483  // To see there this new frame block it, we need to look at the call
484  // site information from
485  const InlineFunctionInfo *curr_inlined_block_inlined_info =
486  curr_inlined_block->GetInlinedFunctionInfo();
487  next_frame_pc = range.GetBaseAddress();
488  next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
489  next_frame_sc.line_entry.file =
490  curr_inlined_block_inlined_info->GetCallSite().GetFile();
491  next_frame_sc.line_entry.original_file =
492  curr_inlined_block_inlined_info->GetCallSite().GetFile();
493  next_frame_sc.line_entry.line =
494  curr_inlined_block_inlined_info->GetCallSite().GetLine();
495  next_frame_sc.line_entry.column =
496  curr_inlined_block_inlined_info->GetCallSite().GetColumn();
497  return true;
498  } else {
500 
501  if (log) {
502  log->Printf(
503  "warning: inlined block 0x%8.8" PRIx64
504  " doesn't have a range that contains file address 0x%" PRIx64,
505  curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
506  }
507 #ifdef LLDB_CONFIGURATION_DEBUG
508  else {
509  ObjectFile *objfile = NULL;
510  if (module_sp) {
511  SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
512  if (symbol_vendor) {
513  SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
514  if (symbol_file)
515  objfile = symbol_file->GetObjectFile();
516  }
517  }
518  if (objfile) {
521  "warning: inlined block 0x%8.8" PRIx64
522  " doesn't have a range that contains file address 0x%" PRIx64
523  " in %s\n",
524  curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress(),
525  objfile->GetFileSpec().GetPath().c_str());
526  } else {
529  "warning: inlined block 0x%8.8" PRIx64
530  " doesn't have a range that contains file address 0x%" PRIx64
531  "\n",
532  curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
533  }
534  }
535 #endif
536  }
537  }
538  }
539 
540  return false;
541 }
542 
544  if (function) {
545  if (block) {
546  // If this symbol context has a block, check to see if this block is
547  // itself, or is contained within a block with inlined function
548  // information. If so, then the inlined block is the block that defines
549  // the function.
550  Block *inlined_block = block->GetContainingInlinedBlock();
551  if (inlined_block)
552  return inlined_block;
553 
554  // The block in this symbol context is not inside an inlined block, so
555  // the block that defines the function is the function's top level block,
556  // which is returned below.
557  }
558 
559  // There is no block information in this symbol context, so we must assume
560  // that the block that is desired is the top level block of the function
561  // itself.
562  return &function->GetBlock(true);
563  }
564  return nullptr;
565 }
566 
568  bool &is_instance_method,
569  ConstString &language_object_name)
570 
571 {
572  Block *function_block = GetFunctionBlock();
573  if (function_block) {
574  CompilerDeclContext decl_ctx = function_block->GetDeclContext();
575  if (decl_ctx)
576  return decl_ctx.IsClassMethod(&language, &is_instance_method,
577  &language_object_name);
578  }
579  return false;
580 }
581 
582 void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
583  Block *curr_block = block;
584  bool isInlinedblock = false;
585  if (curr_block != nullptr &&
586  curr_block->GetContainingInlinedBlock() != nullptr)
587  isInlinedblock = true;
588 
589  // Find all types that match the current block if we have one and put them
590  // first in the list. Keep iterating up through all blocks.
591  while (curr_block != nullptr && !isInlinedblock) {
592  type_map.ForEach(
593  [curr_block, &type_list](const lldb::TypeSP &type_sp) -> bool {
594  SymbolContextScope *scs = type_sp->GetSymbolContextScope();
595  if (scs && curr_block == scs->CalculateSymbolContextBlock())
596  type_list.Insert(type_sp);
597  return true; // Keep iterating
598  });
599 
600  // Remove any entries that are now in "type_list" from "type_map" since we
601  // can't remove from type_map while iterating
602  type_list.ForEach([&type_map](const lldb::TypeSP &type_sp) -> bool {
603  type_map.Remove(type_sp);
604  return true; // Keep iterating
605  });
606  curr_block = curr_block->GetParent();
607  }
608  // Find all types that match the current function, if we have onem, and put
609  // them next in the list.
610  if (function != nullptr && !type_map.Empty()) {
611  const size_t old_type_list_size = type_list.GetSize();
612  type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
613  SymbolContextScope *scs = type_sp->GetSymbolContextScope();
614  if (scs && function == scs->CalculateSymbolContextFunction())
615  type_list.Insert(type_sp);
616  return true; // Keep iterating
617  });
618 
619  // Remove any entries that are now in "type_list" from "type_map" since we
620  // can't remove from type_map while iterating
621  const size_t new_type_list_size = type_list.GetSize();
622  if (new_type_list_size > old_type_list_size) {
623  for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
624  type_map.Remove(type_list.GetTypeAtIndex(i));
625  }
626  }
627  // Find all types that match the current compile unit, if we have one, and
628  // put them next in the list.
629  if (comp_unit != nullptr && !type_map.Empty()) {
630  const size_t old_type_list_size = type_list.GetSize();
631 
632  type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
633  SymbolContextScope *scs = type_sp->GetSymbolContextScope();
634  if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit())
635  type_list.Insert(type_sp);
636  return true; // Keep iterating
637  });
638 
639  // Remove any entries that are now in "type_list" from "type_map" since we
640  // can't remove from type_map while iterating
641  const size_t new_type_list_size = type_list.GetSize();
642  if (new_type_list_size > old_type_list_size) {
643  for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
644  type_map.Remove(type_list.GetTypeAtIndex(i));
645  }
646  }
647  // Find all types that match the current module, if we have one, and put them
648  // next in the list.
649  if (module_sp && !type_map.Empty()) {
650  const size_t old_type_list_size = type_list.GetSize();
651  type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
652  SymbolContextScope *scs = type_sp->GetSymbolContextScope();
653  if (scs && module_sp == scs->CalculateSymbolContextModule())
654  type_list.Insert(type_sp);
655  return true; // Keep iterating
656  });
657  // Remove any entries that are now in "type_list" from "type_map" since we
658  // can't remove from type_map while iterating
659  const size_t new_type_list_size = type_list.GetSize();
660  if (new_type_list_size > old_type_list_size) {
661  for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
662  type_map.Remove(type_list.GetTypeAtIndex(i));
663  }
664  }
665  // Any types that are left get copied into the list an any order.
666  if (!type_map.Empty()) {
667  type_map.ForEach([&type_list](const lldb::TypeSP &type_sp) -> bool {
668  type_list.Insert(type_sp);
669  return true; // Keep iterating
670  });
671  }
672 }
673 
675 SymbolContext::GetFunctionName(Mangled::NamePreference preference) const {
676  if (function) {
677  if (block) {
678  Block *inlined_block = block->GetContainingInlinedBlock();
679 
680  if (inlined_block) {
681  const InlineFunctionInfo *inline_info =
682  inlined_block->GetInlinedFunctionInfo();
683  if (inline_info)
684  return inline_info->GetName(function->GetLanguage());
685  }
686  }
687  return function->GetMangled().GetName(function->GetLanguage(), preference);
688  } else if (symbol && symbol->ValueIsAddress()) {
689  return symbol->GetMangled().GetName(symbol->GetLanguage(), preference);
690  } else {
691  // No function, return an empty string.
692  return ConstString();
693  }
694 }
695 
698  Address start_addr;
699  if (block) {
700  Block *inlined_block = block->GetContainingInlinedBlock();
701  if (inlined_block) {
702  if (inlined_block->GetStartAddress(start_addr)) {
703  if (start_addr.CalculateSymbolContextLineEntry(line_entry))
704  return line_entry;
705  }
706  return LineEntry();
707  }
708  }
709 
710  if (function) {
712  .GetBaseAddress()
713  .CalculateSymbolContextLineEntry(line_entry))
714  return line_entry;
715  }
716  return LineEntry();
717 }
718 
720  AddressRange &range,
721  Status &error) {
722  if (!line_entry.IsValid()) {
723  error.SetErrorString("Symbol context has no line table.");
724  return false;
725  }
726 
727  range = line_entry.range;
728  if (line_entry.line > end_line) {
730  "end line option %d must be after the current line: %d", end_line,
731  line_entry.line);
732  return false;
733  }
734 
735  uint32_t line_index = 0;
736  bool found = false;
737  while (1) {
738  LineEntry this_line;
739  line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr,
740  false, &this_line);
741  if (line_index == UINT32_MAX)
742  break;
743  if (LineEntry::Compare(this_line, line_entry) == 0) {
744  found = true;
745  break;
746  }
747  }
748 
749  LineEntry end_entry;
750  if (!found) {
751  // Can't find the index of the SymbolContext's line entry in the
752  // SymbolContext's CompUnit.
753  error.SetErrorString(
754  "Can't find the current line entry in the CompUnit - can't process "
755  "the end-line option");
756  return false;
757  }
758 
759  line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false,
760  &end_entry);
761  if (line_index == UINT32_MAX) {
763  "could not find a line table entry corresponding "
764  "to end line number %d",
765  end_line);
766  return false;
767  }
768 
769  Block *func_block = GetFunctionBlock();
770  if (func_block &&
771  func_block->GetRangeIndexContainingAddress(
772  end_entry.range.GetBaseAddress()) == UINT32_MAX) {
774  "end line number %d is not contained within the current function.",
775  end_line);
776  return false;
777  }
778 
779  lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress() -
780  range.GetBaseAddress().GetFileAddress();
781  range.SetByteSize(range_size);
782  return true;
783 }
784 
785 const Symbol *
787  error.Clear();
788 
789  if (!target_sp) {
790  return nullptr;
791  }
792 
793  Target &target = *target_sp;
794  Module *module = module_sp.get();
795 
796  auto ProcessMatches = [this, &name, &target, module]
797  (SymbolContextList &sc_list, Status &error) -> const Symbol* {
798  llvm::SmallVector<const Symbol *, 1> external_symbols;
799  llvm::SmallVector<const Symbol *, 1> internal_symbols;
800  const uint32_t matches = sc_list.GetSize();
801  for (uint32_t i = 0; i < matches; ++i) {
802  SymbolContext sym_ctx;
803  sc_list.GetContextAtIndex(i, sym_ctx);
804  if (sym_ctx.symbol) {
805  const Symbol *symbol = sym_ctx.symbol;
806  const Address sym_address = symbol->GetAddress();
807 
808  if (sym_address.IsValid()) {
809  switch (symbol->GetType()) {
810  case eSymbolTypeData:
811  case eSymbolTypeRuntime:
812  case eSymbolTypeAbsolute:
815  case eSymbolTypeObjCIVar:
816  if (symbol->GetDemangledNameIsSynthesized()) {
817  // If the demangled name was synthesized, then don't use it for
818  // expressions. Only let the symbol match if the mangled named
819  // matches for these symbols.
820  if (symbol->GetMangled().GetMangledName() != name)
821  break;
822  }
823  if (symbol->IsExternal()) {
824  external_symbols.push_back(symbol);
825  } else {
826  internal_symbols.push_back(symbol);
827  }
828  break;
829  case eSymbolTypeReExported: {
830  ConstString reexport_name = symbol->GetReExportedSymbolName();
831  if (reexport_name) {
832  ModuleSP reexport_module_sp;
833  ModuleSpec reexport_module_spec;
834  reexport_module_spec.GetPlatformFileSpec() =
836  if (reexport_module_spec.GetPlatformFileSpec()) {
837  reexport_module_sp =
838  target.GetImages().FindFirstModule(reexport_module_spec);
839  if (!reexport_module_sp) {
840  reexport_module_spec.GetPlatformFileSpec()
841  .GetDirectory()
842  .Clear();
843  reexport_module_sp =
844  target.GetImages().FindFirstModule(reexport_module_spec);
845  }
846  }
847  // Don't allow us to try and resolve a re-exported symbol if it
848  // is the same as the current symbol
849  if (name == symbol->GetReExportedSymbolName() &&
850  module == reexport_module_sp.get())
851  return nullptr;
852 
854  symbol->GetReExportedSymbolName(), error);
855  }
856  } break;
857 
858  case eSymbolTypeCode: // We already lookup functions elsewhere
859  case eSymbolTypeVariable:
860  case eSymbolTypeLocal:
861  case eSymbolTypeParam:
863  case eSymbolTypeInvalid:
869  case eSymbolTypeBlock:
874  case eSymbolTypeScopeEnd:
876  case eSymbolTypeCompiler:
879  case eSymbolTypeResolver:
880  break;
881  }
882  }
883  }
884  }
885 
886  if (external_symbols.size() > 1) {
887  StreamString ss;
888  ss.Printf("Multiple external symbols found for '%s'\n", name.AsCString());
889  for (const Symbol *symbol : external_symbols) {
891  }
892  ss.PutChar('\n');
893  error.SetErrorString(ss.GetData());
894  return nullptr;
895  } else if (external_symbols.size()) {
896  return external_symbols[0];
897  } else if (internal_symbols.size() > 1) {
898  StreamString ss;
899  ss.Printf("Multiple internal symbols found for '%s'\n", name.AsCString());
900  for (const Symbol *symbol : internal_symbols) {
902  ss.PutChar('\n');
903  }
904  error.SetErrorString(ss.GetData());
905  return nullptr;
906  } else if (internal_symbols.size()) {
907  return internal_symbols[0];
908  } else {
909  return nullptr;
910  }
911  };
912 
913  if (module) {
914  SymbolContextList sc_list;
915  module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
916  const Symbol *const module_symbol = ProcessMatches(sc_list, error);
917 
918  if (!error.Success()) {
919  return nullptr;
920  } else if (module_symbol) {
921  return module_symbol;
922  }
923  }
924 
925  {
926  SymbolContextList sc_list;
927  target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny,
928  sc_list);
929  const Symbol *const target_symbol = ProcessMatches(sc_list, error);
930 
931  if (!error.Success()) {
932  return nullptr;
933  } else if (target_symbol) {
934  return target_symbol;
935  }
936  }
937 
938  return nullptr; // no error; we just didn't find anything
939 }
940 
941 
942 //
943 // SymbolContextSpecifier
944 //
945 
947  : m_target_sp(target_sp), m_module_spec(), m_module_sp(), m_file_spec_up(),
948  m_start_line(0), m_end_line(0), m_function_spec(), m_class_name(),
949  m_address_range_up(), m_type(eNothingSpecified) {}
950 
952 
954  SpecificationType type) {
955  bool return_value = true;
956  switch (type) {
957  case eNothingSpecified:
958  Clear();
959  break;
960  case eLineStartSpecified:
961  m_start_line = line_no;
962  m_type |= eLineStartSpecified;
963  break;
964  case eLineEndSpecified:
965  m_end_line = line_no;
966  m_type |= eLineEndSpecified;
967  break;
968  default:
969  return_value = false;
970  break;
971  }
972  return return_value;
973 }
974 
975 bool SymbolContextSpecifier::AddSpecification(const char *spec_string,
976  SpecificationType type) {
977  bool return_value = true;
978  switch (type) {
979  case eNothingSpecified:
980  Clear();
981  break;
982  case eModuleSpecified: {
983  // See if we can find the Module, if so stick it in the SymbolContext.
984  FileSpec module_file_spec(spec_string);
985  ModuleSpec module_spec(module_file_spec);
986  lldb::ModuleSP module_sp(
987  m_target_sp->GetImages().FindFirstModule(module_spec));
988  m_type |= eModuleSpecified;
989  if (module_sp)
990  m_module_sp = module_sp;
991  else
992  m_module_spec.assign(spec_string);
993  } break;
994  case eFileSpecified:
995  // CompUnits can't necessarily be resolved here, since an inlined function
996  // might show up in a number of CompUnits. Instead we just convert to a
997  // FileSpec and store it away.
998  m_file_spec_up.reset(new FileSpec(spec_string));
999  m_type |= eFileSpecified;
1000  break;
1001  case eLineStartSpecified:
1002  m_start_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
1003  if (return_value)
1004  m_type |= eLineStartSpecified;
1005  break;
1006  case eLineEndSpecified:
1007  m_end_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
1008  if (return_value)
1009  m_type |= eLineEndSpecified;
1010  break;
1011  case eFunctionSpecified:
1012  m_function_spec.assign(spec_string);
1013  m_type |= eFunctionSpecified;
1014  break;
1016  Clear();
1017  m_class_name.assign(spec_string);
1018  m_type = eClassOrNamespaceSpecified;
1019  break;
1021  // Not specified yet...
1022  break;
1023  }
1024 
1025  return return_value;
1026 }
1027 
1029  m_module_spec.clear();
1030  m_file_spec_up.reset();
1031  m_function_spec.clear();
1032  m_class_name.clear();
1033  m_start_line = 0;
1034  m_end_line = 0;
1035  m_address_range_up.reset();
1036 
1037  m_type = eNothingSpecified;
1038 }
1039 
1041  if (m_type == eNothingSpecified)
1042  return true;
1043 
1044  if (m_target_sp.get() != sc.target_sp.get())
1045  return false;
1046 
1047  if (m_type & eModuleSpecified) {
1048  if (sc.module_sp) {
1049  if (m_module_sp.get() != nullptr) {
1050  if (m_module_sp.get() != sc.module_sp.get())
1051  return false;
1052  } else {
1053  FileSpec module_file_spec(m_module_spec);
1054  if (!FileSpec::Equal(module_file_spec, sc.module_sp->GetFileSpec(),
1055  false))
1056  return false;
1057  }
1058  }
1059  }
1060  if (m_type & eFileSpecified) {
1061  if (m_file_spec_up) {
1062  // If we don't have a block or a comp_unit, then we aren't going to match
1063  // a source file.
1064  if (sc.block == nullptr && sc.comp_unit == nullptr)
1065  return false;
1066 
1067  // Check if the block is present, and if so is it inlined:
1068  bool was_inlined = false;
1069  if (sc.block != nullptr) {
1070  const InlineFunctionInfo *inline_info =
1072  if (inline_info != nullptr) {
1073  was_inlined = true;
1074  if (!FileSpec::Equal(inline_info->GetDeclaration().GetFile(),
1075  *(m_file_spec_up.get()), false))
1076  return false;
1077  }
1078  }
1079 
1080  // Next check the comp unit, but only if the SymbolContext was not
1081  // inlined.
1082  if (!was_inlined && sc.comp_unit != nullptr) {
1083  if (!FileSpec::Equal(*(sc.comp_unit), *(m_file_spec_up.get()), false))
1084  return false;
1085  }
1086  }
1087  }
1088  if (m_type & eLineStartSpecified || m_type & eLineEndSpecified) {
1089  if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
1090  return false;
1091  }
1092 
1093  if (m_type & eFunctionSpecified) {
1094  // First check the current block, and if it is inlined, get the inlined
1095  // function name:
1096  bool was_inlined = false;
1097  ConstString func_name(m_function_spec.c_str());
1098 
1099  if (sc.block != nullptr) {
1100  const InlineFunctionInfo *inline_info =
1102  if (inline_info != nullptr) {
1103  was_inlined = true;
1104  const Mangled &name = inline_info->GetMangled();
1105  if (!name.NameMatches(func_name, sc.function->GetLanguage()))
1106  return false;
1107  }
1108  }
1109  // If it wasn't inlined, check the name in the function or symbol:
1110  if (!was_inlined) {
1111  if (sc.function != nullptr) {
1112  if (!sc.function->GetMangled().NameMatches(func_name,
1113  sc.function->GetLanguage()))
1114  return false;
1115  } else if (sc.symbol != nullptr) {
1116  if (!sc.symbol->GetMangled().NameMatches(func_name,
1117  sc.symbol->GetLanguage()))
1118  return false;
1119  }
1120  }
1121  }
1122 
1123  return true;
1124 }
1125 
1127  if (m_type & eAddressRangeSpecified) {
1128 
1129  } else {
1130  Address match_address(addr, nullptr);
1131  SymbolContext sc;
1132  m_target_sp->GetImages().ResolveSymbolContextForAddress(
1133  match_address, eSymbolContextEverything, sc);
1134  return SymbolContextMatches(sc);
1135  }
1136  return true;
1137 }
1138 
1140  Stream *s, lldb::DescriptionLevel level) const {
1141  char path_str[PATH_MAX + 1];
1142 
1143  if (m_type == eNothingSpecified) {
1144  s->Printf("Nothing specified.\n");
1145  }
1146 
1147  if (m_type == eModuleSpecified) {
1148  s->Indent();
1149  if (m_module_sp) {
1150  m_module_sp->GetFileSpec().GetPath(path_str, PATH_MAX);
1151  s->Printf("Module: %s\n", path_str);
1152  } else
1153  s->Printf("Module: %s\n", m_module_spec.c_str());
1154  }
1155 
1156  if (m_type == eFileSpecified && m_file_spec_up != nullptr) {
1157  m_file_spec_up->GetPath(path_str, PATH_MAX);
1158  s->Indent();
1159  s->Printf("File: %s", path_str);
1160  if (m_type == eLineStartSpecified) {
1161  s->Printf(" from line %" PRIu64 "", (uint64_t)m_start_line);
1162  if (m_type == eLineEndSpecified)
1163  s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
1164  else
1165  s->Printf("to end");
1166  } else if (m_type == eLineEndSpecified) {
1167  s->Printf(" from start to line %" PRIu64 "", (uint64_t)m_end_line);
1168  }
1169  s->Printf(".\n");
1170  }
1171 
1172  if (m_type == eLineStartSpecified) {
1173  s->Indent();
1174  s->Printf("From line %" PRIu64 "", (uint64_t)m_start_line);
1175  if (m_type == eLineEndSpecified)
1176  s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
1177  else
1178  s->Printf("to end");
1179  s->Printf(".\n");
1180  } else if (m_type == eLineEndSpecified) {
1181  s->Printf("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
1182  }
1183 
1184  if (m_type == eFunctionSpecified) {
1185  s->Indent();
1186  s->Printf("Function: %s.\n", m_function_spec.c_str());
1187  }
1188 
1189  if (m_type == eClassOrNamespaceSpecified) {
1190  s->Indent();
1191  s->Printf("Class name: %s.\n", m_class_name.c_str());
1192  }
1193 
1194  if (m_type == eAddressRangeSpecified && m_address_range_up != nullptr) {
1195  s->Indent();
1196  s->PutCString("Address range: ");
1197  m_address_range_up->Dump(s, m_target_sp.get(),
1200  s->PutCString("\n");
1201  }
1202 }
1203 
1204 //
1205 // SymbolContextList
1206 //
1207 
1208 SymbolContextList::SymbolContextList() : m_symbol_contexts() {}
1209 
1211 
1213  m_symbol_contexts.push_back(sc);
1214 }
1215 
1217  collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1218  for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
1219  m_symbol_contexts.push_back(*pos);
1220 }
1221 
1223  bool merge_symbol_into_function) {
1224  uint32_t unique_sc_add_count = 0;
1225  collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1226  for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) {
1227  if (AppendIfUnique(*pos, merge_symbol_into_function))
1228  ++unique_sc_add_count;
1229  }
1230  return unique_sc_add_count;
1231 }
1232 
1234  bool merge_symbol_into_function) {
1235  collection::iterator pos, end = m_symbol_contexts.end();
1236  for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1237  if (*pos == sc)
1238  return false;
1239  }
1240  if (merge_symbol_into_function && sc.symbol != nullptr &&
1241  sc.comp_unit == nullptr && sc.function == nullptr &&
1242  sc.block == nullptr && !sc.line_entry.IsValid()) {
1243  if (sc.symbol->ValueIsAddress()) {
1244  for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1245  // Don't merge symbols into inlined function symbol contexts
1246  if (pos->block && pos->block->GetContainingInlinedBlock())
1247  continue;
1248 
1249  if (pos->function) {
1250  if (pos->function->GetAddressRange().GetBaseAddress() ==
1251  sc.symbol->GetAddressRef()) {
1252  // Do we already have a function with this symbol?
1253  if (pos->symbol == sc.symbol)
1254  return false;
1255  if (pos->symbol == nullptr) {
1256  pos->symbol = sc.symbol;
1257  return false;
1258  }
1259  }
1260  }
1261  }
1262  }
1263  }
1264  m_symbol_contexts.push_back(sc);
1265  return true;
1266 }
1267 
1269 
1270 void SymbolContextList::Dump(Stream *s, Target *target) const {
1271 
1272  *s << this << ": ";
1273  s->Indent();
1274  s->PutCString("SymbolContextList");
1275  s->EOL();
1276  s->IndentMore();
1277 
1278  collection::const_iterator pos, end = m_symbol_contexts.end();
1279  for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1280  // pos->Dump(s, target);
1281  pos->GetDescription(s, eDescriptionLevelVerbose, target);
1282  }
1283  s->IndentLess();
1284 }
1285 
1287  if (idx < m_symbol_contexts.size()) {
1288  sc = m_symbol_contexts[idx];
1289  return true;
1290  }
1291  return false;
1292 }
1293 
1295  if (idx < m_symbol_contexts.size()) {
1296  m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1297  return true;
1298  }
1299  return false;
1300 }
1301 
1303 
1305  uint32_t match_count = 0;
1306  const size_t size = m_symbol_contexts.size();
1307  for (size_t idx = 0; idx < size; ++idx) {
1308  if (m_symbol_contexts[idx].line_entry.line == line)
1309  ++match_count;
1310  }
1311  return match_count;
1312 }
1313 
1315  Target *target) const {
1316  const size_t size = m_symbol_contexts.size();
1317  for (size_t idx = 0; idx < size; ++idx)
1318  m_symbol_contexts[idx].GetDescription(s, level, target);
1319 }
1320 
1322  const SymbolContextList &rhs) {
1323  const uint32_t size = lhs.GetSize();
1324  if (size != rhs.GetSize())
1325  return false;
1326 
1327  SymbolContext lhs_sc;
1328  SymbolContext rhs_sc;
1329  for (uint32_t i = 0; i < size; ++i) {
1330  lhs.GetContextAtIndex(i, lhs_sc);
1331  rhs.GetContextAtIndex(i, rhs_sc);
1332  if (lhs_sc != rhs_sc)
1333  return false;
1334  }
1335  return true;
1336 }
1337 
1339  const SymbolContextList &rhs) {
1340  return !(lhs == rhs);
1341 }
uint32_t GetRangeIndexContainingAddress(const Address &addr)
Definition: Block.cpp:276
Address & GetAddressRef()
Definition: Symbol.h:56
uint32_t FindLineEntry(uint32_t start_idx, uint32_t line, const FileSpec *file_spec_ptr, bool exact, LineEntry *line_entry)
Find the line entry by line and optional inlined file spec.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
A line table entry class.
Definition: LineEntry.h:20
lldb::TargetSP target_sp
The Target for a given query.
void GetDescription(Stream *s, lldb::DescriptionLevel level) const
Definition: CompileUnit.cpp:61
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
lldb::TypeSP GetTypeAtIndex(uint32_t idx)
Definition: TypeList.cpp:66
Defines a list of symbol context objects.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
lldb::LanguageType GetLanguage() const
Definition: Symbol.h:112
bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function)
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
bool Remove(const lldb::TypeSP &type_sp)
Definition: TypeMap.cpp:123
bool AddressMatches(lldb::addr_t addr)
Block * GetParent() const
Get the parent block.
Definition: Block.cpp:192
FileSpec original_file
The original source file, from debug info.
Definition: LineEntry.h:153
bool GetStartAddress(Address &addr)
Definition: Block.cpp:307
lldb::LanguageType GetLanguage() const
Definition: Variable.cpp:56
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:269
void Clear()
Clear the object&#39;s state.
Definition: LineEntry.cpp:34
bool IsValid() const
Check if a line entry object is valid.
Definition: LineEntry.cpp:47
void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name)
Definition: Type.cpp:150
SymbolFile * GetSymbolFile()
Definition: SymbolVendor.h:125
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, bool show_function_arguments, bool show_function_name) const
Dump the stop context in this object to a Stream.
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX) const
Dump a description of this object to a Stream.
Definition: Address.cpp:374
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
bool IsClassMethod(lldb::LanguageType *language_ptr, bool *is_instance_method_ptr, ConstString *language_object_name_ptr)
Checks if this decl context represents a method of a class.
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
A file utility class.
Definition: FileSpec.h:55
static int Compare(const LineEntry &lhs, const LineEntry &rhs)
Compare two LineEntry objects.
Definition: LineEntry.cpp:158
A class that describes a function.
Definition: Function.h:323
static void SystemLog(SystemLogType type, const char *format,...) __attribute__((format(printf
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:272
lldb::LanguageType GetLanguage()
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
CompileUnit * comp_unit
The CompileUnit for a given query.
SymbolContext()
Default constructor.
void Dump(Stream *s, bool show_context)
Definition: Type.cpp:212
Address GetAddress() const
Definition: Symbol.h:72
const SymbolContext & operator=(const SymbolContext &rhs)
Assignment operator.
bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Status &error)
int32_t ToSInt32(const char *s, int32_t fail_value=0, int base=0, bool *success_ptr=nullptr)
const char * GetData() const
Definition: StreamString.h:43
A class that describes a single lexical block.
Definition: Block.h:41
bool GetParentOfInlinedScope(const Address &curr_frame_pc, SymbolContext &next_frame_sc, Address &inlined_frame_addr) const
Find the block containing the inlined block that contains this block.
bool GetRangeContainingAddress(const Address &addr, AddressRange &range)
Definition: Block.cpp:240
lldb::LanguageType GetLanguage() const
Definition: Function.cpp:591
Symbol * symbol
The Symbol for a given query.
Mangled & GetMangled()
Get accessor for the mangled name object.
Definition: Function.cpp:122
A class that describes a compilation unit.
Definition: CompileUnit.h:35
uint32_t GetSize() const
Definition: TypeList.cpp:60
void SortTypeList(TypeMap &type_map, TypeList &type_list) const
Sorts the types in TypeMap according to SymbolContext to TypeList.
bool DumpStopContext(Stream *s, bool show_fullpaths) const
Dumps information specific to a process that stops at this line entry to the supplied stream s...
Definition: LineEntry.cpp:51
size_t FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list)
Definition: Module.cpp:1364
uint32_t GetSize() const
Get accessor for a symbol context list size.
#define LIBLLDB_LOG_SYMBOLS
Definition: Logging.h:34
Function * function
The Function for a given query.
lldb::SymbolType GetType() const
Definition: Symbol.h:136
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition: Address.h:317
bool operator==(const Address &lhs, const Address &rhs)
Definition: Address.cpp:973
virtual CompileUnit * CalculateSymbolContextCompileUnit()
ConstString GetName() const
Definition: Variable.cpp:64
#define UINT32_MAX
Definition: lldb-defines.h:31
bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range)
Definition: Block.cpp:293
FileSpec & GetFile()
Get accessor for file specification.
Definition: Declaration.h:148
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:408
Block * GetFunctionBlock()
Find a block that defines the function represented by this symbol context.
LanguageType
Programming language type.
void Dump(Stream *s, Target *target) const
Dump a description of this object to a Stream.
bool DumpStopContext(Stream *s, bool show_fullpaths) const
Definition: Declaration.cpp:42
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
void Insert(const lldb::TypeSP &type)
Definition: TypeList.cpp:27
void Clear(bool clear_target)
Clear the object&#39;s state.
SymbolContextSpecifier(const lldb::TargetSP &target_sp)
uint16_t column
The column number of the source line, or zero if there is no column information.
Definition: LineEntry.h:156
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
ConstString GetName(lldb::LanguageType language) const
Definition: Function.cpp:104
void Clear()
Clear the object state.
Definition: Status.cpp:167
LineEntry GetFunctionStartLineEntry() const
Get the line entry that corresponds to the function.
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
Definition: Block.cpp:198
virtual lldb::ModuleSP CalculateSymbolContextModule()
lldb::LanguageType GetLanguage() const
Declaration & GetCallSite()
Get accessor for the call site declaration information.
Definition: Function.cpp:116
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
FileSpec file
The source file, possibly mapped by the target.source-map setting.
Definition: LineEntry.h:151
void Clear()
Clear the object&#39;s state.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
uint32_t line
The source line number, or zero if there is no line number information.
Definition: LineEntry.h:154
bool ValueIsAddress() const
Definition: Symbol.cpp:114
void IndentLess(int amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:221
bool GetFunctionMethodInfo(lldb::LanguageType &language, bool &is_instance_method, ConstString &language_object_name)
If this symbol context represents a function that is a method, return true and provide information ab...
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
bool Success() const
Test for success condition.
Definition: Status.cpp:287
uint32_t GetResolvedMask() const
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object&#39;s symbol context into sc.
Definition: Block.cpp:126
uint32_t GetLine() const
Get accessor for the declaration line number.
Definition: Declaration.h:161
void Dump(Stream *s, const char *value_if_empty=nullptr) const
Dump the object description to a stream.
lldb::ValueType GetScope() const
Definition: Variable.h:66
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:343
A section + offset based address class.
Definition: Address.h:80
const Mangled & GetMangled() const
Definition: Function.h:447
bool Empty() const
Definition: TypeMap.cpp:90
bool operator!=(const Address &lhs, const Address &rhs)
Definition: Address.cpp:979
uint32_t NumLineEntriesWithLine(uint32_t line) const
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Definition: Block.h:296
virtual Block * CalculateSymbolContextBlock()
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Definition: Symbol.cpp:174
CompilerDeclContext GetDeclContext()
Definition: Block.cpp:470
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
SymbolContextList()
Default constructor.
bool SymbolContextMatches(SymbolContext &sc)
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const
Definition: Address.cpp:864
void ForEach(std::function< bool(const lldb::TypeSP &type_sp)> const &callback) const
Definition: TypeList.cpp:78
virtual Function * CalculateSymbolContextFunction()
ConstString GetReExportedSymbolName() const
Definition: Symbol.cpp:122
size_t PutChar(char ch)
Definition: Stream.cpp:103
virtual void CalculateSymbolContext(SymbolContext *sc)=0
Reconstruct the object&#39;s symbol context into sc.
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:363
bool AddSpecification(const char *spec_string, SpecificationType type)
A class that describes information for an inlined function.
Definition: Function.h:122
uint64_t addr_t
Definition: lldb-types.h:83
void GetDescription(Stream *s, lldb::DescriptionLevel level) const
Display as the load address (if resolved).
Definition: Address.h:104
void ForEach(std::function< bool(const lldb::TypeSP &type_sp)> const &callback) const
Definition: TypeMap.cpp:107
A uniqued constant string class.
Definition: ConstString.h:38
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
Unknown or invalid language value.
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
static bool Equal(const FileSpec &a, const FileSpec &b, bool full)
Definition: FileSpec.cpp:319
lldb::ModuleSP module_sp
The Module for a given query.
LineEntry line_entry
The LineEntry for a given query.
Definition: SBAddress.h:15
collection m_symbol_contexts
The list of symbol contexts.
ConstString GetName() const
Definition: Symbol.cpp:494
bool AddLineSpecification(uint32_t line_no, SpecificationType type)
size_t Indent(const char *s=nullptr)
Indent the current line in the stream.
Definition: Stream.cpp:131
ObjectFile * GetObjectFile()
Definition: SymbolFile.h:213
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
FileSpec GetReExportedSymbolSharedLibrary() const
Definition: Symbol.cpp:136
#define PATH_MAX
Display as the file address with the module name prepended (if any).
Definition: Address.h:99
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:220
bool IsExternal() const
Definition: Symbol.h:161
Variable * variable
The global variable matching the given query.
Declaration & GetDeclaration()
Get accessor for the declaration information.
Definition: Function.cpp:51
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
FileSpec & GetPlatformFileSpec()
Definition: ModuleSpec.h:87
void IndentMore(int amount=2)
Increment the current indentation level.
Definition: Stream.cpp:218
const AddressRange & GetAddressRange()
Definition: Function.h:371
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
const Symbol * FindBestGlobalDataSymbol(ConstString name, Status &error)
Find the best global data symbol visible from this context.
A class that describes the declaration location of a lldb object.
Definition: Declaration.h:24
Block * block
The Block for a given query.
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
A section + offset based address range class.
Definition: AddressRange.h:32
void Clear()
Clear the object&#39;s state.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
bool Dump(Stream *s, Target *target, bool show_file, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_range) const
Dump a description of this object to a Stream.
Definition: LineEntry.cpp:71
void Dump(Stream *s, Target *target) const
Dump a description of this object to a Stream.
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:150
bool GetDescription(Stream *s, lldb::DescriptionLevel level, CompileUnit *cu, Target *target, bool show_address_only) const
Definition: LineEntry.cpp:106
bool GetDemangledNameIsSynthesized() const
Definition: Symbol.h:186
void Clear()
Clear this object&#39;s state.
Definition: ConstString.h:263
An error handling class.
Definition: Status.h:44
void Clear()
Clear the object&#39;s state.
Definition: Address.h:189
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
Definition: AddressRange.h:248
Display as the file address (if any).
Definition: Address.h:95
uint32_t GetColumn() const
Get accessor for the declaration column number.
Definition: Declaration.h:136
Mangled & GetMangled()
Definition: Symbol.h:120