//===-- CompileUnit.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/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"

using namespace lldb;
using namespace lldb_private;

CompileUnit::CompileUnit (Module *module, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) :
    ModuleChild(module),
    FileSpec (pathname, false),
    UserID(cu_sym_id),
    Language (language),
    m_user_data (user_data),
    m_flags (0),
    m_functions (),
    m_support_files (),
    m_line_table_ap (),
    m_variables()
{
    assert(module != NULL);
}

CompileUnit::CompileUnit (Module *module, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) :
    ModuleChild(module),
    FileSpec (fspec),
    UserID(cu_sym_id),
    Language (language),
    m_user_data (user_data),
    m_flags (0),
    m_functions (),
    m_support_files (),
    m_line_table_ap (),
    m_variables()
{
    assert(module != NULL);
}

CompileUnit::~CompileUnit ()
{
}

void
CompileUnit::CalculateSymbolContext(SymbolContext* sc)
{
    sc->comp_unit = this;
    GetModule()->CalculateSymbolContext(sc);
}

void
CompileUnit::DumpSymbolContext(Stream *s)
{
    GetModule()->DumpSymbolContext(s);
    s->Printf(", CompileUnit{0x%8.8x}", GetID());
}


void
CompileUnit::GetDescription(Stream *s, lldb::DescriptionLevel level) const
{
    *s << "id = " << (const UserID&)*this << ", file = \"" << (const FileSpec&)*this << "\", language = \"" << (const Language&)*this << '"';
}


//----------------------------------------------------------------------
// Dump the current contents of this object. No functions that cause on
// demand parsing of functions, globals, statics are called, so this
// is a good function to call to get an idea of the current contents of
// the CompileUnit object.
//----------------------------------------------------------------------
void
CompileUnit::Dump(Stream *s, bool show_context) const
{
    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
    s->Indent();
    *s << "CompileUnit" << (const UserID&)*this
        << ", language = \"" << (const Language&)*this
        << "\", file = '" << (const FileSpec&)*this << "'\n";

//  m_types.Dump(s);

    if (m_variables.get())
    {
        s->IndentMore();
        m_variables->Dump(s, show_context);
        s->IndentLess();
    }

    if (!m_functions.empty())
    {
        s->IndentMore();
        std::vector<FunctionSP>::const_iterator pos;
        std::vector<FunctionSP>::const_iterator end = m_functions.end();
        for (pos = m_functions.begin(); pos != end; ++pos)
        {
            (*pos)->Dump(s, show_context);
        }

        s->IndentLess();
        s->EOL();
    }
}

//----------------------------------------------------------------------
// Add a function to this compile unit
//----------------------------------------------------------------------
void
CompileUnit::AddFunction(FunctionSP& funcSP)
{
    // TODO: order these by address
    m_functions.push_back(funcSP);
}

FunctionSP
CompileUnit::GetFunctionAtIndex (size_t idx)
{
    FunctionSP funcSP;
    if (idx < m_functions.size())
        funcSP = m_functions[idx];
    return funcSP;
}

//----------------------------------------------------------------------
// Find functions using the a Mangled::Tokens token list. This
// function currently implements an interative approach designed to find
// all instances of certain functions. It isn't designed to the the
// quickest way to lookup functions as it will need to iterate through
// all functions and see if they match, though it does provide a powerful
// and context sensitive way to search for all functions with a certain
// name, all functions in a namespace, or all functions of a template
// type. See Mangled::Tokens::Parse() comments for more information.
//
// The function prototype will need to change to return a list of
// results. It was originally used to help debug the Mangled class
// and the Mangled::Tokens::MatchesQuery() function and it currently
// will print out a list of matching results for the functions that
// are currently in this compile unit.
//
// A FindFunctions method should be called prior to this that takes
// a regular function name (const char * or ConstString as a parameter)
// before resorting to this slower but more complete function. The
// other FindFunctions method should be able to take advantage of any
// accelerator tables available in the debug information (which is
// parsed by the SymbolFile parser plug-ins and registered with each
// Module).
//----------------------------------------------------------------------
//void
//CompileUnit::FindFunctions(const Mangled::Tokens& tokens)
//{
//  if (!m_functions.empty())
//  {
//      Stream s(stdout);
//      std::vector<FunctionSP>::const_iterator pos;
//      std::vector<FunctionSP>::const_iterator end = m_functions.end();
//      for (pos = m_functions.begin(); pos != end; ++pos)
//      {
//          const ConstString& demangled = (*pos)->Mangled().Demangled();
//          if (demangled)
//          {
//              const Mangled::Tokens& func_tokens = (*pos)->Mangled().GetTokens();
//              if (func_tokens.MatchesQuery (tokens))
//                  s << "demangled MATCH found: " << demangled << "\n";
//          }
//      }
//  }
//}

FunctionSP
CompileUnit::FindFunctionByUID (lldb::user_id_t func_uid)
{
    FunctionSP funcSP;
    if (!m_functions.empty())
    {
        std::vector<FunctionSP>::const_iterator pos;
        std::vector<FunctionSP>::const_iterator end = m_functions.end();
        for (pos = m_functions.begin(); pos != end; ++pos)
        {
            if ((*pos)->GetID() == func_uid)
            {
                funcSP = *pos;
                break;
            }
        }
    }
    return funcSP;
}


LineTable*
CompileUnit::GetLineTable()
{
    if (m_line_table_ap.get() == NULL)
    {
        if (m_flags.IsClear(flagsParsedLineTable))
        {
            m_flags.Set(flagsParsedLineTable);
            SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor();
            if (symbol_vendor)
            {
                SymbolContext sc;
                CalculateSymbolContext(&sc);
                symbol_vendor->ParseCompileUnitLineTable(sc);
            }
        }
    }
    return m_line_table_ap.get();
}

