//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/SymbolContext.h"

#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

SymbolContext::SymbolContext() :
    target_sp   (),
    module_sp   (),
    comp_unit   (nullptr),
    function    (nullptr),
    block       (nullptr),
    line_entry  (),
    symbol      (nullptr),
    variable    (nullptr)
{
}

SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
    target_sp   (),
    module_sp   (m),
    comp_unit   (cu),
    function    (f),
    block       (b),
    line_entry  (),
    symbol      (s),
    variable    (nullptr)
{
    if (le)
        line_entry = *le;
}

SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
    target_sp   (t),
    module_sp   (m),
    comp_unit   (cu),
    function    (f),
    block       (b),
    line_entry  (),
    symbol      (s),
    variable    (nullptr)
{
    if (le)
        line_entry = *le;
}

SymbolContext::SymbolContext(const SymbolContext& rhs) :
    target_sp   (rhs.target_sp),
    module_sp   (rhs.module_sp),
    comp_unit   (rhs.comp_unit),
    function    (rhs.function),
    block       (rhs.block),
    line_entry  (rhs.line_entry),
    symbol      (rhs.symbol),
    variable    (rhs.variable)
{
}


SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
    target_sp   (),
    module_sp   (),
    comp_unit   (nullptr),
    function    (nullptr),
    block       (nullptr),
    line_entry  (),
    symbol      (nullptr),
    variable    (nullptr)
{
    sc_scope->CalculateSymbolContext (this);
}

SymbolContext::~SymbolContext ()
{
}

const SymbolContext&
SymbolContext::operator= (const SymbolContext& rhs)
{
    if (this != &rhs)
    {
        target_sp   = rhs.target_sp;
        module_sp   = rhs.module_sp;
        comp_unit   = rhs.comp_unit;
        function    = rhs.function;
        block       = rhs.block;
        line_entry  = rhs.line_entry;
        symbol      = rhs.symbol;
        variable    = rhs.variable;
    }
    return *this;
}

void
SymbolContext::Clear(bool clear_target)
{
    if (clear_target)
        target_sp.reset();
    module_sp.reset();
    comp_unit   = nullptr;
    function    = nullptr;
    block       = nullptr;
    line_entry.Clear();
    symbol      = nullptr;
    variable    = nullptr;
}

bool
SymbolContext::DumpStopContext (
    Stream *s,
    ExecutionContextScope *exe_scope,
    const Address &addr,
    bool show_fullpaths,
    bool show_module,
    bool show_inlined_frames,
    bool show_function_arguments,
    bool show_function_name
) const
{
    bool dumped_something = false;
    if (show_module && module_sp)
    {
        if (show_fullpaths)
            *s << module_sp->GetFileSpec();
        else
            *s << module_sp->GetFileSpec().GetFilename();
        s->PutChar('`');
        dumped_something = true;
    }

    if (function != nullptr)
    {
        SymbolContext inline_parent_sc;
        Address inline_parent_addr;
        if (show_function_name == false)
        {
            s->Printf("<");
            dumped_something = true;
        }
        else
        {
            ConstString name;
            if (show_function_arguments == false)
                name = function->GetNameNoArguments();
            if (!name)
                name = function->GetName();
            if (name)
                name.Dump(s);
        }
        
        if (addr.IsValid())
        {
            const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
            if (show_function_name == false)
            {
                // Print +offset even if offset is 0
                dumped_something = true;
                s->Printf("+%" PRIu64 ">", function_offset);
            }
            else if (function_offset)
            {
                dumped_something = true;
                s->Printf(" + %" PRIu64, function_offset);
            }
        }

        if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr))
        {
            dumped_something = true;
            Block *inlined_block = block->GetContainingInlinedBlock();
            const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo();
            s->Printf (" [inlined] %s", inlined_block_info->GetName(function->GetLanguage()).GetCString());
            
            lldb_private::AddressRange block_range;
            if (inlined_block->GetRangeContainingAddress(addr, block_range))
            {
                const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
                if (inlined_function_offset)
                {
                    s->Printf(" + %" PRIu64, inlined_function_offset);
                }
            }
            const Declaration &call_site = inlined_block_info->GetCallSite();
            if (call_site.IsValid())
            {
                s->PutCString(" at ");
                call_site.DumpStopContext (s, show_fullpaths);
            }
            if (show_inlined_frames)
            {
                s->EOL();
                s->Indent();
                const bool show_function_name = true;
                return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments, show_function_name);
            }
        }
        else
        {
            if (line_entry.IsValid())
            {
                dumped_something = true;
                s->PutCString(" at ");
                if (line_entry.DumpStopContext(s, show_fullpaths))
                    dumped_something = true;
            }
        }
    }
    else if (symbol != nullptr)
    {
        if (show_function_name == false)
        {
            s->Printf("<");
            dumped_something = true;
        }
        else if (symbol->GetName())
        {
            dumped_something = true;
            if (symbol->GetType() == eSymbolTypeTrampoline)
                s->PutCString("symbol stub for: ");
            symbol->GetName().Dump(s);
        }

        if (addr.IsValid() && symbol->ValueIsAddress())
        {
            const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRef().GetOffset();
            if (show_function_name == false)
            {
                // Print +offset even if offset is 0
                dumped_something = true;
                s->Printf("+%" PRIu64 ">", symbol_offset);
            }
            else if (symbol_offset)
            {
                dumped_something = true;
                s->Printf(" + %" PRIu64, symbol_offset);
            }
        }
    }
    else if (addr.IsValid())
    {
        addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
        dumped_something = true;
    }
    return dumped_something;
}

