1254721Semaste//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Symbol/SymbolContext.h"
11254721Semaste
12254721Semaste#include "lldb/Core/Log.h"
13254721Semaste#include "lldb/Core/Module.h"
14254721Semaste#include "lldb/Core/ModuleSpec.h"
15254721Semaste#include "lldb/Host/Host.h"
16288943Sdim#include "lldb/Host/StringConvert.h"
17254721Semaste#include "lldb/Symbol/Block.h"
18254721Semaste#include "lldb/Symbol/ClangASTContext.h"
19254721Semaste#include "lldb/Symbol/CompileUnit.h"
20254721Semaste#include "lldb/Symbol/ObjectFile.h"
21254721Semaste#include "lldb/Symbol/Symbol.h"
22254721Semaste#include "lldb/Symbol/SymbolFile.h"
23254721Semaste#include "lldb/Symbol/SymbolVendor.h"
24288943Sdim#include "lldb/Symbol/Variable.h"
25254721Semaste#include "lldb/Target/Target.h"
26254721Semaste
27254721Semasteusing namespace lldb;
28254721Semasteusing namespace lldb_private;
29254721Semaste
30254721SemasteSymbolContext::SymbolContext() :
31254721Semaste    target_sp   (),
32254721Semaste    module_sp   (),
33276479Sdim    comp_unit   (nullptr),
34276479Sdim    function    (nullptr),
35276479Sdim    block       (nullptr),
36254721Semaste    line_entry  (),
37288943Sdim    symbol      (nullptr),
38288943Sdim    variable    (nullptr)
39254721Semaste{
40254721Semaste}
41254721Semaste
42254721SemasteSymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
43254721Semaste    target_sp   (),
44254721Semaste    module_sp   (m),
45254721Semaste    comp_unit   (cu),
46254721Semaste    function    (f),
47254721Semaste    block       (b),
48254721Semaste    line_entry  (),
49288943Sdim    symbol      (s),
50288943Sdim    variable    (nullptr)
51254721Semaste{
52254721Semaste    if (le)
53254721Semaste        line_entry = *le;
54254721Semaste}
55254721Semaste
56254721SemasteSymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
57254721Semaste    target_sp   (t),
58254721Semaste    module_sp   (m),
59254721Semaste    comp_unit   (cu),
60254721Semaste    function    (f),
61254721Semaste    block       (b),
62254721Semaste    line_entry  (),
63288943Sdim    symbol      (s),
64288943Sdim    variable    (nullptr)
65254721Semaste{
66254721Semaste    if (le)
67254721Semaste        line_entry = *le;
68254721Semaste}
69254721Semaste
70254721SemasteSymbolContext::SymbolContext(const SymbolContext& rhs) :
71254721Semaste    target_sp   (rhs.target_sp),
72254721Semaste    module_sp   (rhs.module_sp),
73254721Semaste    comp_unit   (rhs.comp_unit),
74254721Semaste    function    (rhs.function),
75254721Semaste    block       (rhs.block),
76254721Semaste    line_entry  (rhs.line_entry),
77288943Sdim    symbol      (rhs.symbol),
78288943Sdim    variable    (rhs.variable)
79254721Semaste{
80254721Semaste}
81254721Semaste
82254721Semaste
83254721SemasteSymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
84254721Semaste    target_sp   (),
85254721Semaste    module_sp   (),
86276479Sdim    comp_unit   (nullptr),
87276479Sdim    function    (nullptr),
88276479Sdim    block       (nullptr),
89254721Semaste    line_entry  (),
90288943Sdim    symbol      (nullptr),
91288943Sdim    variable    (nullptr)
92254721Semaste{
93254721Semaste    sc_scope->CalculateSymbolContext (this);
94254721Semaste}
95254721Semaste
96254721SemasteSymbolContext::~SymbolContext ()
97254721Semaste{
98254721Semaste}
99254721Semaste
100254721Semasteconst SymbolContext&
101254721SemasteSymbolContext::operator= (const SymbolContext& rhs)
102254721Semaste{
103254721Semaste    if (this != &rhs)
104254721Semaste    {
105254721Semaste        target_sp   = rhs.target_sp;
106254721Semaste        module_sp   = rhs.module_sp;
107254721Semaste        comp_unit   = rhs.comp_unit;
108254721Semaste        function    = rhs.function;
109254721Semaste        block       = rhs.block;
110254721Semaste        line_entry  = rhs.line_entry;
111254721Semaste        symbol      = rhs.symbol;
112288943Sdim        variable    = rhs.variable;
113254721Semaste    }
114254721Semaste    return *this;
115254721Semaste}
116254721Semaste
117254721Semastevoid
118254721SemasteSymbolContext::Clear(bool clear_target)
119254721Semaste{
120254721Semaste    if (clear_target)
121254721Semaste        target_sp.reset();
122254721Semaste    module_sp.reset();
123276479Sdim    comp_unit   = nullptr;
124276479Sdim    function    = nullptr;
125276479Sdim    block       = nullptr;
126254721Semaste    line_entry.Clear();
127276479Sdim    symbol      = nullptr;
128288943Sdim    variable    = nullptr;
129254721Semaste}
130254721Semaste
131254721Semastebool
132288943SdimSymbolContext::DumpStopContext (
133254721Semaste    Stream *s,
134254721Semaste    ExecutionContextScope *exe_scope,
135254721Semaste    const Address &addr,
136254721Semaste    bool show_fullpaths,
137254721Semaste    bool show_module,
138280031Sdim    bool show_inlined_frames,
139288943Sdim    bool show_function_arguments,
140288943Sdim    bool show_function_name
141254721Semaste) const
142254721Semaste{
143254721Semaste    bool dumped_something = false;
144254721Semaste    if (show_module && module_sp)
145254721Semaste    {
146254721Semaste        if (show_fullpaths)
147254721Semaste            *s << module_sp->GetFileSpec();
148254721Semaste        else
149254721Semaste            *s << module_sp->GetFileSpec().GetFilename();
150254721Semaste        s->PutChar('`');
151254721Semaste        dumped_something = true;
152254721Semaste    }
153254721Semaste
154276479Sdim    if (function != nullptr)
155254721Semaste    {
156254721Semaste        SymbolContext inline_parent_sc;
157254721Semaste        Address inline_parent_addr;
158288943Sdim        if (show_function_name == false)
159254721Semaste        {
160288943Sdim            s->Printf("<");
161254721Semaste            dumped_something = true;
162280031Sdim        }
163288943Sdim        else
164280031Sdim        {
165288943Sdim            ConstString name;
166288943Sdim            if (show_function_arguments == false)
167288943Sdim                name = function->GetNameNoArguments();
168288943Sdim            if (!name)
169288943Sdim                name = function->GetName();
170288943Sdim            if (name)
171288943Sdim                name.Dump(s);
172254721Semaste        }
173254721Semaste
174254721Semaste        if (addr.IsValid())
175254721Semaste        {
176254721Semaste            const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
177288943Sdim            if (show_function_name == false)
178254721Semaste            {
179288943Sdim                // Print +offset even if offset is 0
180254721Semaste                dumped_something = true;
181288943Sdim                s->Printf("+%" PRIu64 ">", function_offset);
182288943Sdim            }
183288943Sdim            else if (function_offset)
184288943Sdim            {
185288943Sdim                dumped_something = true;
186254721Semaste                s->Printf(" + %" PRIu64, function_offset);
187254721Semaste            }
188254721Semaste        }
189254721Semaste
190254721Semaste        if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr))
191254721Semaste        {
192254721Semaste            dumped_something = true;
193254721Semaste            Block *inlined_block = block->GetContainingInlinedBlock();
194254721Semaste            const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo();
195288943Sdim            s->Printf (" [inlined] %s", inlined_block_info->GetName(function->GetLanguage()).GetCString());
196254721Semaste
197254721Semaste            lldb_private::AddressRange block_range;
198254721Semaste            if (inlined_block->GetRangeContainingAddress(addr, block_range))
199254721Semaste            {
200254721Semaste                const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
201254721Semaste                if (inlined_function_offset)
202254721Semaste                {
203254721Semaste                    s->Printf(" + %" PRIu64, inlined_function_offset);
204254721Semaste                }
205254721Semaste            }
206254721Semaste            const Declaration &call_site = inlined_block_info->GetCallSite();
207254721Semaste            if (call_site.IsValid())
208254721Semaste            {
209254721Semaste                s->PutCString(" at ");
210254721Semaste                call_site.DumpStopContext (s, show_fullpaths);
211254721Semaste            }
212254721Semaste            if (show_inlined_frames)
213254721Semaste            {
214254721Semaste                s->EOL();
215254721Semaste                s->Indent();
216288943Sdim                const bool show_function_name = true;
217288943Sdim                return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments, show_function_name);
218254721Semaste            }
219254721Semaste        }
220254721Semaste        else
221254721Semaste        {
222254721Semaste            if (line_entry.IsValid())
223254721Semaste            {
224254721Semaste                dumped_something = true;
225254721Semaste                s->PutCString(" at ");
226254721Semaste                if (line_entry.DumpStopContext(s, show_fullpaths))
227254721Semaste                    dumped_something = true;
228254721Semaste            }
229254721Semaste        }
230254721Semaste    }
231276479Sdim    else if (symbol != nullptr)
232254721Semaste    {
233288943Sdim        if (show_function_name == false)
234254721Semaste        {
235288943Sdim            s->Printf("<");
236254721Semaste            dumped_something = true;
237288943Sdim        }
238288943Sdim        else if (symbol->GetName())
239288943Sdim        {
240288943Sdim            dumped_something = true;
241254721Semaste            if (symbol->GetType() == eSymbolTypeTrampoline)
242254721Semaste                s->PutCString("symbol stub for: ");
243288943Sdim            symbol->GetName().Dump(s);
244254721Semaste        }
245254721Semaste
246254721Semaste        if (addr.IsValid() && symbol->ValueIsAddress())
247254721Semaste        {
248288943Sdim            const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRef().GetOffset();
249288943Sdim            if (show_function_name == false)
250254721Semaste            {
251288943Sdim                // Print +offset even if offset is 0
252254721Semaste                dumped_something = true;
253288943Sdim                s->Printf("+%" PRIu64 ">", symbol_offset);
254288943Sdim            }
255288943Sdim            else if (symbol_offset)
256288943Sdim            {
257288943Sdim                dumped_something = true;
258254721Semaste                s->Printf(" + %" PRIu64, symbol_offset);
259254721Semaste            }
260254721Semaste        }
261254721Semaste    }
262254721Semaste    else if (addr.IsValid())
263254721Semaste    {
264254721Semaste        addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
265254721Semaste        dumped_something = true;
266254721Semaste    }
267254721Semaste    return dumped_something;
268254721Semaste}
269254721Semaste
270254721Semastevoid
271254721SemasteSymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
272254721Semaste{
273254721Semaste    if (module_sp)
274254721Semaste    {
275254721Semaste        s->Indent("     Module: file = \"");
276254721Semaste        module_sp->GetFileSpec().Dump(s);
277254721Semaste        *s << '"';
278254721Semaste        if (module_sp->GetArchitecture().IsValid())
279254721Semaste            s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
280254721Semaste        s->EOL();
281254721Semaste    }
282254721Semaste
283276479Sdim    if (comp_unit != nullptr)
284254721Semaste    {
285254721Semaste        s->Indent("CompileUnit: ");
286254721Semaste        comp_unit->GetDescription (s, level);
287254721Semaste        s->EOL();
288254721Semaste    }
289254721Semaste
290276479Sdim    if (function != nullptr)
291254721Semaste    {
292254721Semaste        s->Indent("   Function: ");
293254721Semaste        function->GetDescription (s, level, target);
294254721Semaste        s->EOL();
295254721Semaste
296254721Semaste        Type *func_type = function->GetType();
297254721Semaste        if (func_type)
298254721Semaste        {
299254721Semaste            s->Indent("   FuncType: ");
300254721Semaste            func_type->GetDescription (s, level, false);
301254721Semaste            s->EOL();
302254721Semaste        }
303254721Semaste    }
304254721Semaste
305276479Sdim    if (block != nullptr)
306254721Semaste    {
307254721Semaste        std::vector<Block *> blocks;
308254721Semaste        blocks.push_back (block);
309254721Semaste        Block *parent_block = block->GetParent();
310254721Semaste
311254721Semaste        while (parent_block)
312254721Semaste        {
313254721Semaste            blocks.push_back (parent_block);
314254721Semaste            parent_block = parent_block->GetParent();
315254721Semaste        }
316254721Semaste        std::vector<Block *>::reverse_iterator pos;
317254721Semaste        std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
318254721Semaste        std::vector<Block *>::reverse_iterator end = blocks.rend();
319254721Semaste        for (pos = begin; pos != end; ++pos)
320254721Semaste        {
321254721Semaste            if (pos == begin)
322254721Semaste                s->Indent("     Blocks: ");
323254721Semaste            else
324254721Semaste                s->Indent("             ");
325254721Semaste            (*pos)->GetDescription(s, function, level, target);
326254721Semaste            s->EOL();
327254721Semaste        }
328254721Semaste    }
329254721Semaste
330254721Semaste    if (line_entry.IsValid())
331254721Semaste    {
332254721Semaste        s->Indent("  LineEntry: ");
333254721Semaste        line_entry.GetDescription (s, level, comp_unit, target, false);
334254721Semaste        s->EOL();
335254721Semaste    }
336254721Semaste
337276479Sdim    if (symbol != nullptr)
338254721Semaste    {
339254721Semaste        s->Indent("     Symbol: ");
340254721Semaste        symbol->GetDescription(s, level, target);
341254721Semaste        s->EOL();
342254721Semaste    }
343288943Sdim
344288943Sdim    if (variable != nullptr)
345288943Sdim    {
346288943Sdim        s->Indent("   Variable: ");
347288943Sdim
348288943Sdim        s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
349288943Sdim
350288943Sdim        switch (variable->GetScope())
351288943Sdim        {
352288943Sdim            case eValueTypeVariableGlobal:
353288943Sdim                s->PutCString("kind = global, ");
354288943Sdim                break;
355288943Sdim
356288943Sdim            case eValueTypeVariableStatic:
357288943Sdim                s->PutCString("kind = static, ");
358288943Sdim                break;
359288943Sdim
360288943Sdim            case eValueTypeVariableArgument:
361288943Sdim                s->PutCString("kind = argument, ");
362288943Sdim                break;
363288943Sdim
364288943Sdim            case eValueTypeVariableLocal:
365288943Sdim                s->PutCString("kind = local, ");
366288943Sdim                break;
367288943Sdim
368288943Sdim            default:
369288943Sdim                break;
370288943Sdim        }
371288943Sdim
372288943Sdim        s->Printf ("name = \"%s\"\n", variable->GetName().GetCString());
373288943Sdim    }
374254721Semaste}
375254721Semaste
376254721Semasteuint32_t
377254721SemasteSymbolContext::GetResolvedMask () const
378254721Semaste{
379254721Semaste    uint32_t resolved_mask = 0;
380254721Semaste    if (target_sp)              resolved_mask |= eSymbolContextTarget;
381254721Semaste    if (module_sp)              resolved_mask |= eSymbolContextModule;
382254721Semaste    if (comp_unit)              resolved_mask |= eSymbolContextCompUnit;
383254721Semaste    if (function)               resolved_mask |= eSymbolContextFunction;
384254721Semaste    if (block)                  resolved_mask |= eSymbolContextBlock;
385254721Semaste    if (line_entry.IsValid())   resolved_mask |= eSymbolContextLineEntry;
386254721Semaste    if (symbol)                 resolved_mask |= eSymbolContextSymbol;
387288943Sdim    if (variable)               resolved_mask |= eSymbolContextVariable;
388254721Semaste    return resolved_mask;
389254721Semaste}
390254721Semaste
391254721Semastevoid
392254721SemasteSymbolContext::Dump(Stream *s, Target *target) const
393254721Semaste{
394296417Sdim    *s << this << ": ";
395254721Semaste    s->Indent();
396254721Semaste    s->PutCString("SymbolContext");
397254721Semaste    s->IndentMore();
398254721Semaste    s->EOL();
399254721Semaste    s->IndentMore();
400254721Semaste    s->Indent();
401296417Sdim    *s << "Module       = " << module_sp.get() << ' ';
402254721Semaste    if (module_sp)
403254721Semaste        module_sp->GetFileSpec().Dump(s);
404254721Semaste    s->EOL();
405254721Semaste    s->Indent();
406296417Sdim    *s << "CompileUnit  = " << comp_unit;
407276479Sdim    if (comp_unit != nullptr)
408254721Semaste        *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
409254721Semaste    s->EOL();
410254721Semaste    s->Indent();
411296417Sdim    *s << "Function     = " << function;
412276479Sdim    if (function != nullptr)
413254721Semaste    {
414254721Semaste        *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
415254721Semaste        function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
416254721Semaste        s->EOL();
417254721Semaste        s->Indent();
418254721Semaste        Type* func_type = function->GetType();
419254721Semaste        if (func_type)
420254721Semaste        {
421254721Semaste            *s << "        Type = ";
422254721Semaste            func_type->Dump (s, false);
423254721Semaste        }
424254721Semaste    }
425254721Semaste    s->EOL();
426254721Semaste    s->Indent();
427296417Sdim    *s << "Block        = " << block;
428276479Sdim    if (block != nullptr)
429254721Semaste        *s << " {0x" << block->GetID() << '}';
430254721Semaste    // Dump the block and pass it a negative depth to we print all the parent blocks
431254721Semaste    //if (block != NULL)
432254721Semaste    //  block->Dump(s, function->GetFileAddress(), INT_MIN);
433254721Semaste    s->EOL();
434254721Semaste    s->Indent();
435254721Semaste    *s << "LineEntry    = ";
436254721Semaste    line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
437254721Semaste    s->EOL();
438254721Semaste    s->Indent();
439296417Sdim    *s << "Symbol       = " << symbol;
440276479Sdim    if (symbol != nullptr && symbol->GetMangled())
441288943Sdim        *s << ' ' << symbol->GetName().AsCString();
442254721Semaste    s->EOL();
443296417Sdim    *s << "Variable     = " << variable;
444288943Sdim    if (variable != nullptr)
445288943Sdim    {
446288943Sdim        *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName();
447288943Sdim        s->EOL();
448288943Sdim    }
449254721Semaste    s->IndentLess();
450254721Semaste    s->IndentLess();
451254721Semaste}
452254721Semaste
453254721Semastebool
454254721Semastelldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
455254721Semaste{
456254721Semaste    return  lhs.function == rhs.function
457254721Semaste            && lhs.symbol == rhs.symbol
458254721Semaste            && lhs.module_sp.get() == rhs.module_sp.get()
459254721Semaste            && lhs.comp_unit == rhs.comp_unit
460254721Semaste            && lhs.target_sp.get() == rhs.target_sp.get()
461288943Sdim            && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0
462288943Sdim            && lhs.variable == rhs.variable;
463254721Semaste}
464254721Semaste
465254721Semastebool
466254721Semastelldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
467254721Semaste{
468254721Semaste    return  lhs.function != rhs.function
469254721Semaste            || lhs.symbol != rhs.symbol
470254721Semaste            || lhs.module_sp.get() != rhs.module_sp.get()
471254721Semaste            || lhs.comp_unit != rhs.comp_unit
472254721Semaste            || lhs.target_sp.get() != rhs.target_sp.get()
473288943Sdim            || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0
474288943Sdim            || lhs.variable != rhs.variable;
475254721Semaste}
476254721Semaste
477254721Semastebool
478254721SemasteSymbolContext::GetAddressRange (uint32_t scope,
479254721Semaste                                uint32_t range_idx,
480254721Semaste                                bool use_inline_block_range,
481254721Semaste                                AddressRange &range) const
482254721Semaste{
483254721Semaste    if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
484254721Semaste    {
485254721Semaste        range = line_entry.range;
486254721Semaste        return true;
487254721Semaste    }
488254721Semaste
489276479Sdim    if ((scope & eSymbolContextBlock) && (block != nullptr))
490254721Semaste    {
491254721Semaste        if (use_inline_block_range)
492254721Semaste        {
493254721Semaste            Block *inline_block = block->GetContainingInlinedBlock();
494254721Semaste            if (inline_block)
495254721Semaste                return inline_block->GetRangeAtIndex (range_idx, range);
496254721Semaste        }
497254721Semaste        else
498254721Semaste        {
499254721Semaste            return block->GetRangeAtIndex (range_idx, range);
500254721Semaste        }
501254721Semaste    }
502254721Semaste
503276479Sdim    if ((scope & eSymbolContextFunction) && (function != nullptr))
504254721Semaste    {
505254721Semaste        if (range_idx == 0)
506254721Semaste        {
507254721Semaste            range = function->GetAddressRange();
508254721Semaste            return true;
509254721Semaste        }
510254721Semaste    }
511254721Semaste
512276479Sdim    if ((scope & eSymbolContextSymbol) && (symbol != nullptr))
513254721Semaste    {
514254721Semaste        if (range_idx == 0)
515254721Semaste        {
516254721Semaste            if (symbol->ValueIsAddress())
517254721Semaste            {
518288943Sdim                range.GetBaseAddress() = symbol->GetAddressRef();
519254721Semaste                range.SetByteSize (symbol->GetByteSize());
520254721Semaste                return true;
521254721Semaste            }
522254721Semaste        }
523254721Semaste    }
524254721Semaste    range.Clear();
525254721Semaste    return false;
526254721Semaste}
527254721Semaste
528296417SdimLanguageType
529296417SdimSymbolContext::GetLanguage () const
530296417Sdim{
531296417Sdim    LanguageType lang;
532296417Sdim    if (function &&
533296417Sdim        (lang = function->GetLanguage()) != eLanguageTypeUnknown)
534296417Sdim    {
535296417Sdim        return lang;
536296417Sdim    }
537296417Sdim    else if (variable &&
538296417Sdim             (lang = variable->GetLanguage()) != eLanguageTypeUnknown)
539296417Sdim    {
540296417Sdim        return lang;
541296417Sdim    }
542296417Sdim    else if (symbol &&
543296417Sdim             (lang = symbol->GetLanguage()) != eLanguageTypeUnknown)
544296417Sdim    {
545296417Sdim        return lang;
546296417Sdim    }
547296417Sdim    else if (comp_unit &&
548296417Sdim             (lang = comp_unit->GetLanguage()) != eLanguageTypeUnknown)
549296417Sdim    {
550296417Sdim        return lang;
551296417Sdim    }
552296417Sdim    else if (symbol)
553296417Sdim    {
554296417Sdim        // If all else fails, try to guess the language from the name.
555296417Sdim        return symbol->GetMangled().GuessLanguage();
556296417Sdim    }
557296417Sdim    return eLanguageTypeUnknown;
558296417Sdim}
559296417Sdim
560254721Semastebool
561254721SemasteSymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
562254721Semaste                                        SymbolContext &next_frame_sc,
563254721Semaste                                        Address &next_frame_pc) const
564254721Semaste{
565254721Semaste    next_frame_sc.Clear(false);
566254721Semaste    next_frame_pc.Clear();
567254721Semaste
568254721Semaste    if (block)
569254721Semaste    {
570254721Semaste        //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
571254721Semaste
572254721Semaste        // In order to get the parent of an inlined function we first need to
573254721Semaste        // see if we are in an inlined block as "this->block" could be an
574254721Semaste        // inlined block, or a parent of "block" could be. So lets check if
575254721Semaste        // this block or one of this blocks parents is an inlined function.
576254721Semaste        Block *curr_inlined_block = block->GetContainingInlinedBlock();
577254721Semaste        if (curr_inlined_block)
578254721Semaste        {
579254721Semaste            // "this->block" is contained in an inline function block, so to
580254721Semaste            // get the scope above the inlined block, we get the parent of the
581254721Semaste            // inlined block itself
582254721Semaste            Block *next_frame_block = curr_inlined_block->GetParent();
583254721Semaste            // Now calculate the symbol context of the containing block
584254721Semaste            next_frame_block->CalculateSymbolContext (&next_frame_sc);
585254721Semaste
586254721Semaste            // If we get here we weren't able to find the return line entry using the nesting of the blocks and
587254721Semaste            // the line table.  So just use the call site info from our inlined block.
588254721Semaste
589254721Semaste            AddressRange range;
590254721Semaste            if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
591254721Semaste            {
592254721Semaste                // To see there this new frame block it, we need to look at the
593254721Semaste                // call site information from
594254721Semaste                const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
595254721Semaste                next_frame_pc = range.GetBaseAddress();
596254721Semaste                next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
597254721Semaste                next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
598254721Semaste                next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
599254721Semaste                next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
600254721Semaste                return true;
601254721Semaste            }
602254721Semaste            else
603254721Semaste            {
604254721Semaste                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
605254721Semaste
606254721Semaste                if (log)
607254721Semaste                {
608254721Semaste                    log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
609254721Semaste                                 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
610254721Semaste                }
611254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG
612254721Semaste                else
613254721Semaste                {
614254721Semaste                    ObjectFile *objfile = NULL;
615254721Semaste                    if (module_sp)
616254721Semaste                    {
617254721Semaste                        SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
618254721Semaste                        if (symbol_vendor)
619254721Semaste                        {
620254721Semaste                            SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
621254721Semaste                            if (symbol_file)
622254721Semaste                                objfile = symbol_file->GetObjectFile();
623254721Semaste                        }
624254721Semaste                    }
625254721Semaste                    if (objfile)
626254721Semaste                    {
627254721Semaste                        Host::SystemLog (Host::eSystemLogWarning,
628254721Semaste                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n",
629254721Semaste                                         curr_inlined_block->GetID(),
630254721Semaste                                         curr_frame_pc.GetFileAddress(),
631254721Semaste                                         objfile->GetFileSpec().GetPath().c_str());
632254721Semaste                    }
633254721Semaste                    else
634254721Semaste                    {
635254721Semaste                        Host::SystemLog (Host::eSystemLogWarning,
636254721Semaste                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
637254721Semaste                                         curr_inlined_block->GetID(),
638254721Semaste                                         curr_frame_pc.GetFileAddress());
639254721Semaste                    }
640254721Semaste                }
641254721Semaste#endif
642254721Semaste            }
643254721Semaste        }
644254721Semaste    }
645254721Semaste
646254721Semaste    return false;
647254721Semaste}
648254721Semaste
649254721SemasteBlock *
650254721SemasteSymbolContext::GetFunctionBlock ()
651254721Semaste{
652254721Semaste    if (function)
653254721Semaste    {
654254721Semaste        if (block)
655254721Semaste        {
656254721Semaste            // If this symbol context has a block, check to see if this block
657254721Semaste            // is itself, or is contained within a block with inlined function
658254721Semaste            // information. If so, then the inlined block is the block that
659254721Semaste            // defines the function.
660254721Semaste            Block *inlined_block = block->GetContainingInlinedBlock();
661254721Semaste            if (inlined_block)
662254721Semaste                return inlined_block;
663254721Semaste
664254721Semaste            // The block in this symbol context is not inside an inlined
665254721Semaste            // block, so the block that defines the function is the function's
666254721Semaste            // top level block, which is returned below.
667254721Semaste        }
668254721Semaste
669254721Semaste        // There is no block information in this symbol context, so we must
670254721Semaste        // assume that the block that is desired is the top level block of
671254721Semaste        // the function itself.
672254721Semaste        return &function->GetBlock(true);
673254721Semaste    }
674276479Sdim    return nullptr;
675254721Semaste}
676254721Semaste
677254721Semastebool
678254721SemasteSymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language,
679254721Semaste                                      bool &is_instance_method,
680254721Semaste                                      ConstString &language_object_name)
681254721Semaste
682254721Semaste
683254721Semaste{
684296417Sdim    Block *function_block = GetFunctionBlock();
685254721Semaste    if (function_block)
686254721Semaste    {
687296417Sdim        CompilerDeclContext decl_ctx = function_block->GetDeclContext();
688296417Sdim        if (decl_ctx)
689296417Sdim            return decl_ctx.IsClassMethod(&language, &is_instance_method, &language_object_name);
690296417Sdim    }
691296417Sdim    return false;
692296417Sdim}
693296417Sdim
694296417Sdimvoid
695296417SdimSymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const
696296417Sdim{
697296417Sdim    Block * curr_block = block;
698296417Sdim    bool isInlinedblock = false;
699296417Sdim    if (curr_block != nullptr && curr_block->GetContainingInlinedBlock() != nullptr)
700296417Sdim        isInlinedblock = true;
701296417Sdim
702296417Sdim    //----------------------------------------------------------------------
703296417Sdim    // Find all types that match the current block if we have one and put
704296417Sdim    // them first in the list. Keep iterating up through all blocks.
705296417Sdim    //----------------------------------------------------------------------
706296417Sdim    while (curr_block != nullptr && !isInlinedblock)
707296417Sdim    {
708296417Sdim        type_map.ForEach([curr_block, &type_list](const lldb::TypeSP& type_sp) -> bool {
709296417Sdim            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
710296417Sdim            if (scs && curr_block == scs->CalculateSymbolContextBlock())
711296417Sdim                type_list.Insert(type_sp);
712296417Sdim            return true; // Keep iterating
713296417Sdim        });
714296417Sdim
715296417Sdim        // Remove any entries that are now in "type_list" from "type_map"
716296417Sdim        // since we can't remove from type_map while iterating
717296417Sdim        type_list.ForEach([&type_map](const lldb::TypeSP& type_sp) -> bool {
718296417Sdim            type_map.Remove(type_sp);
719296417Sdim            return true; // Keep iterating
720296417Sdim        });
721296417Sdim        curr_block = curr_block->GetParent();
722296417Sdim    }
723296417Sdim    //----------------------------------------------------------------------
724296417Sdim    // Find all types that match the current function, if we have onem, and
725296417Sdim    // put them next in the list.
726296417Sdim    //----------------------------------------------------------------------
727296417Sdim    if (function != nullptr && !type_map.Empty())
728296417Sdim    {
729296417Sdim        const size_t old_type_list_size = type_list.GetSize();
730296417Sdim        type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool {
731296417Sdim            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
732296417Sdim            if (scs && function == scs->CalculateSymbolContextFunction())
733296417Sdim                type_list.Insert(type_sp);
734296417Sdim            return true; // Keep iterating
735296417Sdim        });
736296417Sdim
737296417Sdim        // Remove any entries that are now in "type_list" from "type_map"
738296417Sdim        // since we can't remove from type_map while iterating
739296417Sdim        const size_t new_type_list_size = type_list.GetSize();
740296417Sdim        if (new_type_list_size > old_type_list_size)
741254721Semaste        {
742296417Sdim            for (size_t i=old_type_list_size; i<new_type_list_size; ++i)
743296417Sdim                type_map.Remove(type_list.GetTypeAtIndex(i));
744254721Semaste        }
745254721Semaste    }
746296417Sdim    //----------------------------------------------------------------------
747296417Sdim    // Find all types that match the current compile unit, if we have one,
748296417Sdim    // and put them next in the list.
749296417Sdim    //----------------------------------------------------------------------
750296417Sdim    if (comp_unit != nullptr && !type_map.Empty())
751296417Sdim    {
752296417Sdim        const size_t old_type_list_size = type_list.GetSize();
753296417Sdim
754296417Sdim        type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool {
755296417Sdim            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
756296417Sdim            if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit())
757296417Sdim                type_list.Insert(type_sp);
758296417Sdim            return true; // Keep iterating
759296417Sdim        });
760296417Sdim
761296417Sdim        // Remove any entries that are now in "type_list" from "type_map"
762296417Sdim        // since we can't remove from type_map while iterating
763296417Sdim        const size_t new_type_list_size = type_list.GetSize();
764296417Sdim        if (new_type_list_size > old_type_list_size)
765296417Sdim        {
766296417Sdim            for (size_t i=old_type_list_size; i<new_type_list_size; ++i)
767296417Sdim                type_map.Remove(type_list.GetTypeAtIndex(i));
768296417Sdim        }
769296417Sdim    }
770296417Sdim    //----------------------------------------------------------------------
771296417Sdim    // Find all types that match the current module, if we have one, and put
772296417Sdim    // them next in the list.
773296417Sdim    //----------------------------------------------------------------------
774296417Sdim    if (module_sp && !type_map.Empty())
775296417Sdim    {
776296417Sdim        const size_t old_type_list_size = type_list.GetSize();
777296417Sdim        type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool {
778296417Sdim            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
779296417Sdim            if (scs &&  module_sp == scs->CalculateSymbolContextModule())
780296417Sdim                type_list.Insert(type_sp);
781296417Sdim            return true; // Keep iterating
782296417Sdim        });
783296417Sdim        // Remove any entries that are now in "type_list" from "type_map"
784296417Sdim        // since we can't remove from type_map while iterating
785296417Sdim        const size_t new_type_list_size = type_list.GetSize();
786296417Sdim        if (new_type_list_size > old_type_list_size)
787296417Sdim        {
788296417Sdim            for (size_t i=old_type_list_size; i<new_type_list_size; ++i)
789296417Sdim                type_map.Remove(type_list.GetTypeAtIndex(i));
790296417Sdim        }
791296417Sdim    }
792296417Sdim    //----------------------------------------------------------------------
793296417Sdim    // Any types that are left get copied into the list an any order.
794296417Sdim    //----------------------------------------------------------------------
795296417Sdim    if (!type_map.Empty())
796296417Sdim    {
797296417Sdim        type_map.ForEach([&type_list](const lldb::TypeSP& type_sp) -> bool {
798296417Sdim            type_list.Insert(type_sp);
799296417Sdim            return true; // Keep iterating
800296417Sdim        });
801296417Sdim    }
802254721Semaste}
803254721Semaste
804254721SemasteConstString
805254721SemasteSymbolContext::GetFunctionName (Mangled::NamePreference preference) const
806254721Semaste{
807254721Semaste    if (function)
808254721Semaste    {
809254721Semaste        if (block)
810254721Semaste        {
811254721Semaste            Block *inlined_block = block->GetContainingInlinedBlock();
812254721Semaste
813254721Semaste            if (inlined_block)
814254721Semaste            {
815254721Semaste                const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo();
816254721Semaste                if (inline_info)
817288943Sdim                    return inline_info->GetName(function->GetLanguage());
818254721Semaste            }
819254721Semaste        }
820288943Sdim        return function->GetMangled().GetName(function->GetLanguage(), preference);
821254721Semaste    }
822254721Semaste    else if (symbol && symbol->ValueIsAddress())
823254721Semaste    {
824288943Sdim        return symbol->GetMangled().GetName(symbol->GetLanguage(), preference);
825254721Semaste    }
826254721Semaste    else
827254721Semaste    {
828254721Semaste        // No function, return an empty string.
829254721Semaste        return ConstString();
830254721Semaste    }
831254721Semaste}
832254721Semaste
833254721SemasteLineEntry
834254721SemasteSymbolContext::GetFunctionStartLineEntry () const
835254721Semaste{
836254721Semaste    LineEntry line_entry;
837254721Semaste    Address start_addr;
838254721Semaste    if (block)
839254721Semaste    {
840254721Semaste        Block *inlined_block = block->GetContainingInlinedBlock();
841254721Semaste        if (inlined_block)
842254721Semaste        {
843254721Semaste            if (inlined_block->GetStartAddress (start_addr))
844254721Semaste            {
845254721Semaste                if (start_addr.CalculateSymbolContextLineEntry (line_entry))
846254721Semaste                    return line_entry;
847254721Semaste            }
848254721Semaste            return LineEntry();
849254721Semaste        }
850254721Semaste    }
851254721Semaste
852254721Semaste    if (function)
853254721Semaste    {
854254721Semaste        if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry))
855254721Semaste            return line_entry;
856254721Semaste    }
857254721Semaste    return LineEntry();
858254721Semaste}
859254721Semaste
860254721Semaste//----------------------------------------------------------------------
861254721Semaste//
862254721Semaste//  SymbolContextSpecifier
863254721Semaste//
864254721Semaste//----------------------------------------------------------------------
865254721Semaste
866254721SemasteSymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
867254721Semaste    m_target_sp (target_sp),
868254721Semaste    m_module_spec (),
869254721Semaste    m_module_sp (),
870254721Semaste    m_file_spec_ap (),
871254721Semaste    m_start_line (0),
872254721Semaste    m_end_line (0),
873254721Semaste    m_function_spec (),
874254721Semaste    m_class_name (),
875254721Semaste    m_address_range_ap (),
876254721Semaste    m_type (eNothingSpecified)
877254721Semaste{
878254721Semaste}
879254721Semaste
880254721SemasteSymbolContextSpecifier::~SymbolContextSpecifier()
881254721Semaste{
882254721Semaste}
883254721Semaste
884254721Semastebool
885254721SemasteSymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
886254721Semaste{
887254721Semaste    bool return_value = true;
888254721Semaste    switch (type)
889254721Semaste    {
890254721Semaste    case eNothingSpecified:
891254721Semaste        Clear();
892254721Semaste        break;
893254721Semaste    case eLineStartSpecified:
894254721Semaste        m_start_line = line_no;
895254721Semaste        m_type |= eLineStartSpecified;
896254721Semaste        break;
897254721Semaste    case eLineEndSpecified:
898254721Semaste        m_end_line = line_no;
899254721Semaste        m_type |= eLineEndSpecified;
900254721Semaste        break;
901254721Semaste    default:
902254721Semaste        return_value = false;
903254721Semaste        break;
904254721Semaste    }
905254721Semaste    return return_value;
906254721Semaste}
907254721Semaste
908254721Semastebool
909254721SemasteSymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
910254721Semaste{
911254721Semaste    bool return_value = true;
912254721Semaste    switch (type)
913254721Semaste    {
914254721Semaste    case eNothingSpecified:
915254721Semaste        Clear();
916254721Semaste        break;
917254721Semaste    case eModuleSpecified:
918254721Semaste        {
919254721Semaste            // See if we can find the Module, if so stick it in the SymbolContext.
920254721Semaste            FileSpec module_file_spec(spec_string, false);
921254721Semaste            ModuleSpec module_spec (module_file_spec);
922254721Semaste            lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec));
923254721Semaste            m_type |= eModuleSpecified;
924254721Semaste            if (module_sp)
925254721Semaste                m_module_sp = module_sp;
926254721Semaste            else
927254721Semaste                m_module_spec.assign (spec_string);
928254721Semaste        }
929254721Semaste        break;
930254721Semaste    case eFileSpecified:
931254721Semaste        // CompUnits can't necessarily be resolved here, since an inlined function might show up in
932254721Semaste        // a number of CompUnits.  Instead we just convert to a FileSpec and store it away.
933254721Semaste        m_file_spec_ap.reset (new FileSpec (spec_string, false));
934254721Semaste        m_type |= eFileSpecified;
935254721Semaste        break;
936254721Semaste    case eLineStartSpecified:
937288943Sdim        m_start_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
938254721Semaste        if (return_value)
939254721Semaste            m_type |= eLineStartSpecified;
940254721Semaste        break;
941254721Semaste    case eLineEndSpecified:
942288943Sdim        m_end_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
943254721Semaste        if (return_value)
944254721Semaste            m_type |= eLineEndSpecified;
945254721Semaste        break;
946254721Semaste    case eFunctionSpecified:
947254721Semaste        m_function_spec.assign(spec_string);
948254721Semaste        m_type |= eFunctionSpecified;
949254721Semaste        break;
950254721Semaste    case eClassOrNamespaceSpecified:
951254721Semaste        Clear();
952254721Semaste        m_class_name.assign (spec_string);
953254721Semaste        m_type = eClassOrNamespaceSpecified;
954254721Semaste        break;
955254721Semaste    case eAddressRangeSpecified:
956254721Semaste        // Not specified yet...
957254721Semaste        break;
958254721Semaste    }
959254721Semaste
960254721Semaste    return return_value;
961254721Semaste}
962254721Semaste
963254721Semastevoid
964254721SemasteSymbolContextSpecifier::Clear()
965254721Semaste{
966254721Semaste    m_module_spec.clear();
967254721Semaste    m_file_spec_ap.reset();
968254721Semaste    m_function_spec.clear();
969254721Semaste    m_class_name.clear();
970254721Semaste    m_start_line = 0;
971254721Semaste    m_end_line = 0;
972254721Semaste    m_address_range_ap.reset();
973254721Semaste
974254721Semaste    m_type = eNothingSpecified;
975254721Semaste}
976254721Semaste
977254721Semastebool
978254721SemasteSymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
979254721Semaste{
980254721Semaste    if (m_type == eNothingSpecified)
981254721Semaste        return true;
982254721Semaste
983254721Semaste    if (m_target_sp.get() != sc.target_sp.get())
984254721Semaste        return false;
985254721Semaste
986254721Semaste    if (m_type & eModuleSpecified)
987254721Semaste    {
988254721Semaste        if (sc.module_sp)
989254721Semaste        {
990276479Sdim            if (m_module_sp.get() != nullptr)
991254721Semaste            {
992254721Semaste                if (m_module_sp.get() != sc.module_sp.get())
993254721Semaste                    return false;
994254721Semaste            }
995254721Semaste            else
996254721Semaste            {
997254721Semaste                FileSpec module_file_spec (m_module_spec.c_str(), false);
998254721Semaste                if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
999254721Semaste                    return false;
1000254721Semaste            }
1001254721Semaste        }
1002254721Semaste    }
1003254721Semaste    if (m_type & eFileSpecified)
1004254721Semaste    {
1005254721Semaste        if (m_file_spec_ap.get())
1006254721Semaste        {
1007254721Semaste            // If we don't have a block or a comp_unit, then we aren't going to match a source file.
1008276479Sdim            if (sc.block == nullptr && sc.comp_unit == nullptr)
1009254721Semaste                return false;
1010254721Semaste
1011254721Semaste            // Check if the block is present, and if so is it inlined:
1012254721Semaste            bool was_inlined = false;
1013276479Sdim            if (sc.block != nullptr)
1014254721Semaste            {
1015254721Semaste                const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
1016276479Sdim                if (inline_info != nullptr)
1017254721Semaste                {
1018254721Semaste                    was_inlined = true;
1019254721Semaste                    if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
1020254721Semaste                        return false;
1021254721Semaste                }
1022254721Semaste            }
1023254721Semaste
1024254721Semaste            // Next check the comp unit, but only if the SymbolContext was not inlined.
1025276479Sdim            if (!was_inlined && sc.comp_unit != nullptr)
1026254721Semaste            {
1027254721Semaste                if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
1028254721Semaste                    return false;
1029254721Semaste            }
1030254721Semaste        }
1031254721Semaste    }
1032254721Semaste    if (m_type & eLineStartSpecified
1033254721Semaste        || m_type & eLineEndSpecified)
1034254721Semaste    {
1035254721Semaste        if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
1036254721Semaste            return false;
1037254721Semaste    }
1038254721Semaste
1039254721Semaste    if (m_type & eFunctionSpecified)
1040254721Semaste    {
1041254721Semaste        // First check the current block, and if it is inlined, get the inlined function name:
1042254721Semaste        bool was_inlined = false;
1043254721Semaste        ConstString func_name(m_function_spec.c_str());
1044254721Semaste
1045276479Sdim        if (sc.block != nullptr)
1046254721Semaste        {
1047254721Semaste            const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
1048276479Sdim            if (inline_info != nullptr)
1049254721Semaste            {
1050254721Semaste                was_inlined = true;
1051254721Semaste                const Mangled &name = inline_info->GetMangled();
1052288943Sdim                if (!name.NameMatches (func_name, sc.function->GetLanguage()))
1053254721Semaste                    return false;
1054254721Semaste            }
1055254721Semaste        }
1056254721Semaste        //  If it wasn't inlined, check the name in the function or symbol:
1057254721Semaste        if (!was_inlined)
1058254721Semaste        {
1059276479Sdim            if (sc.function != nullptr)
1060254721Semaste            {
1061288943Sdim                if (!sc.function->GetMangled().NameMatches(func_name, sc.function->GetLanguage()))
1062254721Semaste                    return false;
1063254721Semaste            }
1064276479Sdim            else if (sc.symbol != nullptr)
1065254721Semaste            {
1066296417Sdim                if (!sc.symbol->GetMangled().NameMatches(func_name, sc.symbol->GetLanguage()))
1067254721Semaste                    return false;
1068254721Semaste            }
1069254721Semaste        }
1070254721Semaste
1071254721Semaste
1072254721Semaste    }
1073254721Semaste
1074254721Semaste    return true;
1075254721Semaste}
1076254721Semaste
1077254721Semastebool
1078254721SemasteSymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
1079254721Semaste{
1080254721Semaste    if (m_type & eAddressRangeSpecified)
1081254721Semaste    {
1082254721Semaste
1083254721Semaste    }
1084254721Semaste    else
1085254721Semaste    {
1086276479Sdim        Address match_address (addr, nullptr);
1087254721Semaste        SymbolContext sc;
1088254721Semaste        m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
1089254721Semaste        return SymbolContextMatches(sc);
1090254721Semaste    }
1091254721Semaste    return true;
1092254721Semaste}
1093254721Semaste
1094254721Semastevoid
1095254721SemasteSymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
1096254721Semaste{
1097254721Semaste    char path_str[PATH_MAX + 1];
1098254721Semaste
1099254721Semaste    if (m_type == eNothingSpecified)
1100254721Semaste    {
1101254721Semaste        s->Printf ("Nothing specified.\n");
1102254721Semaste    }
1103254721Semaste
1104254721Semaste    if (m_type == eModuleSpecified)
1105254721Semaste    {
1106254721Semaste        s->Indent();
1107254721Semaste        if (m_module_sp)
1108254721Semaste        {
1109254721Semaste            m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
1110254721Semaste            s->Printf ("Module: %s\n", path_str);
1111254721Semaste        }
1112254721Semaste        else
1113254721Semaste            s->Printf ("Module: %s\n", m_module_spec.c_str());
1114254721Semaste    }
1115254721Semaste
1116276479Sdim    if (m_type == eFileSpecified  && m_file_spec_ap.get() != nullptr)
1117254721Semaste    {
1118254721Semaste        m_file_spec_ap->GetPath (path_str, PATH_MAX);
1119254721Semaste        s->Indent();
1120254721Semaste        s->Printf ("File: %s", path_str);
1121254721Semaste        if (m_type == eLineStartSpecified)
1122254721Semaste        {
1123276479Sdim            s->Printf (" from line %" PRIu64 "", (uint64_t)m_start_line);
1124254721Semaste            if (m_type == eLineEndSpecified)
1125276479Sdim                s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
1126254721Semaste            else
1127254721Semaste                s->Printf ("to end");
1128254721Semaste        }
1129254721Semaste        else if (m_type == eLineEndSpecified)
1130254721Semaste        {
1131276479Sdim            s->Printf (" from start to line %" PRIu64 "", (uint64_t)m_end_line);
1132254721Semaste        }
1133254721Semaste        s->Printf (".\n");
1134254721Semaste    }
1135254721Semaste
1136254721Semaste    if (m_type == eLineStartSpecified)
1137254721Semaste    {
1138254721Semaste        s->Indent();
1139276479Sdim        s->Printf ("From line %" PRIu64 "", (uint64_t)m_start_line);
1140254721Semaste        if (m_type == eLineEndSpecified)
1141276479Sdim            s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
1142254721Semaste        else
1143254721Semaste            s->Printf ("to end");
1144254721Semaste        s->Printf (".\n");
1145254721Semaste    }
1146254721Semaste    else if (m_type == eLineEndSpecified)
1147254721Semaste    {
1148276479Sdim        s->Printf ("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
1149254721Semaste    }
1150254721Semaste
1151254721Semaste    if (m_type == eFunctionSpecified)
1152254721Semaste    {
1153254721Semaste        s->Indent();
1154254721Semaste        s->Printf ("Function: %s.\n", m_function_spec.c_str());
1155254721Semaste    }
1156254721Semaste
1157254721Semaste    if (m_type == eClassOrNamespaceSpecified)
1158254721Semaste    {
1159254721Semaste        s->Indent();
1160254721Semaste        s->Printf ("Class name: %s.\n", m_class_name.c_str());
1161254721Semaste    }
1162254721Semaste
1163276479Sdim    if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != nullptr)
1164254721Semaste    {
1165254721Semaste        s->Indent();
1166254721Semaste        s->PutCString ("Address range: ");
1167254721Semaste        m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
1168254721Semaste        s->PutCString ("\n");
1169254721Semaste    }
1170254721Semaste}
1171254721Semaste
1172254721Semaste//----------------------------------------------------------------------
1173254721Semaste//
1174254721Semaste//  SymbolContextList
1175254721Semaste//
1176254721Semaste//----------------------------------------------------------------------
1177254721Semaste
1178254721Semaste
1179254721SemasteSymbolContextList::SymbolContextList() :
1180254721Semaste    m_symbol_contexts()
1181254721Semaste{
1182254721Semaste}
1183254721Semaste
1184254721SemasteSymbolContextList::~SymbolContextList()
1185254721Semaste{
1186254721Semaste}
1187254721Semaste
1188254721Semastevoid
1189254721SemasteSymbolContextList::Append(const SymbolContext& sc)
1190254721Semaste{
1191254721Semaste    m_symbol_contexts.push_back(sc);
1192254721Semaste}
1193254721Semaste
1194254721Semastevoid
1195254721SemasteSymbolContextList::Append (const SymbolContextList& sc_list)
1196254721Semaste{
1197254721Semaste    collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1198254721Semaste    for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
1199254721Semaste        m_symbol_contexts.push_back (*pos);
1200254721Semaste}
1201254721Semaste
1202254721Semaste
1203254721Semasteuint32_t
1204254721SemasteSymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function)
1205254721Semaste{
1206254721Semaste    uint32_t unique_sc_add_count = 0;
1207254721Semaste    collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1208254721Semaste    for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
1209254721Semaste    {
1210254721Semaste        if (AppendIfUnique (*pos, merge_symbol_into_function))
1211254721Semaste            ++unique_sc_add_count;
1212254721Semaste    }
1213254721Semaste    return unique_sc_add_count;
1214254721Semaste}
1215254721Semaste
1216254721Semastebool
1217254721SemasteSymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
1218254721Semaste{
1219254721Semaste    collection::iterator pos, end = m_symbol_contexts.end();
1220254721Semaste    for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1221254721Semaste    {
1222254721Semaste        if (*pos == sc)
1223254721Semaste            return false;
1224254721Semaste    }
1225254721Semaste    if (merge_symbol_into_function
1226276479Sdim        && sc.symbol    != nullptr
1227276479Sdim        && sc.comp_unit == nullptr
1228276479Sdim        && sc.function  == nullptr
1229276479Sdim        && sc.block     == nullptr
1230254721Semaste        && sc.line_entry.IsValid() == false)
1231254721Semaste    {
1232254721Semaste        if (sc.symbol->ValueIsAddress())
1233254721Semaste        {
1234254721Semaste            for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1235254721Semaste            {
1236254721Semaste                // Don't merge symbols into inlined function symbol contexts
1237254721Semaste                if (pos->block && pos->block->GetContainingInlinedBlock())
1238254721Semaste                    continue;
1239254721Semaste
1240254721Semaste                if (pos->function)
1241254721Semaste                {
1242288943Sdim                    if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddressRef())
1243254721Semaste                    {
1244254721Semaste                        // Do we already have a function with this symbol?
1245254721Semaste                        if (pos->symbol == sc.symbol)
1246254721Semaste                            return false;
1247276479Sdim                        if (pos->symbol == nullptr)
1248254721Semaste                        {
1249254721Semaste                            pos->symbol = sc.symbol;
1250254721Semaste                            return false;
1251254721Semaste                        }
1252254721Semaste                    }
1253254721Semaste                }
1254254721Semaste            }
1255254721Semaste        }
1256254721Semaste    }
1257254721Semaste    m_symbol_contexts.push_back(sc);
1258254721Semaste    return true;
1259254721Semaste}
1260254721Semaste
1261254721Semastebool
1262254721SemasteSymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
1263254721Semaste                                                          uint32_t start_idx,
1264254721Semaste                                                          uint32_t stop_idx)
1265254721Semaste{
1266276479Sdim    if (symbol_sc.symbol    != nullptr
1267276479Sdim        && symbol_sc.comp_unit == nullptr
1268276479Sdim        && symbol_sc.function  == nullptr
1269276479Sdim        && symbol_sc.block     == nullptr
1270254721Semaste        && symbol_sc.line_entry.IsValid() == false)
1271254721Semaste    {
1272254721Semaste        if (symbol_sc.symbol->ValueIsAddress())
1273254721Semaste        {
1274254721Semaste            const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx);
1275254721Semaste            for (size_t i=start_idx; i<end; ++i)
1276254721Semaste            {
1277254721Semaste                const SymbolContext &function_sc = m_symbol_contexts[i];
1278254721Semaste                // Don't merge symbols into inlined function symbol contexts
1279254721Semaste                if (function_sc.block && function_sc.block->GetContainingInlinedBlock())
1280254721Semaste                    continue;
1281254721Semaste
1282254721Semaste                if (function_sc.function)
1283254721Semaste                {
1284288943Sdim                    if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
1285254721Semaste                    {
1286254721Semaste                        // Do we already have a function with this symbol?
1287254721Semaste                        if (function_sc.symbol == symbol_sc.symbol)
1288254721Semaste                            return true; // Already have a symbol context with this symbol, return true
1289254721Semaste
1290276479Sdim                        if (function_sc.symbol == nullptr)
1291254721Semaste                        {
1292254721Semaste                            // We successfully merged this symbol into an existing symbol context
1293254721Semaste                            m_symbol_contexts[i].symbol = symbol_sc.symbol;
1294254721Semaste                            return true;
1295254721Semaste                        }
1296254721Semaste                    }
1297254721Semaste                }
1298254721Semaste            }
1299254721Semaste        }
1300254721Semaste    }
1301254721Semaste    return false;
1302254721Semaste}
1303254721Semaste
1304254721Semastevoid
1305254721SemasteSymbolContextList::Clear()
1306254721Semaste{
1307254721Semaste    m_symbol_contexts.clear();
1308254721Semaste}
1309254721Semaste
1310254721Semastevoid
1311254721SemasteSymbolContextList::Dump(Stream *s, Target *target) const
1312254721Semaste{
1313254721Semaste
1314296417Sdim    *s << this << ": ";
1315254721Semaste    s->Indent();
1316254721Semaste    s->PutCString("SymbolContextList");
1317254721Semaste    s->EOL();
1318254721Semaste    s->IndentMore();
1319254721Semaste
1320254721Semaste    collection::const_iterator pos, end = m_symbol_contexts.end();
1321254721Semaste    for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1322254721Semaste    {
1323254721Semaste        //pos->Dump(s, target);
1324254721Semaste        pos->GetDescription(s, eDescriptionLevelVerbose, target);
1325254721Semaste    }
1326254721Semaste    s->IndentLess();
1327254721Semaste}
1328254721Semaste
1329254721Semastebool
1330254721SemasteSymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const
1331254721Semaste{
1332254721Semaste    if (idx < m_symbol_contexts.size())
1333254721Semaste    {
1334254721Semaste        sc = m_symbol_contexts[idx];
1335254721Semaste        return true;
1336254721Semaste    }
1337254721Semaste    return false;
1338254721Semaste}
1339254721Semaste
1340254721Semastebool
1341254721SemasteSymbolContextList::GetLastContext(SymbolContext& sc) const
1342254721Semaste{
1343254721Semaste    if (!m_symbol_contexts.empty())
1344254721Semaste    {
1345254721Semaste        sc = m_symbol_contexts.back();
1346254721Semaste        return true;
1347254721Semaste    }
1348254721Semaste    return false;
1349254721Semaste}
1350254721Semaste
1351254721Semastebool
1352254721SemasteSymbolContextList::RemoveContextAtIndex (size_t idx)
1353254721Semaste{
1354254721Semaste    if (idx < m_symbol_contexts.size())
1355254721Semaste    {
1356254721Semaste        m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1357254721Semaste        return true;
1358254721Semaste    }
1359254721Semaste    return false;
1360254721Semaste}
1361254721Semaste
1362254721Semasteuint32_t
1363254721SemasteSymbolContextList::GetSize() const
1364254721Semaste{
1365254721Semaste    return m_symbol_contexts.size();
1366254721Semaste}
1367254721Semaste
1368254721Semasteuint32_t
1369254721SemasteSymbolContextList::NumLineEntriesWithLine (uint32_t line) const
1370254721Semaste{
1371254721Semaste    uint32_t match_count = 0;
1372254721Semaste    const size_t size = m_symbol_contexts.size();
1373254721Semaste    for (size_t idx = 0; idx<size; ++idx)
1374254721Semaste    {
1375254721Semaste        if (m_symbol_contexts[idx].line_entry.line == line)
1376254721Semaste            ++match_count;
1377254721Semaste    }
1378254721Semaste    return match_count;
1379254721Semaste}
1380254721Semaste
1381254721Semastevoid
1382254721SemasteSymbolContextList::GetDescription(Stream *s,
1383254721Semaste                                  lldb::DescriptionLevel level,
1384254721Semaste                                  Target *target) const
1385254721Semaste{
1386254721Semaste    const size_t size = m_symbol_contexts.size();
1387254721Semaste    for (size_t idx = 0; idx<size; ++idx)
1388254721Semaste        m_symbol_contexts[idx].GetDescription (s, level, target);
1389254721Semaste}
1390254721Semaste
1391254721Semastebool
1392254721Semastelldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs)
1393254721Semaste{
1394254721Semaste    const uint32_t size = lhs.GetSize();
1395254721Semaste    if (size != rhs.GetSize())
1396254721Semaste        return false;
1397254721Semaste
1398254721Semaste    SymbolContext lhs_sc;
1399254721Semaste    SymbolContext rhs_sc;
1400254721Semaste    for (uint32_t i=0; i<size; ++i)
1401254721Semaste    {
1402254721Semaste        lhs.GetContextAtIndex(i, lhs_sc);
1403254721Semaste        rhs.GetContextAtIndex(i, rhs_sc);
1404254721Semaste        if (lhs_sc != rhs_sc)
1405254721Semaste            return false;
1406254721Semaste    }
1407254721Semaste    return true;
1408254721Semaste}
1409254721Semaste
1410254721Semastebool
1411254721Semastelldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs)
1412254721Semaste{
1413254721Semaste    return !(lhs == rhs);
1414254721Semaste}
1415254721Semaste
1416