//===-- PDBASTParser.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "PDBASTParser.h"

#include "SymbolFilePDB.h"

#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"

#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Declaration.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/LLDBLog.h"
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"

#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace llvm::pdb;

static int TranslateUdtKind(PDB_UdtType pdb_kind) {
  switch (pdb_kind) {
  case PDB_UdtType::Class:
    return llvm::to_underlying(clang::TagTypeKind::Class);
  case PDB_UdtType::Struct:
    return llvm::to_underlying(clang::TagTypeKind::Struct);
  case PDB_UdtType::Union:
    return llvm::to_underlying(clang::TagTypeKind::Union);
  case PDB_UdtType::Interface:
    return llvm::to_underlying(clang::TagTypeKind::Interface);
  }
  llvm_unreachable("unsuported PDB UDT type");
}

static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
  switch (type) {
  case PDB_BuiltinType::Float:
    return lldb::eEncodingIEEE754;
  case PDB_BuiltinType::Int:
  case PDB_BuiltinType::Long:
  case PDB_BuiltinType::Char:
    return lldb::eEncodingSint;
  case PDB_BuiltinType::Bool:
  case PDB_BuiltinType::Char16:
  case PDB_BuiltinType::Char32:
  case PDB_BuiltinType::UInt:
  case PDB_BuiltinType::ULong:
  case PDB_BuiltinType::HResult:
  case PDB_BuiltinType::WCharT:
    return lldb::eEncodingUint;
  default:
    return lldb::eEncodingInvalid;
  }
}

static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
  switch (type) {
  case PDB_VariantType::Int8:
  case PDB_VariantType::Int16:
  case PDB_VariantType::Int32:
  case PDB_VariantType::Int64:
    return lldb::eEncodingSint;

  case PDB_VariantType::UInt8:
  case PDB_VariantType::UInt16:
  case PDB_VariantType::UInt32:
  case PDB_VariantType::UInt64:
    return lldb::eEncodingUint;

  default:
    break;
  }

  return lldb::eEncodingSint;
}

static CompilerType
GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast,
                                       const PDBSymbolTypeBuiltin &pdb_type,
                                       Encoding encoding, uint32_t width) {
  clang::ASTContext &ast = clang_ast.getASTContext();

  switch (pdb_type.getBuiltinType()) {
  default:
    break;
  case PDB_BuiltinType::None:
    return CompilerType();
  case PDB_BuiltinType::Void:
    return clang_ast.GetBasicType(eBasicTypeVoid);
  case PDB_BuiltinType::Char:
    return clang_ast.GetBasicType(eBasicTypeChar);
  case PDB_BuiltinType::Bool:
    return clang_ast.GetBasicType(eBasicTypeBool);
  case PDB_BuiltinType::Long:
    if (width == ast.getTypeSize(ast.LongTy))
      return CompilerType(clang_ast.weak_from_this(),
                          ast.LongTy.getAsOpaquePtr());
    if (width == ast.getTypeSize(ast.LongLongTy))
      return CompilerType(clang_ast.weak_from_this(),
                          ast.LongLongTy.getAsOpaquePtr());
    break;
  case PDB_BuiltinType::ULong:
    if (width == ast.getTypeSize(ast.UnsignedLongTy))
      return CompilerType(clang_ast.weak_from_this(),
                          ast.UnsignedLongTy.getAsOpaquePtr());
    if (width == ast.getTypeSize(ast.UnsignedLongLongTy))
      return CompilerType(clang_ast.weak_from_this(),
                          ast.UnsignedLongLongTy.getAsOpaquePtr());
    break;
  case PDB_BuiltinType::WCharT:
    if (width == ast.getTypeSize(ast.WCharTy))
      return CompilerType(clang_ast.weak_from_this(),
                          ast.WCharTy.getAsOpaquePtr());
    break;
  case PDB_BuiltinType::Char16:
    return CompilerType(clang_ast.weak_from_this(),
                        ast.Char16Ty.getAsOpaquePtr());
  case PDB_BuiltinType::Char32:
    return CompilerType(clang_ast.weak_from_this(),
                        ast.Char32Ty.getAsOpaquePtr());
  case PDB_BuiltinType::Float:
    // Note: types `long double` and `double` have same bit size in MSVC and
    // there is no information in the PDB to distinguish them. So when falling
    // back to default search, the compiler type of `long double` will be
    // represented by the one generated for `double`.
    break;
  }
  // If there is no match on PDB_BuiltinType, fall back to default search by
  // encoding and width only
  return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
}

static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
                                         CompilerType &compiler_type) {
  PDB_BuiltinType kind = pdb_type.getBuiltinType();
  switch (kind) {
  default:
    break;
  case PDB_BuiltinType::Currency:
    return ConstString("CURRENCY");
  case PDB_BuiltinType::Date:
    return ConstString("DATE");
  case PDB_BuiltinType::Variant:
    return ConstString("VARIANT");
  case PDB_BuiltinType::Complex:
    return ConstString("complex");
  case PDB_BuiltinType::Bitfield:
    return ConstString("bitfield");
  case PDB_BuiltinType::BSTR:
    return ConstString("BSTR");
  case PDB_BuiltinType::HResult:
    return ConstString("HRESULT");
  case PDB_BuiltinType::BCD:
    return ConstString("BCD");
  case PDB_BuiltinType::Char16:
    return ConstString("char16_t");
  case PDB_BuiltinType::Char32:
    return ConstString("char32_t");
  case PDB_BuiltinType::None:
    return ConstString("...");
  }
  return compiler_type.GetTypeName();
}

