//===-- ClangASTImporter.cpp ------------------------------------*- C++ -*-===//
//
// 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 "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "llvm/Support/raw_ostream.h"

#include <memory>

using namespace lldb_private;
using namespace clang;

ClangASTMetrics::Counters ClangASTMetrics::global_counters = {0, 0, 0, 0, 0, 0};
ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0};

void ClangASTMetrics::DumpCounters(Log *log,
                                   ClangASTMetrics::Counters &counters) {
  LLDB_LOGF(log, "  Number of visible Decl queries by name     : %" PRIu64,
            counters.m_visible_query_count);
  LLDB_LOGF(log, "  Number of lexical Decl queries             : %" PRIu64,
            counters.m_lexical_query_count);
  LLDB_LOGF(log, "  Number of imports initiated by LLDB        : %" PRIu64,
            counters.m_lldb_import_count);
  LLDB_LOGF(log, "  Number of imports conducted by Clang       : %" PRIu64,
            counters.m_clang_import_count);
  LLDB_LOGF(log, "  Number of Decls completed                  : %" PRIu64,
            counters.m_decls_completed_count);
  LLDB_LOGF(log, "  Number of records laid out                 : %" PRIu64,
            counters.m_record_layout_count);
}

void ClangASTMetrics::DumpCounters(Log *log) {
  if (!log)
    return;

  LLDB_LOGF(log, "== ClangASTMetrics output ==");
  LLDB_LOGF(log, "-- Global metrics --");
  DumpCounters(log, global_counters);
  LLDB_LOGF(log, "-- Local metrics --");
  DumpCounters(log, local_counters);
}

clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
                                           clang::ASTContext *src_ast,
                                           clang::QualType type) {
  ImporterDelegateSP delegate_sp(GetDelegate(dst_ast, src_ast));

  ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);

  if (!delegate_sp)
    return QualType();

  llvm::Expected<QualType> ret_or_error = delegate_sp->Import(type);
  if (!ret_or_error) {
    Log *log =
      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
    LLDB_LOG_ERROR(log, ret_or_error.takeError(),
        "Couldn't import type: {0}");
    return QualType();
  }
  return *ret_or_error;
}

lldb::opaque_compiler_type_t
ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
                           clang::ASTContext *src_ast,
                           lldb::opaque_compiler_type_t type) {
  return CopyType(dst_ast, src_ast, QualType::getFromOpaquePtr(type))
      .getAsOpaquePtr();
}

CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast,
                                        const CompilerType &src_type) {
  clang::ASTContext *dst_clang_ast = dst_ast.getASTContext();
  if (dst_clang_ast) {
    ClangASTContext *src_ast =
        llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
    if (src_ast) {
      clang::ASTContext *src_clang_ast = src_ast->getASTContext();
      if (src_clang_ast) {
        lldb::opaque_compiler_type_t dst_clang_type = CopyType(
            dst_clang_ast, src_clang_ast, src_type.GetOpaqueQualType());

        if (dst_clang_type)
          return CompilerType(&dst_ast, dst_clang_type);
      }
    }
  }
  return CompilerType();
}

clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
                                        clang::ASTContext *src_ast,
                                        clang::Decl *decl) {
  ImporterDelegateSP delegate_sp;

  delegate_sp = GetDelegate(dst_ast, src_ast);

  ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);

  if (!delegate_sp)
    return nullptr;

  llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl);
  if (!result) {
    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
    LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}");
    if (log) {
      lldb::user_id_t user_id = LLDB_INVALID_UID;
      ClangASTMetadata *metadata = GetDeclMetadata(decl);
      if (metadata)
        user_id = metadata->GetUserID();

      if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
        LLDB_LOGF(log,
                  "  [ClangASTImporter] WARNING: Failed to import a %s "
                  "'%s', metadata 0x%" PRIx64,
                  decl->getDeclKindName(),
                  named_decl->getNameAsString().c_str(), user_id);
      else
        LLDB_LOGF(log,
                  "  [ClangASTImporter] WARNING: Failed to import a %s, "
                  "metadata 0x%" PRIx64,
                  decl->getDeclKindName(), user_id);
    }
    return nullptr;
  }

  return *result;
}