void
CompileUnit::SetLineTable(LineTable* line_table)
{
    if (line_table == NULL)
        m_flags.Clear(flagsParsedLineTable);
    else
        m_flags.Set(flagsParsedLineTable);
    m_line_table_ap.reset(line_table);
}

VariableListSP
CompileUnit::GetVariableList(bool can_create)
{
    if (m_variables.get() == NULL && can_create)
    {
        SymbolContext sc;
        CalculateSymbolContext(&sc);
        assert(sc.module_sp);
        sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
    }

    return m_variables;
}

uint32_t
CompileUnit::FindLineEntry (uint32_t start_idx, uint32_t line, const FileSpec* file_spec_ptr, LineEntry *line_entry_ptr)
{
    uint32_t file_idx = 0;

    if (file_spec_ptr)
    {
        file_idx = GetSupportFiles().FindFileIndex (1, *file_spec_ptr);
        if (file_idx == UINT32_MAX)
            return UINT32_MAX;
    }
    else
    {
        // All the line table entries actually point to the version of the Compile
        // Unit that is in the support files (the one at 0 was artifically added.)
        // So prefer the one further on in the support files if it exists...
        FileSpecList &support_files = GetSupportFiles();
        file_idx = support_files.FindFileIndex (1, support_files.GetFileSpecAtIndex(0));
        if (file_idx == UINT32_MAX)
            file_idx = 0;
    }
    LineTable *line_table = GetLineTable();
    if (line_table)
        return line_table->FindLineEntryIndexByFileIndex (start_idx, file_idx, line, true, line_entry_ptr);
    return UINT32_MAX;
}




uint32_t
CompileUnit::ResolveSymbolContext
(
    const FileSpec& file_spec,
    uint32_t line,
    bool check_inlines,
    bool exact,
    uint32_t resolve_scope,
    SymbolContextList &sc_list
)
{
    // First find all of the file indexes that match our "file_spec". If 
    // "file_spec" has an empty directory, then only compare the basenames
    // when finding file indexes
    std::vector<uint32_t> file_indexes;
    bool file_spec_matches_cu_file_spec = FileSpec::Compare(file_spec, this, !file_spec.GetDirectory().IsEmpty()) == 0;

    // If we are not looking for inlined functions and our file spec doesn't
    // match then we are done...
    if (file_spec_matches_cu_file_spec == false && check_inlines == false)
        return 0;

    uint32_t file_idx = GetSupportFiles().FindFileIndex (1, file_spec);
    while (file_idx != UINT32_MAX)
    {
        file_indexes.push_back (file_idx);
        file_idx = GetSupportFiles().FindFileIndex (file_idx + 1, file_spec);
    }
    
    const size_t num_file_indexes = file_indexes.size();
    if (num_file_indexes == 0)
        return 0;

    const uint32_t prev_size = sc_list.GetSize();

    SymbolContext sc(GetModule());
    sc.comp_unit = this;


    if (line != 0)
    {
        LineTable *line_table = sc.comp_unit->GetLineTable();

        if (line_table != NULL)
        {
            uint32_t found_line;
            uint32_t line_idx;
            
            if (num_file_indexes == 1)
            {
                // We only have a single support file that matches, so use
                // the line table function that searches for a line entries
                // that match a single support file index
                line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_indexes.front(), line, exact, &sc.line_entry);

                // If "exact == true", then "found_line" will be the same
                // as "line". If "exact == false", the "found_line" will be the
                // closest line entry with a line number greater than "line" and 
                // we will use this for our subsequent line exact matches below.
                found_line = sc.line_entry.line;

                while (line_idx != UINT32_MAX)
                {
                    sc_list.Append(sc);
                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes.front(), found_line, true, &sc.line_entry);
                }
            }
            else
            {
                // We found multiple support files that match "file_spec" so use
                // the line table function that searches for a line entries
                // that match a multiple support file indexes.
                line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_indexes, line, exact, &sc.line_entry);

                // If "exact == true", then "found_line" will be the same
                // as "line". If "exact == false", the "found_line" will be the
                // closest line entry with a line number greater than "line" and 
                // we will use this for our subsequent line exact matches below.
                found_line = sc.line_entry.line;

                while (line_idx != UINT32_MAX)
                {
                    sc_list.Append(sc);
                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes, found_line, true, &sc.line_entry);
                }
            }
        }
    }
    else if (file_spec_matches_cu_file_spec && !check_inlines)
    {
        // only append the context if we aren't looking for inline call sites
        // by file and line and if the file spec matches that of the compile unit
        sc_list.Append(sc);
    }
    return sc_list.GetSize() - prev_size;
}

void
CompileUnit::SetVariableList(VariableListSP &variables)
{
    m_variables = variables;
}

FileSpecList&
CompileUnit::GetSupportFiles ()
{
    if (m_support_files.GetSize() == 0)
    {
        if (m_flags.IsClear(flagsParsedSupportFiles))
        {
            m_flags.Set(flagsParsedSupportFiles);
            SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor();
            if (symbol_vendor)
            {
                SymbolContext sc;
                CalculateSymbolContext(&sc);
                symbol_vendor->ParseCompileUnitSupportFiles(sc, m_support_files);
            }
        }
    }
    return m_support_files;
}

void *
CompileUnit::GetUserData () const
{
    return m_user_data;
}


