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

#include "lldb/Symbol/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 "llvm/Support/raw_ostream.h"

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) {
  log->Printf("  Number of visible Decl queries by name     : %" PRIu64,
              counters.m_visible_query_count);
  log->Printf("  Number of lexical Decl queries             : %" PRIu64,
              counters.m_lexical_query_count);
  log->Printf("  Number of imports initiated by LLDB        : %" PRIu64,
              counters.m_lldb_import_count);
  log->Printf("  Number of imports conducted by Clang       : %" PRIu64,
              counters.m_clang_import_count);
  log->Printf("  Number of Decls completed                  : %" PRIu64,
              counters.m_decls_completed_count);
  log->Printf("  Number of records laid out                 : %" PRIu64,
              counters.m_record_layout_count);
}

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

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

clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
                                           clang::ASTContext *src_ast,
                                           clang::QualType type) {
  MinionSP minion_sp(GetMinion(dst_ast, src_ast));

  if (minion_sp)
    return minion_sp->Import(type);

  return QualType();
}

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) {
  MinionSP minion_sp;

  minion_sp = GetMinion(dst_ast, src_ast);

  if (minion_sp) {
    clang::Decl *result = minion_sp->Import(decl);

    if (!result) {
      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

      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))
          log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s "
                      "'%s', metadata 0x%" PRIx64,
                      decl->getDeclKindName(),
                      named_decl->getNameAsString().c_str(), user_id);
        else
          log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s, "
                      "metadata 0x%" PRIx64,
                      decl->getDeclKindName(), user_id);
      }
    }

    return result;
  }

  return nullptr;
}

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

      if (log)
        log->Printf("    [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);
    }
  }
};

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

  if (log)
    log->Printf("    [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));

  MinionSP minion_sp(GetMinion(dst_ctx, src_ctx));

  if (!minion_sp)
    return nullptr;

  std::set<NamedDecl *> decls_to_deport;
  std::set<NamedDecl *> decls_already_deported;

  DeclContextOverride decl_context_override;

  if (const clang::TagType *tag_type =
          clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) {
    decl_context_override.OverrideAllDeclsFromContainingFunction(
        tag_type->getDecl());
  }

  minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported);

  lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type);

  minion_sp->ExecuteDeportWorkQueues();

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

  if (log)
    log->Printf("    [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));

  MinionSP minion_sp(GetMinion(dst_ctx, src_ctx));

  if (!minion_sp)
    return nullptr;

  std::set<NamedDecl *> decls_to_deport;
  std::set<NamedDecl *> decls_already_deported;

  DeclContextOverride decl_context_override;

  decl_context_override.OverrideAllDeclsFromContainingFunction(decl);

  minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported);

  clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);

  minion_sp->ExecuteDeportWorkQueues();

  if (!result)
    return nullptr;

  if (log)
    log->Printf(
        "    [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, NULL, NULL))
        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, NULL, NULL))
        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, NULL, NULL))
          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, NULL, NULL))
        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, NULL, NULL))
        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, NULL, NULL))
          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));

  if (log)
    log->Printf("    [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;

  MinionSP minion_sp(GetMinion(&decl->getASTContext(), decl_origin.ctx));

  if (minion_sp)
    minion_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;

  MinionSP minion_sp(GetMinion(&decl->getASTContext(), origin_ast_ctx));

  if (minion_sp)
    minion_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;

  MinionSP minion_sp(
      GetMinion(&interface_decl->getASTContext(), decl_origin.ctx));

  if (minion_sp)
    minion_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;

  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;

    MinionSP minion_sp(GetMinion(&tag_decl->getASTContext(), decl_origin.ctx));

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

    for (Decl *origin_child_decl : origin_tag_decl->decls()) {
      minion_sp->Import(origin_child_decl);
    }

    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;

      MinionSP minion_sp(
          GetMinion(&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()) {
        minion_sp->Import(origin_child_decl);
      }

      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.reset(new 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));

  if (log)
    log->Printf("    [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));

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

  if (!md)
    return;

  md->m_minions.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; }

void ClangASTImporter::Minion::InitDeportWorkQueues(
    std::set<clang::NamedDecl *> *decls_to_deport,
    std::set<clang::NamedDecl *> *decls_already_deported) {
  assert(!m_decls_to_deport);
  assert(!m_decls_already_deported);

  m_decls_to_deport = decls_to_deport;
  m_decls_already_deported = decls_already_deported;
}

void ClangASTImporter::Minion::ExecuteDeportWorkQueues() {
  assert(m_decls_to_deport);
  assert(m_decls_already_deported);

  ASTContextMetadataSP to_context_md =
      m_master.GetContextMetadata(&getToContext());

  while (!m_decls_to_deport->empty()) {
    NamedDecl *decl = *m_decls_to_deport->begin();

    m_decls_already_deported->insert(decl);
    m_decls_to_deport->erase(decl);

    DeclOrigin &origin = to_context_md->m_origins[decl];
    UNUSED_IF_ASSERT_DISABLED(origin);

    assert(origin.ctx ==
           m_source_ctx); // otherwise we should never have added this
                          // because it doesn't need to be deported

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

    ClangASTContext::GetCompleteDecl(m_source_ctx, original_decl);

    if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) {
      if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
        if (original_tag_decl->isCompleteDefinition()) {
          ImportDefinitionTo(tag_decl, original_tag_decl);
          tag_decl->setCompleteDefinition(true);
        }
      }

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

    to_context_md->m_origins.erase(decl);
  }

  m_decls_to_deport = nullptr;
  m_decls_already_deported = nullptr;
}

void ClangASTImporter::Minion::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();
  */

  ImportDefinition(from);

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

      Decl *imported_from_superclass_decl = Import(from_superclass);

      if (!imported_from_superclass_decl)
        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 (0);
  }
}

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

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

  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();

      log->Printf("    [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 {
      log->Printf("    [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;
      }

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

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

      if (log)
        log->Printf("    [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_decls_to_deport && m_decls_already_deported) {
        if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) {
          RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
          if (from_record_decl == nullptr ||
              from_record_decl->isInjectedClassName() == false) {
            NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);

            if (!m_decls_already_deported->count(to_named_decl))
              m_decls_to_deport->insert(to_named_decl);
          }
        }
      }

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

      if (log)
        log->Printf("    [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);

    if (log)
      log->Printf("    [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->setMustBuildLookupTable();

    if (log)
      log->Printf(
          "    [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)) {
        log->Printf(
            "    [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 {
        log->Printf(
            "    [ClangASTImporter] To is an %sDecl - attributes %s%s",
            ((Decl *)to_container_decl)->getDeclKindName(),
            (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
            (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
      }
    }
  }

  return clang::ASTImporter::Imported(from, to);
}

clang::Decl *ClangASTImporter::Minion::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);
}