static bool AddSourceInfoToDecl(const PDBSymbol &symbol, Declaration &decl) {
  auto &raw_sym = symbol.getRawSymbol();
  auto first_line_up = raw_sym.getSrcLineOnTypeDefn();

  if (!first_line_up) {
    auto lines_up = symbol.getSession().findLineNumbersByAddress(
        raw_sym.getVirtualAddress(), raw_sym.getLength());
    if (!lines_up)
      return false;
    first_line_up = lines_up->getNext();
    if (!first_line_up)
      return false;
  }
  uint32_t src_file_id = first_line_up->getSourceFileId();
  auto src_file_up = symbol.getSession().getSourceFileById(src_file_id);
  if (!src_file_up)
    return false;

  FileSpec spec(src_file_up->getFileName());
  decl.SetFile(spec);
  decl.SetColumn(first_line_up->getColumnNumber());
  decl.SetLine(first_line_up->getLineNumber());
  return true;
}

static AccessType TranslateMemberAccess(PDB_MemberAccess access) {
  switch (access) {
  case PDB_MemberAccess::Private:
    return eAccessPrivate;
  case PDB_MemberAccess::Protected:
    return eAccessProtected;
  case PDB_MemberAccess::Public:
    return eAccessPublic;
  }
  return eAccessNone;
}

static clang::MSInheritanceAttr::Spelling
GetMSInheritance(const PDBSymbolTypeUDT &udt) {
  int base_count = 0;
  bool has_virtual = false;

  auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
  if (bases_enum) {
    while (auto base = bases_enum->getNext()) {
      base_count++;
      has_virtual |= base->isVirtualBaseClass();
    }
  }

  if (has_virtual)
    return clang::MSInheritanceAttr::Keyword_virtual_inheritance;
  if (base_count > 1)
    return clang::MSInheritanceAttr::Keyword_multiple_inheritance;
  return clang::MSInheritanceAttr::Keyword_single_inheritance;
}

static std::unique_ptr<llvm::pdb::PDBSymbol>
GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) {
  const IPDBSession &session = symbol.getSession();
  const IPDBRawSymbol &raw = symbol.getRawSymbol();
  auto tag = symbol.getSymTag();

  // For items that are nested inside of a class, return the class that it is
  // nested inside of.
  // Note that only certain items can be nested inside of classes.
  switch (tag) {
  case PDB_SymType::Function:
  case PDB_SymType::Data:
  case PDB_SymType::UDT:
  case PDB_SymType::Enum:
  case PDB_SymType::FunctionSig:
  case PDB_SymType::Typedef:
  case PDB_SymType::BaseClass:
  case PDB_SymType::VTable: {
    auto class_parent_id = raw.getClassParentId();
    if (auto class_parent = session.getSymbolById(class_parent_id))
      return class_parent;
    break;
  }
  default:
    break;
  }

  // Otherwise, if it is nested inside of a function, return the function.
  // Note that only certain items can be nested inside of functions.
  switch (tag) {
  case PDB_SymType::Block:
  case PDB_SymType::Data: {
    auto lexical_parent_id = raw.getLexicalParentId();
    auto lexical_parent = session.getSymbolById(lexical_parent_id);
    if (!lexical_parent)
      return nullptr;

    auto lexical_parent_tag = lexical_parent->getSymTag();
    if (lexical_parent_tag == PDB_SymType::Function)
      return lexical_parent;
    if (lexical_parent_tag == PDB_SymType::Exe)
      return nullptr;

    return GetClassOrFunctionParent(*lexical_parent);
  }
  default:
    return nullptr;
  }
}

static clang::NamedDecl *
GetDeclFromContextByName(const clang::ASTContext &ast,
                         const clang::DeclContext &decl_context,
                         llvm::StringRef name) {
  clang::IdentifierInfo &ident = ast.Idents.get(name);
  clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident);
  clang::DeclContext::lookup_result result = decl_context.lookup(decl_name);
  if (result.empty())
    return nullptr;

  return *result.begin();
}

static bool IsAnonymousNamespaceName(llvm::StringRef name) {
  return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
}

static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
  switch (pdb_cc) {
  case llvm::codeview::CallingConvention::NearC:
    return clang::CC_C;
  case llvm::codeview::CallingConvention::NearStdCall:
    return clang::CC_X86StdCall;
  case llvm::codeview::CallingConvention::NearFast:
    return clang::CC_X86FastCall;
  case llvm::codeview::CallingConvention::ThisCall:
    return clang::CC_X86ThisCall;
  case llvm::codeview::CallingConvention::NearVector:
    return clang::CC_X86VectorCall;
  case llvm::codeview::CallingConvention::NearPascal:
    return clang::CC_X86Pascal;
  default:
    assert(false && "Unknown calling convention");
    return clang::CC_C;
  }
}

PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}

PDBASTParser::~PDBASTParser() = default;

// DebugInfoASTParser interface

lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
  Declaration decl;
  switch (type.getSymTag()) {
  case PDB_SymType::BaseClass: {
    auto symbol_file = m_ast.GetSymbolFile();
    if (!symbol_file)
      return nullptr;

    auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId());
    return ty ? ty->shared_from_this() : nullptr;
  } break;
  case PDB_SymType::UDT: {
    auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);
    assert(udt);

    // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol
    // other than a Typedef symbol in PDB. For example,
    //    typedef union { short Row; short Col; } Union;
    // is generated as a named UDT in PDB:
    //    union Union { short Row; short Col; }
    // Such symbols will be handled here.

    // Some UDT with trival ctor has zero length. Just ignore.
    if (udt->getLength() == 0)
      return nullptr;

    // Ignore unnamed-tag UDTs.
    std::string name =
        std::string(MSVCUndecoratedNameParser::DropScope(udt->getName()));
    if (name.empty())
      return nullptr;

    auto decl_context = GetDeclContextContainingSymbol(type);

    // Check if such an UDT already exists in the current context.
    // This may occur with const or volatile types. There are separate type
    // symbols in PDB for types with const or volatile modifiers, but we need
    // to create only one declaration for them all.
    Type::ResolveState type_resolve_state;
    CompilerType clang_type = m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(
        m_ast.getASTContext(), name, decl_context);
    if (!clang_type.IsValid()) {
      auto tag_type_kind = TranslateUdtKind(udt->getUdtKind());

      ClangASTMetadata metadata;
      metadata.SetUserID(type.getSymIndexId());
      metadata.SetIsDynamicCXXType(false);

      clang_type = m_ast.CreateRecordType(
          decl_context, OptionalClangModuleID(), name, tag_type_kind,
          lldb::eLanguageTypeC_plus_plus, metadata);
      assert(clang_type.IsValid());

      auto record_decl =
          m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
      assert(record_decl);
      m_uid_to_decl[type.getSymIndexId()] = record_decl;

      auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit(
          m_ast.getASTContext(), GetMSInheritance(*udt));
      record_decl->addAttr(inheritance_attr);

      TypeSystemClang::StartTagDeclarationDefinition(clang_type);

      auto children = udt->findAllChildren();
      if (!children || children->getChildCount() == 0) {
        // PDB does not have symbol of forwarder. We assume we get an udt w/o
        // any fields. Just complete it at this point.
        TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);

        TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
                                               false);

        type_resolve_state = Type::ResolveState::Full;
      } else {
        // Add the type to the forward declarations. It will help us to avoid
        // an endless recursion in CompleteTypeFromUdt function.
        m_forward_decl_to_uid[record_decl] = type.getSymIndexId();

        TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
                                               true);

        type_resolve_state = Type::ResolveState::Forward;
      }
    } else
      type_resolve_state = Type::ResolveState::Forward;

    if (udt->isConstType())
      clang_type = clang_type.AddConstModifier();

    if (udt->isVolatileType())
      clang_type = clang_type.AddVolatileModifier();

    AddSourceInfoToDecl(type, decl);
    return m_ast.GetSymbolFile()->MakeType(
        type.getSymIndexId(), ConstString(name), udt->getLength(), nullptr,
        LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type,
        type_resolve_state);
  } break;
  case PDB_SymType::Enum: {
    auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);
    assert(enum_type);

    std::string name =
        std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName()));
    auto decl_context = GetDeclContextContainingSymbol(type);
    uint64_t bytes = enum_type->getLength();

    // Check if such an enum already exists in the current context
    CompilerType ast_enum = m_ast.GetTypeForIdentifier<clang::EnumDecl>(
        m_ast.getASTContext(), name, decl_context);
    if (!ast_enum.IsValid()) {
      auto underlying_type_up = enum_type->getUnderlyingType();
      if (!underlying_type_up)
        return nullptr;

      lldb::Encoding encoding =
          TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());
      // FIXME: Type of underlying builtin is always `Int`. We correct it with
      // the very first enumerator's encoding if any.
      auto first_child = enum_type->findOneChild<PDBSymbolData>();
      if (first_child)
        encoding = TranslateEnumEncoding(first_child->getValue().Type);

      CompilerType builtin_type;
      if (bytes > 0)
        builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(
            m_ast, *underlying_type_up, encoding, bytes * 8);
      else
        builtin_type = m_ast.GetBasicType(eBasicTypeInt);

      // FIXME: PDB does not have information about scoped enumeration (Enum
      // Class). Set it false for now.
      bool isScoped = false;

      ast_enum = m_ast.CreateEnumerationType(name, decl_context,
                                             OptionalClangModuleID(), decl,
                                             builtin_type, isScoped);

      auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
      assert(enum_decl);
      m_uid_to_decl[type.getSymIndexId()] = enum_decl;

      auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
      if (enum_values) {
        while (auto enum_value = enum_values->getNext()) {
          if (enum_value->getDataKind() != PDB_DataKind::Constant)
            continue;
          AddEnumValue(ast_enum, *enum_value);
        }
      }

      if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum))
        TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum);
    }

    if (enum_type->isConstType())
      ast_enum = ast_enum.AddConstModifier();

    if (enum_type->isVolatileType())
      ast_enum = ast_enum.AddVolatileModifier();

    AddSourceInfoToDecl(type, decl);
    return m_ast.GetSymbolFile()->MakeType(
        type.getSymIndexId(), ConstString(name), bytes, nullptr,
        LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ast_enum,
        lldb_private::Type::ResolveState::Full);
  } break;
  case PDB_SymType::Typedef: {
    auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
    assert(type_def);

    SymbolFile *symbol_file = m_ast.GetSymbolFile();
    if (!symbol_file)
      return nullptr;

    lldb_private::Type *target_type =
        symbol_file->ResolveTypeUID(type_def->getTypeId());
    if (!target_type)
      return nullptr;

    std::string name =
        std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName()));
    auto decl_ctx = GetDeclContextContainingSymbol(type);

    // Check if such a typedef already exists in the current context
    CompilerType ast_typedef =
        m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(
            m_ast.getASTContext(), name, decl_ctx);
    if (!ast_typedef.IsValid()) {
      CompilerType target_ast_type = target_type->GetFullCompilerType();

      ast_typedef = target_ast_type.CreateTypedef(
          name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
      if (!ast_typedef)
        return nullptr;

      auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef);
      assert(typedef_decl);
      m_uid_to_decl[type.getSymIndexId()] = typedef_decl;
    }

    if (type_def->isConstType())
      ast_typedef = ast_typedef.AddConstModifier();

    if (type_def->isVolatileType())
      ast_typedef = ast_typedef.AddVolatileModifier();

    AddSourceInfoToDecl(type, decl);
    std::optional<uint64_t> size;
    if (type_def->getLength())
      size = type_def->getLength();
    return m_ast.GetSymbolFile()->MakeType(
        type_def->getSymIndexId(), ConstString(name), size, nullptr,
        target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, decl,
        ast_typedef, lldb_private::Type::ResolveState::Full);
  } break;
  case PDB_SymType::Function:
  case PDB_SymType::FunctionSig: {
    std::string name;
    PDBSymbolTypeFunctionSig *func_sig = nullptr;
    if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) {
      if (pdb_func->isCompilerGenerated())
        return nullptr;

      auto sig = pdb_func->getSignature();
      if (!sig)
        return nullptr;
      func_sig = sig.release();
      // Function type is named.
      name = std::string(
          MSVCUndecoratedNameParser::DropScope(pdb_func->getName()));
    } else if (auto pdb_func_sig =
                   llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
      func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);
    } else
      llvm_unreachable("Unexpected PDB symbol!");

    auto arg_enum = func_sig->getArguments();
    uint32_t num_args = arg_enum->getChildCount();
    std::vector<CompilerType> arg_list;

    bool is_variadic = func_sig->isCVarArgs();
    // Drop last variadic argument.
    if (is_variadic)
      --num_args;
    for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) {
      auto arg = arg_enum->getChildAtIndex(arg_idx);
      if (!arg)
        break;

      SymbolFile *symbol_file = m_ast.GetSymbolFile();
      if (!symbol_file)
        return nullptr;

      lldb_private::Type *arg_type =
          symbol_file->ResolveTypeUID(arg->getSymIndexId());
      // If there's some error looking up one of the dependent types of this
      // function signature, bail.
      if (!arg_type)
        return nullptr;
      CompilerType arg_ast_type = arg_type->GetFullCompilerType();
      arg_list.push_back(arg_ast_type);
    }
    lldbassert(arg_list.size() <= num_args);

    auto pdb_return_type = func_sig->getReturnType();
    SymbolFile *symbol_file = m_ast.GetSymbolFile();
    if (!symbol_file)
      return nullptr;

    lldb_private::Type *return_type =
        symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId());
    // If there's some error looking up one of the dependent types of this
    // function signature, bail.
    if (!return_type)
      return nullptr;
    CompilerType return_ast_type = return_type->GetFullCompilerType();
    uint32_t type_quals = 0;
    if (func_sig->isConstType())
      type_quals |= clang::Qualifiers::Const;
    if (func_sig->isVolatileType())
      type_quals |= clang::Qualifiers::Volatile;
    auto cc = TranslateCallingConvention(func_sig->getCallingConvention());
    CompilerType func_sig_ast_type = m_ast.CreateFunctionType(
        return_ast_type, arg_list, is_variadic, type_quals, cc);

    AddSourceInfoToDecl(type, decl);
    return m_ast.GetSymbolFile()->MakeType(
        type.getSymIndexId(), ConstString(name), std::nullopt, nullptr,
        LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
        func_sig_ast_type, lldb_private::Type::ResolveState::Full);
  } break;
  case PDB_SymType::ArrayType: {
    auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
    assert(array_type);
    uint32_t num_elements = array_type->getCount();
    uint32_t element_uid = array_type->getElementTypeId();
    std::optional<uint64_t> bytes;
    if (uint64_t size = array_type->getLength())
      bytes = size;

    SymbolFile *symbol_file = m_ast.GetSymbolFile();
    if (!symbol_file)
      return nullptr;

    // If array rank > 0, PDB gives the element type at N=0. So element type
    // will parsed in the order N=0, N=1,..., N=rank sequentially.
    lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid);
    if (!element_type)
      return nullptr;

    CompilerType element_ast_type = element_type->GetForwardCompilerType();
    // If element type is UDT, it needs to be complete.
    if (TypeSystemClang::IsCXXClassType(element_ast_type) &&
        !element_ast_type.GetCompleteType()) {
      if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) {
        TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type);
      } else {
        // We are not able to start definition.
        return nullptr;
      }
    }
    CompilerType array_ast_type = m_ast.CreateArrayType(
        element_ast_type, num_elements, /*is_gnu_vector*/ false);
    TypeSP type_sp = m_ast.GetSymbolFile()->MakeType(
        array_type->getSymIndexId(), ConstString(), bytes, nullptr,
        LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
        array_ast_type, lldb_private::Type::ResolveState::Full);
    type_sp->SetEncodingType(element_type);
    return type_sp;
  } break;
  case PDB_SymType::BuiltinType: {
    auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);
    assert(builtin_type);
    PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType();
    if (builtin_kind == PDB_BuiltinType::None)
      return nullptr;

    std::optional<uint64_t> bytes;
    if (uint64_t size = builtin_type->getLength())
      bytes = size;
    Encoding encoding = TranslateBuiltinEncoding(builtin_kind);
    CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(
        m_ast, *builtin_type, encoding, bytes.value_or(0) * 8);

    if (builtin_type->isConstType())
      builtin_ast_type = builtin_ast_type.AddConstModifier();

    if (builtin_type->isVolatileType())
      builtin_ast_type = builtin_ast_type.AddVolatileModifier();

    auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type);

    return m_ast.GetSymbolFile()->MakeType(
        builtin_type->getSymIndexId(), type_name, bytes, nullptr,
        LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
        builtin_ast_type, lldb_private::Type::ResolveState::Full);
  } break;
  case PDB_SymType::PointerType: {
    auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
    assert(pointer_type);

    SymbolFile *symbol_file = m_ast.GetSymbolFile();
    if (!symbol_file)
      return nullptr;

    Type *pointee_type = symbol_file->ResolveTypeUID(
        pointer_type->getPointeeType()->getSymIndexId());
    if (!pointee_type)
      return nullptr;

    if (pointer_type->isPointerToDataMember() ||
        pointer_type->isPointerToMemberFunction()) {
      auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();
      auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid);
      assert(class_parent_type);

      CompilerType pointer_ast_type;
      pointer_ast_type = TypeSystemClang::CreateMemberPointerType(
          class_parent_type->GetLayoutCompilerType(),
          pointee_type->GetForwardCompilerType());
      assert(pointer_ast_type);

      return m_ast.GetSymbolFile()->MakeType(
          pointer_type->getSymIndexId(), ConstString(),
          pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
          lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
          lldb_private::Type::ResolveState::Forward);
    }

    CompilerType pointer_ast_type;
    pointer_ast_type = pointee_type->GetFullCompilerType();
    if (pointer_type->isReference())
      pointer_ast_type = pointer_ast_type.GetLValueReferenceType();
    else if (pointer_type->isRValueReference())
      pointer_ast_type = pointer_ast_type.GetRValueReferenceType();
    else
      pointer_ast_type = pointer_ast_type.GetPointerType();

    if (pointer_type->isConstType())
      pointer_ast_type = pointer_ast_type.AddConstModifier();

    if (pointer_type->isVolatileType())
      pointer_ast_type = pointer_ast_type.AddVolatileModifier();

    if (pointer_type->isRestrictedType())
      pointer_ast_type = pointer_ast_type.AddRestrictModifier();

    return m_ast.GetSymbolFile()->MakeType(
        pointer_type->getSymIndexId(), ConstString(), pointer_type->getLength(),
        nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
        pointer_ast_type, lldb_private::Type::ResolveState::Full);
  } break;
  default:
    break;
  }
  return nullptr;
}

