//===-- 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 (const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) :
    ModuleChild(module_sp),
    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_sp);
}

CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) :
    ModuleChild(module_sp),
    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_sp);
}

CompileUnit::~CompileUnit ()
{
}

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

ModuleSP
CompileUnit::CalculateSymbolContextModule ()
{
    return GetModule();
}

CompileUnit *
CompileUnit::CalculateSymbolContextCompileUnit ()
{
    return this;
}

void
CompileUnit::DumpSymbolContext(Stream *s)
{
    GetModule()->DumpSymbolContext(s);
    s->Printf(", CompileUnit{0x%8.8llx}", 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: ", 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, bool exact, LineEntry *line_entry_ptr)
{
    uint32_t file_idx = 0;

    if (file_spec_ptr)
    {
        file_idx = GetSupportFiles().FindFileIndex (1, *file_spec_ptr, true);
        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();
        const bool full = true;
        file_idx = support_files.FindFileIndex (1, support_files.GetFileSpecAtIndex(0), full);
        if (file_idx == UINT32_MAX)
            file_idx = 0;
    }
    LineTable *line_table = GetLineTable();
    if (line_table)
        return line_table->FindLineEntryIndexByFileIndex (start_idx, file_idx, line, exact, 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::Equal(file_spec, this, !file_spec.GetDirectory().IsEmpty());

    // 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, true);
    while (file_idx != UINT32_MAX)
    {
        file_indexes.push_back (file_idx);
        file_idx = GetSupportFiles().FindFileIndex (file_idx + 1, file_spec, true);
    }
    
    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;
}