class DeclContextOverride {
private:
  struct Backup {
    clang::DeclContext *decl_context;
    clang::DeclContext *lexical_decl_context;
  };

  std::map<clang::Decl *, Backup> m_backups;

  void OverrideOne(clang::Decl *decl) {
    if (m_backups.find(decl) != m_backups.end()) {
      return;
    }

    m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()};

    decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl());
    decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl());
  }

  bool ChainPassesThrough(
      clang::Decl *decl, clang::DeclContext *base,
      clang::DeclContext *(clang::Decl::*contextFromDecl)(),
      clang::DeclContext *(clang::DeclContext::*contextFromContext)()) {
    for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx;
         decl_ctx = (decl_ctx->*contextFromContext)()) {
      if (decl_ctx == base) {
        return true;
      }
    }

    return false;
  }

  clang::Decl *GetEscapedChild(clang::Decl *decl,
                               clang::DeclContext *base = nullptr) {
    if (base) {
      // decl's DeclContext chains must pass through base.

      if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext,
                              &clang::DeclContext::getParent) ||
          !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext,
                              &clang::DeclContext::getLexicalParent)) {
        return decl;
      }
    } else {
      base = clang::dyn_cast<clang::DeclContext>(decl);

      if (!base) {
        return nullptr;
      }
    }

    if (clang::DeclContext *context =
            clang::dyn_cast<clang::DeclContext>(decl)) {
      for (clang::Decl *decl : context->decls()) {
        if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
          return escaped_child;
        }
      }
    }

    return nullptr;
  }

  void Override(clang::Decl *decl) {
    if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

      LLDB_LOGF(log,
                "    [ClangASTImporter] DeclContextOverride couldn't "
                "override (%sDecl*)%p - its child (%sDecl*)%p escapes",
                decl->getDeclKindName(), static_cast<void *>(decl),
                escaped_child->getDeclKindName(),
                static_cast<void *>(escaped_child));
      lldbassert(0 && "Couldn't override!");
    }

    OverrideOne(decl);
  }

public:
  DeclContextOverride() {}

  void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
    for (DeclContext *decl_context = decl->getLexicalDeclContext();
         decl_context; decl_context = decl_context->getLexicalParent()) {
      DeclContext *redecl_context = decl_context->getRedeclContext();

      if (llvm::isa<FunctionDecl>(redecl_context) &&
          llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) {
        for (clang::Decl *child_decl : decl_context->decls()) {
          Override(child_decl);
        }
      }
    }
  }

  ~DeclContextOverride() {
    for (const std::pair<clang::Decl *, Backup> &backup : m_backups) {
      backup.first->setDeclContext(backup.second.decl_context);
      backup.first->setLexicalDeclContext(backup.second.lexical_decl_context);
    }
  }
};

namespace {
/// Completes all imported TagDecls at the end of the scope.
///
/// While in a CompleteTagDeclsScope, every decl that could be completed will
/// be completed at the end of the scope (including all Decls that are
/// imported while completing the original Decls).
class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener {
  ClangASTImporter::ImporterDelegateSP m_delegate;
  // FIXME: Investigate how many decls we usually have in these sets and
  // see if we can use SmallPtrSet instead here.
  std::set<NamedDecl *> m_decls_to_complete;
  std::set<NamedDecl *> m_decls_already_completed;
  clang::ASTContext *m_dst_ctx;
  clang::ASTContext *m_src_ctx;
  ClangASTImporter &importer;

public:
  /// Constructs a CompleteTagDeclsScope.
  /// \param importer The ClangASTImporter that we should observe.
  /// \param dst_ctx The ASTContext to which Decls are imported.
  /// \param src_ctx The ASTContext from which Decls are imported.
  explicit CompleteTagDeclsScope(ClangASTImporter &importer,
                            clang::ASTContext *dst_ctx,
                            clang::ASTContext *src_ctx)
      : m_delegate(importer.GetDelegate(dst_ctx, src_ctx)), m_dst_ctx(dst_ctx),
        m_src_ctx(src_ctx), importer(importer) {
    m_delegate->SetImportListener(this);
  }