bool PDBASTParser::CompleteTypeFromPDB(
    lldb_private::CompilerType &compiler_type) {
  if (GetClangASTImporter().CanImport(compiler_type))
    return GetClangASTImporter().CompleteType(compiler_type);

  // Remove the type from the forward declarations to avoid
  // an endless recursion for types like a linked list.
  clang::CXXRecordDecl *record_decl =
      m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
  auto uid_it = m_forward_decl_to_uid.find(record_decl);
  if (uid_it == m_forward_decl_to_uid.end())
    return true;

  auto symbol_file = static_cast<SymbolFilePDB *>(
      m_ast.GetSymbolFile()->GetBackingSymbolFile());
  if (!symbol_file)
    return false;

  std::unique_ptr<PDBSymbol> symbol =
      symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond());
  if (!symbol)
    return false;

  m_forward_decl_to_uid.erase(uid_it);

  TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
                                         false);

  switch (symbol->getSymTag()) {
  case PDB_SymType::UDT: {
    auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get());
    if (!udt)
      return false;

    return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt);
  }
  default:
    llvm_unreachable("not a forward clang type decl!");
  }
}

clang::Decl *
PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
  uint32_t sym_id = symbol.getSymIndexId();
  auto it = m_uid_to_decl.find(sym_id);
  if (it != m_uid_to_decl.end())
    return it->second;

  auto symbol_file = static_cast<SymbolFilePDB *>(
      m_ast.GetSymbolFile()->GetBackingSymbolFile());
  if (!symbol_file)
    return nullptr;

  // First of all, check if the symbol is a member of a class. Resolve the full
  // class type and return the declaration from the cache if so.
  auto tag = symbol.getSymTag();
  if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) {
    const IPDBSession &session = symbol.getSession();
    const IPDBRawSymbol &raw = symbol.getRawSymbol();

    auto class_parent_id = raw.getClassParentId();
    if (std::unique_ptr<PDBSymbol> class_parent =
            session.getSymbolById(class_parent_id)) {
      auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id);
      if (!class_parent_type)
        return nullptr;

      CompilerType class_parent_ct = class_parent_type->GetFullCompilerType();

      // Look a declaration up in the cache after completing the class
      clang::Decl *decl = m_uid_to_decl.lookup(sym_id);
      if (decl)
        return decl;

      // A declaration was not found in the cache. It means that the symbol
      // has the class parent, but the class doesn't have the symbol in its
      // children list.
      if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) {
        // Try to find a class child method with the same RVA and use its
        // declaration if found.
        if (uint32_t rva = func->getRelativeVirtualAddress()) {
          if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>>
                  methods_enum =
                      class_parent->findAllChildren<PDBSymbolFunc>()) {
            while (std::unique_ptr<PDBSymbolFunc> method =
                       methods_enum->getNext()) {
              if (method->getRelativeVirtualAddress() == rva) {
                decl = m_uid_to_decl.lookup(method->getSymIndexId());
                if (decl)
                  break;
              }
            }
          }
        }

        // If no class methods with the same RVA were found, then create a new
        // method. It is possible for template methods.
        if (!decl)
          decl = AddRecordMethod(*symbol_file, class_parent_ct, *func);
      }

      if (decl)
        m_uid_to_decl[sym_id] = decl;

      return decl;
    }
  }

  // If we are here, then the symbol is not belonging to a class and is not
  // contained in the cache. So create a declaration for it.
  switch (symbol.getSymTag()) {
  case PDB_SymType::Data: {
    auto data = llvm::dyn_cast<PDBSymbolData>(&symbol);
    assert(data);

    auto decl_context = GetDeclContextContainingSymbol(symbol);
    assert(decl_context);

    // May be the current context is a class really, but we haven't found
    // any class parent. This happens e.g. in the case of class static
    // variables - they has two symbols, one is a child of the class when
    // another is a child of the exe. So always complete the parent and use
    // an existing declaration if possible.
    if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context))
      m_ast.GetCompleteDecl(parent_decl);

    std::string name =
        std::string(MSVCUndecoratedNameParser::DropScope(data->getName()));

    // Check if the current context already contains the symbol with the name.
    clang::Decl *decl =
        GetDeclFromContextByName(m_ast.getASTContext(), *decl_context, name);
    if (!decl) {
      auto type = symbol_file->ResolveTypeUID(data->getTypeId());
      if (!type)
        return nullptr;

      decl = m_ast.CreateVariableDeclaration(
          decl_context, OptionalClangModuleID(), name.c_str(),
          ClangUtil::GetQualType(type->GetLayoutCompilerType()));
    }

    m_uid_to_decl[sym_id] = decl;

    return decl;
  }
  case PDB_SymType::Function: {
    auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol);
    assert(func);

    auto decl_context = GetDeclContextContainingSymbol(symbol);
    assert(decl_context);

    std::string name =
        std::string(MSVCUndecoratedNameParser::DropScope(func->getName()));

    Type *type = symbol_file->ResolveTypeUID(sym_id);
    if (!type)
      return nullptr;

    auto storage = func->isStatic() ? clang::StorageClass::SC_Static
                                    : clang::StorageClass::SC_None;

    auto decl = m_ast.CreateFunctionDeclaration(
        decl_context, OptionalClangModuleID(), name,
        type->GetForwardCompilerType(), storage, func->hasInlineAttribute(),
        /*asm_label=*/{});

    std::vector<clang::ParmVarDecl *> params;
    if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
      if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>>
              arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) {
        while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg =
                   arg_enum->getNext()) {
          Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId());
          if (!arg_type)
            continue;

          clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
              decl, OptionalClangModuleID(), nullptr,
              arg_type->GetForwardCompilerType(), clang::SC_None, true);
          if (param)
            params.push_back(param);
        }
      }
    }
    if (params.size() && decl)
      decl->setParams(params);

    m_uid_to_decl[sym_id] = decl;

    return decl;
  }
  default: {
    // It's not a variable and not a function, check if it's a type
    Type *type = symbol_file->ResolveTypeUID(sym_id);
    if (!type)
      return nullptr;

    return m_uid_to_decl.lookup(sym_id);
  }
  }
}