void
SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
{
    if (module_sp)
    {
        s->Indent("     Module: file = \"");
        module_sp->GetFileSpec().Dump(s);
        *s << '"';
        if (module_sp->GetArchitecture().IsValid())
            s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
        s->EOL();
    }

    if (comp_unit != nullptr)
    {
        s->Indent("CompileUnit: ");
        comp_unit->GetDescription (s, level);
        s->EOL();
    }

    if (function != nullptr)
    {
        s->Indent("   Function: ");
        function->GetDescription (s, level, target);
        s->EOL();

        Type *func_type = function->GetType();
        if (func_type)
        {
            s->Indent("   FuncType: ");
            func_type->GetDescription (s, level, false);
            s->EOL();
        }
    }

    if (block != nullptr)
    {
        std::vector<Block *> blocks;
        blocks.push_back (block);
        Block *parent_block = block->GetParent();
        
        while (parent_block)
        {
            blocks.push_back (parent_block);
            parent_block = parent_block->GetParent();
        }
        std::vector<Block *>::reverse_iterator pos;        
        std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
        std::vector<Block *>::reverse_iterator end = blocks.rend();
        for (pos = begin; pos != end; ++pos)
        {
            if (pos == begin)
                s->Indent("     Blocks: ");
            else
                s->Indent("             ");
            (*pos)->GetDescription(s, function, level, target);
            s->EOL();
        }
    }

    if (line_entry.IsValid())
    {
        s->Indent("  LineEntry: ");
        line_entry.GetDescription (s, level, comp_unit, target, false);
        s->EOL();
    }

    if (symbol != nullptr)
    {
        s->Indent("     Symbol: ");
        symbol->GetDescription(s, level, target);
        s->EOL();
    }

    if (variable != nullptr)
    {
        s->Indent("   Variable: ");

        s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());

        switch (variable->GetScope())
        {
            case eValueTypeVariableGlobal:
                s->PutCString("kind = global, ");
                break;

            case eValueTypeVariableStatic:
                s->PutCString("kind = static, ");
                break;

            case eValueTypeVariableArgument:
                s->PutCString("kind = argument, ");
                break;

            case eValueTypeVariableLocal:
                s->PutCString("kind = local, ");
                break;

            case eValueTypeVariableThreadLocal:
                s->PutCString("kind = thread local, ");
                break;

            default:
                break;
        }

        s->Printf ("name = \"%s\"\n", variable->GetName().GetCString());
    }
}

uint32_t
SymbolContext::GetResolvedMask () const
{
    uint32_t resolved_mask = 0;
    if (target_sp)              resolved_mask |= eSymbolContextTarget;
    if (module_sp)              resolved_mask |= eSymbolContextModule;
    if (comp_unit)              resolved_mask |= eSymbolContextCompUnit;
    if (function)               resolved_mask |= eSymbolContextFunction;
    if (block)                  resolved_mask |= eSymbolContextBlock;
    if (line_entry.IsValid())   resolved_mask |= eSymbolContextLineEntry;
    if (symbol)                 resolved_mask |= eSymbolContextSymbol;
    if (variable)               resolved_mask |= eSymbolContextVariable;
    return resolved_mask;
}

