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

#include "DWARFDebugAbbrev.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Stream.h"

using namespace lldb;
using namespace lldb_private;
using namespace std;

//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Clear()
//----------------------------------------------------------------------
void
DWARFAbbreviationDeclarationSet::Clear()
{
    m_idx_offset = 0;
    m_decls.clear();
}


//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Extract()
//----------------------------------------------------------------------
bool
DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
{
    const uint32_t begin_offset = *offset_ptr;
    m_offset = begin_offset;
    Clear();
    DWARFAbbreviationDeclaration abbrevDeclaration;
    dw_uleb128_t prev_abbr_code = 0;
    while (abbrevDeclaration.Extract(data, offset_ptr))
    {
        m_decls.push_back(abbrevDeclaration);
        if (m_idx_offset == 0)
            m_idx_offset = abbrevDeclaration.Code();
        else
        {
            if (prev_abbr_code + 1 != abbrevDeclaration.Code())
                m_idx_offset = UINT32_MAX;    // Out of order indexes, we can't do O(1) lookups...
        }
        prev_abbr_code = abbrevDeclaration.Code();
    }
    return begin_offset != *offset_ptr;
}


//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Dump()
//----------------------------------------------------------------------
void
DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
{
    std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
}


//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
//----------------------------------------------------------------------
const DWARFAbbreviationDeclaration*
DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
{
    if (m_idx_offset == UINT32_MAX)
    {
        DWARFAbbreviationDeclarationCollConstIter pos;
        DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
        for (pos = m_decls.begin(); pos != end; ++pos)
        {
            if (pos->Code() == abbrCode)
                return &(*pos);
        }
    }
    else
    {
        uint32_t idx = abbrCode - m_idx_offset;
        if (idx < m_decls.size())
            return &m_decls[idx];
    }
    return NULL;
}

//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
//
// Append an abbreviation declaration with a sequential code for O(n)
// lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
//----------------------------------------------------------------------
dw_uleb128_t
DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
{
    // Get the next abbreviation code based on our current array size
    dw_uleb128_t code = m_decls.size()+1;

    // Push the new declaration on the back
    m_decls.push_back(abbrevDecl);

    // Update the code for this new declaration
    m_decls.back().SetCode(code);

    return code;    // return the new abbreviation code!
}


//----------------------------------------------------------------------
// Encode
//
// Encode the abbreviation table onto the end of the buffer provided
// into a byte representation as would be found in a ".debug_abbrev"
// debug information section.
//----------------------------------------------------------------------
//void
//DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
//{
//  DWARFAbbreviationDeclarationCollConstIter pos;
//  DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
//  for (pos = m_decls.begin(); pos != end; ++pos)
//      pos->Append(debug_abbrev_buf);
//  debug_abbrev_buf.Append8(0);
//}


//----------------------------------------------------------------------
// DWARFDebugAbbrev constructor
//----------------------------------------------------------------------
DWARFDebugAbbrev::DWARFDebugAbbrev() :
    m_abbrevCollMap(),
    m_prev_abbr_offset_pos(m_abbrevCollMap.end())
{
}


//----------------------------------------------------------------------
// DWARFDebugAbbrev::Parse()
//----------------------------------------------------------------------
void
DWARFDebugAbbrev::Parse(const DataExtractor& data)
{
    uint32_t offset = 0;

    while (data.ValidOffset(offset))
    {
        uint32_t initial_cu_offset = offset;
        DWARFAbbreviationDeclarationSet abbrevDeclSet;

        if (abbrevDeclSet.Extract(data, &offset))
            m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
        else
            break;
    }
    m_prev_abbr_offset_pos = m_abbrevCollMap.end();
}

//----------------------------------------------------------------------
// DWARFDebugAbbrev::Dump()
//----------------------------------------------------------------------
void
DWARFDebugAbbrev::Dump(Stream *s) const
{
    if (m_abbrevCollMap.empty())
    {
        s->PutCString("< EMPTY >\n");
        return;
    }

    DWARFAbbreviationDeclarationCollMapConstIter pos;
    for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
    {
        s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
        pos->second.Dump(s);
    }
}


//----------------------------------------------------------------------
// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
//----------------------------------------------------------------------
const DWARFAbbreviationDeclarationSet*
DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
{
    DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
    DWARFAbbreviationDeclarationCollMapConstIter pos;
    if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
        return &(m_prev_abbr_offset_pos->second);
    else
    {
        pos = m_abbrevCollMap.find(cu_abbr_offset);
        m_prev_abbr_offset_pos = pos;
    }

    if (pos != m_abbrevCollMap.end())
        return &(pos->second);
    return NULL;
}