clang::DeclContext *
PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) {
  if (symbol.getSymTag() == PDB_SymType::Function) {
    clang::DeclContext *result =
        llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol));

    if (result)
      m_decl_context_to_uid[result] = symbol.getSymIndexId();

    return result;
  }

  auto symbol_file = static_cast<SymbolFilePDB *>(
      m_ast.GetSymbolFile()->GetBackingSymbolFile());
  if (!symbol_file)
    return nullptr;

  auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId());
  if (!type)
    return nullptr;

  clang::DeclContext *result =
      m_ast.GetDeclContextForType(type->GetForwardCompilerType());

  if (result)
    m_decl_context_to_uid[result] = symbol.getSymIndexId();

  return result;
}

clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
    const llvm::pdb::PDBSymbol &symbol) {
  auto parent = GetClassOrFunctionParent(symbol);
  while (parent) {
    if (auto parent_context = GetDeclContextForSymbol(*parent))
      return parent_context;

    parent = GetClassOrFunctionParent(*parent);
  }

  // We can't find any class or function parent of the symbol. So analyze
  // the full symbol name. The symbol may be belonging to a namespace
  // or function (or even to a class if it's e.g. a static variable symbol).

  // TODO: Make clang to emit full names for variables in namespaces
  // (as MSVC does)

  std::string name(symbol.getRawSymbol().getName());
  MSVCUndecoratedNameParser parser(name);
  llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
  if (specs.empty())
    return m_ast.GetTranslationUnitDecl();

  auto symbol_file = static_cast<SymbolFilePDB *>(
      m_ast.GetSymbolFile()->GetBackingSymbolFile());
  if (!symbol_file)
    return m_ast.GetTranslationUnitDecl();

  auto global = symbol_file->GetPDBSession().getGlobalScope();
  if (!global)
    return m_ast.GetTranslationUnitDecl();

  bool has_type_or_function_parent = false;
  clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl();
  for (std::size_t i = 0; i < specs.size() - 1; i++) {
    // Check if there is a function or a type with the current context's name.
    if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren(
            PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) {
      while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child =
                 children_enum->getNext()) {
        if (clang::DeclContext *child_context =
                GetDeclContextForSymbol(*child)) {
          // Note that `GetDeclContextForSymbol' retrieves
          // a declaration context for functions and types only,
          // so if we are here then `child_context' is guaranteed
          // a function or a type declaration context.
          has_type_or_function_parent = true;
          curr_context = child_context;
        }
      }
    }

    // If there were no functions or types above then retrieve a namespace with
    // the current context's name. There can be no namespaces inside a function
    // or a type. We check it to avoid fake namespaces such as `__l2':
    // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct'
    if (!has_type_or_function_parent) {
      std::string namespace_name = std::string(specs[i].GetBaseName());
      const char *namespace_name_c_str =
          IsAnonymousNamespaceName(namespace_name) ? nullptr
                                                   : namespace_name.data();
      clang::NamespaceDecl *namespace_decl =
          m_ast.GetUniqueNamespaceDeclaration(
              namespace_name_c_str, curr_context, OptionalClangModuleID());

      m_parent_to_namespaces[curr_context].insert(namespace_decl);
      m_namespaces.insert(namespace_decl);

      curr_context = namespace_decl;
    }
  }

  return curr_context;
}

