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

#include "DWARFDebugPubnamesSet.h"

#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Log.h"

#include "SymbolFileDWARF.h"

using namespace lldb_private;

DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
    m_offset(DW_INVALID_OFFSET),
    m_header(),
    m_descriptors(),
    m_name_to_descriptor_index()
{
}

DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
    m_offset(debug_aranges_offset),
    m_header(),
    m_descriptors(),
    m_name_to_descriptor_index()
{
    m_header.length = 10;               // set the length to only include the header right for now
    m_header.version = 2;               // The DWARF version number
    m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
    m_header.die_length = cu_die_length;// compile unit .debug_info length
}

void
DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
{
    if (name && name[0])
    {
        // Adjust our header length
        m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
        Descriptor pubnameDesc(cu_rel_offset, name);
        m_descriptors.push_back(pubnameDesc);
    }
}

void
DWARFDebugPubnamesSet::Clear()
{
    m_offset = DW_INVALID_OFFSET;
    m_header.length = 10;
    m_header.version = 2;
    m_header.die_offset = DW_INVALID_OFFSET;
    m_header.die_length = 0;
    m_descriptors.clear();
}


//----------------------------------------------------------------------
// InitNameIndexes
//----------------------------------------------------------------------
void
DWARFDebugPubnamesSet::InitNameIndexes() const
{
    // Create the name index vector to be able to quickly search by name
    const size_t count = m_descriptors.size();
    for (uint32_t idx = 0; idx < count; ++idx)
    {
        const char* name = m_descriptors[idx].name.c_str();
        if (name && name[0])
            m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
    }
}


bool
DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr)
{
    if (data.ValidOffset(*offset_ptr))
    {
        m_descriptors.clear();
        m_offset = *offset_ptr;
        m_header.length     = data.GetDWARFInitialLength(offset_ptr);
        m_header.version    = data.GetU16(offset_ptr);
        m_header.die_offset = data.GetDWARFOffset(offset_ptr);
        m_header.die_length = data.GetDWARFOffset(offset_ptr);

        Descriptor pubnameDesc;
        while (data.ValidOffset(*offset_ptr))
        {
            pubnameDesc.offset  = data.GetDWARFOffset(offset_ptr);

            if (pubnameDesc.offset)
            {
                const char* name = data.GetCStr(offset_ptr);
                if (name && name[0])
                {
                    pubnameDesc.name = name;
                    m_descriptors.push_back(pubnameDesc);
                }
            }
            else
                break;  // We are done if we get a zero 4 byte offset
        }

        return !m_descriptors.empty();
    }
    return false;
}

dw_offset_t
DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
{
    return m_offset + m_header.length + 4;
}

void
DWARFDebugPubnamesSet::Dump(Log *log) const
{
    log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
        m_header.length,
        m_header.version,
        m_header.die_offset,
        m_header.die_length);

    bool verbose = log->GetVerbose();

    DescriptorConstIter pos;
    DescriptorConstIter end = m_descriptors.end();
    for (pos = m_descriptors.begin(); pos != end; ++pos)
    {
        if (verbose)
            log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str());
        else
            log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
    }
}


void
DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
{
    if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
        InitNameIndexes();

    std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
    for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
        die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
}

void
DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
{
    DescriptorConstIter pos;
    DescriptorConstIter end = m_descriptors.end();
    for (pos = m_descriptors.begin(); pos != end; ++pos)
    {
        if ( regex.Execute(pos->name.c_str()) )
            die_offset_coll.push_back(m_header.die_offset + pos->offset);
    }
}