void
SymbolContext::Dump(Stream *s, Target *target) const
{
    *s << this << ": ";
    s->Indent();
    s->PutCString("SymbolContext");
    s->IndentMore();
    s->EOL();
    s->IndentMore();
    s->Indent();
    *s << "Module       = " << module_sp.get() << ' ';
    if (module_sp)
        module_sp->GetFileSpec().Dump(s);
    s->EOL();
    s->Indent();
    *s << "CompileUnit  = " << comp_unit;
    if (comp_unit != nullptr)
        *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
    s->EOL();
    s->Indent();
    *s << "Function     = " << function;
    if (function != nullptr)
    {
        *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
        function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
        s->EOL();
        s->Indent();
        Type* func_type = function->GetType();
        if (func_type)
        {
            *s << "        Type = ";
            func_type->Dump (s, false);
        }
    }
    s->EOL();
    s->Indent();
    *s << "Block        = " << block;
    if (block != nullptr)
        *s << " {0x" << block->GetID() << '}';
    // Dump the block and pass it a negative depth to we print all the parent blocks
    //if (block != NULL)
    //  block->Dump(s, function->GetFileAddress(), INT_MIN);
    s->EOL();
    s->Indent();
    *s << "LineEntry    = ";
    line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
    s->EOL();
    s->Indent();
    *s << "Symbol       = " << symbol;
    if (symbol != nullptr && symbol->GetMangled())
        *s << ' ' << symbol->GetName().AsCString();
    s->EOL();
    *s << "Variable     = " << variable;
    if (variable != nullptr)
    {
        *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName();
        s->EOL();
    }
    s->IndentLess();
    s->IndentLess();
}

bool
lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
{
    return  lhs.function == rhs.function
            && lhs.symbol == rhs.symbol 
            && lhs.module_sp.get() == rhs.module_sp.get()
            && lhs.comp_unit == rhs.comp_unit
            && lhs.target_sp.get() == rhs.target_sp.get() 
            && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0
            && lhs.variable == rhs.variable;
}

bool
lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
{
    return  lhs.function != rhs.function
            || lhs.symbol != rhs.symbol 
            || lhs.module_sp.get() != rhs.module_sp.get()
            || lhs.comp_unit != rhs.comp_unit
            || lhs.target_sp.get() != rhs.target_sp.get() 
            || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0
            || lhs.variable != rhs.variable;
}

bool
SymbolContext::GetAddressRange (uint32_t scope, 
                                uint32_t range_idx, 
                                bool use_inline_block_range,
                                AddressRange &range) const
{
    if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
    {
        range = line_entry.range;
        return true;
    }
    
    if ((scope & eSymbolContextBlock) && (block != nullptr))
    {
        if (use_inline_block_range)
        {
            Block *inline_block = block->GetContainingInlinedBlock();
            if (inline_block)
                return inline_block->GetRangeAtIndex (range_idx, range);
        }
        else
        {
            return block->GetRangeAtIndex (range_idx, range);
        }
    }

    if ((scope & eSymbolContextFunction) && (function != nullptr))
    {
        if (range_idx == 0)
        {
            range = function->GetAddressRange();
            return true;
        }            
    } 
    
    if ((scope & eSymbolContextSymbol) && (symbol != nullptr))
    {
        if (range_idx == 0)
        {
            if (symbol->ValueIsAddress())
            {
                range.GetBaseAddress() = symbol->GetAddressRef();
                range.SetByteSize (symbol->GetByteSize());
                return true;
            }
        }
    }
    range.Clear();
    return false;
}

LanguageType
SymbolContext::GetLanguage () const
{
    LanguageType lang;
    if (function &&
        (lang = function->GetLanguage()) != eLanguageTypeUnknown)
    {
        return lang;
    }
    else if (variable &&
             (lang = variable->GetLanguage()) != eLanguageTypeUnknown)
    {
        return lang;
    }
    else if (symbol &&
             (lang = symbol->GetLanguage()) != eLanguageTypeUnknown)
    {
        return lang;
    }
    else if (comp_unit &&
             (lang = comp_unit->GetLanguage()) != eLanguageTypeUnknown)
    {
        return lang;
    }
    else if (symbol)
    {
        // If all else fails, try to guess the language from the name.
        return symbol->GetMangled().GuessLanguage();
    }
    return eLanguageTypeUnknown;
}

