1 //===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Symbol/SymbolContext.h"
12 #include "lldb/Core/Log.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Host/Host.h"
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Symbol/Block.h"
18 #include "lldb/Symbol/ClangASTContext.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/Symbol.h"
22 #include "lldb/Symbol/SymbolFile.h"
23 #include "lldb/Symbol/SymbolVendor.h"
24 #include "lldb/Target/Target.h"
27 using namespace lldb_private;
29 SymbolContext::SymbolContext() :
40 SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
53 SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
66 SymbolContext::SymbolContext(const SymbolContext& rhs) :
67 target_sp (rhs.target_sp),
68 module_sp (rhs.module_sp),
69 comp_unit (rhs.comp_unit),
70 function (rhs.function),
72 line_entry (rhs.line_entry),
78 SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
87 sc_scope->CalculateSymbolContext (this);
90 SymbolContext::~SymbolContext ()
95 SymbolContext::operator= (const SymbolContext& rhs)
99 target_sp = rhs.target_sp;
100 module_sp = rhs.module_sp;
101 comp_unit = rhs.comp_unit;
102 function = rhs.function;
104 line_entry = rhs.line_entry;
111 SymbolContext::Clear(bool clear_target)
124 SymbolContext::DumpStopContext
127 ExecutionContextScope *exe_scope,
131 bool show_inlined_frames,
132 bool show_function_arguments
135 bool dumped_something = false;
136 if (show_module && module_sp)
139 *s << module_sp->GetFileSpec();
141 *s << module_sp->GetFileSpec().GetFilename();
143 dumped_something = true;
146 if (function != nullptr)
148 SymbolContext inline_parent_sc;
149 Address inline_parent_addr;
150 if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments))
152 dumped_something = true;
153 function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments).Dump(s);
155 else if (function->GetMangled().GetName())
157 dumped_something = true;
158 function->GetMangled().GetName().Dump(s);
163 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
166 dumped_something = true;
167 s->Printf(" + %" PRIu64, function_offset);
171 if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr))
173 dumped_something = true;
174 Block *inlined_block = block->GetContainingInlinedBlock();
175 const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo();
176 s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString());
178 lldb_private::AddressRange block_range;
179 if (inlined_block->GetRangeContainingAddress(addr, block_range))
181 const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
182 if (inlined_function_offset)
184 s->Printf(" + %" PRIu64, inlined_function_offset);
187 const Declaration &call_site = inlined_block_info->GetCallSite();
188 if (call_site.IsValid())
190 s->PutCString(" at ");
191 call_site.DumpStopContext (s, show_fullpaths);
193 if (show_inlined_frames)
197 return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments);
202 if (line_entry.IsValid())
204 dumped_something = true;
205 s->PutCString(" at ");
206 if (line_entry.DumpStopContext(s, show_fullpaths))
207 dumped_something = true;
211 else if (symbol != nullptr)
213 if (symbol->GetMangled().GetName())
215 dumped_something = true;
216 if (symbol->GetType() == eSymbolTypeTrampoline)
217 s->PutCString("symbol stub for: ");
218 symbol->GetMangled().GetName().Dump(s);
221 if (addr.IsValid() && symbol->ValueIsAddress())
223 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset();
226 dumped_something = true;
227 s->Printf(" + %" PRIu64, symbol_offset);
231 else if (addr.IsValid())
233 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
234 dumped_something = true;
236 return dumped_something;
240 SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
244 s->Indent(" Module: file = \"");
245 module_sp->GetFileSpec().Dump(s);
247 if (module_sp->GetArchitecture().IsValid())
248 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
252 if (comp_unit != nullptr)
254 s->Indent("CompileUnit: ");
255 comp_unit->GetDescription (s, level);
259 if (function != nullptr)
261 s->Indent(" Function: ");
262 function->GetDescription (s, level, target);
265 Type *func_type = function->GetType();
268 s->Indent(" FuncType: ");
269 func_type->GetDescription (s, level, false);
274 if (block != nullptr)
276 std::vector<Block *> blocks;
277 blocks.push_back (block);
278 Block *parent_block = block->GetParent();
282 blocks.push_back (parent_block);
283 parent_block = parent_block->GetParent();
285 std::vector<Block *>::reverse_iterator pos;
286 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
287 std::vector<Block *>::reverse_iterator end = blocks.rend();
288 for (pos = begin; pos != end; ++pos)
291 s->Indent(" Blocks: ");
294 (*pos)->GetDescription(s, function, level, target);
299 if (line_entry.IsValid())
301 s->Indent(" LineEntry: ");
302 line_entry.GetDescription (s, level, comp_unit, target, false);
306 if (symbol != nullptr)
308 s->Indent(" Symbol: ");
309 symbol->GetDescription(s, level, target);
315 SymbolContext::GetResolvedMask () const
317 uint32_t resolved_mask = 0;
318 if (target_sp) resolved_mask |= eSymbolContextTarget;
319 if (module_sp) resolved_mask |= eSymbolContextModule;
320 if (comp_unit) resolved_mask |= eSymbolContextCompUnit;
321 if (function) resolved_mask |= eSymbolContextFunction;
322 if (block) resolved_mask |= eSymbolContextBlock;
323 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
324 if (symbol) resolved_mask |= eSymbolContextSymbol;
325 return resolved_mask;
329 SymbolContext::Dump(Stream *s, Target *target) const
331 *s << (void *)this << ": ";
333 s->PutCString("SymbolContext");
338 *s << "Module = " << (void *)module_sp.get() << ' ';
340 module_sp->GetFileSpec().Dump(s);
343 *s << "CompileUnit = " << (void *)comp_unit;
344 if (comp_unit != nullptr)
345 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
348 *s << "Function = " << (void *)function;
349 if (function != nullptr)
351 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
352 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
355 Type* func_type = function->GetType();
359 func_type->Dump (s, false);
364 *s << "Block = " << (void *)block;
365 if (block != nullptr)
366 *s << " {0x" << block->GetID() << '}';
367 // Dump the block and pass it a negative depth to we print all the parent blocks
369 // block->Dump(s, function->GetFileAddress(), INT_MIN);
372 *s << "LineEntry = ";
373 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
376 *s << "Symbol = " << (void *)symbol;
377 if (symbol != nullptr && symbol->GetMangled())
378 *s << ' ' << symbol->GetMangled().GetName().AsCString();
385 lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
387 return lhs.function == rhs.function
388 && lhs.symbol == rhs.symbol
389 && lhs.module_sp.get() == rhs.module_sp.get()
390 && lhs.comp_unit == rhs.comp_unit
391 && lhs.target_sp.get() == rhs.target_sp.get()
392 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
396 lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
398 return lhs.function != rhs.function
399 || lhs.symbol != rhs.symbol
400 || lhs.module_sp.get() != rhs.module_sp.get()
401 || lhs.comp_unit != rhs.comp_unit
402 || lhs.target_sp.get() != rhs.target_sp.get()
403 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
407 SymbolContext::GetAddressRange (uint32_t scope,
409 bool use_inline_block_range,
410 AddressRange &range) const
412 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
414 range = line_entry.range;
418 if ((scope & eSymbolContextBlock) && (block != nullptr))
420 if (use_inline_block_range)
422 Block *inline_block = block->GetContainingInlinedBlock();
424 return inline_block->GetRangeAtIndex (range_idx, range);
428 return block->GetRangeAtIndex (range_idx, range);
432 if ((scope & eSymbolContextFunction) && (function != nullptr))
436 range = function->GetAddressRange();
441 if ((scope & eSymbolContextSymbol) && (symbol != nullptr))
445 if (symbol->ValueIsAddress())
447 range.GetBaseAddress() = symbol->GetAddress();
448 range.SetByteSize (symbol->GetByteSize());
458 SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
459 SymbolContext &next_frame_sc,
460 Address &next_frame_pc) const
462 next_frame_sc.Clear(false);
463 next_frame_pc.Clear();
467 //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
469 // In order to get the parent of an inlined function we first need to
470 // see if we are in an inlined block as "this->block" could be an
471 // inlined block, or a parent of "block" could be. So lets check if
472 // this block or one of this blocks parents is an inlined function.
473 Block *curr_inlined_block = block->GetContainingInlinedBlock();
474 if (curr_inlined_block)
476 // "this->block" is contained in an inline function block, so to
477 // get the scope above the inlined block, we get the parent of the
478 // inlined block itself
479 Block *next_frame_block = curr_inlined_block->GetParent();
480 // Now calculate the symbol context of the containing block
481 next_frame_block->CalculateSymbolContext (&next_frame_sc);
483 // If we get here we weren't able to find the return line entry using the nesting of the blocks and
484 // the line table. So just use the call site info from our inlined block.
487 if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
489 // To see there this new frame block it, we need to look at the
490 // call site information from
491 const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
492 next_frame_pc = range.GetBaseAddress();
493 next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
494 next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
495 next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
496 next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
501 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
505 log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
506 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
508 #ifdef LLDB_CONFIGURATION_DEBUG
511 ObjectFile *objfile = NULL;
514 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
517 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
519 objfile = symbol_file->GetObjectFile();
524 Host::SystemLog (Host::eSystemLogWarning,
525 "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n",
526 curr_inlined_block->GetID(),
527 curr_frame_pc.GetFileAddress(),
528 objfile->GetFileSpec().GetPath().c_str());
532 Host::SystemLog (Host::eSystemLogWarning,
533 "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
534 curr_inlined_block->GetID(),
535 curr_frame_pc.GetFileAddress());
547 SymbolContext::GetFunctionBlock ()
553 // If this symbol context has a block, check to see if this block
554 // is itself, or is contained within a block with inlined function
555 // information. If so, then the inlined block is the block that
556 // defines the function.
557 Block *inlined_block = block->GetContainingInlinedBlock();
559 return inlined_block;
561 // The block in this symbol context is not inside an inlined
562 // block, so the block that defines the function is the function's
563 // top level block, which is returned below.
566 // There is no block information in this symbol context, so we must
567 // assume that the block that is desired is the top level block of
568 // the function itself.
569 return &function->GetBlock(true);
575 SymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language,
576 bool &is_instance_method,
577 ConstString &language_object_name)
581 Block *function_block = GetFunctionBlock ();
584 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
588 return ClangASTContext::GetClassMethodInfoForDeclContext (decl_context,
591 language_object_name);
594 language = eLanguageTypeUnknown;
595 is_instance_method = false;
596 language_object_name.Clear();
601 SymbolContext::GetFunctionName (Mangled::NamePreference preference) const
607 Block *inlined_block = block->GetContainingInlinedBlock();
611 const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo();
613 return inline_info->GetName();
616 return function->GetMangled().GetName(preference);
618 else if (symbol && symbol->ValueIsAddress())
620 return symbol->GetMangled().GetName(preference);
624 // No function, return an empty string.
625 return ConstString();
630 SymbolContext::GetFunctionStartLineEntry () const
632 LineEntry line_entry;
636 Block *inlined_block = block->GetContainingInlinedBlock();
639 if (inlined_block->GetStartAddress (start_addr))
641 if (start_addr.CalculateSymbolContextLineEntry (line_entry))
650 if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry))
656 //----------------------------------------------------------------------
658 // SymbolContextSpecifier
660 //----------------------------------------------------------------------
662 SymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
663 m_target_sp (target_sp),
671 m_address_range_ap (),
672 m_type (eNothingSpecified)
676 SymbolContextSpecifier::~SymbolContextSpecifier()
681 SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
683 bool return_value = true;
686 case eNothingSpecified:
689 case eLineStartSpecified:
690 m_start_line = line_no;
691 m_type |= eLineStartSpecified;
693 case eLineEndSpecified:
694 m_end_line = line_no;
695 m_type |= eLineEndSpecified;
698 return_value = false;
705 SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
707 bool return_value = true;
710 case eNothingSpecified:
713 case eModuleSpecified:
715 // See if we can find the Module, if so stick it in the SymbolContext.
716 FileSpec module_file_spec(spec_string, false);
717 ModuleSpec module_spec (module_file_spec);
718 lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec));
719 m_type |= eModuleSpecified;
721 m_module_sp = module_sp;
723 m_module_spec.assign (spec_string);
727 // CompUnits can't necessarily be resolved here, since an inlined function might show up in
728 // a number of CompUnits. Instead we just convert to a FileSpec and store it away.
729 m_file_spec_ap.reset (new FileSpec (spec_string, false));
730 m_type |= eFileSpecified;
732 case eLineStartSpecified:
733 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
735 m_type |= eLineStartSpecified;
737 case eLineEndSpecified:
738 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
740 m_type |= eLineEndSpecified;
742 case eFunctionSpecified:
743 m_function_spec.assign(spec_string);
744 m_type |= eFunctionSpecified;
746 case eClassOrNamespaceSpecified:
748 m_class_name.assign (spec_string);
749 m_type = eClassOrNamespaceSpecified;
751 case eAddressRangeSpecified:
752 // Not specified yet...
760 SymbolContextSpecifier::Clear()
762 m_module_spec.clear();
763 m_file_spec_ap.reset();
764 m_function_spec.clear();
765 m_class_name.clear();
768 m_address_range_ap.reset();
770 m_type = eNothingSpecified;
774 SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
776 if (m_type == eNothingSpecified)
779 if (m_target_sp.get() != sc.target_sp.get())
782 if (m_type & eModuleSpecified)
786 if (m_module_sp.get() != nullptr)
788 if (m_module_sp.get() != sc.module_sp.get())
793 FileSpec module_file_spec (m_module_spec.c_str(), false);
794 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
799 if (m_type & eFileSpecified)
801 if (m_file_spec_ap.get())
803 // If we don't have a block or a comp_unit, then we aren't going to match a source file.
804 if (sc.block == nullptr && sc.comp_unit == nullptr)
807 // Check if the block is present, and if so is it inlined:
808 bool was_inlined = false;
809 if (sc.block != nullptr)
811 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
812 if (inline_info != nullptr)
815 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
820 // Next check the comp unit, but only if the SymbolContext was not inlined.
821 if (!was_inlined && sc.comp_unit != nullptr)
823 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
828 if (m_type & eLineStartSpecified
829 || m_type & eLineEndSpecified)
831 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
835 if (m_type & eFunctionSpecified)
837 // First check the current block, and if it is inlined, get the inlined function name:
838 bool was_inlined = false;
839 ConstString func_name(m_function_spec.c_str());
841 if (sc.block != nullptr)
843 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
844 if (inline_info != nullptr)
847 const Mangled &name = inline_info->GetMangled();
848 if (!name.NameMatches (func_name))
852 // If it wasn't inlined, check the name in the function or symbol:
855 if (sc.function != nullptr)
857 if (!sc.function->GetMangled().NameMatches(func_name))
860 else if (sc.symbol != nullptr)
862 if (!sc.symbol->GetMangled().NameMatches(func_name))
874 SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
876 if (m_type & eAddressRangeSpecified)
882 Address match_address (addr, nullptr);
884 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
885 return SymbolContextMatches(sc);
891 SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
893 char path_str[PATH_MAX + 1];
895 if (m_type == eNothingSpecified)
897 s->Printf ("Nothing specified.\n");
900 if (m_type == eModuleSpecified)
905 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
906 s->Printf ("Module: %s\n", path_str);
909 s->Printf ("Module: %s\n", m_module_spec.c_str());
912 if (m_type == eFileSpecified && m_file_spec_ap.get() != nullptr)
914 m_file_spec_ap->GetPath (path_str, PATH_MAX);
916 s->Printf ("File: %s", path_str);
917 if (m_type == eLineStartSpecified)
919 s->Printf (" from line %" PRIu64 "", (uint64_t)m_start_line);
920 if (m_type == eLineEndSpecified)
921 s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
923 s->Printf ("to end");
925 else if (m_type == eLineEndSpecified)
927 s->Printf (" from start to line %" PRIu64 "", (uint64_t)m_end_line);
932 if (m_type == eLineStartSpecified)
935 s->Printf ("From line %" PRIu64 "", (uint64_t)m_start_line);
936 if (m_type == eLineEndSpecified)
937 s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
939 s->Printf ("to end");
942 else if (m_type == eLineEndSpecified)
944 s->Printf ("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
947 if (m_type == eFunctionSpecified)
950 s->Printf ("Function: %s.\n", m_function_spec.c_str());
953 if (m_type == eClassOrNamespaceSpecified)
956 s->Printf ("Class name: %s.\n", m_class_name.c_str());
959 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != nullptr)
962 s->PutCString ("Address range: ");
963 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
964 s->PutCString ("\n");
968 //----------------------------------------------------------------------
972 //----------------------------------------------------------------------
975 SymbolContextList::SymbolContextList() :
980 SymbolContextList::~SymbolContextList()
985 SymbolContextList::Append(const SymbolContext& sc)
987 m_symbol_contexts.push_back(sc);
991 SymbolContextList::Append (const SymbolContextList& sc_list)
993 collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
994 for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
995 m_symbol_contexts.push_back (*pos);
1000 SymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function)
1002 uint32_t unique_sc_add_count = 0;
1003 collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1004 for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
1006 if (AppendIfUnique (*pos, merge_symbol_into_function))
1007 ++unique_sc_add_count;
1009 return unique_sc_add_count;
1013 SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
1015 collection::iterator pos, end = m_symbol_contexts.end();
1016 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1021 if (merge_symbol_into_function
1022 && sc.symbol != nullptr
1023 && sc.comp_unit == nullptr
1024 && sc.function == nullptr
1025 && sc.block == nullptr
1026 && sc.line_entry.IsValid() == false)
1028 if (sc.symbol->ValueIsAddress())
1030 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1032 // Don't merge symbols into inlined function symbol contexts
1033 if (pos->block && pos->block->GetContainingInlinedBlock())
1038 if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress())
1040 // Do we already have a function with this symbol?
1041 if (pos->symbol == sc.symbol)
1043 if (pos->symbol == nullptr)
1045 pos->symbol = sc.symbol;
1053 m_symbol_contexts.push_back(sc);
1058 SymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
1062 if (symbol_sc.symbol != nullptr
1063 && symbol_sc.comp_unit == nullptr
1064 && symbol_sc.function == nullptr
1065 && symbol_sc.block == nullptr
1066 && symbol_sc.line_entry.IsValid() == false)
1068 if (symbol_sc.symbol->ValueIsAddress())
1070 const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx);
1071 for (size_t i=start_idx; i<end; ++i)
1073 const SymbolContext &function_sc = m_symbol_contexts[i];
1074 // Don't merge symbols into inlined function symbol contexts
1075 if (function_sc.block && function_sc.block->GetContainingInlinedBlock())
1078 if (function_sc.function)
1080 if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
1082 // Do we already have a function with this symbol?
1083 if (function_sc.symbol == symbol_sc.symbol)
1084 return true; // Already have a symbol context with this symbol, return true
1086 if (function_sc.symbol == nullptr)
1088 // We successfully merged this symbol into an existing symbol context
1089 m_symbol_contexts[i].symbol = symbol_sc.symbol;
1101 SymbolContextList::Clear()
1103 m_symbol_contexts.clear();
1107 SymbolContextList::Dump(Stream *s, Target *target) const
1110 *s << (void *)this << ": ";
1112 s->PutCString("SymbolContextList");
1116 collection::const_iterator pos, end = m_symbol_contexts.end();
1117 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1119 //pos->Dump(s, target);
1120 pos->GetDescription(s, eDescriptionLevelVerbose, target);
1126 SymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const
1128 if (idx < m_symbol_contexts.size())
1130 sc = m_symbol_contexts[idx];
1137 SymbolContextList::GetLastContext(SymbolContext& sc) const
1139 if (!m_symbol_contexts.empty())
1141 sc = m_symbol_contexts.back();
1148 SymbolContextList::RemoveContextAtIndex (size_t idx)
1150 if (idx < m_symbol_contexts.size())
1152 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1159 SymbolContextList::GetSize() const
1161 return m_symbol_contexts.size();
1165 SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
1167 uint32_t match_count = 0;
1168 const size_t size = m_symbol_contexts.size();
1169 for (size_t idx = 0; idx<size; ++idx)
1171 if (m_symbol_contexts[idx].line_entry.line == line)
1178 SymbolContextList::GetDescription(Stream *s,
1179 lldb::DescriptionLevel level,
1180 Target *target) const
1182 const size_t size = m_symbol_contexts.size();
1183 for (size_t idx = 0; idx<size; ++idx)
1184 m_symbol_contexts[idx].GetDescription (s, level, target);
1188 lldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs)
1190 const uint32_t size = lhs.GetSize();
1191 if (size != rhs.GetSize())
1194 SymbolContext lhs_sc;
1195 SymbolContext rhs_sc;
1196 for (uint32_t i=0; i<size; ++i)
1198 lhs.GetContextAtIndex(i, lhs_sc);
1199 rhs.GetContextAtIndex(i, rhs_sc);
1200 if (lhs_sc != rhs_sc)
1207 lldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs)
1209 return !(lhs == rhs);