//===-- 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/Core/Module.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Language.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,
                         lldb_private::LazyBool is_optimized)
    : ModuleChild(module_sp), FileSpec(pathname, false), UserID(cu_sym_id),
      m_user_data(user_data), m_language(language), m_flags(0), m_functions(),
      m_support_files(), m_line_table_ap(), m_variables(),
      m_is_optimized(is_optimized) {
  if (language != eLanguageTypeUnknown)
    m_flags.Set(flagsParsedLanguage);
  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,
                         lldb_private::LazyBool is_optimized)
    : ModuleChild(module_sp), FileSpec(fspec), UserID(cu_sym_id),
      m_user_data(user_data), m_language(language), m_flags(0), m_functions(),
      m_support_files(), m_line_table_ap(), m_variables(),
      m_is_optimized(is_optimized) {
  if (language != eLanguageTypeUnknown)
    m_flags.Set(flagsParsedLanguage);
  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.8" PRIx64 "}", GetID());
}

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

//----------------------------------------------------------------------
// 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 {
  const char *language = Language::GetNameForLanguageType(m_language);

  s->Printf("%p: ", static_cast<const void *>(this));
  s->Indent();
  *s << "CompileUnit" << static_cast<const UserID &>(*this) << ", language = \""
     << language << "\", file = '" << static_cast<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 Mangled::Tokens token list. This function currently
// implements an interactive approach designed to find all instances of certain
// functions. It isn't designed to 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;
}

lldb::LanguageType CompileUnit::GetLanguage() {
  if (m_language == eLanguageTypeUnknown) {
    if (m_flags.IsClear(flagsParsedLanguage)) {
      m_flags.Set(flagsParsedLanguage);
      SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
      if (symbol_vendor) {
        SymbolContext sc;
        CalculateSymbolContext(&sc);
        m_language = symbol_vendor->ParseCompileUnitLanguage(sc);
      }
    }
  }
  return m_language;
}

LineTable *CompileUnit::GetLineTable() {
  if (m_line_table_ap.get() == nullptr) {
    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 == nullptr)
    m_flags.Clear(flagsParsedLineTable);
  else
    m_flags.Set(flagsParsedLineTable);
  m_line_table_ap.reset(line_table);
}

DebugMacros *CompileUnit::GetDebugMacros() {
  if (m_debug_macros_sp.get() == nullptr) {
    if (m_flags.IsClear(flagsParsedDebugMacros)) {
      m_flags.Set(flagsParsedDebugMacros);
      SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
      if (symbol_vendor) {
        SymbolContext sc;
        CalculateSymbolContext(&sc);
        symbol_vendor->ParseCompileUnitDebugMacros(sc);
      }
    }
  }

  return m_debug_macros_sp.get();
}

void CompileUnit::SetDebugMacros(const DebugMacrosSP &debug_macros_sp) {
  if (debug_macros_sp.get() == nullptr)
    m_flags.Clear(flagsParsedDebugMacros);
  else
    m_flags.Set(flagsParsedDebugMacros);
  m_debug_macros_sp = debug_macros_sp;
}

VariableListSP CompileUnit::GetVariableList(bool can_create) {
  if (m_variables.get() == nullptr && 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 artificially 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;
  const bool full_match = (bool)file_spec.GetDirectory();
  bool file_spec_matches_cu_file_spec =
      FileSpec::Equal(file_spec, *this, full_match);

  // 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 != nullptr) {
      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
        LineEntry line_entry;
        line_idx = line_table->FindLineEntryIndexByFileIndex(
            0, file_indexes.front(), line, exact, &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 = line_entry.line;

        while (line_idx != UINT32_MAX) {
          // If they only asked for the line entry, then we're done, we can
          // just copy that over. But if they wanted more than just the line
          // number, fill it in.
          if (resolve_scope == eSymbolContextLineEntry) {
            sc.line_entry = line_entry;
          } else {
            line_entry.range.GetBaseAddress().CalculateSymbolContext(
                &sc, resolve_scope);
          }

          sc_list.Append(sc);
          line_idx = line_table->FindLineEntryIndexByFileIndex(
              line_idx + 1, file_indexes.front(), found_line, true,
              &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.
        LineEntry line_entry;
        line_idx = line_table->FindLineEntryIndexByFileIndex(
            0, file_indexes, line, exact, &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 = line_entry.line;

        while (line_idx != UINT32_MAX) {
          if (resolve_scope == eSymbolContextLineEntry) {
            sc.line_entry = line_entry;
          } else {
            line_entry.range.GetBaseAddress().CalculateSymbolContext(
                &sc, resolve_scope);
          }

          sc_list.Append(sc);
          line_idx = line_table->FindLineEntryIndexByFileIndex(
              line_idx + 1, file_indexes, found_line, true, &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;
}

bool CompileUnit::GetIsOptimized() {
  if (m_is_optimized == eLazyBoolCalculate) {
    m_is_optimized = eLazyBoolNo;
    if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) {
      SymbolContext sc;
      CalculateSymbolContext(&sc);
      if (symbol_vendor->ParseCompileUnitIsOptimized(sc))
        m_is_optimized = eLazyBoolYes;
    }
  }
  return m_is_optimized;
}

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

const std::vector<ConstString> &CompileUnit::GetImportedModules() {
  if (m_imported_modules.empty() &&
      m_flags.IsClear(flagsParsedImportedModules)) {
    m_flags.Set(flagsParsedImportedModules);
    if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) {
      SymbolContext sc;
      CalculateSymbolContext(&sc);
      symbol_vendor->ParseImportedModules(sc, m_imported_modules);
    }
  }
  return m_imported_modules;
}

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; }
