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

#include "DWARFASTParserJava.h"
#include "DWARFAttribute.h"
#include "DWARFUnit.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDeclContext.h"
#include "SymbolFileDWARF.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/TypeList.h"

using namespace lldb;
using namespace lldb_private;

DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {}

DWARFASTParserJava::~DWARFASTParserJava() {}

TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) {
  SymbolFileDWARF *dwarf = die.GetDWARF();
  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

  ConstString type_name;
  uint64_t byte_size = 0;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  for (uint32_t i = 0; i < num_attributes; ++i) {
    DWARFFormValue form_value;
    dw_attr_t attr = attributes.AttributeAtIndex(i);
    if (attributes.ExtractFormValueAtIndex(i, form_value)) {
      switch (attr) {
      case DW_AT_name:
        type_name.SetCString(form_value.AsCString());
        break;
      case DW_AT_byte_size:
        byte_size = form_value.Unsigned();
        break;
      case DW_AT_encoding:
        break;
      default:
        assert(false && "Unsupported attribute for DW_TAG_base_type");
      }
    }
  }

  Declaration decl;
  CompilerType compiler_type = m_ast.CreateBaseType(type_name);
  return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
                                nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
                                decl, compiler_type, Type::eResolveStateFull);
}

TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) {
  SymbolFileDWARF *dwarf = die.GetDWARF();
  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

  ConstString linkage_name;
  DWARFFormValue type_attr_value;
  lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
  DWARFExpression length_expression(die.GetCU());

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  for (uint32_t i = 0; i < num_attributes; ++i) {
    DWARFFormValue form_value;
    dw_attr_t attr = attributes.AttributeAtIndex(i);
    if (attributes.ExtractFormValueAtIndex(i, form_value)) {
      switch (attr) {
      case DW_AT_linkage_name:
        linkage_name.SetCString(form_value.AsCString());
        break;
      case DW_AT_type:
        type_attr_value = form_value;
        break;
      case DW_AT_data_member_location:
        data_offset = form_value.Unsigned();
        break;
      case DW_AT_declaration:
        break;
      default:
        assert(false && "Unsupported attribute for DW_TAG_array_type");
      }
    }
  }

  for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
       child_die = child_die.GetSibling()) {
    if (child_die.Tag() == DW_TAG_subrange_type) {
      DWARFAttributes attributes;
      const size_t num_attributes = child_die.GetAttributes(attributes);
      for (uint32_t i = 0; i < num_attributes; ++i) {
        DWARFFormValue form_value;
        dw_attr_t attr = attributes.AttributeAtIndex(i);
        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
          switch (attr) {
          case DW_AT_count:
            if (form_value.BlockData())
              length_expression.CopyOpcodeData(
                  form_value.BlockData(), form_value.Unsigned(),
                  child_die.GetCU()->GetByteOrder(),
                  child_die.GetCU()->GetAddressByteSize());
            break;
          default:
            assert(false && "Unsupported attribute for DW_TAG_subrange_type");
          }
        }
      }
    } else {
      assert(false && "Unsupported child for DW_TAG_array_type");
    }
  }

  DIERef type_die_ref(type_attr_value);
  Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
  if (!element_type)
    return nullptr;

  CompilerType element_compiler_type = element_type->GetForwardCompilerType();
  CompilerType array_compiler_type = m_ast.CreateArrayType(
      linkage_name, element_compiler_type, length_expression, data_offset);

  Declaration decl;
  TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(),
                          -1, nullptr, type_die_ref.GetUID(dwarf),
                          Type::eEncodingIsUID, &decl, array_compiler_type,
                          Type::eResolveStateFull));
  type_sp->SetEncodingType(element_type);
  return type_sp;
}

TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) {
  SymbolFileDWARF *dwarf = die.GetDWARF();
  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

  Declaration decl;
  DWARFFormValue type_attr_value;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  for (uint32_t i = 0; i < num_attributes; ++i) {
    DWARFFormValue form_value;
    dw_attr_t attr = attributes.AttributeAtIndex(i);
    if (attributes.ExtractFormValueAtIndex(i, form_value)) {
      switch (attr) {
      case DW_AT_type:
        type_attr_value = form_value;
        break;
      default:
        assert(false && "Unsupported attribute for DW_TAG_array_type");
      }
    }
  }

  DIERef type_die_ref(type_attr_value);
  Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
  if (!pointee_type)
    return nullptr;

  CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
  CompilerType reference_compiler_type =
      m_ast.CreateReferenceType(pointee_compiler_type);
  TypeSP type_sp(
      new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1,
               nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
               reference_compiler_type, Type::eResolveStateFull));
  type_sp->SetEncodingType(pointee_type);
  return type_sp;
}

lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die,
                                                       bool &is_new_type) {
  SymbolFileDWARF *dwarf = die.GetDWARF();
  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;

  Declaration decl;
  ConstString name;
  ConstString linkage_name;
  bool is_forward_declaration = false;
  uint32_t byte_size = 0;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  for (uint32_t i = 0; i < num_attributes; ++i) {
    DWARFFormValue form_value;
    dw_attr_t attr = attributes.AttributeAtIndex(i);
    if (attributes.ExtractFormValueAtIndex(i, form_value)) {
      switch (attr) {
      case DW_AT_name:
        name.SetCString(form_value.AsCString());
        break;
      case DW_AT_declaration:
        is_forward_declaration = form_value.Boolean();
        break;
      case DW_AT_byte_size:
        byte_size = form_value.Unsigned();
        break;
      case DW_AT_linkage_name:
        linkage_name.SetCString(form_value.AsCString());
        break;
      default:
        assert(false && "Unsupported attribute for DW_TAG_class_type");
      }
    }
  }

  UniqueDWARFASTType unique_ast_entry;
  if (name) {
    std::string qualified_name;
    if (die.GetQualifiedName(qualified_name)) {
      name.SetCString(qualified_name.c_str());
      if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1,
                                                 unique_ast_entry)) {
        if (unique_ast_entry.m_type_sp) {
          dwarf->GetDIEToType()[die.GetDIE()] =
              unique_ast_entry.m_type_sp.get();
          is_new_type = false;
          return unique_ast_entry.m_type_sp;
        }
      }
    }
  }

  if (is_forward_declaration) {
    DWARFDeclContext die_decl_ctx;
    die.GetDWARFDeclContext(die_decl_ctx);

    TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
    if (type_sp) {
      // We found a real definition for this type elsewhere so lets use it
      dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
      is_new_type = false;
      return type_sp;
    }
  }

  CompilerType compiler_type(
      &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
  if (!compiler_type)
    compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);

  is_new_type = true;
  TypeSP type_sp(new Type(die.GetID(), dwarf, name,
                          -1, // byte size isn't specified
                          nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
                          &decl, compiler_type, Type::eResolveStateForward));

  // Add our type to the unique type map
  unique_ast_entry.m_type_sp = type_sp;
  unique_ast_entry.m_die = die;
  unique_ast_entry.m_declaration = decl;
  unique_ast_entry.m_byte_size = -1;
  dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);

  if (!is_forward_declaration) {
    // Leave this as a forward declaration until we need to know the details of
    // the type
    dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
        compiler_type.GetOpaqueQualType();
    dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] =
        die.GetDIERef();
  }
  return type_sp;
}

lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
    const lldb_private::SymbolContext &sc, const DWARFDIE &die,
    lldb_private::Log *log, bool *type_is_new_ptr) {
  if (type_is_new_ptr)
    *type_is_new_ptr = false;

  if (!die)
    return nullptr;

  SymbolFileDWARF *dwarf = die.GetDWARF();

  Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
  if (type_ptr == DIE_IS_BEING_PARSED)
    return nullptr;
  if (type_ptr != nullptr)
    return type_ptr->shared_from_this();

  TypeSP type_sp;
  if (type_is_new_ptr)
    *type_is_new_ptr = true;

  switch (die.Tag()) {
  case DW_TAG_base_type: {
    type_sp = ParseBaseTypeFromDIE(die);
    break;
  }
  case DW_TAG_array_type: {
    type_sp = ParseArrayTypeFromDIE(die);
    break;
  }
  case DW_TAG_class_type: {
    bool is_new_type = false;
    type_sp = ParseClassTypeFromDIE(die, is_new_type);
    if (!is_new_type)
      return type_sp;
    break;
  }
  case DW_TAG_reference_type: {
    type_sp = ParseReferenceTypeFromDIE(die);
    break;
  }
  }

  if (!type_sp)
    return nullptr;

  DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
  dw_tag_t sc_parent_tag = sc_parent_die.Tag();

  SymbolContextScope *symbol_context_scope = nullptr;
  if (sc_parent_tag == DW_TAG_compile_unit ||
      sc_parent_tag == DW_TAG_partial_unit) {
    symbol_context_scope = sc.comp_unit;
  } else if (sc.function != nullptr && sc_parent_die) {
    symbol_context_scope =
        sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
    if (symbol_context_scope == nullptr)
      symbol_context_scope = sc.function;
  }

  if (symbol_context_scope != nullptr)
    type_sp->SetSymbolContextScope(symbol_context_scope);

  dwarf->GetTypeList()->Insert(type_sp);
  dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();

  return type_sp;
}

lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF(
    const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
  assert(die.Tag() == DW_TAG_subprogram);

  const char *name = nullptr;
  const char *mangled = nullptr;
  int decl_file = 0;
  int decl_line = 0;
  int decl_column = 0;
  int call_file = 0;
  int call_line = 0;
  int call_column = 0;
  DWARFRangeList func_ranges;
  DWARFExpression frame_base(die.GetCU());

  if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
                               decl_column, call_file, call_line, call_column,
                               &frame_base)) {
    // Union of all ranges in the function DIE (if the function is
    // discontiguous)
    AddressRange func_range;
    lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
    lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
    if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
        lowest_func_addr <= highest_func_addr) {
      ModuleSP module_sp(die.GetModule());
      func_range.GetBaseAddress().ResolveAddressUsingFileSections(
          lowest_func_addr, module_sp->GetSectionList());
      if (func_range.GetBaseAddress().IsValid())
        func_range.SetByteSize(highest_func_addr - lowest_func_addr);
    }

    if (func_range.GetBaseAddress().IsValid()) {
      std::unique_ptr<Declaration> decl_ap;
      if (decl_file != 0 || decl_line != 0 || decl_column != 0)
        decl_ap.reset(new Declaration(
            sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
            decl_line, decl_column));

      if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) {
        FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
                                        Mangled(ConstString(name), false),
                                        nullptr, // No function types in java
                                        func_range));
        if (frame_base.IsValid())
          func_sp->GetFrameBaseExpression() = frame_base;
        sc.comp_unit->AddFunction(func_sp);

        return func_sp.get();
      }
    }
  }
  return nullptr;
}

bool DWARFASTParserJava::CompleteTypeFromDWARF(
    const DWARFDIE &die, lldb_private::Type *type,
    lldb_private::CompilerType &java_type) {
  switch (die.Tag()) {
  case DW_TAG_class_type: {
    if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) {
      if (die.HasChildren())
        ParseChildMembers(die, java_type);
      m_ast.CompleteObjectType(java_type);
      return java_type.IsValid();
    }
  } break;
  default:
    assert(false && "Not a forward java type declaration!");
    break;
  }
  return false;
}

void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die,
                                           CompilerType &compiler_type) {
  DWARFUnit *dwarf_cu = parent_die.GetCU();
  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
       die = die.GetSibling()) {
    switch (die.Tag()) {
    case DW_TAG_member: {
      const char *name = nullptr;
      DWARFFormValue encoding_uid;
      uint32_t member_byte_offset = UINT32_MAX;
      DWARFExpression member_location_expression(dwarf_cu);

      DWARFAttributes attributes;
      size_t num_attributes = die.GetAttributes(attributes);
      for (size_t i = 0; i < num_attributes; ++i) {
        DWARFFormValue form_value;
        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
          switch (attributes.AttributeAtIndex(i)) {
          case DW_AT_name:
            name = form_value.AsCString();
            break;
          case DW_AT_type:
            encoding_uid = form_value;
            break;
          case DW_AT_data_member_location:
            if (form_value.BlockData())
              member_location_expression.CopyOpcodeData(
                  form_value.BlockData(), form_value.Unsigned(),
                  dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize());
            else
              member_byte_offset = form_value.Unsigned();
            break;
          case DW_AT_artificial:
            static_cast<void>(form_value.Boolean());
            break;
          case DW_AT_accessibility:
            // TODO: Handle when needed
            break;
          default:
            assert(false && "Unhandled attribute for DW_TAG_member");
            break;
          }
        }
      }

      if (strcmp(name, ".dynamic_type") == 0)
        m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
      else {
        if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
          m_ast.AddMemberToObject(compiler_type, ConstString(name),
                                  member_type->GetFullCompilerType(),
                                  member_byte_offset);
      }
      break;
    }
    case DW_TAG_inheritance: {
      DWARFFormValue encoding_uid;
      uint32_t member_byte_offset = UINT32_MAX;

      DWARFAttributes attributes;
      size_t num_attributes = die.GetAttributes(attributes);
      for (size_t i = 0; i < num_attributes; ++i) {
        DWARFFormValue form_value;
        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
          switch (attributes.AttributeAtIndex(i)) {
          case DW_AT_type:
            encoding_uid = form_value;
            break;
          case DW_AT_data_member_location:
            member_byte_offset = form_value.Unsigned();
            break;
          case DW_AT_accessibility:
            // In java all base class is public so we can ignore this attribute
            break;
          default:
            assert(false && "Unhandled attribute for DW_TAG_member");
            break;
          }
        }
      }
      if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
        m_ast.AddBaseClassToObject(compiler_type,
                                   base_type->GetFullCompilerType(),
                                   member_byte_offset);
      break;
    }
    default:
      break;
    }
  }
}