void PDBASTParser::ParseDeclsForDeclContext(
    const clang::DeclContext *decl_context) {
  auto symbol_file = static_cast<SymbolFilePDB *>(
      m_ast.GetSymbolFile()->GetBackingSymbolFile());
  if (!symbol_file)
    return;

  IPDBSession &session = symbol_file->GetPDBSession();
  auto symbol_up =
      session.getSymbolById(m_decl_context_to_uid.lookup(decl_context));
  auto global_up = session.getGlobalScope();

  PDBSymbol *symbol;
  if (symbol_up)
    symbol = symbol_up.get();
  else if (global_up)
    symbol = global_up.get();
  else
    return;

  if (auto children = symbol->findAllChildren())
    while (auto child = children->getNext())
      GetDeclForSymbol(*child);
}

clang::NamespaceDecl *
PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent,
                                llvm::StringRef name) {
  NamespacesSet *set;
  if (parent) {
    auto pit = m_parent_to_namespaces.find(parent);
    if (pit == m_parent_to_namespaces.end())
      return nullptr;

    set = &pit->second;
  } else {
    set = &m_namespaces;
  }
  assert(set);

  for (clang::NamespaceDecl *namespace_decl : *set)
    if (namespace_decl->getName() == name)
      return namespace_decl;

  for (clang::NamespaceDecl *namespace_decl : *set)
    if (namespace_decl->isAnonymousNamespace())
      return FindNamespaceDecl(namespace_decl, name);

  return nullptr;
}

