xref: /freebsd-src/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- SymbolContext.cpp -------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
100b57cec5SDimitry Andric 
115f757f3fSDimitry Andric #include "lldb/Core/Address.h"
1281ad6265SDimitry Andric #include "lldb/Core/Debugger.h"
130b57cec5SDimitry Andric #include "lldb/Core/Module.h"
140b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
150b57cec5SDimitry Andric #include "lldb/Host/Host.h"
160b57cec5SDimitry Andric #include "lldb/Symbol/Block.h"
170b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
180b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
190b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h"
200b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
210b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
220b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h"
2306c3fb27SDimitry Andric #include "lldb/Target/Language.h"
240b57cec5SDimitry Andric #include "lldb/Target/Target.h"
2581ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
260b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
277a6dacacSDimitry Andric #include "lldb/Utility/Stream.h"
289dba64beSDimitry Andric #include "lldb/Utility/StreamString.h"
2906c3fb27SDimitry Andric #include "lldb/lldb-enumerations.h"
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace lldb;
320b57cec5SDimitry Andric using namespace lldb_private;
330b57cec5SDimitry Andric 
34fe6060f1SDimitry Andric SymbolContext::SymbolContext() : target_sp(), module_sp(), line_entry() {}
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric SymbolContext::SymbolContext(const ModuleSP &m, CompileUnit *cu, Function *f,
370b57cec5SDimitry Andric                              Block *b, LineEntry *le, Symbol *s)
380b57cec5SDimitry Andric     : target_sp(), module_sp(m), comp_unit(cu), function(f), block(b),
3981ad6265SDimitry Andric       line_entry(), symbol(s) {
400b57cec5SDimitry Andric   if (le)
410b57cec5SDimitry Andric     line_entry = *le;
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP &m,
450b57cec5SDimitry Andric                              CompileUnit *cu, Function *f, Block *b,
460b57cec5SDimitry Andric                              LineEntry *le, Symbol *s)
470b57cec5SDimitry Andric     : target_sp(t), module_sp(m), comp_unit(cu), function(f), block(b),
4881ad6265SDimitry Andric       line_entry(), symbol(s) {
490b57cec5SDimitry Andric   if (le)
500b57cec5SDimitry Andric     line_entry = *le;
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric SymbolContext::SymbolContext(SymbolContextScope *sc_scope)
5481ad6265SDimitry Andric     : target_sp(), module_sp(), line_entry() {
550b57cec5SDimitry Andric   sc_scope->CalculateSymbolContext(this);
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
58fe6060f1SDimitry Andric SymbolContext::~SymbolContext() = default;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric void SymbolContext::Clear(bool clear_target) {
610b57cec5SDimitry Andric   if (clear_target)
620b57cec5SDimitry Andric     target_sp.reset();
630b57cec5SDimitry Andric   module_sp.reset();
640b57cec5SDimitry Andric   comp_unit = nullptr;
650b57cec5SDimitry Andric   function = nullptr;
660b57cec5SDimitry Andric   block = nullptr;
670b57cec5SDimitry Andric   line_entry.Clear();
680b57cec5SDimitry Andric   symbol = nullptr;
690b57cec5SDimitry Andric   variable = nullptr;
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
727a6dacacSDimitry Andric bool SymbolContext::DumpStopContext(
737a6dacacSDimitry Andric     Stream *s, ExecutionContextScope *exe_scope, const Address &addr,
747a6dacacSDimitry Andric     bool show_fullpaths, bool show_module, bool show_inlined_frames,
757a6dacacSDimitry Andric     bool show_function_arguments, bool show_function_name,
76*0fca6ea1SDimitry Andric     bool show_function_display_name,
777a6dacacSDimitry Andric     std::optional<Stream::HighlightSettings> settings) const {
780b57cec5SDimitry Andric   bool dumped_something = false;
790b57cec5SDimitry Andric   if (show_module && module_sp) {
800b57cec5SDimitry Andric     if (show_fullpaths)
810b57cec5SDimitry Andric       *s << module_sp->GetFileSpec();
820b57cec5SDimitry Andric     else
830b57cec5SDimitry Andric       *s << module_sp->GetFileSpec().GetFilename();
840b57cec5SDimitry Andric     s->PutChar('`');
850b57cec5SDimitry Andric     dumped_something = true;
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric   if (function != nullptr) {
880b57cec5SDimitry Andric     SymbolContext inline_parent_sc;
890b57cec5SDimitry Andric     Address inline_parent_addr;
900b57cec5SDimitry Andric     if (!show_function_name) {
910b57cec5SDimitry Andric       s->Printf("<");
920b57cec5SDimitry Andric       dumped_something = true;
930b57cec5SDimitry Andric     } else {
940b57cec5SDimitry Andric       ConstString name;
950b57cec5SDimitry Andric       if (!show_function_arguments)
960b57cec5SDimitry Andric         name = function->GetNameNoArguments();
97*0fca6ea1SDimitry Andric       if (!name && show_function_display_name)
98*0fca6ea1SDimitry Andric         name = function->GetDisplayName();
990b57cec5SDimitry Andric       if (!name)
1000b57cec5SDimitry Andric         name = function->GetName();
1017a6dacacSDimitry Andric       if (name)
1027a6dacacSDimitry Andric         s->PutCStringColorHighlighted(name.GetStringRef(), settings);
1030b57cec5SDimitry Andric     }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric     if (addr.IsValid()) {
1060b57cec5SDimitry Andric       const addr_t function_offset =
1070b57cec5SDimitry Andric           addr.GetOffset() -
1080b57cec5SDimitry Andric           function->GetAddressRange().GetBaseAddress().GetOffset();
1090b57cec5SDimitry Andric       if (!show_function_name) {
1100b57cec5SDimitry Andric         // Print +offset even if offset is 0
1110b57cec5SDimitry Andric         dumped_something = true;
1120b57cec5SDimitry Andric         s->Printf("+%" PRIu64 ">", function_offset);
1130b57cec5SDimitry Andric       } else if (function_offset) {
1140b57cec5SDimitry Andric         dumped_something = true;
1150b57cec5SDimitry Andric         s->Printf(" + %" PRIu64, function_offset);
1160b57cec5SDimitry Andric       }
1170b57cec5SDimitry Andric     }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric     if (GetParentOfInlinedScope(addr, inline_parent_sc, inline_parent_addr)) {
1200b57cec5SDimitry Andric       dumped_something = true;
1210b57cec5SDimitry Andric       Block *inlined_block = block->GetContainingInlinedBlock();
1220b57cec5SDimitry Andric       const InlineFunctionInfo *inlined_block_info =
1230b57cec5SDimitry Andric           inlined_block->GetInlinedFunctionInfo();
1245ffd83dbSDimitry Andric       s->Printf(" [inlined] %s", inlined_block_info->GetName().GetCString());
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric       lldb_private::AddressRange block_range;
1270b57cec5SDimitry Andric       if (inlined_block->GetRangeContainingAddress(addr, block_range)) {
1280b57cec5SDimitry Andric         const addr_t inlined_function_offset =
1290b57cec5SDimitry Andric             addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
1300b57cec5SDimitry Andric         if (inlined_function_offset) {
1310b57cec5SDimitry Andric           s->Printf(" + %" PRIu64, inlined_function_offset);
1320b57cec5SDimitry Andric         }
1330b57cec5SDimitry Andric       }
134fe6060f1SDimitry Andric       // "line_entry" will always be valid as GetParentOfInlinedScope(...) will
135fe6060f1SDimitry Andric       // fill it in correctly with the calling file and line. Previous code
136fe6060f1SDimitry Andric       // was extracting the calling file and line from inlined_block_info and
137fe6060f1SDimitry Andric       // using it right away which is not correct. On the first call to this
138fe6060f1SDimitry Andric       // function "line_entry" will contain the actual line table entry. On
139fe6060f1SDimitry Andric       // susequent calls "line_entry" will contain the calling file and line
140fe6060f1SDimitry Andric       // from the previous inline info.
141fe6060f1SDimitry Andric       if (line_entry.IsValid()) {
142e8d8bef9SDimitry Andric         s->PutCString(" at ");
143e8d8bef9SDimitry Andric         line_entry.DumpStopContext(s, show_fullpaths);
144e8d8bef9SDimitry Andric       }
145e8d8bef9SDimitry Andric 
1460b57cec5SDimitry Andric       if (show_inlined_frames) {
1470b57cec5SDimitry Andric         s->EOL();
1480b57cec5SDimitry Andric         s->Indent();
1490b57cec5SDimitry Andric         const bool show_function_name = true;
1500b57cec5SDimitry Andric         return inline_parent_sc.DumpStopContext(
1510b57cec5SDimitry Andric             s, exe_scope, inline_parent_addr, show_fullpaths, show_module,
152*0fca6ea1SDimitry Andric             show_inlined_frames, show_function_arguments, show_function_name,
153*0fca6ea1SDimitry Andric             show_function_display_name);
1540b57cec5SDimitry Andric       }
1550b57cec5SDimitry Andric     } else {
1560b57cec5SDimitry Andric       if (line_entry.IsValid()) {
1570b57cec5SDimitry Andric         dumped_something = true;
1580b57cec5SDimitry Andric         s->PutCString(" at ");
1590b57cec5SDimitry Andric         if (line_entry.DumpStopContext(s, show_fullpaths))
1600b57cec5SDimitry Andric           dumped_something = true;
1610b57cec5SDimitry Andric       }
1620b57cec5SDimitry Andric     }
1630b57cec5SDimitry Andric   } else if (symbol != nullptr) {
1640b57cec5SDimitry Andric     if (!show_function_name) {
1650b57cec5SDimitry Andric       s->Printf("<");
1660b57cec5SDimitry Andric       dumped_something = true;
1670b57cec5SDimitry Andric     } else if (symbol->GetName()) {
1680b57cec5SDimitry Andric       dumped_something = true;
1690b57cec5SDimitry Andric       if (symbol->GetType() == eSymbolTypeTrampoline)
1700b57cec5SDimitry Andric         s->PutCString("symbol stub for: ");
171*0fca6ea1SDimitry Andric       ConstString name;
172*0fca6ea1SDimitry Andric       if (show_function_display_name)
173*0fca6ea1SDimitry Andric         name = symbol->GetDisplayName();
174*0fca6ea1SDimitry Andric       if (!name)
175*0fca6ea1SDimitry Andric         name = symbol->GetName();
176*0fca6ea1SDimitry Andric       s->PutCStringColorHighlighted(name.GetStringRef(), settings);
1770b57cec5SDimitry Andric     }
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric     if (addr.IsValid() && symbol->ValueIsAddress()) {
1800b57cec5SDimitry Andric       const addr_t symbol_offset =
1810b57cec5SDimitry Andric           addr.GetOffset() - symbol->GetAddressRef().GetOffset();
1820b57cec5SDimitry Andric       if (!show_function_name) {
1830b57cec5SDimitry Andric         // Print +offset even if offset is 0
1840b57cec5SDimitry Andric         dumped_something = true;
1850b57cec5SDimitry Andric         s->Printf("+%" PRIu64 ">", symbol_offset);
1860b57cec5SDimitry Andric       } else if (symbol_offset) {
1870b57cec5SDimitry Andric         dumped_something = true;
1880b57cec5SDimitry Andric         s->Printf(" + %" PRIu64, symbol_offset);
1890b57cec5SDimitry Andric       }
1900b57cec5SDimitry Andric     }
1910b57cec5SDimitry Andric   } else if (addr.IsValid()) {
1920b57cec5SDimitry Andric     addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
1930b57cec5SDimitry Andric     dumped_something = true;
1940b57cec5SDimitry Andric   }
1950b57cec5SDimitry Andric   return dumped_something;
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
1987a6dacacSDimitry Andric void SymbolContext::GetDescription(
1997a6dacacSDimitry Andric     Stream *s, lldb::DescriptionLevel level, Target *target,
2007a6dacacSDimitry Andric     std::optional<Stream::HighlightSettings> settings) const {
2010b57cec5SDimitry Andric   if (module_sp) {
2020b57cec5SDimitry Andric     s->Indent("     Module: file = \"");
203480093f4SDimitry Andric     module_sp->GetFileSpec().Dump(s->AsRawOstream());
2040b57cec5SDimitry Andric     *s << '"';
2050b57cec5SDimitry Andric     if (module_sp->GetArchitecture().IsValid())
2060b57cec5SDimitry Andric       s->Printf(", arch = \"%s\"",
2070b57cec5SDimitry Andric                 module_sp->GetArchitecture().GetArchitectureName());
2080b57cec5SDimitry Andric     s->EOL();
2090b57cec5SDimitry Andric   }
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   if (comp_unit != nullptr) {
2120b57cec5SDimitry Andric     s->Indent("CompileUnit: ");
2130b57cec5SDimitry Andric     comp_unit->GetDescription(s, level);
2140b57cec5SDimitry Andric     s->EOL();
2150b57cec5SDimitry Andric   }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   if (function != nullptr) {
2180b57cec5SDimitry Andric     s->Indent("   Function: ");
2190b57cec5SDimitry Andric     function->GetDescription(s, level, target);
2200b57cec5SDimitry Andric     s->EOL();
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric     Type *func_type = function->GetType();
2230b57cec5SDimitry Andric     if (func_type) {
2240b57cec5SDimitry Andric       s->Indent("   FuncType: ");
225e8d8bef9SDimitry Andric       func_type->GetDescription(s, level, false, target);
2260b57cec5SDimitry Andric       s->EOL();
2270b57cec5SDimitry Andric     }
2280b57cec5SDimitry Andric   }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   if (block != nullptr) {
2310b57cec5SDimitry Andric     std::vector<Block *> blocks;
2320b57cec5SDimitry Andric     blocks.push_back(block);
2330b57cec5SDimitry Andric     Block *parent_block = block->GetParent();
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     while (parent_block) {
2360b57cec5SDimitry Andric       blocks.push_back(parent_block);
2370b57cec5SDimitry Andric       parent_block = parent_block->GetParent();
2380b57cec5SDimitry Andric     }
2390b57cec5SDimitry Andric     std::vector<Block *>::reverse_iterator pos;
2400b57cec5SDimitry Andric     std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
2410b57cec5SDimitry Andric     std::vector<Block *>::reverse_iterator end = blocks.rend();
2420b57cec5SDimitry Andric     for (pos = begin; pos != end; ++pos) {
2430b57cec5SDimitry Andric       if (pos == begin)
2440b57cec5SDimitry Andric         s->Indent("     Blocks: ");
2450b57cec5SDimitry Andric       else
2460b57cec5SDimitry Andric         s->Indent("             ");
2470b57cec5SDimitry Andric       (*pos)->GetDescription(s, function, level, target);
2480b57cec5SDimitry Andric       s->EOL();
2490b57cec5SDimitry Andric     }
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   if (line_entry.IsValid()) {
2530b57cec5SDimitry Andric     s->Indent("  LineEntry: ");
2540b57cec5SDimitry Andric     line_entry.GetDescription(s, level, comp_unit, target, false);
2550b57cec5SDimitry Andric     s->EOL();
2560b57cec5SDimitry Andric   }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   if (symbol != nullptr) {
2590b57cec5SDimitry Andric     s->Indent("     Symbol: ");
2607a6dacacSDimitry Andric     symbol->GetDescription(s, level, target, settings);
2610b57cec5SDimitry Andric     s->EOL();
2620b57cec5SDimitry Andric   }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   if (variable != nullptr) {
2650b57cec5SDimitry Andric     s->Indent("   Variable: ");
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric     s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric     switch (variable->GetScope()) {
2700b57cec5SDimitry Andric     case eValueTypeVariableGlobal:
2710b57cec5SDimitry Andric       s->PutCString("kind = global, ");
2720b57cec5SDimitry Andric       break;
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric     case eValueTypeVariableStatic:
2750b57cec5SDimitry Andric       s->PutCString("kind = static, ");
2760b57cec5SDimitry Andric       break;
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric     case eValueTypeVariableArgument:
2790b57cec5SDimitry Andric       s->PutCString("kind = argument, ");
2800b57cec5SDimitry Andric       break;
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric     case eValueTypeVariableLocal:
2830b57cec5SDimitry Andric       s->PutCString("kind = local, ");
2840b57cec5SDimitry Andric       break;
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric     case eValueTypeVariableThreadLocal:
2870b57cec5SDimitry Andric       s->PutCString("kind = thread local, ");
2880b57cec5SDimitry Andric       break;
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric     default:
2910b57cec5SDimitry Andric       break;
2920b57cec5SDimitry Andric     }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric     s->Printf("name = \"%s\"\n", variable->GetName().GetCString());
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric uint32_t SymbolContext::GetResolvedMask() const {
2990b57cec5SDimitry Andric   uint32_t resolved_mask = 0;
3000b57cec5SDimitry Andric   if (target_sp)
3010b57cec5SDimitry Andric     resolved_mask |= eSymbolContextTarget;
3020b57cec5SDimitry Andric   if (module_sp)
3030b57cec5SDimitry Andric     resolved_mask |= eSymbolContextModule;
3040b57cec5SDimitry Andric   if (comp_unit)
3050b57cec5SDimitry Andric     resolved_mask |= eSymbolContextCompUnit;
3060b57cec5SDimitry Andric   if (function)
3070b57cec5SDimitry Andric     resolved_mask |= eSymbolContextFunction;
3080b57cec5SDimitry Andric   if (block)
3090b57cec5SDimitry Andric     resolved_mask |= eSymbolContextBlock;
3100b57cec5SDimitry Andric   if (line_entry.IsValid())
3110b57cec5SDimitry Andric     resolved_mask |= eSymbolContextLineEntry;
3120b57cec5SDimitry Andric   if (symbol)
3130b57cec5SDimitry Andric     resolved_mask |= eSymbolContextSymbol;
3140b57cec5SDimitry Andric   if (variable)
3150b57cec5SDimitry Andric     resolved_mask |= eSymbolContextVariable;
3160b57cec5SDimitry Andric   return resolved_mask;
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric void SymbolContext::Dump(Stream *s, Target *target) const {
3200b57cec5SDimitry Andric   *s << this << ": ";
3210b57cec5SDimitry Andric   s->Indent();
3220b57cec5SDimitry Andric   s->PutCString("SymbolContext");
3230b57cec5SDimitry Andric   s->IndentMore();
3240b57cec5SDimitry Andric   s->EOL();
3250b57cec5SDimitry Andric   s->IndentMore();
3260b57cec5SDimitry Andric   s->Indent();
3270b57cec5SDimitry Andric   *s << "Module       = " << module_sp.get() << ' ';
3280b57cec5SDimitry Andric   if (module_sp)
329480093f4SDimitry Andric     module_sp->GetFileSpec().Dump(s->AsRawOstream());
3300b57cec5SDimitry Andric   s->EOL();
3310b57cec5SDimitry Andric   s->Indent();
3320b57cec5SDimitry Andric   *s << "CompileUnit  = " << comp_unit;
3330b57cec5SDimitry Andric   if (comp_unit != nullptr)
334480093f4SDimitry Andric     s->Format(" {{{0:x-16}} {1}", comp_unit->GetID(),
335480093f4SDimitry Andric               comp_unit->GetPrimaryFile());
3360b57cec5SDimitry Andric   s->EOL();
3370b57cec5SDimitry Andric   s->Indent();
3380b57cec5SDimitry Andric   *s << "Function     = " << function;
3390b57cec5SDimitry Andric   if (function != nullptr) {
340480093f4SDimitry Andric     s->Format(" {{{0:x-16}} {1}, address-range = ", function->GetID(),
341480093f4SDimitry Andric               function->GetType()->GetName());
3420b57cec5SDimitry Andric     function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress,
3430b57cec5SDimitry Andric                                      Address::DumpStyleModuleWithFileAddress);
3440b57cec5SDimitry Andric     s->EOL();
3450b57cec5SDimitry Andric     s->Indent();
3460b57cec5SDimitry Andric     Type *func_type = function->GetType();
3470b57cec5SDimitry Andric     if (func_type) {
3480b57cec5SDimitry Andric       *s << "        Type = ";
3490b57cec5SDimitry Andric       func_type->Dump(s, false);
3500b57cec5SDimitry Andric     }
3510b57cec5SDimitry Andric   }
3520b57cec5SDimitry Andric   s->EOL();
3530b57cec5SDimitry Andric   s->Indent();
3540b57cec5SDimitry Andric   *s << "Block        = " << block;
3550b57cec5SDimitry Andric   if (block != nullptr)
356480093f4SDimitry Andric     s->Format(" {{{0:x-16}}", block->GetID());
3570b57cec5SDimitry Andric   s->EOL();
3580b57cec5SDimitry Andric   s->Indent();
3590b57cec5SDimitry Andric   *s << "LineEntry    = ";
3600b57cec5SDimitry Andric   line_entry.Dump(s, target, true, Address::DumpStyleLoadAddress,
3610b57cec5SDimitry Andric                   Address::DumpStyleModuleWithFileAddress, true);
3620b57cec5SDimitry Andric   s->EOL();
3630b57cec5SDimitry Andric   s->Indent();
3640b57cec5SDimitry Andric   *s << "Symbol       = " << symbol;
3650b57cec5SDimitry Andric   if (symbol != nullptr && symbol->GetMangled())
3660b57cec5SDimitry Andric     *s << ' ' << symbol->GetName().AsCString();
3670b57cec5SDimitry Andric   s->EOL();
3680b57cec5SDimitry Andric   *s << "Variable     = " << variable;
3690b57cec5SDimitry Andric   if (variable != nullptr) {
370480093f4SDimitry Andric     s->Format(" {{{0:x-16}} {1}", variable->GetID(),
371480093f4SDimitry Andric               variable->GetType()->GetName());
3720b57cec5SDimitry Andric     s->EOL();
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric   s->IndentLess();
3750b57cec5SDimitry Andric   s->IndentLess();
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric bool lldb_private::operator==(const SymbolContext &lhs,
3790b57cec5SDimitry Andric                               const SymbolContext &rhs) {
3800b57cec5SDimitry Andric   return lhs.function == rhs.function && lhs.symbol == rhs.symbol &&
3810b57cec5SDimitry Andric          lhs.module_sp.get() == rhs.module_sp.get() &&
3820b57cec5SDimitry Andric          lhs.comp_unit == rhs.comp_unit &&
3830b57cec5SDimitry Andric          lhs.target_sp.get() == rhs.target_sp.get() &&
3840b57cec5SDimitry Andric          LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
3850b57cec5SDimitry Andric          lhs.variable == rhs.variable;
3860b57cec5SDimitry Andric }
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric bool lldb_private::operator!=(const SymbolContext &lhs,
3890b57cec5SDimitry Andric                               const SymbolContext &rhs) {
3900b57cec5SDimitry Andric   return !(lhs == rhs);
3910b57cec5SDimitry Andric }
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric bool SymbolContext::GetAddressRange(uint32_t scope, uint32_t range_idx,
3940b57cec5SDimitry Andric                                     bool use_inline_block_range,
3950b57cec5SDimitry Andric                                     AddressRange &range) const {
3960b57cec5SDimitry Andric   if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) {
3970b57cec5SDimitry Andric     range = line_entry.range;
3980b57cec5SDimitry Andric     return true;
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   if ((scope & eSymbolContextBlock) && (block != nullptr)) {
4020b57cec5SDimitry Andric     if (use_inline_block_range) {
4030b57cec5SDimitry Andric       Block *inline_block = block->GetContainingInlinedBlock();
4040b57cec5SDimitry Andric       if (inline_block)
4050b57cec5SDimitry Andric         return inline_block->GetRangeAtIndex(range_idx, range);
4060b57cec5SDimitry Andric     } else {
4070b57cec5SDimitry Andric       return block->GetRangeAtIndex(range_idx, range);
4080b57cec5SDimitry Andric     }
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   if ((scope & eSymbolContextFunction) && (function != nullptr)) {
4120b57cec5SDimitry Andric     if (range_idx == 0) {
4130b57cec5SDimitry Andric       range = function->GetAddressRange();
4140b57cec5SDimitry Andric       return true;
4150b57cec5SDimitry Andric     }
4160b57cec5SDimitry Andric   }
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   if ((scope & eSymbolContextSymbol) && (symbol != nullptr)) {
4190b57cec5SDimitry Andric     if (range_idx == 0) {
4200b57cec5SDimitry Andric       if (symbol->ValueIsAddress()) {
4210b57cec5SDimitry Andric         range.GetBaseAddress() = symbol->GetAddressRef();
4220b57cec5SDimitry Andric         range.SetByteSize(symbol->GetByteSize());
4230b57cec5SDimitry Andric         return true;
4240b57cec5SDimitry Andric       }
4250b57cec5SDimitry Andric     }
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric   range.Clear();
4280b57cec5SDimitry Andric   return false;
4290b57cec5SDimitry Andric }
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric LanguageType SymbolContext::GetLanguage() const {
4320b57cec5SDimitry Andric   LanguageType lang;
4330b57cec5SDimitry Andric   if (function && (lang = function->GetLanguage()) != eLanguageTypeUnknown) {
4340b57cec5SDimitry Andric     return lang;
4350b57cec5SDimitry Andric   } else if (variable &&
4360b57cec5SDimitry Andric              (lang = variable->GetLanguage()) != eLanguageTypeUnknown) {
4370b57cec5SDimitry Andric     return lang;
4380b57cec5SDimitry Andric   } else if (symbol && (lang = symbol->GetLanguage()) != eLanguageTypeUnknown) {
4390b57cec5SDimitry Andric     return lang;
4400b57cec5SDimitry Andric   } else if (comp_unit &&
4410b57cec5SDimitry Andric              (lang = comp_unit->GetLanguage()) != eLanguageTypeUnknown) {
4420b57cec5SDimitry Andric     return lang;
4430b57cec5SDimitry Andric   } else if (symbol) {
4440b57cec5SDimitry Andric     // If all else fails, try to guess the language from the name.
4450b57cec5SDimitry Andric     return symbol->GetMangled().GuessLanguage();
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric   return eLanguageTypeUnknown;
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc,
4510b57cec5SDimitry Andric                                             SymbolContext &next_frame_sc,
4520b57cec5SDimitry Andric                                             Address &next_frame_pc) const {
4530b57cec5SDimitry Andric   next_frame_sc.Clear(false);
4540b57cec5SDimitry Andric   next_frame_pc.Clear();
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric   if (block) {
4570b57cec5SDimitry Andric     // const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric     // In order to get the parent of an inlined function we first need to see
4600b57cec5SDimitry Andric     // if we are in an inlined block as "this->block" could be an inlined
4610b57cec5SDimitry Andric     // block, or a parent of "block" could be. So lets check if this block or
4620b57cec5SDimitry Andric     // one of this blocks parents is an inlined function.
4630b57cec5SDimitry Andric     Block *curr_inlined_block = block->GetContainingInlinedBlock();
4640b57cec5SDimitry Andric     if (curr_inlined_block) {
4650b57cec5SDimitry Andric       // "this->block" is contained in an inline function block, so to get the
4660b57cec5SDimitry Andric       // scope above the inlined block, we get the parent of the inlined block
4670b57cec5SDimitry Andric       // itself
4680b57cec5SDimitry Andric       Block *next_frame_block = curr_inlined_block->GetParent();
4690b57cec5SDimitry Andric       // Now calculate the symbol context of the containing block
4700b57cec5SDimitry Andric       next_frame_block->CalculateSymbolContext(&next_frame_sc);
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric       // If we get here we weren't able to find the return line entry using the
4730b57cec5SDimitry Andric       // nesting of the blocks and the line table.  So just use the call site
4740b57cec5SDimitry Andric       // info from our inlined block.
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric       AddressRange range;
4770b57cec5SDimitry Andric       if (curr_inlined_block->GetRangeContainingAddress(curr_frame_pc, range)) {
4780b57cec5SDimitry Andric         // To see there this new frame block it, we need to look at the call
4790b57cec5SDimitry Andric         // site information from
4800b57cec5SDimitry Andric         const InlineFunctionInfo *curr_inlined_block_inlined_info =
4810b57cec5SDimitry Andric             curr_inlined_block->GetInlinedFunctionInfo();
4820b57cec5SDimitry Andric         next_frame_pc = range.GetBaseAddress();
4830b57cec5SDimitry Andric         next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
484*0fca6ea1SDimitry Andric         next_frame_sc.line_entry.file_sp = std::make_shared<SupportFile>(
485*0fca6ea1SDimitry Andric             curr_inlined_block_inlined_info->GetCallSite().GetFile());
4867a6dacacSDimitry Andric         next_frame_sc.line_entry.original_file_sp =
4877a6dacacSDimitry Andric             std::make_shared<SupportFile>(
4887a6dacacSDimitry Andric                 curr_inlined_block_inlined_info->GetCallSite().GetFile());
4890b57cec5SDimitry Andric         next_frame_sc.line_entry.line =
4900b57cec5SDimitry Andric             curr_inlined_block_inlined_info->GetCallSite().GetLine();
4910b57cec5SDimitry Andric         next_frame_sc.line_entry.column =
4920b57cec5SDimitry Andric             curr_inlined_block_inlined_info->GetCallSite().GetColumn();
4930b57cec5SDimitry Andric         return true;
4940b57cec5SDimitry Andric       } else {
49581ad6265SDimitry Andric         Log *log = GetLog(LLDBLog::Symbols);
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric         if (log) {
4989dba64beSDimitry Andric           LLDB_LOGF(
4999dba64beSDimitry Andric               log,
5000b57cec5SDimitry Andric               "warning: inlined block 0x%8.8" PRIx64
5010b57cec5SDimitry Andric               " doesn't have a range that contains file address 0x%" PRIx64,
5020b57cec5SDimitry Andric               curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
5030b57cec5SDimitry Andric         }
5040b57cec5SDimitry Andric #ifdef LLDB_CONFIGURATION_DEBUG
5050b57cec5SDimitry Andric         else {
5060b57cec5SDimitry Andric           ObjectFile *objfile = nullptr;
5070b57cec5SDimitry Andric           if (module_sp) {
5089dba64beSDimitry Andric             if (SymbolFile *symbol_file = module_sp->GetSymbolFile())
5090b57cec5SDimitry Andric               objfile = symbol_file->GetObjectFile();
5100b57cec5SDimitry Andric           }
5110b57cec5SDimitry Andric           if (objfile) {
51281ad6265SDimitry Andric             Debugger::ReportWarning(llvm::formatv(
51381ad6265SDimitry Andric                 "inlined block {0:x} doesn't have a range that contains file "
51481ad6265SDimitry Andric                 "address {1:x} in {2}",
5150b57cec5SDimitry Andric                 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress(),
51681ad6265SDimitry Andric                 objfile->GetFileSpec().GetPath()));
5170b57cec5SDimitry Andric           } else {
51881ad6265SDimitry Andric             Debugger::ReportWarning(llvm::formatv(
51981ad6265SDimitry Andric                 "inlined block {0:x} doesn't have a range that contains file "
52081ad6265SDimitry Andric                 "address {1:x}",
52181ad6265SDimitry Andric                 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()));
5220b57cec5SDimitry Andric           }
5230b57cec5SDimitry Andric         }
5240b57cec5SDimitry Andric #endif
5250b57cec5SDimitry Andric       }
5260b57cec5SDimitry Andric     }
5270b57cec5SDimitry Andric   }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   return false;
5300b57cec5SDimitry Andric }
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric Block *SymbolContext::GetFunctionBlock() {
5330b57cec5SDimitry Andric   if (function) {
5340b57cec5SDimitry Andric     if (block) {
5350b57cec5SDimitry Andric       // If this symbol context has a block, check to see if this block is
5360b57cec5SDimitry Andric       // itself, or is contained within a block with inlined function
5370b57cec5SDimitry Andric       // information. If so, then the inlined block is the block that defines
5380b57cec5SDimitry Andric       // the function.
5390b57cec5SDimitry Andric       Block *inlined_block = block->GetContainingInlinedBlock();
5400b57cec5SDimitry Andric       if (inlined_block)
5410b57cec5SDimitry Andric         return inlined_block;
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric       // The block in this symbol context is not inside an inlined block, so
5440b57cec5SDimitry Andric       // the block that defines the function is the function's top level block,
5450b57cec5SDimitry Andric       // which is returned below.
5460b57cec5SDimitry Andric     }
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric     // There is no block information in this symbol context, so we must assume
5490b57cec5SDimitry Andric     // that the block that is desired is the top level block of the function
5500b57cec5SDimitry Andric     // itself.
5510b57cec5SDimitry Andric     return &function->GetBlock(true);
5520b57cec5SDimitry Andric   }
5530b57cec5SDimitry Andric   return nullptr;
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric 
55606c3fb27SDimitry Andric llvm::StringRef SymbolContext::GetInstanceVariableName() {
55706c3fb27SDimitry Andric   LanguageType lang_type = eLanguageTypeUnknown;
5580b57cec5SDimitry Andric 
55906c3fb27SDimitry Andric   if (Block *function_block = GetFunctionBlock())
56006c3fb27SDimitry Andric     if (CompilerDeclContext decl_ctx = function_block->GetDeclContext())
56106c3fb27SDimitry Andric       lang_type = decl_ctx.GetLanguage();
56206c3fb27SDimitry Andric 
56306c3fb27SDimitry Andric   if (lang_type == eLanguageTypeUnknown)
56406c3fb27SDimitry Andric     lang_type = GetLanguage();
56506c3fb27SDimitry Andric 
56606c3fb27SDimitry Andric   if (auto *lang = Language::FindPlugin(lang_type))
56706c3fb27SDimitry Andric     return lang->GetInstanceVariableName();
56806c3fb27SDimitry Andric 
56906c3fb27SDimitry Andric   return {};
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
5730b57cec5SDimitry Andric   Block *curr_block = block;
5740b57cec5SDimitry Andric   bool isInlinedblock = false;
5750b57cec5SDimitry Andric   if (curr_block != nullptr &&
5760b57cec5SDimitry Andric       curr_block->GetContainingInlinedBlock() != nullptr)
5770b57cec5SDimitry Andric     isInlinedblock = true;
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   // Find all types that match the current block if we have one and put them
5800b57cec5SDimitry Andric   // first in the list. Keep iterating up through all blocks.
5810b57cec5SDimitry Andric   while (curr_block != nullptr && !isInlinedblock) {
5820b57cec5SDimitry Andric     type_map.ForEach(
5830b57cec5SDimitry Andric         [curr_block, &type_list](const lldb::TypeSP &type_sp) -> bool {
5840b57cec5SDimitry Andric           SymbolContextScope *scs = type_sp->GetSymbolContextScope();
5850b57cec5SDimitry Andric           if (scs && curr_block == scs->CalculateSymbolContextBlock())
5860b57cec5SDimitry Andric             type_list.Insert(type_sp);
5870b57cec5SDimitry Andric           return true; // Keep iterating
5880b57cec5SDimitry Andric         });
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric     // Remove any entries that are now in "type_list" from "type_map" since we
5910b57cec5SDimitry Andric     // can't remove from type_map while iterating
5920b57cec5SDimitry Andric     type_list.ForEach([&type_map](const lldb::TypeSP &type_sp) -> bool {
5930b57cec5SDimitry Andric       type_map.Remove(type_sp);
5940b57cec5SDimitry Andric       return true; // Keep iterating
5950b57cec5SDimitry Andric     });
5960b57cec5SDimitry Andric     curr_block = curr_block->GetParent();
5970b57cec5SDimitry Andric   }
5980b57cec5SDimitry Andric   // Find all types that match the current function, if we have onem, and put
5990b57cec5SDimitry Andric   // them next in the list.
6000b57cec5SDimitry Andric   if (function != nullptr && !type_map.Empty()) {
6010b57cec5SDimitry Andric     const size_t old_type_list_size = type_list.GetSize();
6020b57cec5SDimitry Andric     type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
6030b57cec5SDimitry Andric       SymbolContextScope *scs = type_sp->GetSymbolContextScope();
6040b57cec5SDimitry Andric       if (scs && function == scs->CalculateSymbolContextFunction())
6050b57cec5SDimitry Andric         type_list.Insert(type_sp);
6060b57cec5SDimitry Andric       return true; // Keep iterating
6070b57cec5SDimitry Andric     });
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric     // Remove any entries that are now in "type_list" from "type_map" since we
6100b57cec5SDimitry Andric     // can't remove from type_map while iterating
6110b57cec5SDimitry Andric     const size_t new_type_list_size = type_list.GetSize();
6120b57cec5SDimitry Andric     if (new_type_list_size > old_type_list_size) {
6130b57cec5SDimitry Andric       for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
6140b57cec5SDimitry Andric         type_map.Remove(type_list.GetTypeAtIndex(i));
6150b57cec5SDimitry Andric     }
6160b57cec5SDimitry Andric   }
6170b57cec5SDimitry Andric   // Find all types that match the current compile unit, if we have one, and
6180b57cec5SDimitry Andric   // put them next in the list.
6190b57cec5SDimitry Andric   if (comp_unit != nullptr && !type_map.Empty()) {
6200b57cec5SDimitry Andric     const size_t old_type_list_size = type_list.GetSize();
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric     type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
6230b57cec5SDimitry Andric       SymbolContextScope *scs = type_sp->GetSymbolContextScope();
6240b57cec5SDimitry Andric       if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit())
6250b57cec5SDimitry Andric         type_list.Insert(type_sp);
6260b57cec5SDimitry Andric       return true; // Keep iterating
6270b57cec5SDimitry Andric     });
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric     // Remove any entries that are now in "type_list" from "type_map" since we
6300b57cec5SDimitry Andric     // can't remove from type_map while iterating
6310b57cec5SDimitry Andric     const size_t new_type_list_size = type_list.GetSize();
6320b57cec5SDimitry Andric     if (new_type_list_size > old_type_list_size) {
6330b57cec5SDimitry Andric       for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
6340b57cec5SDimitry Andric         type_map.Remove(type_list.GetTypeAtIndex(i));
6350b57cec5SDimitry Andric     }
6360b57cec5SDimitry Andric   }
6370b57cec5SDimitry Andric   // Find all types that match the current module, if we have one, and put them
6380b57cec5SDimitry Andric   // next in the list.
6390b57cec5SDimitry Andric   if (module_sp && !type_map.Empty()) {
6400b57cec5SDimitry Andric     const size_t old_type_list_size = type_list.GetSize();
6410b57cec5SDimitry Andric     type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
6420b57cec5SDimitry Andric       SymbolContextScope *scs = type_sp->GetSymbolContextScope();
6430b57cec5SDimitry Andric       if (scs && module_sp == scs->CalculateSymbolContextModule())
6440b57cec5SDimitry Andric         type_list.Insert(type_sp);
6450b57cec5SDimitry Andric       return true; // Keep iterating
6460b57cec5SDimitry Andric     });
6470b57cec5SDimitry Andric     // Remove any entries that are now in "type_list" from "type_map" since we
6480b57cec5SDimitry Andric     // can't remove from type_map while iterating
6490b57cec5SDimitry Andric     const size_t new_type_list_size = type_list.GetSize();
6500b57cec5SDimitry Andric     if (new_type_list_size > old_type_list_size) {
6510b57cec5SDimitry Andric       for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
6520b57cec5SDimitry Andric         type_map.Remove(type_list.GetTypeAtIndex(i));
6530b57cec5SDimitry Andric     }
6540b57cec5SDimitry Andric   }
6550b57cec5SDimitry Andric   // Any types that are left get copied into the list an any order.
6560b57cec5SDimitry Andric   if (!type_map.Empty()) {
6570b57cec5SDimitry Andric     type_map.ForEach([&type_list](const lldb::TypeSP &type_sp) -> bool {
6580b57cec5SDimitry Andric       type_list.Insert(type_sp);
6590b57cec5SDimitry Andric       return true; // Keep iterating
6600b57cec5SDimitry Andric     });
6610b57cec5SDimitry Andric   }
6620b57cec5SDimitry Andric }
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric ConstString
6650b57cec5SDimitry Andric SymbolContext::GetFunctionName(Mangled::NamePreference preference) const {
6660b57cec5SDimitry Andric   if (function) {
6670b57cec5SDimitry Andric     if (block) {
6680b57cec5SDimitry Andric       Block *inlined_block = block->GetContainingInlinedBlock();
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric       if (inlined_block) {
6710b57cec5SDimitry Andric         const InlineFunctionInfo *inline_info =
6720b57cec5SDimitry Andric             inlined_block->GetInlinedFunctionInfo();
6730b57cec5SDimitry Andric         if (inline_info)
6745ffd83dbSDimitry Andric           return inline_info->GetName();
6750b57cec5SDimitry Andric       }
6760b57cec5SDimitry Andric     }
6775ffd83dbSDimitry Andric     return function->GetMangled().GetName(preference);
6780b57cec5SDimitry Andric   } else if (symbol && symbol->ValueIsAddress()) {
6795ffd83dbSDimitry Andric     return symbol->GetMangled().GetName(preference);
6800b57cec5SDimitry Andric   } else {
6810b57cec5SDimitry Andric     // No function, return an empty string.
6820b57cec5SDimitry Andric     return ConstString();
6830b57cec5SDimitry Andric   }
6840b57cec5SDimitry Andric }
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric LineEntry SymbolContext::GetFunctionStartLineEntry() const {
6870b57cec5SDimitry Andric   LineEntry line_entry;
6880b57cec5SDimitry Andric   Address start_addr;
6890b57cec5SDimitry Andric   if (block) {
6900b57cec5SDimitry Andric     Block *inlined_block = block->GetContainingInlinedBlock();
6910b57cec5SDimitry Andric     if (inlined_block) {
6920b57cec5SDimitry Andric       if (inlined_block->GetStartAddress(start_addr)) {
6930b57cec5SDimitry Andric         if (start_addr.CalculateSymbolContextLineEntry(line_entry))
6940b57cec5SDimitry Andric           return line_entry;
6950b57cec5SDimitry Andric       }
6960b57cec5SDimitry Andric       return LineEntry();
6970b57cec5SDimitry Andric     }
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   if (function) {
7010b57cec5SDimitry Andric     if (function->GetAddressRange()
7020b57cec5SDimitry Andric             .GetBaseAddress()
7030b57cec5SDimitry Andric             .CalculateSymbolContextLineEntry(line_entry))
7040b57cec5SDimitry Andric       return line_entry;
7050b57cec5SDimitry Andric   }
7060b57cec5SDimitry Andric   return LineEntry();
7070b57cec5SDimitry Andric }
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line,
7100b57cec5SDimitry Andric                                                      AddressRange &range,
7110b57cec5SDimitry Andric                                                      Status &error) {
7120b57cec5SDimitry Andric   if (!line_entry.IsValid()) {
7130b57cec5SDimitry Andric     error.SetErrorString("Symbol context has no line table.");
7140b57cec5SDimitry Andric     return false;
7150b57cec5SDimitry Andric   }
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric   range = line_entry.range;
7180b57cec5SDimitry Andric   if (line_entry.line > end_line) {
7190b57cec5SDimitry Andric     error.SetErrorStringWithFormat(
7200b57cec5SDimitry Andric         "end line option %d must be after the current line: %d", end_line,
7210b57cec5SDimitry Andric         line_entry.line);
7220b57cec5SDimitry Andric     return false;
7230b57cec5SDimitry Andric   }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   uint32_t line_index = 0;
7260b57cec5SDimitry Andric   bool found = false;
7270b57cec5SDimitry Andric   while (true) {
7280b57cec5SDimitry Andric     LineEntry this_line;
7290b57cec5SDimitry Andric     line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr,
7300b57cec5SDimitry Andric                                           false, &this_line);
7310b57cec5SDimitry Andric     if (line_index == UINT32_MAX)
7320b57cec5SDimitry Andric       break;
7330b57cec5SDimitry Andric     if (LineEntry::Compare(this_line, line_entry) == 0) {
7340b57cec5SDimitry Andric       found = true;
7350b57cec5SDimitry Andric       break;
7360b57cec5SDimitry Andric     }
7370b57cec5SDimitry Andric   }
7380b57cec5SDimitry Andric 
7390b57cec5SDimitry Andric   LineEntry end_entry;
7400b57cec5SDimitry Andric   if (!found) {
7410b57cec5SDimitry Andric     // Can't find the index of the SymbolContext's line entry in the
7420b57cec5SDimitry Andric     // SymbolContext's CompUnit.
7430b57cec5SDimitry Andric     error.SetErrorString(
7440b57cec5SDimitry Andric         "Can't find the current line entry in the CompUnit - can't process "
7450b57cec5SDimitry Andric         "the end-line option");
7460b57cec5SDimitry Andric     return false;
7470b57cec5SDimitry Andric   }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric   line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false,
7500b57cec5SDimitry Andric                                         &end_entry);
7510b57cec5SDimitry Andric   if (line_index == UINT32_MAX) {
7520b57cec5SDimitry Andric     error.SetErrorStringWithFormat(
7530b57cec5SDimitry Andric         "could not find a line table entry corresponding "
7540b57cec5SDimitry Andric         "to end line number %d",
7550b57cec5SDimitry Andric         end_line);
7560b57cec5SDimitry Andric     return false;
7570b57cec5SDimitry Andric   }
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   Block *func_block = GetFunctionBlock();
7609dba64beSDimitry Andric   if (func_block && func_block->GetRangeIndexContainingAddress(
7610b57cec5SDimitry Andric                         end_entry.range.GetBaseAddress()) == UINT32_MAX) {
7620b57cec5SDimitry Andric     error.SetErrorStringWithFormat(
7630b57cec5SDimitry Andric         "end line number %d is not contained within the current function.",
7640b57cec5SDimitry Andric         end_line);
7650b57cec5SDimitry Andric     return false;
7660b57cec5SDimitry Andric   }
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress() -
7690b57cec5SDimitry Andric                             range.GetBaseAddress().GetFileAddress();
7700b57cec5SDimitry Andric   range.SetByteSize(range_size);
7710b57cec5SDimitry Andric   return true;
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric 
7749dba64beSDimitry Andric const Symbol *SymbolContext::FindBestGlobalDataSymbol(ConstString name,
7759dba64beSDimitry Andric                                                       Status &error) {
7760b57cec5SDimitry Andric   error.Clear();
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric   if (!target_sp) {
7790b57cec5SDimitry Andric     return nullptr;
7800b57cec5SDimitry Andric   }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   Target &target = *target_sp;
7830b57cec5SDimitry Andric   Module *module = module_sp.get();
7840b57cec5SDimitry Andric 
7859dba64beSDimitry Andric   auto ProcessMatches = [this, &name, &target,
78606c3fb27SDimitry Andric                          module](const SymbolContextList &sc_list,
7879dba64beSDimitry Andric                                  Status &error) -> const Symbol * {
7880b57cec5SDimitry Andric     llvm::SmallVector<const Symbol *, 1> external_symbols;
7890b57cec5SDimitry Andric     llvm::SmallVector<const Symbol *, 1> internal_symbols;
79006c3fb27SDimitry Andric     for (const SymbolContext &sym_ctx : sc_list) {
7910b57cec5SDimitry Andric       if (sym_ctx.symbol) {
7920b57cec5SDimitry Andric         const Symbol *symbol = sym_ctx.symbol;
7930b57cec5SDimitry Andric         const Address sym_address = symbol->GetAddress();
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric         if (sym_address.IsValid()) {
7960b57cec5SDimitry Andric           switch (symbol->GetType()) {
7970b57cec5SDimitry Andric           case eSymbolTypeData:
7980b57cec5SDimitry Andric           case eSymbolTypeRuntime:
7990b57cec5SDimitry Andric           case eSymbolTypeAbsolute:
8000b57cec5SDimitry Andric           case eSymbolTypeObjCClass:
8010b57cec5SDimitry Andric           case eSymbolTypeObjCMetaClass:
8020b57cec5SDimitry Andric           case eSymbolTypeObjCIVar:
8030b57cec5SDimitry Andric             if (symbol->GetDemangledNameIsSynthesized()) {
8040b57cec5SDimitry Andric               // If the demangled name was synthesized, then don't use it for
8050b57cec5SDimitry Andric               // expressions. Only let the symbol match if the mangled named
8060b57cec5SDimitry Andric               // matches for these symbols.
8070b57cec5SDimitry Andric               if (symbol->GetMangled().GetMangledName() != name)
8080b57cec5SDimitry Andric                 break;
8090b57cec5SDimitry Andric             }
8100b57cec5SDimitry Andric             if (symbol->IsExternal()) {
8110b57cec5SDimitry Andric               external_symbols.push_back(symbol);
8120b57cec5SDimitry Andric             } else {
8130b57cec5SDimitry Andric               internal_symbols.push_back(symbol);
8140b57cec5SDimitry Andric             }
8150b57cec5SDimitry Andric             break;
8160b57cec5SDimitry Andric           case eSymbolTypeReExported: {
8170b57cec5SDimitry Andric             ConstString reexport_name = symbol->GetReExportedSymbolName();
8180b57cec5SDimitry Andric             if (reexport_name) {
8190b57cec5SDimitry Andric               ModuleSP reexport_module_sp;
8200b57cec5SDimitry Andric               ModuleSpec reexport_module_spec;
8210b57cec5SDimitry Andric               reexport_module_spec.GetPlatformFileSpec() =
8220b57cec5SDimitry Andric                   symbol->GetReExportedSymbolSharedLibrary();
8230b57cec5SDimitry Andric               if (reexport_module_spec.GetPlatformFileSpec()) {
8240b57cec5SDimitry Andric                 reexport_module_sp =
8250b57cec5SDimitry Andric                     target.GetImages().FindFirstModule(reexport_module_spec);
8260b57cec5SDimitry Andric                 if (!reexport_module_sp) {
827bdd1243dSDimitry Andric                   reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
8280b57cec5SDimitry Andric                   reexport_module_sp =
8290b57cec5SDimitry Andric                       target.GetImages().FindFirstModule(reexport_module_spec);
8300b57cec5SDimitry Andric                 }
8310b57cec5SDimitry Andric               }
8320b57cec5SDimitry Andric               // Don't allow us to try and resolve a re-exported symbol if it
8330b57cec5SDimitry Andric               // is the same as the current symbol
8340b57cec5SDimitry Andric               if (name == symbol->GetReExportedSymbolName() &&
8350b57cec5SDimitry Andric                   module == reexport_module_sp.get())
8360b57cec5SDimitry Andric                 return nullptr;
8370b57cec5SDimitry Andric 
8389dba64beSDimitry Andric               return FindBestGlobalDataSymbol(symbol->GetReExportedSymbolName(),
8399dba64beSDimitry Andric                                               error);
8400b57cec5SDimitry Andric             }
8410b57cec5SDimitry Andric           } break;
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric           case eSymbolTypeCode: // We already lookup functions elsewhere
8440b57cec5SDimitry Andric           case eSymbolTypeVariable:
8450b57cec5SDimitry Andric           case eSymbolTypeLocal:
8460b57cec5SDimitry Andric           case eSymbolTypeParam:
8470b57cec5SDimitry Andric           case eSymbolTypeTrampoline:
8480b57cec5SDimitry Andric           case eSymbolTypeInvalid:
8490b57cec5SDimitry Andric           case eSymbolTypeException:
8500b57cec5SDimitry Andric           case eSymbolTypeSourceFile:
8510b57cec5SDimitry Andric           case eSymbolTypeHeaderFile:
8520b57cec5SDimitry Andric           case eSymbolTypeObjectFile:
8530b57cec5SDimitry Andric           case eSymbolTypeCommonBlock:
8540b57cec5SDimitry Andric           case eSymbolTypeBlock:
8550b57cec5SDimitry Andric           case eSymbolTypeVariableType:
8560b57cec5SDimitry Andric           case eSymbolTypeLineEntry:
8570b57cec5SDimitry Andric           case eSymbolTypeLineHeader:
8580b57cec5SDimitry Andric           case eSymbolTypeScopeBegin:
8590b57cec5SDimitry Andric           case eSymbolTypeScopeEnd:
8600b57cec5SDimitry Andric           case eSymbolTypeAdditional:
8610b57cec5SDimitry Andric           case eSymbolTypeCompiler:
8620b57cec5SDimitry Andric           case eSymbolTypeInstrumentation:
8630b57cec5SDimitry Andric           case eSymbolTypeUndefined:
8640b57cec5SDimitry Andric           case eSymbolTypeResolver:
8650b57cec5SDimitry Andric             break;
8660b57cec5SDimitry Andric           }
8670b57cec5SDimitry Andric         }
8680b57cec5SDimitry Andric       }
8690b57cec5SDimitry Andric     }
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric     if (external_symbols.size() > 1) {
8720b57cec5SDimitry Andric       StreamString ss;
8730b57cec5SDimitry Andric       ss.Printf("Multiple external symbols found for '%s'\n", name.AsCString());
8740b57cec5SDimitry Andric       for (const Symbol *symbol : external_symbols) {
8750b57cec5SDimitry Andric         symbol->GetDescription(&ss, eDescriptionLevelFull, &target);
8760b57cec5SDimitry Andric       }
8770b57cec5SDimitry Andric       ss.PutChar('\n');
8780b57cec5SDimitry Andric       error.SetErrorString(ss.GetData());
8790b57cec5SDimitry Andric       return nullptr;
8800b57cec5SDimitry Andric     } else if (external_symbols.size()) {
8810b57cec5SDimitry Andric       return external_symbols[0];
8820b57cec5SDimitry Andric     } else if (internal_symbols.size() > 1) {
8830b57cec5SDimitry Andric       StreamString ss;
8840b57cec5SDimitry Andric       ss.Printf("Multiple internal symbols found for '%s'\n", name.AsCString());
8850b57cec5SDimitry Andric       for (const Symbol *symbol : internal_symbols) {
8860b57cec5SDimitry Andric         symbol->GetDescription(&ss, eDescriptionLevelVerbose, &target);
8870b57cec5SDimitry Andric         ss.PutChar('\n');
8880b57cec5SDimitry Andric       }
8890b57cec5SDimitry Andric       error.SetErrorString(ss.GetData());
8900b57cec5SDimitry Andric       return nullptr;
8910b57cec5SDimitry Andric     } else if (internal_symbols.size()) {
8920b57cec5SDimitry Andric       return internal_symbols[0];
8930b57cec5SDimitry Andric     } else {
8940b57cec5SDimitry Andric       return nullptr;
8950b57cec5SDimitry Andric     }
8960b57cec5SDimitry Andric   };
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric   if (module) {
8990b57cec5SDimitry Andric     SymbolContextList sc_list;
9000b57cec5SDimitry Andric     module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
9010b57cec5SDimitry Andric     const Symbol *const module_symbol = ProcessMatches(sc_list, error);
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric     if (!error.Success()) {
9040b57cec5SDimitry Andric       return nullptr;
9050b57cec5SDimitry Andric     } else if (module_symbol) {
9060b57cec5SDimitry Andric       return module_symbol;
9070b57cec5SDimitry Andric     }
9080b57cec5SDimitry Andric   }
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric   {
9110b57cec5SDimitry Andric     SymbolContextList sc_list;
9120b57cec5SDimitry Andric     target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny,
9130b57cec5SDimitry Andric                                                   sc_list);
9140b57cec5SDimitry Andric     const Symbol *const target_symbol = ProcessMatches(sc_list, error);
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric     if (!error.Success()) {
9170b57cec5SDimitry Andric       return nullptr;
9180b57cec5SDimitry Andric     } else if (target_symbol) {
9190b57cec5SDimitry Andric       return target_symbol;
9200b57cec5SDimitry Andric     }
9210b57cec5SDimitry Andric   }
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric   return nullptr; // no error; we just didn't find anything
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric //
9270b57cec5SDimitry Andric //  SymbolContextSpecifier
9280b57cec5SDimitry Andric //
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric SymbolContextSpecifier::SymbolContextSpecifier(const TargetSP &target_sp)
9310b57cec5SDimitry Andric     : m_target_sp(target_sp), m_module_spec(), m_module_sp(), m_file_spec_up(),
9320b57cec5SDimitry Andric       m_start_line(0), m_end_line(0), m_function_spec(), m_class_name(),
9330b57cec5SDimitry Andric       m_address_range_up(), m_type(eNothingSpecified) {}
9340b57cec5SDimitry Andric 
935fe6060f1SDimitry Andric SymbolContextSpecifier::~SymbolContextSpecifier() = default;
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric bool SymbolContextSpecifier::AddLineSpecification(uint32_t line_no,
9380b57cec5SDimitry Andric                                                   SpecificationType type) {
9390b57cec5SDimitry Andric   bool return_value = true;
9400b57cec5SDimitry Andric   switch (type) {
9410b57cec5SDimitry Andric   case eNothingSpecified:
9420b57cec5SDimitry Andric     Clear();
9430b57cec5SDimitry Andric     break;
9440b57cec5SDimitry Andric   case eLineStartSpecified:
9450b57cec5SDimitry Andric     m_start_line = line_no;
9460b57cec5SDimitry Andric     m_type |= eLineStartSpecified;
9470b57cec5SDimitry Andric     break;
9480b57cec5SDimitry Andric   case eLineEndSpecified:
9490b57cec5SDimitry Andric     m_end_line = line_no;
9500b57cec5SDimitry Andric     m_type |= eLineEndSpecified;
9510b57cec5SDimitry Andric     break;
9520b57cec5SDimitry Andric   default:
9530b57cec5SDimitry Andric     return_value = false;
9540b57cec5SDimitry Andric     break;
9550b57cec5SDimitry Andric   }
9560b57cec5SDimitry Andric   return return_value;
9570b57cec5SDimitry Andric }
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric bool SymbolContextSpecifier::AddSpecification(const char *spec_string,
9600b57cec5SDimitry Andric                                               SpecificationType type) {
9610b57cec5SDimitry Andric   bool return_value = true;
9620b57cec5SDimitry Andric   switch (type) {
9630b57cec5SDimitry Andric   case eNothingSpecified:
9640b57cec5SDimitry Andric     Clear();
9650b57cec5SDimitry Andric     break;
9660b57cec5SDimitry Andric   case eModuleSpecified: {
9670b57cec5SDimitry Andric     // See if we can find the Module, if so stick it in the SymbolContext.
9680b57cec5SDimitry Andric     FileSpec module_file_spec(spec_string);
9690b57cec5SDimitry Andric     ModuleSpec module_spec(module_file_spec);
97081ad6265SDimitry Andric     lldb::ModuleSP module_sp =
97181ad6265SDimitry Andric         m_target_sp ? m_target_sp->GetImages().FindFirstModule(module_spec)
97281ad6265SDimitry Andric                     : nullptr;
9730b57cec5SDimitry Andric     m_type |= eModuleSpecified;
9740b57cec5SDimitry Andric     if (module_sp)
9750b57cec5SDimitry Andric       m_module_sp = module_sp;
9760b57cec5SDimitry Andric     else
9770b57cec5SDimitry Andric       m_module_spec.assign(spec_string);
9780b57cec5SDimitry Andric   } break;
9790b57cec5SDimitry Andric   case eFileSpecified:
9800b57cec5SDimitry Andric     // CompUnits can't necessarily be resolved here, since an inlined function
9810b57cec5SDimitry Andric     // might show up in a number of CompUnits.  Instead we just convert to a
9820b57cec5SDimitry Andric     // FileSpec and store it away.
9835ffd83dbSDimitry Andric     m_file_spec_up = std::make_unique<FileSpec>(spec_string);
9840b57cec5SDimitry Andric     m_type |= eFileSpecified;
9850b57cec5SDimitry Andric     break;
9860b57cec5SDimitry Andric   case eLineStartSpecified:
987349cc55cSDimitry Andric     if ((return_value = llvm::to_integer(spec_string, m_start_line)))
9880b57cec5SDimitry Andric       m_type |= eLineStartSpecified;
9890b57cec5SDimitry Andric     break;
9900b57cec5SDimitry Andric   case eLineEndSpecified:
991349cc55cSDimitry Andric     if ((return_value = llvm::to_integer(spec_string, m_end_line)))
9920b57cec5SDimitry Andric       m_type |= eLineEndSpecified;
9930b57cec5SDimitry Andric     break;
9940b57cec5SDimitry Andric   case eFunctionSpecified:
9950b57cec5SDimitry Andric     m_function_spec.assign(spec_string);
9960b57cec5SDimitry Andric     m_type |= eFunctionSpecified;
9970b57cec5SDimitry Andric     break;
9980b57cec5SDimitry Andric   case eClassOrNamespaceSpecified:
9990b57cec5SDimitry Andric     Clear();
10000b57cec5SDimitry Andric     m_class_name.assign(spec_string);
10010b57cec5SDimitry Andric     m_type = eClassOrNamespaceSpecified;
10020b57cec5SDimitry Andric     break;
10030b57cec5SDimitry Andric   case eAddressRangeSpecified:
10040b57cec5SDimitry Andric     // Not specified yet...
10050b57cec5SDimitry Andric     break;
10060b57cec5SDimitry Andric   }
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric   return return_value;
10090b57cec5SDimitry Andric }
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric void SymbolContextSpecifier::Clear() {
10120b57cec5SDimitry Andric   m_module_spec.clear();
10130b57cec5SDimitry Andric   m_file_spec_up.reset();
10140b57cec5SDimitry Andric   m_function_spec.clear();
10150b57cec5SDimitry Andric   m_class_name.clear();
10160b57cec5SDimitry Andric   m_start_line = 0;
10170b57cec5SDimitry Andric   m_end_line = 0;
10180b57cec5SDimitry Andric   m_address_range_up.reset();
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric   m_type = eNothingSpecified;
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric 
1023e8d8bef9SDimitry Andric bool SymbolContextSpecifier::SymbolContextMatches(const SymbolContext &sc) {
10240b57cec5SDimitry Andric   if (m_type == eNothingSpecified)
10250b57cec5SDimitry Andric     return true;
10260b57cec5SDimitry Andric 
1027e8d8bef9SDimitry Andric   // Only compare targets if this specifier has one and it's not the Dummy
1028e8d8bef9SDimitry Andric   // target.  Otherwise if a specifier gets made in the dummy target and
1029e8d8bef9SDimitry Andric   // copied over we'll artificially fail the comparision.
1030e8d8bef9SDimitry Andric   if (m_target_sp && !m_target_sp->IsDummyTarget() &&
1031e8d8bef9SDimitry Andric       m_target_sp != sc.target_sp)
10320b57cec5SDimitry Andric     return false;
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric   if (m_type & eModuleSpecified) {
10350b57cec5SDimitry Andric     if (sc.module_sp) {
10360b57cec5SDimitry Andric       if (m_module_sp.get() != nullptr) {
10370b57cec5SDimitry Andric         if (m_module_sp.get() != sc.module_sp.get())
10380b57cec5SDimitry Andric           return false;
10390b57cec5SDimitry Andric       } else {
10400b57cec5SDimitry Andric         FileSpec module_file_spec(m_module_spec);
1041480093f4SDimitry Andric         if (!FileSpec::Match(module_file_spec, sc.module_sp->GetFileSpec()))
10420b57cec5SDimitry Andric           return false;
10430b57cec5SDimitry Andric       }
10440b57cec5SDimitry Andric     }
10450b57cec5SDimitry Andric   }
10460b57cec5SDimitry Andric   if (m_type & eFileSpecified) {
10470b57cec5SDimitry Andric     if (m_file_spec_up) {
10480b57cec5SDimitry Andric       // If we don't have a block or a comp_unit, then we aren't going to match
10490b57cec5SDimitry Andric       // a source file.
10500b57cec5SDimitry Andric       if (sc.block == nullptr && sc.comp_unit == nullptr)
10510b57cec5SDimitry Andric         return false;
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric       // Check if the block is present, and if so is it inlined:
10540b57cec5SDimitry Andric       bool was_inlined = false;
10550b57cec5SDimitry Andric       if (sc.block != nullptr) {
10560b57cec5SDimitry Andric         const InlineFunctionInfo *inline_info =
10570b57cec5SDimitry Andric             sc.block->GetInlinedFunctionInfo();
10580b57cec5SDimitry Andric         if (inline_info != nullptr) {
10590b57cec5SDimitry Andric           was_inlined = true;
1060480093f4SDimitry Andric           if (!FileSpec::Match(*m_file_spec_up,
1061480093f4SDimitry Andric                                inline_info->GetDeclaration().GetFile()))
10620b57cec5SDimitry Andric             return false;
10630b57cec5SDimitry Andric         }
10640b57cec5SDimitry Andric       }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric       // Next check the comp unit, but only if the SymbolContext was not
10670b57cec5SDimitry Andric       // inlined.
10680b57cec5SDimitry Andric       if (!was_inlined && sc.comp_unit != nullptr) {
1069480093f4SDimitry Andric         if (!FileSpec::Match(*m_file_spec_up, sc.comp_unit->GetPrimaryFile()))
10700b57cec5SDimitry Andric           return false;
10710b57cec5SDimitry Andric       }
10720b57cec5SDimitry Andric     }
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric   if (m_type & eLineStartSpecified || m_type & eLineEndSpecified) {
10750b57cec5SDimitry Andric     if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
10760b57cec5SDimitry Andric       return false;
10770b57cec5SDimitry Andric   }
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   if (m_type & eFunctionSpecified) {
10800b57cec5SDimitry Andric     // First check the current block, and if it is inlined, get the inlined
10810b57cec5SDimitry Andric     // function name:
10820b57cec5SDimitry Andric     bool was_inlined = false;
10830b57cec5SDimitry Andric     ConstString func_name(m_function_spec.c_str());
10840b57cec5SDimitry Andric 
10850b57cec5SDimitry Andric     if (sc.block != nullptr) {
10860b57cec5SDimitry Andric       const InlineFunctionInfo *inline_info =
10870b57cec5SDimitry Andric           sc.block->GetInlinedFunctionInfo();
10880b57cec5SDimitry Andric       if (inline_info != nullptr) {
10890b57cec5SDimitry Andric         was_inlined = true;
10900b57cec5SDimitry Andric         const Mangled &name = inline_info->GetMangled();
10915ffd83dbSDimitry Andric         if (!name.NameMatches(func_name))
10920b57cec5SDimitry Andric           return false;
10930b57cec5SDimitry Andric       }
10940b57cec5SDimitry Andric     }
10950b57cec5SDimitry Andric     //  If it wasn't inlined, check the name in the function or symbol:
10960b57cec5SDimitry Andric     if (!was_inlined) {
10970b57cec5SDimitry Andric       if (sc.function != nullptr) {
10985ffd83dbSDimitry Andric         if (!sc.function->GetMangled().NameMatches(func_name))
10990b57cec5SDimitry Andric           return false;
11000b57cec5SDimitry Andric       } else if (sc.symbol != nullptr) {
11015ffd83dbSDimitry Andric         if (!sc.symbol->GetMangled().NameMatches(func_name))
11020b57cec5SDimitry Andric           return false;
11030b57cec5SDimitry Andric       }
11040b57cec5SDimitry Andric     }
11050b57cec5SDimitry Andric   }
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   return true;
11080b57cec5SDimitry Andric }
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric bool SymbolContextSpecifier::AddressMatches(lldb::addr_t addr) {
11110b57cec5SDimitry Andric   if (m_type & eAddressRangeSpecified) {
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric   } else {
11140b57cec5SDimitry Andric     Address match_address(addr, nullptr);
11150b57cec5SDimitry Andric     SymbolContext sc;
11160b57cec5SDimitry Andric     m_target_sp->GetImages().ResolveSymbolContextForAddress(
11170b57cec5SDimitry Andric         match_address, eSymbolContextEverything, sc);
11180b57cec5SDimitry Andric     return SymbolContextMatches(sc);
11190b57cec5SDimitry Andric   }
11200b57cec5SDimitry Andric   return true;
11210b57cec5SDimitry Andric }
11220b57cec5SDimitry Andric 
11230b57cec5SDimitry Andric void SymbolContextSpecifier::GetDescription(
11240b57cec5SDimitry Andric     Stream *s, lldb::DescriptionLevel level) const {
11250b57cec5SDimitry Andric   char path_str[PATH_MAX + 1];
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric   if (m_type == eNothingSpecified) {
11280b57cec5SDimitry Andric     s->Printf("Nothing specified.\n");
11290b57cec5SDimitry Andric   }
11300b57cec5SDimitry Andric 
11310b57cec5SDimitry Andric   if (m_type == eModuleSpecified) {
11320b57cec5SDimitry Andric     s->Indent();
11330b57cec5SDimitry Andric     if (m_module_sp) {
11340b57cec5SDimitry Andric       m_module_sp->GetFileSpec().GetPath(path_str, PATH_MAX);
11350b57cec5SDimitry Andric       s->Printf("Module: %s\n", path_str);
11360b57cec5SDimitry Andric     } else
11370b57cec5SDimitry Andric       s->Printf("Module: %s\n", m_module_spec.c_str());
11380b57cec5SDimitry Andric   }
11390b57cec5SDimitry Andric 
11400b57cec5SDimitry Andric   if (m_type == eFileSpecified && m_file_spec_up != nullptr) {
11410b57cec5SDimitry Andric     m_file_spec_up->GetPath(path_str, PATH_MAX);
11420b57cec5SDimitry Andric     s->Indent();
11430b57cec5SDimitry Andric     s->Printf("File: %s", path_str);
11440b57cec5SDimitry Andric     if (m_type == eLineStartSpecified) {
11450b57cec5SDimitry Andric       s->Printf(" from line %" PRIu64 "", (uint64_t)m_start_line);
11460b57cec5SDimitry Andric       if (m_type == eLineEndSpecified)
11470b57cec5SDimitry Andric         s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
11480b57cec5SDimitry Andric       else
11490b57cec5SDimitry Andric         s->Printf("to end");
11500b57cec5SDimitry Andric     } else if (m_type == eLineEndSpecified) {
11510b57cec5SDimitry Andric       s->Printf(" from start to line %" PRIu64 "", (uint64_t)m_end_line);
11520b57cec5SDimitry Andric     }
11530b57cec5SDimitry Andric     s->Printf(".\n");
11540b57cec5SDimitry Andric   }
11550b57cec5SDimitry Andric 
11560b57cec5SDimitry Andric   if (m_type == eLineStartSpecified) {
11570b57cec5SDimitry Andric     s->Indent();
11580b57cec5SDimitry Andric     s->Printf("From line %" PRIu64 "", (uint64_t)m_start_line);
11590b57cec5SDimitry Andric     if (m_type == eLineEndSpecified)
11600b57cec5SDimitry Andric       s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
11610b57cec5SDimitry Andric     else
11620b57cec5SDimitry Andric       s->Printf("to end");
11630b57cec5SDimitry Andric     s->Printf(".\n");
11640b57cec5SDimitry Andric   } else if (m_type == eLineEndSpecified) {
11650b57cec5SDimitry Andric     s->Printf("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
11660b57cec5SDimitry Andric   }
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric   if (m_type == eFunctionSpecified) {
11690b57cec5SDimitry Andric     s->Indent();
11700b57cec5SDimitry Andric     s->Printf("Function: %s.\n", m_function_spec.c_str());
11710b57cec5SDimitry Andric   }
11720b57cec5SDimitry Andric 
11730b57cec5SDimitry Andric   if (m_type == eClassOrNamespaceSpecified) {
11740b57cec5SDimitry Andric     s->Indent();
11750b57cec5SDimitry Andric     s->Printf("Class name: %s.\n", m_class_name.c_str());
11760b57cec5SDimitry Andric   }
11770b57cec5SDimitry Andric 
11780b57cec5SDimitry Andric   if (m_type == eAddressRangeSpecified && m_address_range_up != nullptr) {
11790b57cec5SDimitry Andric     s->Indent();
11800b57cec5SDimitry Andric     s->PutCString("Address range: ");
11810b57cec5SDimitry Andric     m_address_range_up->Dump(s, m_target_sp.get(),
11820b57cec5SDimitry Andric                              Address::DumpStyleLoadAddress,
11830b57cec5SDimitry Andric                              Address::DumpStyleFileAddress);
11840b57cec5SDimitry Andric     s->PutCString("\n");
11850b57cec5SDimitry Andric   }
11860b57cec5SDimitry Andric }
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric //
11890b57cec5SDimitry Andric //  SymbolContextList
11900b57cec5SDimitry Andric //
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric SymbolContextList::SymbolContextList() : m_symbol_contexts() {}
11930b57cec5SDimitry Andric 
1194fe6060f1SDimitry Andric SymbolContextList::~SymbolContextList() = default;
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric void SymbolContextList::Append(const SymbolContext &sc) {
11970b57cec5SDimitry Andric   m_symbol_contexts.push_back(sc);
11980b57cec5SDimitry Andric }
11990b57cec5SDimitry Andric 
12000b57cec5SDimitry Andric void SymbolContextList::Append(const SymbolContextList &sc_list) {
12010b57cec5SDimitry Andric   collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
12020b57cec5SDimitry Andric   for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
12030b57cec5SDimitry Andric     m_symbol_contexts.push_back(*pos);
12040b57cec5SDimitry Andric }
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric uint32_t SymbolContextList::AppendIfUnique(const SymbolContextList &sc_list,
12070b57cec5SDimitry Andric                                            bool merge_symbol_into_function) {
12080b57cec5SDimitry Andric   uint32_t unique_sc_add_count = 0;
12090b57cec5SDimitry Andric   collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
12100b57cec5SDimitry Andric   for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) {
12110b57cec5SDimitry Andric     if (AppendIfUnique(*pos, merge_symbol_into_function))
12120b57cec5SDimitry Andric       ++unique_sc_add_count;
12130b57cec5SDimitry Andric   }
12140b57cec5SDimitry Andric   return unique_sc_add_count;
12150b57cec5SDimitry Andric }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric bool SymbolContextList::AppendIfUnique(const SymbolContext &sc,
12180b57cec5SDimitry Andric                                        bool merge_symbol_into_function) {
12190b57cec5SDimitry Andric   collection::iterator pos, end = m_symbol_contexts.end();
12200b57cec5SDimitry Andric   for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
12210b57cec5SDimitry Andric     if (*pos == sc)
12220b57cec5SDimitry Andric       return false;
12230b57cec5SDimitry Andric   }
12240b57cec5SDimitry Andric   if (merge_symbol_into_function && sc.symbol != nullptr &&
12250b57cec5SDimitry Andric       sc.comp_unit == nullptr && sc.function == nullptr &&
12260b57cec5SDimitry Andric       sc.block == nullptr && !sc.line_entry.IsValid()) {
12270b57cec5SDimitry Andric     if (sc.symbol->ValueIsAddress()) {
12280b57cec5SDimitry Andric       for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
12290b57cec5SDimitry Andric         // Don't merge symbols into inlined function symbol contexts
12300b57cec5SDimitry Andric         if (pos->block && pos->block->GetContainingInlinedBlock())
12310b57cec5SDimitry Andric           continue;
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric         if (pos->function) {
12340b57cec5SDimitry Andric           if (pos->function->GetAddressRange().GetBaseAddress() ==
12350b57cec5SDimitry Andric               sc.symbol->GetAddressRef()) {
12360b57cec5SDimitry Andric             // Do we already have a function with this symbol?
12370b57cec5SDimitry Andric             if (pos->symbol == sc.symbol)
12380b57cec5SDimitry Andric               return false;
12390b57cec5SDimitry Andric             if (pos->symbol == nullptr) {
12400b57cec5SDimitry Andric               pos->symbol = sc.symbol;
12410b57cec5SDimitry Andric               return false;
12420b57cec5SDimitry Andric             }
12430b57cec5SDimitry Andric           }
12440b57cec5SDimitry Andric         }
12450b57cec5SDimitry Andric       }
12460b57cec5SDimitry Andric     }
12470b57cec5SDimitry Andric   }
12480b57cec5SDimitry Andric   m_symbol_contexts.push_back(sc);
12490b57cec5SDimitry Andric   return true;
12500b57cec5SDimitry Andric }
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric void SymbolContextList::Clear() { m_symbol_contexts.clear(); }
12530b57cec5SDimitry Andric 
12540b57cec5SDimitry Andric void SymbolContextList::Dump(Stream *s, Target *target) const {
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric   *s << this << ": ";
12570b57cec5SDimitry Andric   s->Indent();
12580b57cec5SDimitry Andric   s->PutCString("SymbolContextList");
12590b57cec5SDimitry Andric   s->EOL();
12600b57cec5SDimitry Andric   s->IndentMore();
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   collection::const_iterator pos, end = m_symbol_contexts.end();
12630b57cec5SDimitry Andric   for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
12640b57cec5SDimitry Andric     // pos->Dump(s, target);
12650b57cec5SDimitry Andric     pos->GetDescription(s, eDescriptionLevelVerbose, target);
12660b57cec5SDimitry Andric   }
12670b57cec5SDimitry Andric   s->IndentLess();
12680b57cec5SDimitry Andric }
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric bool SymbolContextList::GetContextAtIndex(size_t idx, SymbolContext &sc) const {
12710b57cec5SDimitry Andric   if (idx < m_symbol_contexts.size()) {
12720b57cec5SDimitry Andric     sc = m_symbol_contexts[idx];
12730b57cec5SDimitry Andric     return true;
12740b57cec5SDimitry Andric   }
12750b57cec5SDimitry Andric   return false;
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric bool SymbolContextList::RemoveContextAtIndex(size_t idx) {
12790b57cec5SDimitry Andric   if (idx < m_symbol_contexts.size()) {
12800b57cec5SDimitry Andric     m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
12810b57cec5SDimitry Andric     return true;
12820b57cec5SDimitry Andric   }
12830b57cec5SDimitry Andric   return false;
12840b57cec5SDimitry Andric }
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric uint32_t SymbolContextList::GetSize() const { return m_symbol_contexts.size(); }
12870b57cec5SDimitry Andric 
12889dba64beSDimitry Andric bool SymbolContextList::IsEmpty() const { return m_symbol_contexts.empty(); }
12899dba64beSDimitry Andric 
12900b57cec5SDimitry Andric uint32_t SymbolContextList::NumLineEntriesWithLine(uint32_t line) const {
12910b57cec5SDimitry Andric   uint32_t match_count = 0;
12920b57cec5SDimitry Andric   const size_t size = m_symbol_contexts.size();
12930b57cec5SDimitry Andric   for (size_t idx = 0; idx < size; ++idx) {
12940b57cec5SDimitry Andric     if (m_symbol_contexts[idx].line_entry.line == line)
12950b57cec5SDimitry Andric       ++match_count;
12960b57cec5SDimitry Andric   }
12970b57cec5SDimitry Andric   return match_count;
12980b57cec5SDimitry Andric }
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric void SymbolContextList::GetDescription(Stream *s, lldb::DescriptionLevel level,
13010b57cec5SDimitry Andric                                        Target *target) const {
13020b57cec5SDimitry Andric   const size_t size = m_symbol_contexts.size();
13030b57cec5SDimitry Andric   for (size_t idx = 0; idx < size; ++idx)
13040b57cec5SDimitry Andric     m_symbol_contexts[idx].GetDescription(s, level, target);
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric 
13070b57cec5SDimitry Andric bool lldb_private::operator==(const SymbolContextList &lhs,
13080b57cec5SDimitry Andric                               const SymbolContextList &rhs) {
13090b57cec5SDimitry Andric   const uint32_t size = lhs.GetSize();
13100b57cec5SDimitry Andric   if (size != rhs.GetSize())
13110b57cec5SDimitry Andric     return false;
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric   SymbolContext lhs_sc;
13140b57cec5SDimitry Andric   SymbolContext rhs_sc;
13150b57cec5SDimitry Andric   for (uint32_t i = 0; i < size; ++i) {
13160b57cec5SDimitry Andric     lhs.GetContextAtIndex(i, lhs_sc);
13170b57cec5SDimitry Andric     rhs.GetContextAtIndex(i, rhs_sc);
13180b57cec5SDimitry Andric     if (lhs_sc != rhs_sc)
13190b57cec5SDimitry Andric       return false;
13200b57cec5SDimitry Andric   }
13210b57cec5SDimitry Andric   return true;
13220b57cec5SDimitry Andric }
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric bool lldb_private::operator!=(const SymbolContextList &lhs,
13250b57cec5SDimitry Andric                               const SymbolContextList &rhs) {
13260b57cec5SDimitry Andric   return !(lhs == rhs);
13270b57cec5SDimitry Andric }
1328