bool
SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc, 
                                        SymbolContext &next_frame_sc, 
                                        Address &next_frame_pc) const
{
    next_frame_sc.Clear(false);
    next_frame_pc.Clear();

    if (block)
    {
        //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
        
        // In order to get the parent of an inlined function we first need to
        // see if we are in an inlined block as "this->block" could be an 
        // inlined block, or a parent of "block" could be. So lets check if
        // this block or one of this blocks parents is an inlined function.
        Block *curr_inlined_block = block->GetContainingInlinedBlock();
        if (curr_inlined_block)
        {
            // "this->block" is contained in an inline function block, so to
            // get the scope above the inlined block, we get the parent of the
            // inlined block itself
            Block *next_frame_block = curr_inlined_block->GetParent();
            // Now calculate the symbol context of the containing block
            next_frame_block->CalculateSymbolContext (&next_frame_sc);
            
            // If we get here we weren't able to find the return line entry using the nesting of the blocks and
            // the line table.  So just use the call site info from our inlined block.
            
            AddressRange range;
            if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
            {
                // To see there this new frame block it, we need to look at the
                // call site information from 
                const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
                next_frame_pc = range.GetBaseAddress();
                next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
                next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
                next_frame_sc.line_entry.original_file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
                next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
                next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
                return true;
            }
            else
            {
                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));

                if (log)
                {
                    log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
                                 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
                }
#ifdef LLDB_CONFIGURATION_DEBUG
                else
                {
                    ObjectFile *objfile = NULL;
                    if (module_sp)
                    {
                        SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
                        if (symbol_vendor)
                        {
                            SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
                            if (symbol_file)
                                objfile = symbol_file->GetObjectFile();
                        }
                    }
                    if (objfile)
                    {
                        Host::SystemLog (Host::eSystemLogWarning, 
                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n",
                                         curr_inlined_block->GetID(), 
                                         curr_frame_pc.GetFileAddress(),
                                         objfile->GetFileSpec().GetPath().c_str());
                    }
                    else
                    {
                        Host::SystemLog (Host::eSystemLogWarning, 
                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
                                         curr_inlined_block->GetID(), 
                                         curr_frame_pc.GetFileAddress());
                    }
                }
#endif
            }
        }
    }
    
    return false;
}

Block *
SymbolContext::GetFunctionBlock ()
{
    if (function)
    {
        if (block)
        {
            // If this symbol context has a block, check to see if this block
            // is itself, or is contained within a block with inlined function
            // information. If so, then the inlined block is the block that
            // defines the function.
            Block *inlined_block = block->GetContainingInlinedBlock();
            if (inlined_block)
                return inlined_block;

            // The block in this symbol context is not inside an inlined
            // block, so the block that defines the function is the function's
            // top level block, which is returned below.
        }

        // There is no block information in this symbol context, so we must
        // assume that the block that is desired is the top level block of
        // the function itself.
        return &function->GetBlock(true);
    }
    return nullptr;
}

bool
SymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language,
                                      bool &is_instance_method,
                                      ConstString &language_object_name)


{
    Block *function_block = GetFunctionBlock();
    if (function_block)
    {
        CompilerDeclContext decl_ctx = function_block->GetDeclContext();
        if (decl_ctx)
            return decl_ctx.IsClassMethod(&language, &is_instance_method, &language_object_name);
    }
    return false;
}