  virtual ~CompleteTagDeclsScope() {
    ClangASTImporter::ASTContextMetadataSP to_context_md =
        importer.GetContextMetadata(m_dst_ctx);

    // Complete all decls we collected until now.
    while (!m_decls_to_complete.empty()) {
      NamedDecl *decl = *m_decls_to_complete.begin();

      m_decls_already_completed.insert(decl);
      m_decls_to_complete.erase(decl);

      // We should only complete decls coming from the source context.
      assert(to_context_md->m_origins[decl].ctx == m_src_ctx);

      Decl *original_decl = to_context_md->m_origins[decl].decl;

      // Complete the decl now.
      ClangASTContext::GetCompleteDecl(m_src_ctx, original_decl);
      if (auto *tag_decl = dyn_cast<TagDecl>(decl)) {
        if (auto *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
          if (original_tag_decl->isCompleteDefinition()) {
            m_delegate->ImportDefinitionTo(tag_decl, original_tag_decl);
            tag_decl->setCompleteDefinition(true);
          }
        }

        tag_decl->setHasExternalLexicalStorage(false);
        tag_decl->setHasExternalVisibleStorage(false);
      } else if (auto *container_decl = dyn_cast<ObjCContainerDecl>(decl)) {
        container_decl->setHasExternalLexicalStorage(false);
        container_decl->setHasExternalVisibleStorage(false);
      }

      to_context_md->m_origins.erase(decl);
    }

    // Stop listening to imported decls. We do this after clearing the
    // Decls we needed to import to catch all Decls they might have pulled in.
    m_delegate->RemoveImportListener();
  }

  void NewDeclImported(clang::Decl *from, clang::Decl *to) override {
    // Filter out decls that we can't complete later.
    if (!isa<TagDecl>(to) && !isa<ObjCInterfaceDecl>(to))
      return;
    RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
    // We don't need to complete injected class name decls.
    if (from_record_decl && from_record_decl->isInjectedClassName())
      return;

    NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
    // Check if we already completed this type.
    if (m_decls_already_completed.count(to_named_decl) != 0)
      return;
    m_decls_to_complete.insert(to_named_decl);
  }
};
} // namespace

lldb::opaque_compiler_type_t
ClangASTImporter::DeportType(clang::ASTContext *dst_ctx,
                             clang::ASTContext *src_ctx,
                             lldb::opaque_compiler_type_t type) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  LLDB_LOGF(log,
            "    [ClangASTImporter] DeportType called on (%sType*)0x%llx "
            "from (ASTContext*)%p to (ASTContext*)%p",
            QualType::getFromOpaquePtr(type)->getTypeClassName(),
            (unsigned long long)type, static_cast<void *>(src_ctx),
            static_cast<void *>(dst_ctx));

  DeclContextOverride decl_context_override;

  if (auto *t = QualType::getFromOpaquePtr(type)->getAs<TagType>())
    decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl());

  lldb::opaque_compiler_type_t result;
  {
    CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
    result = CopyType(dst_ctx, src_ctx, type);
  }

  if (!result)
    return nullptr;

  return result;
}

clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx,
                                          clang::ASTContext *src_ctx,
                                          clang::Decl *decl) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  LLDB_LOGF(log,
            "    [ClangASTImporter] DeportDecl called on (%sDecl*)%p from "
            "(ASTContext*)%p to (ASTContext*)%p",
            decl->getDeclKindName(), static_cast<void *>(decl),
            static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx));

  DeclContextOverride decl_context_override;

  decl_context_override.OverrideAllDeclsFromContainingFunction(decl);

  clang::Decl *result;
  {
    CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
    result = CopyDecl(dst_ctx, src_ctx, decl);
  }

  if (!result)
    return nullptr;

  LLDB_LOGF(
      log,
      "    [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
      decl->getDeclKindName(), static_cast<void *>(decl),
      result->getDeclKindName(), static_cast<void *>(result));

  return result;
}