bool PDBASTParser::AddEnumValue(CompilerType enum_type,
                                const PDBSymbolData &enum_value) {
  Declaration decl;
  Variant v = enum_value.getValue();
  std::string name =
      std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName()));
  uint64_t raw_value;
  switch (v.Type) {
  case PDB_VariantType::Int8:
    raw_value = v.Value.Int8;
    break;
  case PDB_VariantType::Int16:
    raw_value = v.Value.Int16;
    break;
  case PDB_VariantType::Int32:
    raw_value = v.Value.Int32;
    break;
  case PDB_VariantType::Int64:
    raw_value = v.Value.Int64;
    break;
  case PDB_VariantType::UInt8:
    raw_value = v.Value.UInt8;
    break;
  case PDB_VariantType::UInt16:
    raw_value = v.Value.UInt16;
    break;
  case PDB_VariantType::UInt32:
    raw_value = v.Value.UInt32;
    break;
  case PDB_VariantType::UInt64:
    raw_value = v.Value.UInt64;
    break;
  default:
    return false;
  }
  CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type);
  uint32_t byte_size = m_ast.getASTContext().getTypeSize(
      ClangUtil::GetQualType(underlying_type));
  auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(
      enum_type, decl, name.c_str(), raw_value, byte_size * 8);
  if (!enum_constant_decl)
    return false;

  m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl;

  return true;
}

bool PDBASTParser::CompleteTypeFromUDT(
    lldb_private::SymbolFile &symbol_file,
    lldb_private::CompilerType &compiler_type,
    llvm::pdb::PDBSymbolTypeUDT &udt) {
  ClangASTImporter::LayoutInfo layout_info;
  layout_info.bit_size = udt.getLength() * 8;

  auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>();
  if (nested_enums)
    while (auto nested = nested_enums->getNext())
      symbol_file.ResolveTypeUID(nested->getSymIndexId());

  auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
  if (bases_enum)
    AddRecordBases(symbol_file, compiler_type,
                   TranslateUdtKind(udt.getUdtKind()), *bases_enum,
                   layout_info);

  auto members_enum = udt.findAllChildren<PDBSymbolData>();
  if (members_enum)
    AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info);

  auto methods_enum = udt.findAllChildren<PDBSymbolFunc>();
  if (methods_enum)
    AddRecordMethods(symbol_file, compiler_type, *methods_enum);

  m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType());
  TypeSystemClang::BuildIndirectFields(compiler_type);
  TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);

  clang::CXXRecordDecl *record_decl =
      m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
  if (!record_decl)
    return static_cast<bool>(compiler_type);

  GetClangASTImporter().SetRecordLayout(record_decl, layout_info);

  return static_cast<bool>(compiler_type);
}