void
SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const
{
    Block * curr_block = block;
    bool isInlinedblock = false;
    if (curr_block != nullptr && curr_block->GetContainingInlinedBlock() != nullptr)
        isInlinedblock = true;

    //----------------------------------------------------------------------
    // Find all types that match the current block if we have one and put
    // them first in the list. Keep iterating up through all blocks.
    //----------------------------------------------------------------------
    while (curr_block != nullptr && !isInlinedblock)
    {
        type_map.ForEach([curr_block, &type_list](const lldb::TypeSP& type_sp) -> bool {
            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
            if (scs && curr_block == scs->CalculateSymbolContextBlock())
                type_list.Insert(type_sp);
            return true; // Keep iterating
        });

        // Remove any entries that are now in "type_list" from "type_map"
        // since we can't remove from type_map while iterating
        type_list.ForEach([&type_map](const lldb::TypeSP& type_sp) -> bool {
            type_map.Remove(type_sp);
            return true; // Keep iterating
        });
        curr_block = curr_block->GetParent();
    }
    //----------------------------------------------------------------------
    // Find all types that match the current function, if we have onem, and
    // put them next in the list.
    //----------------------------------------------------------------------
    if (function != nullptr && !type_map.Empty())
    {
        const size_t old_type_list_size = type_list.GetSize();
        type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool {
            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
            if (scs && function == scs->CalculateSymbolContextFunction())
                type_list.Insert(type_sp);
            return true; // Keep iterating
        });

        // Remove any entries that are now in "type_list" from "type_map"
        // since we can't remove from type_map while iterating
        const size_t new_type_list_size = type_list.GetSize();
        if (new_type_list_size > old_type_list_size)
        {
            for (size_t i=old_type_list_size; i<new_type_list_size; ++i)
                type_map.Remove(type_list.GetTypeAtIndex(i));
        }
    }
    //----------------------------------------------------------------------
    // Find all types that match the current compile unit, if we have one,
    // and put them next in the list.
    //----------------------------------------------------------------------
    if (comp_unit != nullptr && !type_map.Empty())
    {
        const size_t old_type_list_size = type_list.GetSize();

        type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool {
            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
            if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit())
                type_list.Insert(type_sp);
            return true; // Keep iterating
        });

        // Remove any entries that are now in "type_list" from "type_map"
        // since we can't remove from type_map while iterating
        const size_t new_type_list_size = type_list.GetSize();
        if (new_type_list_size > old_type_list_size)
        {
            for (size_t i=old_type_list_size; i<new_type_list_size; ++i)
                type_map.Remove(type_list.GetTypeAtIndex(i));
        }
    }
    //----------------------------------------------------------------------
    // Find all types that match the current module, if we have one, and put
    // them next in the list.
    //----------------------------------------------------------------------
    if (module_sp && !type_map.Empty())
    {
        const size_t old_type_list_size = type_list.GetSize();
        type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool {
            SymbolContextScope *scs = type_sp->GetSymbolContextScope();
            if (scs &&  module_sp == scs->CalculateSymbolContextModule())
                type_list.Insert(type_sp);
            return true; // Keep iterating
        });
        // Remove any entries that are now in "type_list" from "type_map"
        // since we can't remove from type_map while iterating
        const size_t new_type_list_size = type_list.GetSize();
        if (new_type_list_size > old_type_list_size)
        {
            for (size_t i=old_type_list_size; i<new_type_list_size; ++i)
                type_map.Remove(type_list.GetTypeAtIndex(i));
        }
    }
    //----------------------------------------------------------------------
    // Any types that are left get copied into the list an any order.
    //----------------------------------------------------------------------
    if (!type_map.Empty())
    {
        type_map.ForEach([&type_list](const lldb::TypeSP& type_sp) -> bool {
            type_list.Insert(type_sp);
            return true; // Keep iterating
        });
    }
}

ConstString
SymbolContext::GetFunctionName (Mangled::NamePreference preference) const
{
    if (function)
    {
        if (block)
        {
            Block *inlined_block = block->GetContainingInlinedBlock();
            
            if (inlined_block)
            {
                const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo();
                if (inline_info)
                    return inline_info->GetName(function->GetLanguage());
            }
        }
        return function->GetMangled().GetName(function->GetLanguage(), preference);
    }
    else if (symbol && symbol->ValueIsAddress())
    {
        return symbol->GetMangled().GetName(symbol->GetLanguage(), preference);
    }
    else
    {
        // No function, return an empty string.
        return ConstString();
    }
}

LineEntry
SymbolContext::GetFunctionStartLineEntry () const
{
    LineEntry line_entry;
    Address start_addr;
    if (block)
    {
        Block *inlined_block = block->GetContainingInlinedBlock();
        if (inlined_block)
        {
            if (inlined_block->GetStartAddress (start_addr))
            {
                if (start_addr.CalculateSymbolContextLineEntry (line_entry))
                    return line_entry;
            }
            return LineEntry();
        }
    }
    
    if (function)
    {
        if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry))
            return line_entry;
    }
    return LineEntry();
}

bool
SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Error &error)
{
    if (!line_entry.IsValid())
    {
        error.SetErrorString("Symbol context has no line table.");
        return false;
    }
    
    range = line_entry.range;
    if (line_entry.line > end_line)
    {
        error.SetErrorStringWithFormat("end line option %d must be after the current line: %d",
                                     end_line,
                                     line_entry.line);
        return false;
    }

    uint32_t line_index = 0;
    bool found = false;
    while (1)
    {
        LineEntry this_line;
        line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr, false, &this_line);
        if (line_index == UINT32_MAX)
            break;
        if (LineEntry::Compare(this_line, line_entry) == 0)
        {
            found = true;
            break;
        }
    }
    
    LineEntry end_entry;
    if (!found)
    {
        // Can't find the index of the SymbolContext's line entry in the SymbolContext's CompUnit.
        error.SetErrorString("Can't find the current line entry in the CompUnit - can't process "
                                     "the end-line option");
        return false;
    }
    
    line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false, &end_entry);
    if (line_index == UINT32_MAX)
    {
        error.SetErrorStringWithFormat("could not find a line table entry corresponding "
                                       "to end line number %d",
                                       end_line);
        return false;
    }
    
    Block *func_block = GetFunctionBlock();
    if (func_block && func_block->GetRangeIndexContainingAddress(end_entry.range.GetBaseAddress()) == UINT32_MAX)
    {
        error.SetErrorStringWithFormat("end line number %d is not contained within the current function.",
                                     end_line);
        return false;
    }
    
    lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress()
                              - range.GetBaseAddress().GetFileAddress();
    range.SetByteSize(range_size);
    return true;
}



