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"
16254721Semaste#include "lldb/Interpreter/Args.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"
24254721Semaste#include "lldb/Target/Target.h"
25254721Semaste
26254721Semasteusing namespace lldb;
27254721Semasteusing namespace lldb_private;
28254721Semaste
29254721SemasteSymbolContext::SymbolContext() :
30254721Semaste    target_sp   (),
31254721Semaste    module_sp   (),
32254721Semaste    comp_unit   (NULL),
33254721Semaste    function    (NULL),
34254721Semaste    block       (NULL),
35254721Semaste    line_entry  (),
36254721Semaste    symbol      (NULL)
37254721Semaste{
38254721Semaste}
39254721Semaste
40254721SemasteSymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
41254721Semaste    target_sp   (),
42254721Semaste    module_sp   (m),
43254721Semaste    comp_unit   (cu),
44254721Semaste    function    (f),
45254721Semaste    block       (b),
46254721Semaste    line_entry  (),
47254721Semaste    symbol      (s)
48254721Semaste{
49254721Semaste    if (le)
50254721Semaste        line_entry = *le;
51254721Semaste}
52254721Semaste
53254721SemasteSymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
54254721Semaste    target_sp   (t),
55254721Semaste    module_sp   (m),
56254721Semaste    comp_unit   (cu),
57254721Semaste    function    (f),
58254721Semaste    block       (b),
59254721Semaste    line_entry  (),
60254721Semaste    symbol      (s)
61254721Semaste{
62254721Semaste    if (le)
63254721Semaste        line_entry = *le;
64254721Semaste}
65254721Semaste
66254721SemasteSymbolContext::SymbolContext(const SymbolContext& rhs) :
67254721Semaste    target_sp   (rhs.target_sp),
68254721Semaste    module_sp   (rhs.module_sp),
69254721Semaste    comp_unit   (rhs.comp_unit),
70254721Semaste    function    (rhs.function),
71254721Semaste    block       (rhs.block),
72254721Semaste    line_entry  (rhs.line_entry),
73254721Semaste    symbol      (rhs.symbol)
74254721Semaste{
75254721Semaste}
76254721Semaste
77254721Semaste
78254721SemasteSymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
79254721Semaste    target_sp   (),
80254721Semaste    module_sp   (),
81254721Semaste    comp_unit   (NULL),
82254721Semaste    function    (NULL),
83254721Semaste    block       (NULL),
84254721Semaste    line_entry  (),
85254721Semaste    symbol      (NULL)
86254721Semaste{
87254721Semaste    sc_scope->CalculateSymbolContext (this);
88254721Semaste}
89254721Semaste
90254721SemasteSymbolContext::~SymbolContext ()
91254721Semaste{
92254721Semaste}
93254721Semaste
94254721Semasteconst SymbolContext&
95254721SemasteSymbolContext::operator= (const SymbolContext& rhs)
96254721Semaste{
97254721Semaste    if (this != &rhs)
98254721Semaste    {
99254721Semaste        target_sp   = rhs.target_sp;
100254721Semaste        module_sp   = rhs.module_sp;
101254721Semaste        comp_unit   = rhs.comp_unit;
102254721Semaste        function    = rhs.function;
103254721Semaste        block       = rhs.block;
104254721Semaste        line_entry  = rhs.line_entry;
105254721Semaste        symbol      = rhs.symbol;
106254721Semaste    }
107254721Semaste    return *this;
108254721Semaste}
109254721Semaste
110254721Semastevoid
111254721SemasteSymbolContext::Clear(bool clear_target)
112254721Semaste{
113254721Semaste    if (clear_target)
114254721Semaste        target_sp.reset();
115254721Semaste    module_sp.reset();
116254721Semaste    comp_unit   = NULL;
117254721Semaste    function    = NULL;
118254721Semaste    block       = NULL;
119254721Semaste    line_entry.Clear();
120254721Semaste    symbol      = NULL;
121254721Semaste}
122254721Semaste
123254721Semastebool
124254721SemasteSymbolContext::DumpStopContext
125254721Semaste(
126254721Semaste    Stream *s,
127254721Semaste    ExecutionContextScope *exe_scope,
128254721Semaste    const Address &addr,
129254721Semaste    bool show_fullpaths,
130254721Semaste    bool show_module,
131254721Semaste    bool show_inlined_frames
132254721Semaste) const
133254721Semaste{
134254721Semaste    bool dumped_something = false;
135254721Semaste    if (show_module && module_sp)
136254721Semaste    {
137254721Semaste        if (show_fullpaths)
138254721Semaste            *s << module_sp->GetFileSpec();
139254721Semaste        else
140254721Semaste            *s << module_sp->GetFileSpec().GetFilename();
141254721Semaste        s->PutChar('`');
142254721Semaste        dumped_something = true;
143254721Semaste    }
144254721Semaste
145254721Semaste    if (function != NULL)
146254721Semaste    {
147254721Semaste        SymbolContext inline_parent_sc;
148254721Semaste        Address inline_parent_addr;
149254721Semaste        if (function->GetMangled().GetName())
150254721Semaste        {
151254721Semaste            dumped_something = true;
152254721Semaste            function->GetMangled().GetName().Dump(s);
153254721Semaste        }
154254721Semaste
155254721Semaste        if (addr.IsValid())
156254721Semaste        {
157254721Semaste            const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
158254721Semaste            if (function_offset)
159254721Semaste            {
160254721Semaste                dumped_something = true;
161254721Semaste                s->Printf(" + %" PRIu64, function_offset);
162254721Semaste            }
163254721Semaste        }
164254721Semaste
165254721Semaste        if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr))
166254721Semaste        {
167254721Semaste            dumped_something = true;
168254721Semaste            Block *inlined_block = block->GetContainingInlinedBlock();
169254721Semaste            const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo();
170254721Semaste            s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString());
171254721Semaste
172254721Semaste            lldb_private::AddressRange block_range;
173254721Semaste            if (inlined_block->GetRangeContainingAddress(addr, block_range))
174254721Semaste            {
175254721Semaste                const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
176254721Semaste                if (inlined_function_offset)
177254721Semaste                {
178254721Semaste                    s->Printf(" + %" PRIu64, inlined_function_offset);
179254721Semaste                }
180254721Semaste            }
181254721Semaste            const Declaration &call_site = inlined_block_info->GetCallSite();
182254721Semaste            if (call_site.IsValid())
183254721Semaste            {
184254721Semaste                s->PutCString(" at ");
185254721Semaste                call_site.DumpStopContext (s, show_fullpaths);
186254721Semaste            }
187254721Semaste            if (show_inlined_frames)
188254721Semaste            {
189254721Semaste                s->EOL();
190254721Semaste                s->Indent();
191254721Semaste                return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames);
192254721Semaste            }
193254721Semaste        }
194254721Semaste        else
195254721Semaste        {
196254721Semaste            if (line_entry.IsValid())
197254721Semaste            {
198254721Semaste                dumped_something = true;
199254721Semaste                s->PutCString(" at ");
200254721Semaste                if (line_entry.DumpStopContext(s, show_fullpaths))
201254721Semaste                    dumped_something = true;
202254721Semaste            }
203254721Semaste        }
204254721Semaste    }
205254721Semaste    else if (symbol != NULL)
206254721Semaste    {
207254721Semaste        if (symbol->GetMangled().GetName())
208254721Semaste        {
209254721Semaste            dumped_something = true;
210254721Semaste            if (symbol->GetType() == eSymbolTypeTrampoline)
211254721Semaste                s->PutCString("symbol stub for: ");
212254721Semaste            symbol->GetMangled().GetName().Dump(s);
213254721Semaste        }
214254721Semaste
215254721Semaste        if (addr.IsValid() && symbol->ValueIsAddress())
216254721Semaste        {
217254721Semaste            const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset();
218254721Semaste            if (symbol_offset)
219254721Semaste            {
220254721Semaste                dumped_something = true;
221254721Semaste                s->Printf(" + %" PRIu64, symbol_offset);
222254721Semaste            }
223254721Semaste        }
224254721Semaste    }
225254721Semaste    else if (addr.IsValid())
226254721Semaste    {
227254721Semaste        addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
228254721Semaste        dumped_something = true;
229254721Semaste    }
230254721Semaste    return dumped_something;
231254721Semaste}
232254721Semaste
233254721Semastevoid
234254721SemasteSymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
235254721Semaste{
236254721Semaste    if (module_sp)
237254721Semaste    {
238254721Semaste        s->Indent("     Module: file = \"");
239254721Semaste        module_sp->GetFileSpec().Dump(s);
240254721Semaste        *s << '"';
241254721Semaste        if (module_sp->GetArchitecture().IsValid())
242254721Semaste            s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
243254721Semaste        s->EOL();
244254721Semaste    }
245254721Semaste
246254721Semaste    if (comp_unit != NULL)
247254721Semaste    {
248254721Semaste        s->Indent("CompileUnit: ");
249254721Semaste        comp_unit->GetDescription (s, level);
250254721Semaste        s->EOL();
251254721Semaste    }
252254721Semaste
253254721Semaste    if (function != NULL)
254254721Semaste    {
255254721Semaste        s->Indent("   Function: ");
256254721Semaste        function->GetDescription (s, level, target);
257254721Semaste        s->EOL();
258254721Semaste
259254721Semaste        Type *func_type = function->GetType();
260254721Semaste        if (func_type)
261254721Semaste        {
262254721Semaste            s->Indent("   FuncType: ");
263254721Semaste            func_type->GetDescription (s, level, false);
264254721Semaste            s->EOL();
265254721Semaste        }
266254721Semaste    }
267254721Semaste
268254721Semaste    if (block != NULL)
269254721Semaste    {
270254721Semaste        std::vector<Block *> blocks;
271254721Semaste        blocks.push_back (block);
272254721Semaste        Block *parent_block = block->GetParent();
273254721Semaste
274254721Semaste        while (parent_block)
275254721Semaste        {
276254721Semaste            blocks.push_back (parent_block);
277254721Semaste            parent_block = parent_block->GetParent();
278254721Semaste        }
279254721Semaste        std::vector<Block *>::reverse_iterator pos;
280254721Semaste        std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
281254721Semaste        std::vector<Block *>::reverse_iterator end = blocks.rend();
282254721Semaste        for (pos = begin; pos != end; ++pos)
283254721Semaste        {
284254721Semaste            if (pos == begin)
285254721Semaste                s->Indent("     Blocks: ");
286254721Semaste            else
287254721Semaste                s->Indent("             ");
288254721Semaste            (*pos)->GetDescription(s, function, level, target);
289254721Semaste            s->EOL();
290254721Semaste        }
291254721Semaste    }
292254721Semaste
293254721Semaste    if (line_entry.IsValid())
294254721Semaste    {
295254721Semaste        s->Indent("  LineEntry: ");
296254721Semaste        line_entry.GetDescription (s, level, comp_unit, target, false);
297254721Semaste        s->EOL();
298254721Semaste    }
299254721Semaste
300254721Semaste    if (symbol != NULL)
301254721Semaste    {
302254721Semaste        s->Indent("     Symbol: ");
303254721Semaste        symbol->GetDescription(s, level, target);
304254721Semaste        s->EOL();
305254721Semaste    }
306254721Semaste}
307254721Semaste
308254721Semasteuint32_t
309254721SemasteSymbolContext::GetResolvedMask () const
310254721Semaste{
311254721Semaste    uint32_t resolved_mask = 0;
312254721Semaste    if (target_sp)              resolved_mask |= eSymbolContextTarget;
313254721Semaste    if (module_sp)              resolved_mask |= eSymbolContextModule;
314254721Semaste    if (comp_unit)              resolved_mask |= eSymbolContextCompUnit;
315254721Semaste    if (function)               resolved_mask |= eSymbolContextFunction;
316254721Semaste    if (block)                  resolved_mask |= eSymbolContextBlock;
317254721Semaste    if (line_entry.IsValid())   resolved_mask |= eSymbolContextLineEntry;
318254721Semaste    if (symbol)                 resolved_mask |= eSymbolContextSymbol;
319254721Semaste    return resolved_mask;
320254721Semaste}
321254721Semaste
322254721Semastevoid
323254721SemasteSymbolContext::Dump(Stream *s, Target *target) const
324254721Semaste{
325254721Semaste    *s << (void *)this << ": ";
326254721Semaste    s->Indent();
327254721Semaste    s->PutCString("SymbolContext");
328254721Semaste    s->IndentMore();
329254721Semaste    s->EOL();
330254721Semaste    s->IndentMore();
331254721Semaste    s->Indent();
332254721Semaste    *s << "Module       = " << (void *)module_sp.get() << ' ';
333254721Semaste    if (module_sp)
334254721Semaste        module_sp->GetFileSpec().Dump(s);
335254721Semaste    s->EOL();
336254721Semaste    s->Indent();
337254721Semaste    *s << "CompileUnit  = " << (void *)comp_unit;
338254721Semaste    if (comp_unit != NULL)
339254721Semaste        *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
340254721Semaste    s->EOL();
341254721Semaste    s->Indent();
342254721Semaste    *s << "Function     = " << (void *)function;
343254721Semaste    if (function != NULL)
344254721Semaste    {
345254721Semaste        *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
346254721Semaste        function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
347254721Semaste        s->EOL();
348254721Semaste        s->Indent();
349254721Semaste        Type* func_type = function->GetType();
350254721Semaste        if (func_type)
351254721Semaste        {
352254721Semaste            *s << "        Type = ";
353254721Semaste            func_type->Dump (s, false);
354254721Semaste        }
355254721Semaste    }
356254721Semaste    s->EOL();
357254721Semaste    s->Indent();
358254721Semaste    *s << "Block        = " << (void *)block;
359254721Semaste    if (block != NULL)
360254721Semaste        *s << " {0x" << block->GetID() << '}';
361254721Semaste    // Dump the block and pass it a negative depth to we print all the parent blocks
362254721Semaste    //if (block != NULL)
363254721Semaste    //  block->Dump(s, function->GetFileAddress(), INT_MIN);
364254721Semaste    s->EOL();
365254721Semaste    s->Indent();
366254721Semaste    *s << "LineEntry    = ";
367254721Semaste    line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
368254721Semaste    s->EOL();
369254721Semaste    s->Indent();
370254721Semaste    *s << "Symbol       = " << (void *)symbol;
371254721Semaste    if (symbol != NULL && symbol->GetMangled())
372254721Semaste        *s << ' ' << symbol->GetMangled().GetName().AsCString();
373254721Semaste    s->EOL();
374254721Semaste    s->IndentLess();
375254721Semaste    s->IndentLess();
376254721Semaste}
377254721Semaste
378254721Semastebool
379254721Semastelldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
380254721Semaste{
381254721Semaste    return  lhs.function == rhs.function
382254721Semaste            && lhs.symbol == rhs.symbol
383254721Semaste            && lhs.module_sp.get() == rhs.module_sp.get()
384254721Semaste            && lhs.comp_unit == rhs.comp_unit
385254721Semaste            && lhs.target_sp.get() == rhs.target_sp.get()
386254721Semaste            && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
387254721Semaste}
388254721Semaste
389254721Semastebool
390254721Semastelldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
391254721Semaste{
392254721Semaste    return  lhs.function != rhs.function
393254721Semaste            || lhs.symbol != rhs.symbol
394254721Semaste            || lhs.module_sp.get() != rhs.module_sp.get()
395254721Semaste            || lhs.comp_unit != rhs.comp_unit
396254721Semaste            || lhs.target_sp.get() != rhs.target_sp.get()
397254721Semaste            || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
398254721Semaste}
399254721Semaste
400254721Semastebool
401254721SemasteSymbolContext::GetAddressRange (uint32_t scope,
402254721Semaste                                uint32_t range_idx,
403254721Semaste                                bool use_inline_block_range,
404254721Semaste                                AddressRange &range) const
405254721Semaste{
406254721Semaste    if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
407254721Semaste    {
408254721Semaste        range = line_entry.range;
409254721Semaste        return true;
410254721Semaste    }
411254721Semaste
412254721Semaste    if ((scope & eSymbolContextBlock) && (block != NULL))
413254721Semaste    {
414254721Semaste        if (use_inline_block_range)
415254721Semaste        {
416254721Semaste            Block *inline_block = block->GetContainingInlinedBlock();
417254721Semaste            if (inline_block)
418254721Semaste                return inline_block->GetRangeAtIndex (range_idx, range);
419254721Semaste        }
420254721Semaste        else
421254721Semaste        {
422254721Semaste            return block->GetRangeAtIndex (range_idx, range);
423254721Semaste        }
424254721Semaste    }
425254721Semaste
426254721Semaste    if ((scope & eSymbolContextFunction) && (function != NULL))
427254721Semaste    {
428254721Semaste        if (range_idx == 0)
429254721Semaste        {
430254721Semaste            range = function->GetAddressRange();
431254721Semaste            return true;
432254721Semaste        }
433254721Semaste    }
434254721Semaste
435254721Semaste    if ((scope & eSymbolContextSymbol) && (symbol != NULL))
436254721Semaste    {
437254721Semaste        if (range_idx == 0)
438254721Semaste        {
439254721Semaste            if (symbol->ValueIsAddress())
440254721Semaste            {
441254721Semaste                range.GetBaseAddress() = symbol->GetAddress();
442254721Semaste                range.SetByteSize (symbol->GetByteSize());
443254721Semaste                return true;
444254721Semaste            }
445254721Semaste        }
446254721Semaste    }
447254721Semaste    range.Clear();
448254721Semaste    return false;
449254721Semaste}
450254721Semaste
451254721Semastebool
452254721SemasteSymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
453254721Semaste                                        SymbolContext &next_frame_sc,
454254721Semaste                                        Address &next_frame_pc) const
455254721Semaste{
456254721Semaste    next_frame_sc.Clear(false);
457254721Semaste    next_frame_pc.Clear();
458254721Semaste
459254721Semaste    if (block)
460254721Semaste    {
461254721Semaste        //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
462254721Semaste
463254721Semaste        // In order to get the parent of an inlined function we first need to
464254721Semaste        // see if we are in an inlined block as "this->block" could be an
465254721Semaste        // inlined block, or a parent of "block" could be. So lets check if
466254721Semaste        // this block or one of this blocks parents is an inlined function.
467254721Semaste        Block *curr_inlined_block = block->GetContainingInlinedBlock();
468254721Semaste        if (curr_inlined_block)
469254721Semaste        {
470254721Semaste            // "this->block" is contained in an inline function block, so to
471254721Semaste            // get the scope above the inlined block, we get the parent of the
472254721Semaste            // inlined block itself
473254721Semaste            Block *next_frame_block = curr_inlined_block->GetParent();
474254721Semaste            // Now calculate the symbol context of the containing block
475254721Semaste            next_frame_block->CalculateSymbolContext (&next_frame_sc);
476254721Semaste
477254721Semaste            // If we get here we weren't able to find the return line entry using the nesting of the blocks and
478254721Semaste            // the line table.  So just use the call site info from our inlined block.
479254721Semaste
480254721Semaste            AddressRange range;
481254721Semaste            if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
482254721Semaste            {
483254721Semaste                // To see there this new frame block it, we need to look at the
484254721Semaste                // call site information from
485254721Semaste                const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
486254721Semaste                next_frame_pc = range.GetBaseAddress();
487254721Semaste                next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
488254721Semaste                next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
489254721Semaste                next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
490254721Semaste                next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
491254721Semaste                return true;
492254721Semaste            }
493254721Semaste            else
494254721Semaste            {
495254721Semaste                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
496254721Semaste
497254721Semaste                if (log)
498254721Semaste                {
499254721Semaste                    log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
500254721Semaste                                 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
501254721Semaste                }
502254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG
503254721Semaste                else
504254721Semaste                {
505254721Semaste                    ObjectFile *objfile = NULL;
506254721Semaste                    if (module_sp)
507254721Semaste                    {
508254721Semaste                        SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
509254721Semaste                        if (symbol_vendor)
510254721Semaste                        {
511254721Semaste                            SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
512254721Semaste                            if (symbol_file)
513254721Semaste                                objfile = symbol_file->GetObjectFile();
514254721Semaste                        }
515254721Semaste                    }
516254721Semaste                    if (objfile)
517254721Semaste                    {
518254721Semaste                        Host::SystemLog (Host::eSystemLogWarning,
519254721Semaste                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n",
520254721Semaste                                         curr_inlined_block->GetID(),
521254721Semaste                                         curr_frame_pc.GetFileAddress(),
522254721Semaste                                         objfile->GetFileSpec().GetPath().c_str());
523254721Semaste                    }
524254721Semaste                    else
525254721Semaste                    {
526254721Semaste                        Host::SystemLog (Host::eSystemLogWarning,
527254721Semaste                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
528254721Semaste                                         curr_inlined_block->GetID(),
529254721Semaste                                         curr_frame_pc.GetFileAddress());
530254721Semaste                    }
531254721Semaste                }
532254721Semaste#endif
533254721Semaste            }
534254721Semaste        }
535254721Semaste    }
536254721Semaste
537254721Semaste    return false;
538254721Semaste}
539254721Semaste
540254721SemasteBlock *
541254721SemasteSymbolContext::GetFunctionBlock ()
542254721Semaste{
543254721Semaste    if (function)
544254721Semaste    {
545254721Semaste        if (block)
546254721Semaste        {
547254721Semaste            // If this symbol context has a block, check to see if this block
548254721Semaste            // is itself, or is contained within a block with inlined function
549254721Semaste            // information. If so, then the inlined block is the block that
550254721Semaste            // defines the function.
551254721Semaste            Block *inlined_block = block->GetContainingInlinedBlock();
552254721Semaste            if (inlined_block)
553254721Semaste                return inlined_block;
554254721Semaste
555254721Semaste            // The block in this symbol context is not inside an inlined
556254721Semaste            // block, so the block that defines the function is the function's
557254721Semaste            // top level block, which is returned below.
558254721Semaste        }
559254721Semaste
560254721Semaste        // There is no block information in this symbol context, so we must
561254721Semaste        // assume that the block that is desired is the top level block of
562254721Semaste        // the function itself.
563254721Semaste        return &function->GetBlock(true);
564254721Semaste    }
565254721Semaste    return NULL;
566254721Semaste}
567254721Semaste
568254721Semastebool
569254721SemasteSymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language,
570254721Semaste                                      bool &is_instance_method,
571254721Semaste                                      ConstString &language_object_name)
572254721Semaste
573254721Semaste
574254721Semaste{
575254721Semaste    Block *function_block = GetFunctionBlock ();
576254721Semaste    if (function_block)
577254721Semaste    {
578254721Semaste        clang::DeclContext *decl_context = function_block->GetClangDeclContext();
579254721Semaste
580254721Semaste        if (decl_context)
581254721Semaste        {
582254721Semaste            return ClangASTContext::GetClassMethodInfoForDeclContext (decl_context,
583254721Semaste                                                                      language,
584254721Semaste                                                                      is_instance_method,
585254721Semaste                                                                      language_object_name);
586254721Semaste        }
587254721Semaste    }
588254721Semaste    language = eLanguageTypeUnknown;
589254721Semaste    is_instance_method = false;
590254721Semaste    language_object_name.Clear();
591254721Semaste    return false;
592254721Semaste}
593254721Semaste
594254721SemasteConstString
595254721SemasteSymbolContext::GetFunctionName (Mangled::NamePreference preference) const
596254721Semaste{
597254721Semaste    if (function)
598254721Semaste    {
599254721Semaste        if (block)
600254721Semaste        {
601254721Semaste            Block *inlined_block = block->GetContainingInlinedBlock();
602254721Semaste
603254721Semaste            if (inlined_block)
604254721Semaste            {
605254721Semaste                const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo();
606254721Semaste                if (inline_info)
607254721Semaste                    return inline_info->GetName();
608254721Semaste            }
609254721Semaste        }
610254721Semaste        return function->GetMangled().GetName(preference);
611254721Semaste    }
612254721Semaste    else if (symbol && symbol->ValueIsAddress())
613254721Semaste    {
614254721Semaste        return symbol->GetMangled().GetName(preference);
615254721Semaste    }
616254721Semaste    else
617254721Semaste    {
618254721Semaste        // No function, return an empty string.
619254721Semaste        return ConstString();
620254721Semaste    }
621254721Semaste}
622254721Semaste
623254721SemasteLineEntry
624254721SemasteSymbolContext::GetFunctionStartLineEntry () const
625254721Semaste{
626254721Semaste    LineEntry line_entry;
627254721Semaste    Address start_addr;
628254721Semaste    if (block)
629254721Semaste    {
630254721Semaste        Block *inlined_block = block->GetContainingInlinedBlock();
631254721Semaste        if (inlined_block)
632254721Semaste        {
633254721Semaste            if (inlined_block->GetStartAddress (start_addr))
634254721Semaste            {
635254721Semaste                if (start_addr.CalculateSymbolContextLineEntry (line_entry))
636254721Semaste                    return line_entry;
637254721Semaste            }
638254721Semaste            return LineEntry();
639254721Semaste        }
640254721Semaste    }
641254721Semaste
642254721Semaste    if (function)
643254721Semaste    {
644254721Semaste        if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry))
645254721Semaste            return line_entry;
646254721Semaste    }
647254721Semaste    return LineEntry();
648254721Semaste}
649254721Semaste
650254721Semaste//----------------------------------------------------------------------
651254721Semaste//
652254721Semaste//  SymbolContextSpecifier
653254721Semaste//
654254721Semaste//----------------------------------------------------------------------
655254721Semaste
656254721SemasteSymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
657254721Semaste    m_target_sp (target_sp),
658254721Semaste    m_module_spec (),
659254721Semaste    m_module_sp (),
660254721Semaste    m_file_spec_ap (),
661254721Semaste    m_start_line (0),
662254721Semaste    m_end_line (0),
663254721Semaste    m_function_spec (),
664254721Semaste    m_class_name (),
665254721Semaste    m_address_range_ap (),
666254721Semaste    m_type (eNothingSpecified)
667254721Semaste{
668254721Semaste}
669254721Semaste
670254721SemasteSymbolContextSpecifier::~SymbolContextSpecifier()
671254721Semaste{
672254721Semaste}
673254721Semaste
674254721Semastebool
675254721SemasteSymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
676254721Semaste{
677254721Semaste    bool return_value = true;
678254721Semaste    switch (type)
679254721Semaste    {
680254721Semaste    case eNothingSpecified:
681254721Semaste        Clear();
682254721Semaste        break;
683254721Semaste    case eLineStartSpecified:
684254721Semaste        m_start_line = line_no;
685254721Semaste        m_type |= eLineStartSpecified;
686254721Semaste        break;
687254721Semaste    case eLineEndSpecified:
688254721Semaste        m_end_line = line_no;
689254721Semaste        m_type |= eLineEndSpecified;
690254721Semaste        break;
691254721Semaste    default:
692254721Semaste        return_value = false;
693254721Semaste        break;
694254721Semaste    }
695254721Semaste    return return_value;
696254721Semaste}
697254721Semaste
698254721Semastebool
699254721SemasteSymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
700254721Semaste{
701254721Semaste    bool return_value = true;
702254721Semaste    switch (type)
703254721Semaste    {
704254721Semaste    case eNothingSpecified:
705254721Semaste        Clear();
706254721Semaste        break;
707254721Semaste    case eModuleSpecified:
708254721Semaste        {
709254721Semaste            // See if we can find the Module, if so stick it in the SymbolContext.
710254721Semaste            FileSpec module_file_spec(spec_string, false);
711254721Semaste            ModuleSpec module_spec (module_file_spec);
712254721Semaste            lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec));
713254721Semaste            m_type |= eModuleSpecified;
714254721Semaste            if (module_sp)
715254721Semaste                m_module_sp = module_sp;
716254721Semaste            else
717254721Semaste                m_module_spec.assign (spec_string);
718254721Semaste        }
719254721Semaste        break;
720254721Semaste    case eFileSpecified:
721254721Semaste        // CompUnits can't necessarily be resolved here, since an inlined function might show up in
722254721Semaste        // a number of CompUnits.  Instead we just convert to a FileSpec and store it away.
723254721Semaste        m_file_spec_ap.reset (new FileSpec (spec_string, false));
724254721Semaste        m_type |= eFileSpecified;
725254721Semaste        break;
726254721Semaste    case eLineStartSpecified:
727254721Semaste        m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
728254721Semaste        if (return_value)
729254721Semaste            m_type |= eLineStartSpecified;
730254721Semaste        break;
731254721Semaste    case eLineEndSpecified:
732254721Semaste        m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
733254721Semaste        if (return_value)
734254721Semaste            m_type |= eLineEndSpecified;
735254721Semaste        break;
736254721Semaste    case eFunctionSpecified:
737254721Semaste        m_function_spec.assign(spec_string);
738254721Semaste        m_type |= eFunctionSpecified;
739254721Semaste        break;
740254721Semaste    case eClassOrNamespaceSpecified:
741254721Semaste        Clear();
742254721Semaste        m_class_name.assign (spec_string);
743254721Semaste        m_type = eClassOrNamespaceSpecified;
744254721Semaste        break;
745254721Semaste    case eAddressRangeSpecified:
746254721Semaste        // Not specified yet...
747254721Semaste        break;
748254721Semaste    }
749254721Semaste
750254721Semaste    return return_value;
751254721Semaste}
752254721Semaste
753254721Semastevoid
754254721SemasteSymbolContextSpecifier::Clear()
755254721Semaste{
756254721Semaste    m_module_spec.clear();
757254721Semaste    m_file_spec_ap.reset();
758254721Semaste    m_function_spec.clear();
759254721Semaste    m_class_name.clear();
760254721Semaste    m_start_line = 0;
761254721Semaste    m_end_line = 0;
762254721Semaste    m_address_range_ap.reset();
763254721Semaste
764254721Semaste    m_type = eNothingSpecified;
765254721Semaste}
766254721Semaste
767254721Semastebool
768254721SemasteSymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
769254721Semaste{
770254721Semaste    if (m_type == eNothingSpecified)
771254721Semaste        return true;
772254721Semaste
773254721Semaste    if (m_target_sp.get() != sc.target_sp.get())
774254721Semaste        return false;
775254721Semaste
776254721Semaste    if (m_type & eModuleSpecified)
777254721Semaste    {
778254721Semaste        if (sc.module_sp)
779254721Semaste        {
780254721Semaste            if (m_module_sp.get() != NULL)
781254721Semaste            {
782254721Semaste                if (m_module_sp.get() != sc.module_sp.get())
783254721Semaste                    return false;
784254721Semaste            }
785254721Semaste            else
786254721Semaste            {
787254721Semaste                FileSpec module_file_spec (m_module_spec.c_str(), false);
788254721Semaste                if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
789254721Semaste                    return false;
790254721Semaste            }
791254721Semaste        }
792254721Semaste    }
793254721Semaste    if (m_type & eFileSpecified)
794254721Semaste    {
795254721Semaste        if (m_file_spec_ap.get())
796254721Semaste        {
797254721Semaste            // If we don't have a block or a comp_unit, then we aren't going to match a source file.
798254721Semaste            if (sc.block == NULL && sc.comp_unit == NULL)
799254721Semaste                return false;
800254721Semaste
801254721Semaste            // Check if the block is present, and if so is it inlined:
802254721Semaste            bool was_inlined = false;
803254721Semaste            if (sc.block != NULL)
804254721Semaste            {
805254721Semaste                const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
806254721Semaste                if (inline_info != NULL)
807254721Semaste                {
808254721Semaste                    was_inlined = true;
809254721Semaste                    if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
810254721Semaste                        return false;
811254721Semaste                }
812254721Semaste            }
813254721Semaste
814254721Semaste            // Next check the comp unit, but only if the SymbolContext was not inlined.
815254721Semaste            if (!was_inlined && sc.comp_unit != NULL)
816254721Semaste            {
817254721Semaste                if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
818254721Semaste                    return false;
819254721Semaste            }
820254721Semaste        }
821254721Semaste    }
822254721Semaste    if (m_type & eLineStartSpecified
823254721Semaste        || m_type & eLineEndSpecified)
824254721Semaste    {
825254721Semaste        if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
826254721Semaste            return false;
827254721Semaste    }
828254721Semaste
829254721Semaste    if (m_type & eFunctionSpecified)
830254721Semaste    {
831254721Semaste        // First check the current block, and if it is inlined, get the inlined function name:
832254721Semaste        bool was_inlined = false;
833254721Semaste        ConstString func_name(m_function_spec.c_str());
834254721Semaste
835254721Semaste        if (sc.block != NULL)
836254721Semaste        {
837254721Semaste            const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
838254721Semaste            if (inline_info != NULL)
839254721Semaste            {
840254721Semaste                was_inlined = true;
841254721Semaste                const Mangled &name = inline_info->GetMangled();
842254721Semaste                if (!name.NameMatches (func_name))
843254721Semaste                    return false;
844254721Semaste            }
845254721Semaste        }
846254721Semaste        //  If it wasn't inlined, check the name in the function or symbol:
847254721Semaste        if (!was_inlined)
848254721Semaste        {
849254721Semaste            if (sc.function != NULL)
850254721Semaste            {
851254721Semaste                if (!sc.function->GetMangled().NameMatches(func_name))
852254721Semaste                    return false;
853254721Semaste            }
854254721Semaste            else if (sc.symbol != NULL)
855254721Semaste            {
856254721Semaste                if (!sc.symbol->GetMangled().NameMatches(func_name))
857254721Semaste                    return false;
858254721Semaste            }
859254721Semaste        }
860254721Semaste
861254721Semaste
862254721Semaste    }
863254721Semaste
864254721Semaste    return true;
865254721Semaste}
866254721Semaste
867254721Semastebool
868254721SemasteSymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
869254721Semaste{
870254721Semaste    if (m_type & eAddressRangeSpecified)
871254721Semaste    {
872254721Semaste
873254721Semaste    }
874254721Semaste    else
875254721Semaste    {
876254721Semaste        Address match_address (addr, NULL);
877254721Semaste        SymbolContext sc;
878254721Semaste        m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
879254721Semaste        return SymbolContextMatches(sc);
880254721Semaste    }
881254721Semaste    return true;
882254721Semaste}
883254721Semaste
884254721Semastevoid
885254721SemasteSymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
886254721Semaste{
887254721Semaste    char path_str[PATH_MAX + 1];
888254721Semaste
889254721Semaste    if (m_type == eNothingSpecified)
890254721Semaste    {
891254721Semaste        s->Printf ("Nothing specified.\n");
892254721Semaste    }
893254721Semaste
894254721Semaste    if (m_type == eModuleSpecified)
895254721Semaste    {
896254721Semaste        s->Indent();
897254721Semaste        if (m_module_sp)
898254721Semaste        {
899254721Semaste            m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
900254721Semaste            s->Printf ("Module: %s\n", path_str);
901254721Semaste        }
902254721Semaste        else
903254721Semaste            s->Printf ("Module: %s\n", m_module_spec.c_str());
904254721Semaste    }
905254721Semaste
906254721Semaste    if (m_type == eFileSpecified  && m_file_spec_ap.get() != NULL)
907254721Semaste    {
908254721Semaste        m_file_spec_ap->GetPath (path_str, PATH_MAX);
909254721Semaste        s->Indent();
910254721Semaste        s->Printf ("File: %s", path_str);
911254721Semaste        if (m_type == eLineStartSpecified)
912254721Semaste        {
913263363Semaste            s->Printf (" from line %zu", m_start_line);
914254721Semaste            if (m_type == eLineEndSpecified)
915263363Semaste                s->Printf ("to line %zu", m_end_line);
916254721Semaste            else
917254721Semaste                s->Printf ("to end");
918254721Semaste        }
919254721Semaste        else if (m_type == eLineEndSpecified)
920254721Semaste        {
921263363Semaste            s->Printf (" from start to line %zu", m_end_line);
922254721Semaste        }
923254721Semaste        s->Printf (".\n");
924254721Semaste    }
925254721Semaste
926254721Semaste    if (m_type == eLineStartSpecified)
927254721Semaste    {
928254721Semaste        s->Indent();
929263363Semaste        s->Printf ("From line %zu", m_start_line);
930254721Semaste        if (m_type == eLineEndSpecified)
931263363Semaste            s->Printf ("to line %zu", m_end_line);
932254721Semaste        else
933254721Semaste            s->Printf ("to end");
934254721Semaste        s->Printf (".\n");
935254721Semaste    }
936254721Semaste    else if (m_type == eLineEndSpecified)
937254721Semaste    {
938263363Semaste        s->Printf ("From start to line %zu.\n", m_end_line);
939254721Semaste    }
940254721Semaste
941254721Semaste    if (m_type == eFunctionSpecified)
942254721Semaste    {
943254721Semaste        s->Indent();
944254721Semaste        s->Printf ("Function: %s.\n", m_function_spec.c_str());
945254721Semaste    }
946254721Semaste
947254721Semaste    if (m_type == eClassOrNamespaceSpecified)
948254721Semaste    {
949254721Semaste        s->Indent();
950254721Semaste        s->Printf ("Class name: %s.\n", m_class_name.c_str());
951254721Semaste    }
952254721Semaste
953254721Semaste    if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
954254721Semaste    {
955254721Semaste        s->Indent();
956254721Semaste        s->PutCString ("Address range: ");
957254721Semaste        m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
958254721Semaste        s->PutCString ("\n");
959254721Semaste    }
960254721Semaste}
961254721Semaste
962254721Semaste//----------------------------------------------------------------------
963254721Semaste//
964254721Semaste//  SymbolContextList
965254721Semaste//
966254721Semaste//----------------------------------------------------------------------
967254721Semaste
968254721Semaste
969254721SemasteSymbolContextList::SymbolContextList() :
970254721Semaste    m_symbol_contexts()
971254721Semaste{
972254721Semaste}
973254721Semaste
974254721SemasteSymbolContextList::~SymbolContextList()
975254721Semaste{
976254721Semaste}
977254721Semaste
978254721Semastevoid
979254721SemasteSymbolContextList::Append(const SymbolContext& sc)
980254721Semaste{
981254721Semaste    m_symbol_contexts.push_back(sc);
982254721Semaste}
983254721Semaste
984254721Semastevoid
985254721SemasteSymbolContextList::Append (const SymbolContextList& sc_list)
986254721Semaste{
987254721Semaste    collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
988254721Semaste    for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
989254721Semaste        m_symbol_contexts.push_back (*pos);
990254721Semaste}
991254721Semaste
992254721Semaste
993254721Semasteuint32_t
994254721SemasteSymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function)
995254721Semaste{
996254721Semaste    uint32_t unique_sc_add_count = 0;
997254721Semaste    collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
998254721Semaste    for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
999254721Semaste    {
1000254721Semaste        if (AppendIfUnique (*pos, merge_symbol_into_function))
1001254721Semaste            ++unique_sc_add_count;
1002254721Semaste    }
1003254721Semaste    return unique_sc_add_count;
1004254721Semaste}
1005254721Semaste
1006254721Semastebool
1007254721SemasteSymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
1008254721Semaste{
1009254721Semaste    collection::iterator pos, end = m_symbol_contexts.end();
1010254721Semaste    for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1011254721Semaste    {
1012254721Semaste        if (*pos == sc)
1013254721Semaste            return false;
1014254721Semaste    }
1015254721Semaste    if (merge_symbol_into_function
1016254721Semaste        && sc.symbol    != NULL
1017254721Semaste        && sc.comp_unit == NULL
1018254721Semaste        && sc.function  == NULL
1019254721Semaste        && sc.block     == NULL
1020254721Semaste        && sc.line_entry.IsValid() == false)
1021254721Semaste    {
1022254721Semaste        if (sc.symbol->ValueIsAddress())
1023254721Semaste        {
1024254721Semaste            for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1025254721Semaste            {
1026254721Semaste                // Don't merge symbols into inlined function symbol contexts
1027254721Semaste                if (pos->block && pos->block->GetContainingInlinedBlock())
1028254721Semaste                    continue;
1029254721Semaste
1030254721Semaste                if (pos->function)
1031254721Semaste                {
1032254721Semaste                    if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress())
1033254721Semaste                    {
1034254721Semaste                        // Do we already have a function with this symbol?
1035254721Semaste                        if (pos->symbol == sc.symbol)
1036254721Semaste                            return false;
1037254721Semaste                        if (pos->symbol == NULL)
1038254721Semaste                        {
1039254721Semaste                            pos->symbol = sc.symbol;
1040254721Semaste                            return false;
1041254721Semaste                        }
1042254721Semaste                    }
1043254721Semaste                }
1044254721Semaste            }
1045254721Semaste        }
1046254721Semaste    }
1047254721Semaste    m_symbol_contexts.push_back(sc);
1048254721Semaste    return true;
1049254721Semaste}
1050254721Semaste
1051254721Semastebool
1052254721SemasteSymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
1053254721Semaste                                                          uint32_t start_idx,
1054254721Semaste                                                          uint32_t stop_idx)
1055254721Semaste{
1056254721Semaste    if (symbol_sc.symbol    != NULL
1057254721Semaste        && symbol_sc.comp_unit == NULL
1058254721Semaste        && symbol_sc.function  == NULL
1059254721Semaste        && symbol_sc.block     == NULL
1060254721Semaste        && symbol_sc.line_entry.IsValid() == false)
1061254721Semaste    {
1062254721Semaste        if (symbol_sc.symbol->ValueIsAddress())
1063254721Semaste        {
1064254721Semaste            const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx);
1065254721Semaste            for (size_t i=start_idx; i<end; ++i)
1066254721Semaste            {
1067254721Semaste                const SymbolContext &function_sc = m_symbol_contexts[i];
1068254721Semaste                // Don't merge symbols into inlined function symbol contexts
1069254721Semaste                if (function_sc.block && function_sc.block->GetContainingInlinedBlock())
1070254721Semaste                    continue;
1071254721Semaste
1072254721Semaste                if (function_sc.function)
1073254721Semaste                {
1074254721Semaste                    if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
1075254721Semaste                    {
1076254721Semaste                        // Do we already have a function with this symbol?
1077254721Semaste                        if (function_sc.symbol == symbol_sc.symbol)
1078254721Semaste                            return true; // Already have a symbol context with this symbol, return true
1079254721Semaste
1080254721Semaste                        if (function_sc.symbol == NULL)
1081254721Semaste                        {
1082254721Semaste                            // We successfully merged this symbol into an existing symbol context
1083254721Semaste                            m_symbol_contexts[i].symbol = symbol_sc.symbol;
1084254721Semaste                            return true;
1085254721Semaste                        }
1086254721Semaste                    }
1087254721Semaste                }
1088254721Semaste            }
1089254721Semaste        }
1090254721Semaste    }
1091254721Semaste    return false;
1092254721Semaste}
1093254721Semaste
1094254721Semastevoid
1095254721SemasteSymbolContextList::Clear()
1096254721Semaste{
1097254721Semaste    m_symbol_contexts.clear();
1098254721Semaste}
1099254721Semaste
1100254721Semastevoid
1101254721SemasteSymbolContextList::Dump(Stream *s, Target *target) const
1102254721Semaste{
1103254721Semaste
1104254721Semaste    *s << (void *)this << ": ";
1105254721Semaste    s->Indent();
1106254721Semaste    s->PutCString("SymbolContextList");
1107254721Semaste    s->EOL();
1108254721Semaste    s->IndentMore();
1109254721Semaste
1110254721Semaste    collection::const_iterator pos, end = m_symbol_contexts.end();
1111254721Semaste    for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1112254721Semaste    {
1113254721Semaste        //pos->Dump(s, target);
1114254721Semaste        pos->GetDescription(s, eDescriptionLevelVerbose, target);
1115254721Semaste    }
1116254721Semaste    s->IndentLess();
1117254721Semaste}
1118254721Semaste
1119254721Semastebool
1120254721SemasteSymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const
1121254721Semaste{
1122254721Semaste    if (idx < m_symbol_contexts.size())
1123254721Semaste    {
1124254721Semaste        sc = m_symbol_contexts[idx];
1125254721Semaste        return true;
1126254721Semaste    }
1127254721Semaste    return false;
1128254721Semaste}
1129254721Semaste
1130254721Semastebool
1131254721SemasteSymbolContextList::GetLastContext(SymbolContext& sc) const
1132254721Semaste{
1133254721Semaste    if (!m_symbol_contexts.empty())
1134254721Semaste    {
1135254721Semaste        sc = m_symbol_contexts.back();
1136254721Semaste        return true;
1137254721Semaste    }
1138254721Semaste    return false;
1139254721Semaste}
1140254721Semaste
1141254721Semastebool
1142254721SemasteSymbolContextList::RemoveContextAtIndex (size_t idx)
1143254721Semaste{
1144254721Semaste    if (idx < m_symbol_contexts.size())
1145254721Semaste    {
1146254721Semaste        m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1147254721Semaste        return true;
1148254721Semaste    }
1149254721Semaste    return false;
1150254721Semaste}
1151254721Semaste
1152254721Semasteuint32_t
1153254721SemasteSymbolContextList::GetSize() const
1154254721Semaste{
1155254721Semaste    return m_symbol_contexts.size();
1156254721Semaste}
1157254721Semaste
1158254721Semasteuint32_t
1159254721SemasteSymbolContextList::NumLineEntriesWithLine (uint32_t line) const
1160254721Semaste{
1161254721Semaste    uint32_t match_count = 0;
1162254721Semaste    const size_t size = m_symbol_contexts.size();
1163254721Semaste    for (size_t idx = 0; idx<size; ++idx)
1164254721Semaste    {
1165254721Semaste        if (m_symbol_contexts[idx].line_entry.line == line)
1166254721Semaste            ++match_count;
1167254721Semaste    }
1168254721Semaste    return match_count;
1169254721Semaste}
1170254721Semaste
1171254721Semastevoid
1172254721SemasteSymbolContextList::GetDescription(Stream *s,
1173254721Semaste                                  lldb::DescriptionLevel level,
1174254721Semaste                                  Target *target) const
1175254721Semaste{
1176254721Semaste    const size_t size = m_symbol_contexts.size();
1177254721Semaste    for (size_t idx = 0; idx<size; ++idx)
1178254721Semaste        m_symbol_contexts[idx].GetDescription (s, level, target);
1179254721Semaste}
1180254721Semaste
1181254721Semastebool
1182254721Semastelldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs)
1183254721Semaste{
1184254721Semaste    const uint32_t size = lhs.GetSize();
1185254721Semaste    if (size != rhs.GetSize())
1186254721Semaste        return false;
1187254721Semaste
1188254721Semaste    SymbolContext lhs_sc;
1189254721Semaste    SymbolContext rhs_sc;
1190254721Semaste    for (uint32_t i=0; i<size; ++i)
1191254721Semaste    {
1192254721Semaste        lhs.GetContextAtIndex(i, lhs_sc);
1193254721Semaste        rhs.GetContextAtIndex(i, rhs_sc);
1194254721Semaste        if (lhs_sc != rhs_sc)
1195254721Semaste            return false;
1196254721Semaste    }
1197254721Semaste    return true;
1198254721Semaste}
1199254721Semaste
1200254721Semastebool
1201254721Semastelldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs)
1202254721Semaste{
1203254721Semaste    return !(lhs == rhs);
1204254721Semaste}
1205254721Semaste
1206