void PDBASTParser::AddRecordMembers(
    lldb_private::SymbolFile &symbol_file,
    lldb_private::CompilerType &record_type,
    PDBDataSymbolEnumerator &members_enum,
    lldb_private::ClangASTImporter::LayoutInfo &layout_info) {
  while (auto member = members_enum.getNext()) {
    if (member->isCompilerGenerated())
      continue;

    auto member_name = member->getName();

    auto member_type = symbol_file.ResolveTypeUID(member->getTypeId());
    if (!member_type)
      continue;

    auto member_comp_type = member_type->GetLayoutCompilerType();
    if (!member_comp_type.GetCompleteType()) {
      symbol_file.GetObjectFile()->GetModule()->ReportError(
          ":: Class '{0}' has a member '{1}' of type '{2}' "
          "which does not have a complete definition.",
          record_type.GetTypeName().GetCString(), member_name.c_str(),
          member_comp_type.GetTypeName().GetCString());
      if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type))
        TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type);
    }

    switch (member->getDataKind()) {
    case PDB_DataKind::Member: {
      auto location_type = member->getLocationType();

      auto bit_size = member->getLength();
      if (location_type == PDB_LocType::ThisRel)
        bit_size *= 8;

      auto decl = TypeSystemClang::AddFieldToRecordType(
          record_type, member_name.c_str(), member_comp_type, bit_size);
      if (!decl)
        continue;

      m_uid_to_decl[member->getSymIndexId()] = decl;

      auto offset = member->getOffset() * 8;
      if (location_type == PDB_LocType::BitField)
        offset += member->getBitPosition();

      layout_info.field_offsets.insert(std::make_pair(decl, offset));

      break;
    }
    case PDB_DataKind::StaticMember: {
      auto decl = TypeSystemClang::AddVariableToRecordType(
          record_type, member_name.c_str(), member_comp_type);
      if (!decl)
        continue;

      // Static constant members may be a const[expr] declaration.
      // Query the symbol's value as the variable initializer if valid.
      if (member_comp_type.IsConst()) {
        auto value = member->getValue();
        if (value.Type == llvm::pdb::Empty) {
          LLDB_LOG(GetLog(LLDBLog::AST),
                   "Class '{0}' has member '{1}' of type '{2}' with an unknown "
                   "constant size.",
                   record_type.GetTypeName(), member_name,
                   member_comp_type.GetTypeName());
          continue;
        }

        clang::QualType qual_type = decl->getType();
        unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type);
        unsigned constant_width = value.getBitWidth();

        if (qual_type->isIntegralOrEnumerationType()) {
          if (type_width >= constant_width) {
            TypeSystemClang::SetIntegerInitializerForVariable(
                decl, value.toAPSInt().extOrTrunc(type_width));
          } else {
            LLDB_LOG(GetLog(LLDBLog::AST),
                     "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
                     "which resolves to a wider constant value ({4} bits). "
                     "Ignoring constant.",
                     record_type.GetTypeName(), member_name,
                     member_comp_type.GetTypeName(), type_width,
                     constant_width);
          }
        } else {
          switch (member_comp_type.GetBasicTypeEnumeration()) {
          case lldb::eBasicTypeFloat:
          case lldb::eBasicTypeDouble:
          case lldb::eBasicTypeLongDouble:
            if (type_width == constant_width) {
              TypeSystemClang::SetFloatingInitializerForVariable(
                  decl, value.toAPFloat());
              decl->setConstexpr(true);
            } else {
              LLDB_LOG(GetLog(LLDBLog::AST),
                       "Class '{0}' has a member '{1}' of type '{2}' ({3} "
                       "bits) which resolves to a constant value of mismatched "
                       "width ({4} bits). Ignoring constant.",
                       record_type.GetTypeName(), member_name,
                       member_comp_type.GetTypeName(), type_width,
                       constant_width);
            }
            break;
          default:
            break;
          }
        }
      }

      m_uid_to_decl[member->getSymIndexId()] = decl;

      break;
    }
    default:
      llvm_unreachable("unsupported PDB data kind");
    }
  }
}

void PDBASTParser::AddRecordBases(
    lldb_private::SymbolFile &symbol_file,
    lldb_private::CompilerType &record_type, int record_kind,
    PDBBaseClassSymbolEnumerator &bases_enum,
    lldb_private::ClangASTImporter::LayoutInfo &layout_info) const {
  std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes;

  while (auto base = bases_enum.getNext()) {
    auto base_type = symbol_file.ResolveTypeUID(base->getTypeId());
    if (!base_type)
      continue;

    auto base_comp_type = base_type->GetFullCompilerType();
    if (!base_comp_type.GetCompleteType()) {
      symbol_file.GetObjectFile()->GetModule()->ReportError(
          ":: Class '{0}' has a base class '{1}' "
          "which does not have a complete definition.",
          record_type.GetTypeName().GetCString(),
          base_comp_type.GetTypeName().GetCString());
      if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type))
        TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type);
    }

    auto access = TranslateMemberAccess(base->getAccess());

    auto is_virtual = base->isVirtualBaseClass();

    std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
        m_ast.CreateBaseClassSpecifier(
            base_comp_type.GetOpaqueQualType(), access, is_virtual,
            record_kind == llvm::to_underlying(clang::TagTypeKind::Class));
    lldbassert(base_spec);

    base_classes.push_back(std::move(base_spec));

    if (is_virtual)
      continue;

    auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType());
    if (!decl)
      continue;

    auto offset = clang::CharUnits::fromQuantity(base->getOffset());
    layout_info.base_offsets.insert(std::make_pair(decl, offset));
  }

  m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(),
                            std::move(base_classes));
}

void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file,
                                    lldb_private::CompilerType &record_type,
                                    PDBFuncSymbolEnumerator &methods_enum) {
  while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext())
    if (clang::CXXMethodDecl *decl =
            AddRecordMethod(symbol_file, record_type, *method))
      m_uid_to_decl[method->getSymIndexId()] = decl;
}

clang::CXXMethodDecl *
PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
                              lldb_private::CompilerType &record_type,
                              const llvm::pdb::PDBSymbolFunc &method) const {
  std::string name =
      std::string(MSVCUndecoratedNameParser::DropScope(method.getName()));

  Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId());
  // MSVC specific __vecDelDtor.
  if (!method_type)
    return nullptr;

  CompilerType method_comp_type = method_type->GetFullCompilerType();
  if (!method_comp_type.GetCompleteType()) {
    symbol_file.GetObjectFile()->GetModule()->ReportError(
        ":: Class '{0}' has a method '{1}' whose type cannot be completed.",
        record_type.GetTypeName().GetCString(),
        method_comp_type.GetTypeName().GetCString());
    if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type))
      TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type);
  }

  // TODO: get mangled name for the method.
  return m_ast.AddMethodToCXXRecordType(
      record_type.GetOpaqueQualType(), name.c_str(),
      /*asm_label=*/{}, method_comp_type, method.isVirtual(), method.isStatic(),
      method.hasInlineAttribute(),
      /*is_explicit*/ false, // FIXME: Need this field in CodeView.
      /*is_attr_used*/ false,
      /*is_artificial*/ method.isCompilerGenerated());
}