bool ClangASTImporter::CanImport(const CompilerType &type) {
  if (!ClangUtil::IsClangType(type))
    return false;

  // TODO: remove external completion BOOL
  // CompleteAndFetchChildren should get the Decl out and check for the

  clang::QualType qual_type(
      ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record: {
    const clang::CXXRecordDecl *cxx_record_decl =
        qual_type->getAsCXXRecordDecl();
    if (cxx_record_decl) {
      if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr))
        return true;
    }
  } break;

  case clang::Type::Enum: {
    clang::EnumDecl *enum_decl =
        llvm::cast<clang::EnumType>(qual_type)->getDecl();
    if (enum_decl) {
      if (ResolveDeclOrigin(enum_decl, nullptr, nullptr))
        return true;
    }
  } break;

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface: {
    const clang::ObjCObjectType *objc_class_type =
        llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
    if (objc_class_type) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_class_type->getInterface();
      // We currently can't complete objective C types through the newly added
      // ASTContext because it only supports TagDecl objects right now...
      if (class_interface_decl) {
        if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr))
          return true;
      }
    }
  } break;

  case clang::Type::Typedef:
    return CanImport(CompilerType(type.GetTypeSystem(),
                                  llvm::cast<clang::TypedefType>(qual_type)
                                      ->getDecl()
                                      ->getUnderlyingType()
                                      .getAsOpaquePtr()));

  case clang::Type::Auto:
    return CanImport(CompilerType(type.GetTypeSystem(),
                                  llvm::cast<clang::AutoType>(qual_type)
                                      ->getDeducedType()
                                      .getAsOpaquePtr()));

  case clang::Type::Elaborated:
    return CanImport(CompilerType(type.GetTypeSystem(),
                                  llvm::cast<clang::ElaboratedType>(qual_type)
                                      ->getNamedType()
                                      .getAsOpaquePtr()));

  case clang::Type::Paren:
    return CanImport(CompilerType(
        type.GetTypeSystem(),
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));

  default:
    break;
  }

  return false;
}

bool ClangASTImporter::Import(const CompilerType &type) {
  if (!ClangUtil::IsClangType(type))
    return false;
  // TODO: remove external completion BOOL
  // CompleteAndFetchChildren should get the Decl out and check for the

  clang::QualType qual_type(
      ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));

  const clang::Type::TypeClass type_class = qual_type->getTypeClass();
  switch (type_class) {
  case clang::Type::Record: {
    const clang::CXXRecordDecl *cxx_record_decl =
        qual_type->getAsCXXRecordDecl();
    if (cxx_record_decl) {
      if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr))
        return CompleteAndFetchChildren(qual_type);
    }
  } break;

  case clang::Type::Enum: {
    clang::EnumDecl *enum_decl =
        llvm::cast<clang::EnumType>(qual_type)->getDecl();
    if (enum_decl) {
      if (ResolveDeclOrigin(enum_decl, nullptr, nullptr))
        return CompleteAndFetchChildren(qual_type);
    }
  } break;

  case clang::Type::ObjCObject:
  case clang::Type::ObjCInterface: {
    const clang::ObjCObjectType *objc_class_type =
        llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
    if (objc_class_type) {
      clang::ObjCInterfaceDecl *class_interface_decl =
          objc_class_type->getInterface();
      // We currently can't complete objective C types through the newly added
      // ASTContext because it only supports TagDecl objects right now...
      if (class_interface_decl) {
        if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr))
          return CompleteAndFetchChildren(qual_type);
      }
    }
  } break;

  case clang::Type::Typedef:
    return Import(CompilerType(type.GetTypeSystem(),
                               llvm::cast<clang::TypedefType>(qual_type)
                                   ->getDecl()
                                   ->getUnderlyingType()
                                   .getAsOpaquePtr()));

  case clang::Type::Auto:
    return Import(CompilerType(type.GetTypeSystem(),
                               llvm::cast<clang::AutoType>(qual_type)
                                   ->getDeducedType()
                                   .getAsOpaquePtr()));

  case clang::Type::Elaborated:
    return Import(CompilerType(type.GetTypeSystem(),
                               llvm::cast<clang::ElaboratedType>(qual_type)
                                   ->getNamedType()
                                   .getAsOpaquePtr()));

  case clang::Type::Paren:
    return Import(CompilerType(
        type.GetTypeSystem(),
        llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));

  default:
    break;
  }
  return false;
}

bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) {
  if (!CanImport(compiler_type))
    return false;

  if (Import(compiler_type)) {
    ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
    return true;
  }

  ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
                                         false);
  return false;
}

bool ClangASTImporter::LayoutRecordType(
    const clang::RecordDecl *record_decl, uint64_t &bit_size,
    uint64_t &alignment,
    llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
        &base_offsets,
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
        &vbase_offsets) {
  RecordDeclToLayoutMap::iterator pos =
      m_record_decl_to_layout_map.find(record_decl);
  bool success = false;
  base_offsets.clear();
  vbase_offsets.clear();
  if (pos != m_record_decl_to_layout_map.end()) {
    bit_size = pos->second.bit_size;
    alignment = pos->second.alignment;
    field_offsets.swap(pos->second.field_offsets);
    base_offsets.swap(pos->second.base_offsets);
    vbase_offsets.swap(pos->second.vbase_offsets);
    m_record_decl_to_layout_map.erase(pos);
    success = true;
  } else {
    bit_size = 0;
    alignment = 0;
    field_offsets.clear();
  }
  return success;
}

void ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl,
                                        const LayoutInfo &layout) {
  m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
}

void ClangASTImporter::CompleteDecl(clang::Decl *decl) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  LLDB_LOGF(log, "    [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
            decl->getDeclKindName(), static_cast<void *>(decl));

  if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) {
    if (!interface_decl->getDefinition()) {
      interface_decl->startDefinition();
      CompleteObjCInterfaceDecl(interface_decl);
    }
  } else if (ObjCProtocolDecl *protocol_decl =
                 dyn_cast<ObjCProtocolDecl>(decl)) {
    if (!protocol_decl->getDefinition())
      protocol_decl->startDefinition();
  } else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) {
    if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) {
      tag_decl->startDefinition();
      CompleteTagDecl(tag_decl);
      tag_decl->setCompleteDefinition(true);
    }
  } else {
    assert(0 && "CompleteDecl called on a Decl that can't be completed");
  }
}

bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) {
  ClangASTMetrics::RegisterDeclCompletion();

  DeclOrigin decl_origin = GetDeclOrigin(decl);

  if (!decl_origin.Valid())
    return false;

  if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
    return false;

  ImporterDelegateSP delegate_sp(
      GetDelegate(&decl->getASTContext(), decl_origin.ctx));

  ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
                                                &decl->getASTContext());
  if (delegate_sp)
    delegate_sp->ImportDefinitionTo(decl, decl_origin.decl);

  return true;
}

bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
                                                 clang::TagDecl *origin_decl) {
  ClangASTMetrics::RegisterDeclCompletion();

  clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();

  if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl))
    return false;

  ImporterDelegateSP delegate_sp(
      GetDelegate(&decl->getASTContext(), origin_ast_ctx));

  if (delegate_sp)
    delegate_sp->ImportDefinitionTo(decl, origin_decl);

  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());

  OriginMap &origins = context_md->m_origins;

  origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);

  return true;
}

bool ClangASTImporter::CompleteObjCInterfaceDecl(
    clang::ObjCInterfaceDecl *interface_decl) {
  ClangASTMetrics::RegisterDeclCompletion();

  DeclOrigin decl_origin = GetDeclOrigin(interface_decl);

  if (!decl_origin.Valid())
    return false;

  if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
    return false;

  ImporterDelegateSP delegate_sp(
      GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx));

  if (delegate_sp)
    delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);

  if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
    RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));

  return true;
}

bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) {
  if (!RequireCompleteType(type))
    return false;

  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);

  if (const TagType *tag_type = type->getAs<TagType>()) {
    TagDecl *tag_decl = tag_type->getDecl();

    DeclOrigin decl_origin = GetDeclOrigin(tag_decl);

    if (!decl_origin.Valid())
      return false;

    ImporterDelegateSP delegate_sp(
        GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx));

    ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
                                                  &tag_decl->getASTContext());

    TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);

    for (Decl *origin_child_decl : origin_tag_decl->decls()) {
      llvm::Expected<Decl *> imported_or_err =
          delegate_sp->Import(origin_child_decl);
      if (!imported_or_err) {
        LLDB_LOG_ERROR(log, imported_or_err.takeError(),
                       "Couldn't import decl: {0}");
        return false;
      }
    }

    if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) {
      record_decl->setHasLoadedFieldsFromExternalStorage(true);
    }

    return true;
  }

  if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
    if (ObjCInterfaceDecl *objc_interface_decl =
            objc_object_type->getInterface()) {
      DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);

      if (!decl_origin.Valid())
        return false;

      ImporterDelegateSP delegate_sp(
          GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx));

      ObjCInterfaceDecl *origin_interface_decl =
          llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);

      for (Decl *origin_child_decl : origin_interface_decl->decls()) {
        llvm::Expected<Decl *> imported_or_err =
            delegate_sp->Import(origin_child_decl);
        if (!imported_or_err) {
          LLDB_LOG_ERROR(log, imported_or_err.takeError(),
                         "Couldn't import decl: {0}");
          return false;
        }
      }

      return true;
    } else {
      return false;
    }
  }

  return true;
}

bool ClangASTImporter::RequireCompleteType(clang::QualType type) {
  if (type.isNull())
    return false;

  if (const TagType *tag_type = type->getAs<TagType>()) {
    TagDecl *tag_decl = tag_type->getDecl();

    if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
      return true;

    return CompleteTagDecl(tag_decl);
  }
  if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
    if (ObjCInterfaceDecl *objc_interface_decl =
            objc_object_type->getInterface())
      return CompleteObjCInterfaceDecl(objc_interface_decl);
    else
      return false;
  }
  if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) {
    return RequireCompleteType(array_type->getElementType());
  }
  if (const AtomicType *atomic_type = type->getAs<AtomicType>()) {
    return RequireCompleteType(atomic_type->getPointeeType());
  }

  return true;
}

ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) {
  DeclOrigin decl_origin = GetDeclOrigin(decl);

  if (decl_origin.Valid())
    return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
  else
    return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
}

ClangASTImporter::DeclOrigin
ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) {
  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());

  OriginMap &origins = context_md->m_origins;

  OriginMap::iterator iter = origins.find(decl);

  if (iter != origins.end())
    return iter->second;
  else
    return DeclOrigin();
}

void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl,
                                     clang::Decl *original_decl) {
  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());

  OriginMap &origins = context_md->m_origins;

  OriginMap::iterator iter = origins.find(decl);

  if (iter != origins.end()) {
    iter->second.decl = original_decl;
    iter->second.ctx = &original_decl->getASTContext();
  } else {
    origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
  }
}

void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
                                            NamespaceMapSP &namespace_map) {
  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());

  context_md->m_namespace_maps[decl] = namespace_map;
}

ClangASTImporter::NamespaceMapSP
ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) {
  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());

  NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;

  NamespaceMetaMap::iterator iter = namespace_maps.find(decl);

  if (iter != namespace_maps.end())
    return iter->second;
  else
    return NamespaceMapSP();
}

void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) {
  assert(decl);
  ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());

  const DeclContext *parent_context = decl->getDeclContext();
  const NamespaceDecl *parent_namespace =
      dyn_cast<NamespaceDecl>(parent_context);
  NamespaceMapSP parent_map;

  if (parent_namespace)
    parent_map = GetNamespaceMap(parent_namespace);

  NamespaceMapSP new_map;

  new_map = std::make_shared<NamespaceMap>();

  if (context_md->m_map_completer) {
    std::string namespace_string = decl->getDeclName().getAsString();

    context_md->m_map_completer->CompleteNamespaceMap(
        new_map, ConstString(namespace_string.c_str()), parent_map);
  }

  context_md->m_namespace_maps[decl] = new_map;
}

void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  LLDB_LOGF(log,
            "    [ClangASTImporter] Forgetting destination (ASTContext*)%p",
            static_cast<void *>(dst_ast));

  m_metadata_map.erase(dst_ast);
}