//----------------------------------------------------------------------
//
//  SymbolContextSpecifier
//
//----------------------------------------------------------------------

SymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
    m_target_sp (target_sp),
    m_module_spec (),
    m_module_sp (),
    m_file_spec_ap (),
    m_start_line (0),
    m_end_line (0),
    m_function_spec (),
    m_class_name (),
    m_address_range_ap (),
    m_type (eNothingSpecified)
{
}   

SymbolContextSpecifier::~SymbolContextSpecifier()
{
}

bool
SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
{
    bool return_value = true;
    switch (type)
    {
    case eNothingSpecified:
        Clear();
        break;
    case eLineStartSpecified:
        m_start_line = line_no;
        m_type |= eLineStartSpecified;
        break;
    case eLineEndSpecified:
        m_end_line = line_no;
        m_type |= eLineEndSpecified;
        break;
    default:
        return_value = false;
        break;
    }
    return return_value;
}

bool
SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
{
    bool return_value = true;
    switch (type)
    {
    case eNothingSpecified:
        Clear();
        break;
    case eModuleSpecified:
        {
            // See if we can find the Module, if so stick it in the SymbolContext.
            FileSpec module_file_spec(spec_string, false);
            ModuleSpec module_spec (module_file_spec);
            lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec));
            m_type |= eModuleSpecified;
            if (module_sp)
                m_module_sp = module_sp;
            else
                m_module_spec.assign (spec_string);
        }
        break;
    case eFileSpecified:
        // CompUnits can't necessarily be resolved here, since an inlined function might show up in 
        // a number of CompUnits.  Instead we just convert to a FileSpec and store it away.
        m_file_spec_ap.reset (new FileSpec (spec_string, false));
        m_type |= eFileSpecified;
        break;
    case eLineStartSpecified:
        m_start_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
        if (return_value)
            m_type |= eLineStartSpecified;
        break;
    case eLineEndSpecified:
        m_end_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
        if (return_value)
            m_type |= eLineEndSpecified;
        break;
    case eFunctionSpecified:
        m_function_spec.assign(spec_string);
        m_type |= eFunctionSpecified;
        break;
    case eClassOrNamespaceSpecified:
        Clear();
        m_class_name.assign (spec_string);
        m_type = eClassOrNamespaceSpecified;
        break;
    case eAddressRangeSpecified:
        // Not specified yet...
        break;
    }
    
    return return_value;
}

void
SymbolContextSpecifier::Clear()
{
    m_module_spec.clear();
    m_file_spec_ap.reset();
    m_function_spec.clear();
    m_class_name.clear();
    m_start_line = 0;
    m_end_line = 0;
    m_address_range_ap.reset();
    
    m_type = eNothingSpecified;
}

