Skip to content
SymbolContext.cpp 38.4 KiB
Newer Older
        s->Printf ("From line %" PRIu64 "", (uint64_t)m_start_line);
            s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line);
        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;
}

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;
    }
        && sc.symbol    != nullptr
        && sc.comp_unit == nullptr
        && sc.function  == nullptr
        && sc.block     == nullptr
        && sc.line_entry.IsValid() == false)
    {
Greg Clayton's avatar
Greg Clayton committed
        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->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)
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);
Greg Clayton's avatar
Greg Clayton committed
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;
}

Greg Clayton's avatar
Greg Clayton committed
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;
Greg Clayton's avatar
Greg Clayton committed
    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
{
Greg Clayton's avatar
Greg Clayton committed
    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);
}