void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
                                    clang::ASTContext *src_ast) {
  ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast);

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  LLDB_LOGF(log,
            "    [ClangASTImporter] Forgetting source->dest "
            "(ASTContext*)%p->(ASTContext*)%p",
            static_cast<void *>(src_ast), static_cast<void *>(dst_ast));

  if (!md)
    return;

  md->m_delegates.erase(src_ast);

  for (OriginMap::iterator iter = md->m_origins.begin();
       iter != md->m_origins.end();) {
    if (iter->second.ctx == src_ast)
      md->m_origins.erase(iter++);
    else
      ++iter;
  }
}

ClangASTImporter::MapCompleter::~MapCompleter() { return; }

llvm::Expected<Decl *>
ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
  if (m_std_handler) {
    llvm::Optional<Decl *> D = m_std_handler->Import(From);
    if (D) {
      // Make sure we don't use this decl later to map it back to it's original
      // decl. The decl the CxxModuleHandler created has nothing to do with
      // the one from debug info, and linking those two would just cause the
      // ASTImporter to try 'updating' the module decl with the minimal one from
      // the debug info.
      m_decls_to_ignore.insert(*D);
      return *D;
    }
  }

  return ASTImporter::ImportImpl(From);
}

void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
    clang::Decl *to, clang::Decl *from) {
  ASTImporter::Imported(from, to);

  /*
  if (to_objc_interface)
      to_objc_interface->startDefinition();

  CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);

  if (to_cxx_record)
      to_cxx_record->startDefinition();
  */

  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);

  if (llvm::Error err = ImportDefinition(from)) {
    LLDB_LOG_ERROR(log, std::move(err),
                   "[ClangASTImporter] Error during importing definition: {0}");
    return;
  }

  if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) {
    if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) {
      to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());

      if (Log *log_ast =
              lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
        std::string name_string;
        if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
          llvm::raw_string_ostream name_stream(name_string);
          from_named_decl->printName(name_stream);
          name_stream.flush();
        }
        LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported "
                          "({1}Decl*){2}, named {3} (from "
                          "(Decl*){4})",
                 static_cast<void *>(to->getTranslationUnitDecl()),
                 from->getDeclKindName(), static_cast<void *>(to), name_string,
                 static_cast<void *>(from));

        // Log the AST of the TU.
        std::string ast_string;
        llvm::raw_string_ostream ast_stream(ast_string);
        to->getTranslationUnitDecl()->dump(ast_stream);
        LLDB_LOG(log_ast, "{0}", ast_string);
      }
    }
  }

  // If we're dealing with an Objective-C class, ensure that the inheritance
  // has been set up correctly.  The ASTImporter may not do this correctly if
  // the class was originally sourced from symbols.

  if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) {
    do {
      ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();

      if (to_superclass)
        break; // we're not going to override it if it's set

      ObjCInterfaceDecl *from_objc_interface =
          dyn_cast<ObjCInterfaceDecl>(from);

      if (!from_objc_interface)
        break;

      ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();

      if (!from_superclass)
        break;

      llvm::Expected<Decl *> imported_from_superclass_decl =
          Import(from_superclass);

      if (!imported_from_superclass_decl) {
        LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(),
                       "Couldn't import decl: {0}");
        break;
      }

      ObjCInterfaceDecl *imported_from_superclass =
          dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl);

      if (!imported_from_superclass)
        break;

      if (!to_objc_interface->hasDefinition())
        to_objc_interface->startDefinition();

      to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo(
          m_source_ctx->getObjCInterfaceType(imported_from_superclass)));
    } while (false);
  }
}