bool
SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
{
    if (m_type == eNothingSpecified)
        return true;
        
    if (m_target_sp.get() != sc.target_sp.get())
        return false;
        
    if (m_type & eModuleSpecified)
    {
        if (sc.module_sp)
        {
            if (m_module_sp.get() != nullptr)
            { 
                if (m_module_sp.get() != sc.module_sp.get())
                    return false;
            }
            else
            {
                FileSpec module_file_spec (m_module_spec.c_str(), false);
                if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
                    return false;
            }
        }
    }
    if (m_type & eFileSpecified)
    {
        if (m_file_spec_ap.get())
        {
            // If we don't have a block or a comp_unit, then we aren't going to match a source file.
            if (sc.block == nullptr && sc.comp_unit == nullptr)
                return false;
                
            // Check if the block is present, and if so is it inlined:
            bool was_inlined = false;
            if (sc.block != nullptr)
            {
                const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
                if (inline_info != nullptr)
                {
                    was_inlined = true;
                    if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
                        return false;
                }
            }
            
            // Next check the comp unit, but only if the SymbolContext was not inlined.
            if (!was_inlined && sc.comp_unit != nullptr)
            {
                if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
                    return false;
            }
        }
    }
    if (m_type & eLineStartSpecified 
        || m_type & eLineEndSpecified)
    {
        if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
            return false;
    }
    
    if (m_type & eFunctionSpecified)
    {
        // First check the current block, and if it is inlined, get the inlined function name:
        bool was_inlined = false;
        ConstString func_name(m_function_spec.c_str());
        
        if (sc.block != nullptr)
        {
            const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
            if (inline_info != nullptr)
            {
                was_inlined = true;
                const Mangled &name = inline_info->GetMangled();
                if (!name.NameMatches (func_name, sc.function->GetLanguage()))
                    return false;
            }
        }
        //  If it wasn't inlined, check the name in the function or symbol:
        if (!was_inlined)
        {
            if (sc.function != nullptr)
            {
                if (!sc.function->GetMangled().NameMatches(func_name, sc.function->GetLanguage()))
                    return false;
            }
            else if (sc.symbol != nullptr)
            {
                if (!sc.symbol->GetMangled().NameMatches(func_name, sc.symbol->GetLanguage()))
                    return false;
            }
        }
        
            
    }
    
    return true;
}

bool
SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
{
    if (m_type & eAddressRangeSpecified)
    {
    
    }
    else
    {
        Address match_address (addr, nullptr);
        SymbolContext sc;
        m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
        return SymbolContextMatches(sc);
    }
    return true;
}

void
SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
{
    char path_str[PATH_MAX + 1];

    if (m_type == eNothingSpecified)
    {
        s->Printf ("Nothing specified.\n");
    }
    
    if (m_type == eModuleSpecified)
    {
        s->Indent();
        if (m_module_sp)
        {
            m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
            s->Printf ("Module: %s\n", path_str);
        }
        else
            s->Printf ("Module: %s\n", m_module_spec.c_str());
    }
    
    if (m_type == eFileSpecified  && m_file_spec_ap.get() != nullptr)
    {
        m_file_spec_ap->GetPath (path_str, PATH_MAX);
        s->Indent();
        s->Printf ("File: %s", path_str);
        if (m_type == eLineStartSpecified)
        {
            s->Printf (" from line %" PRIu64 "", (uint64_t)m_start_line);
            if (m_type == eLineEndSpecified)
                s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
            else
                s->Printf ("to end");
        }
        else if (m_type == eLineEndSpecified)
        {
            s->Printf (" from start to line %" PRIu64 "", (uint64_t)m_end_line);
        }
        s->Printf (".\n");
    }
    
    if (m_type == eLineStartSpecified)
    {
        s->Indent();
        s->Printf ("From line %" PRIu64 "", (uint64_t)m_start_line);
        if (m_type == eLineEndSpecified)
            s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
        else
            s->Printf ("to end");
        s->Printf (".\n");
    }
    else if (m_type == eLineEndSpecified)
    {
        s->Printf ("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
    }
    
    if (m_type == eFunctionSpecified)
    {
        s->Indent();
        s->Printf ("Function: %s.\n", m_function_spec.c_str());
    }
    
    if (m_type == eClassOrNamespaceSpecified)
    {
        s->Indent();
        s->Printf ("Class name: %s.\n", m_class_name.c_str());
    }
    
    if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != nullptr)
    {
        s->Indent();
        s->PutCString ("Address range: ");
        m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
        s->PutCString ("\n");
    }
}

//----------------------------------------------------------------------
//
//  SymbolContextList
//
//----------------------------------------------------------------------


SymbolContextList::SymbolContextList() :
    m_symbol_contexts()
{
}

SymbolContextList::~SymbolContextList()
{
}

void
SymbolContextList::Append(const SymbolContext& sc)
{
    m_symbol_contexts.push_back(sc);
}

void
SymbolContextList::Append (const SymbolContextList& sc_list)
{
    collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
    for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
        m_symbol_contexts.push_back (*pos);
}


uint32_t
SymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function)
{
    uint32_t unique_sc_add_count = 0;
    collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
    for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
    {
        if (AppendIfUnique (*pos, merge_symbol_into_function))
            ++unique_sc_add_count;
    }
    return unique_sc_add_count;
}