void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
                                                     clang::Decl *to) {
  ClangASTMetrics::RegisterClangImport();

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  // Some decls shouldn't be tracked here because they were not created by
  // copying 'from' to 'to'. Just exit early for those.
  if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end())
    return clang::ASTImporter::Imported(from, to);

  lldb::user_id_t user_id = LLDB_INVALID_UID;
  ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
  if (metadata)
    user_id = metadata->GetUserID();

  if (log) {
    if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
      std::string name_string;
      llvm::raw_string_ostream name_stream(name_string);
      from_named_decl->printName(name_stream);
      name_stream.flush();

      LLDB_LOGF(log,
                "    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from "
                "(Decl*)%p), metadata 0x%" PRIx64,
                from->getDeclKindName(), static_cast<void *>(to),
                name_string.c_str(), static_cast<void *>(from), user_id);
    } else {
      LLDB_LOGF(log,
                "    [ClangASTImporter] Imported (%sDecl*)%p (from "
                "(Decl*)%p), metadata 0x%" PRIx64,
                from->getDeclKindName(), static_cast<void *>(to),
                static_cast<void *>(from), user_id);
    }
  }

  ASTContextMetadataSP to_context_md =
      m_master.GetContextMetadata(&to->getASTContext());
  ASTContextMetadataSP from_context_md =
      m_master.MaybeGetContextMetadata(m_source_ctx);

  if (from_context_md) {
    OriginMap &origins = from_context_md->m_origins;

    OriginMap::iterator origin_iter = origins.find(from);

    if (origin_iter != origins.end()) {
      if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
          user_id != LLDB_INVALID_UID) {
        if (origin_iter->second.ctx != &to->getASTContext())
          to_context_md->m_origins[to] = origin_iter->second;
      }

      ImporterDelegateSP direct_completer =
          m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx);

      if (direct_completer.get() != this)
        direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);

      LLDB_LOGF(log,
                "    [ClangASTImporter] Propagated origin "
                "(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to "
                "(ASTContext*)%p",
                static_cast<void *>(origin_iter->second.decl),
                static_cast<void *>(origin_iter->second.ctx),
                static_cast<void *>(&from->getASTContext()),
                static_cast<void *>(&to->getASTContext()));
    } else {
      if (m_new_decl_listener)
        m_new_decl_listener->NewDeclImported(from, to);

      if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
          user_id != LLDB_INVALID_UID) {
        to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
      }

      LLDB_LOGF(log,
                "    [ClangASTImporter] Decl has no origin information in "
                "(ASTContext*)%p",
                static_cast<void *>(&from->getASTContext()));
    }

    if (clang::NamespaceDecl *to_namespace =
            dyn_cast<clang::NamespaceDecl>(to)) {
      clang::NamespaceDecl *from_namespace =
          dyn_cast<clang::NamespaceDecl>(from);

      NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;

      NamespaceMetaMap::iterator namespace_map_iter =
          namespace_maps.find(from_namespace);

      if (namespace_map_iter != namespace_maps.end())
        to_context_md->m_namespace_maps[to_namespace] =
            namespace_map_iter->second;
    }
  } else {
    to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);

    LLDB_LOGF(log,
              "    [ClangASTImporter] Sourced origin "
              "(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
              static_cast<void *>(from), static_cast<void *>(m_source_ctx),
              static_cast<void *>(&to->getASTContext()));
  }

  if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) {
    TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);

    to_tag_decl->setHasExternalLexicalStorage();
    to_tag_decl->getPrimaryContext()->setMustBuildLookupTable();

    LLDB_LOGF(
        log,
        "    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
        (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
        (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
        (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
        (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
  }

  if (isa<NamespaceDecl>(from)) {
    NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);

    m_master.BuildNamespaceMap(to_namespace_decl);

    to_namespace_decl->setHasExternalVisibleStorage();
  }

  if (isa<ObjCContainerDecl>(from)) {
    ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);

    to_container_decl->setHasExternalLexicalStorage();
    to_container_decl->setHasExternalVisibleStorage();

    /*to_interface_decl->setExternallyCompleted();*/

    if (log) {
      if (ObjCInterfaceDecl *to_interface_decl =
              llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
        LLDB_LOGF(
            log,
            "    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
            "%s%s%s",
            (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
            (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
            (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
      } else {
        LLDB_LOGF(
            log, "    [ClangASTImporter] To is an %sDecl - attributes %s%s",
            ((Decl *)to_container_decl)->getDeclKindName(),
            (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
            (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
      }
    }
  }
}

clang::Decl *
ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) {
  ASTContextMetadataSP to_context_md =
      m_master.GetContextMetadata(&To->getASTContext());

  if (!to_context_md)
    return nullptr;

  OriginMap::iterator iter = to_context_md->m_origins.find(To);

  if (iter == to_context_md->m_origins.end())
    return nullptr;

  return const_cast<clang::Decl *>(iter->second.decl);
}