bool
SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
{
    collection::iterator pos, end = m_symbol_contexts.end();
    for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
    {
        if (*pos == sc)
            return false;
    }
    if (merge_symbol_into_function 
        && sc.symbol    != nullptr
        && sc.comp_unit == nullptr
        && sc.function  == nullptr
        && sc.block     == nullptr
        && sc.line_entry.IsValid() == false)
    {
        if (sc.symbol->ValueIsAddress())
        {
            for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
            {
                // Don't merge symbols into inlined function symbol contexts
                if (pos->block && pos->block->GetContainingInlinedBlock())
                    continue;

                if (pos->function)
                {
                    if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddressRef())
                    {
                        // Do we already have a function with this symbol?
                        if (pos->symbol == sc.symbol)
                            return false;
                        if (pos->symbol == nullptr)
                        {
                            pos->symbol = sc.symbol;
                            return false;
                        }
                    }
                }
            }
        }
    }
    m_symbol_contexts.push_back(sc);
    return true;
}

bool
SymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
                                                          uint32_t start_idx,
                                                          uint32_t stop_idx)
{
    if (symbol_sc.symbol    != nullptr
        && symbol_sc.comp_unit == nullptr
        && symbol_sc.function  == nullptr
        && symbol_sc.block     == nullptr
        && symbol_sc.line_entry.IsValid() == false)
    {
        if (symbol_sc.symbol->ValueIsAddress())
        {
            const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx);
            for (size_t i=start_idx; i<end; ++i)
            {
                const SymbolContext &function_sc = m_symbol_contexts[i];
                // Don't merge symbols into inlined function symbol contexts
                if (function_sc.block && function_sc.block->GetContainingInlinedBlock())
                    continue;
                
                if (function_sc.function)
                {
                    if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
                    {
                        // Do we already have a function with this symbol?
                        if (function_sc.symbol == symbol_sc.symbol)
                            return true; // Already have a symbol context with this symbol, return true

                        if (function_sc.symbol == nullptr)
                        {
                            // We successfully merged this symbol into an existing symbol context
                            m_symbol_contexts[i].symbol = symbol_sc.symbol;
                            return true;
                        }
                    }
                }
            }
        }
    }
    return false;
}

void
SymbolContextList::Clear()
{
    m_symbol_contexts.clear();
}

void
SymbolContextList::Dump(Stream *s, Target *target) const
{

    *s << this << ": ";
    s->Indent();
    s->PutCString("SymbolContextList");
    s->EOL();
    s->IndentMore();

    collection::const_iterator pos, end = m_symbol_contexts.end();
    for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
    {
        //pos->Dump(s, target);
        pos->GetDescription(s, eDescriptionLevelVerbose, target);
    }
    s->IndentLess();
}

bool
SymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const
{
    if (idx < m_symbol_contexts.size())
    {
        sc = m_symbol_contexts[idx];
        return true;
    }
    return false;
}

bool
SymbolContextList::GetLastContext(SymbolContext& sc) const
{
    if (!m_symbol_contexts.empty())
    {
        sc = m_symbol_contexts.back();
        return true;
    }
    return false;
}

bool
SymbolContextList::RemoveContextAtIndex (size_t idx)
{
    if (idx < m_symbol_contexts.size())
    {
        m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
        return true;
    }
    return false;
}

uint32_t
SymbolContextList::GetSize() const
{
    return m_symbol_contexts.size();
}

uint32_t
SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
{
    uint32_t match_count = 0;
    const size_t size = m_symbol_contexts.size();
    for (size_t idx = 0; idx<size; ++idx)
    {
        if (m_symbol_contexts[idx].line_entry.line == line)
            ++match_count;
    }
    return match_count;
}

void
SymbolContextList::GetDescription(Stream *s, 
                                  lldb::DescriptionLevel level, 
                                  Target *target) const
{
    const size_t size = m_symbol_contexts.size();
    for (size_t idx = 0; idx<size; ++idx)
        m_symbol_contexts[idx].GetDescription (s, level, target);
}

bool
lldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs)
{
    const uint32_t size = lhs.GetSize();
    if (size != rhs.GetSize())
        return false;
    
    SymbolContext lhs_sc;
    SymbolContext rhs_sc;
    for (uint32_t i=0; i<size; ++i)
    {
        lhs.GetContextAtIndex(i, lhs_sc);
        rhs.GetContextAtIndex(i, rhs_sc);
        if (lhs_sc != rhs_sc)
            return false;
    }
    return true;
}

bool
lldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs)
{
    return !(lhs == rhs);
}

