//===- ASTImporter.h - Importing ASTs from other Contexts -------*- 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
//
//===----------------------------------------------------------------------===//
//
//  This file defines the ASTImporter class which imports AST nodes from one
//  context into another context.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H

#include "clang/AST/APValue.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Error.h"
#include <utility>

namespace clang {

class ASTContext;
class ASTImporterSharedState;
class Attr;
class CXXBaseSpecifier;
class CXXCtorInitializer;
class Decl;
class DeclContext;
class Expr;
class FileManager;
class NamedDecl;
class Stmt;
class TagDecl;
class TranslationUnitDecl;
class TypeSourceInfo;

  class ImportError : public llvm::ErrorInfo<ImportError> {
  public:
    /// \brief Kind of error when importing an AST component.
    enum ErrorKind {
        NameConflict, /// Naming ambiguity (likely ODR violation).
        UnsupportedConstruct, /// Not supported node or case.
        Unknown /// Other error.
    };

    ErrorKind Error;

    static char ID;

    ImportError() : Error(Unknown) {}
    ImportError(const ImportError &Other) : Error(Other.Error) {}
    ImportError &operator=(const ImportError &Other) {
      Error = Other.Error;
      return *this;
    }
    ImportError(ErrorKind Error) : Error(Error) { }

    std::string toString() const;

    void log(raw_ostream &OS) const override;
    std::error_code convertToErrorCode() const override;
  };

  // \brief Returns with a list of declarations started from the canonical decl
  // then followed by subsequent decls in the translation unit.
  // This gives a canonical list for each entry in the redecl chain.
  // `Decl::redecls()` gives a list of decls which always start from the
  // previous decl and the next item is actually the previous item in the order
  // of source locations.  Thus, `Decl::redecls()` gives different lists for
  // the different entries in a given redecl chain.
  llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);

  /// Imports selected nodes from one AST context into another context,
  /// merging AST nodes where appropriate.
  class ASTImporter {
    friend class ASTNodeImporter;
  public:
    using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
    using ImportedCXXBaseSpecifierMap =
        llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;

    enum class ODRHandlingType { Conservative, Liberal };

    // An ImportPath is the list of the AST nodes which we visit during an
    // Import call.
    // If node `A` depends on node `B` then the path contains an `A`->`B` edge.
    // From the call stack of the import functions we can read the very same
    // path.
    //
    // Now imagine the following AST, where the `->` represents dependency in
    // therms of the import.
    // ```
    // A->B->C->D
    //    `->E
    // ```
    // We would like to import A.
    // The import behaves like a DFS, so we will visit the nodes in this order:
    // ABCDE.
    // During the visitation we will have the following ImportPaths:
    // ```
    // A
    // AB
    // ABC
    // ABCD
    // ABC
    // AB
    // ABE
    // AB
    // A
    // ```
    // If during the visit of E there is an error then we set an error for E,
    // then as the call stack shrinks for B, then for A:
    // ```
    // A
    // AB
    // ABC
    // ABCD
    // ABC
    // AB
    // ABE // Error! Set an error to E
    // AB  // Set an error to B
    // A   // Set an error to A
    // ```
    // However, during the import we could import C and D without any error and
    // they are independent from A,B and E.
    // We must not set up an error for C and D.
    // So, at the end of the import we have an entry in `ImportDeclErrors` for
    // A,B,E but not for C,D.
    //
    // Now what happens if there is a cycle in the import path?
    // Let's consider this AST:
    // ```
    // A->B->C->A
    //    `->E
    // ```
    // During the visitation we will have the below ImportPaths and if during
    // the visit of E there is an error then we will set up an error for E,B,A.
    // But what's up with C?
    // ```
    // A
    // AB
    // ABC
    // ABCA
    // ABC
    // AB
    // ABE // Error! Set an error to E
    // AB  // Set an error to B
    // A   // Set an error to A
    // ```
    // This time we know that both B and C are dependent on A.
    // This means we must set up an error for C too.
    // As the call stack reverses back we get to A and we must set up an error
    // to all nodes which depend on A (this includes C).
    // But C is no longer on the import path, it just had been previously.
    // Such situation can happen only if during the visitation we had a cycle.
    // If we didn't have any cycle, then the normal way of passing an Error
    // object through the call stack could handle the situation.
    // This is why we must track cycles during the import process for each
    // visited declaration.
    class ImportPathTy {
    public:
      using VecTy = llvm::SmallVector<Decl *, 32>;

      void push(Decl *D) {
        Nodes.push_back(D);
        ++Aux[D];
      }

      void pop() {
        if (Nodes.empty())
          return;
        --Aux[Nodes.back()];
        Nodes.pop_back();
      }

      /// Returns true if the last element can be found earlier in the path.
      bool hasCycleAtBack() const {
        auto Pos = Aux.find(Nodes.back());
        return Pos != Aux.end() && Pos->second > 1;
      }

      using Cycle = llvm::iterator_range<VecTy::const_reverse_iterator>;
      Cycle getCycleAtBack() const {
        assert(Nodes.size() >= 2);
        return Cycle(Nodes.rbegin(),
                     std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) +
                         1);
      }

      /// Returns the copy of the cycle.
      VecTy copyCycleAtBack() const {
        auto R = getCycleAtBack();
        return VecTy(R.begin(), R.end());
      }

    private:
      // All nodes of the path.
      VecTy Nodes;
      // Auxiliary container to be able to answer "Do we have a cycle ending
      // at last element?" as fast as possible.
      // We count each Decl's occurrence over the path.
      llvm::SmallDenseMap<Decl *, int, 32> Aux;
    };

  private:
    std::shared_ptr<ASTImporterSharedState> SharedState = nullptr;

    /// The path which we go through during the import of a given AST node.
    ImportPathTy ImportPath;
    /// Sometimes we have to save some part of an import path, so later we can
    /// set up properties to the saved nodes.
    /// We may have several of these import paths associated to one Decl.
    using SavedImportPathsForOneDecl =
        llvm::SmallVector<ImportPathTy::VecTy, 32>;
    using SavedImportPathsTy =
        llvm::SmallDenseMap<Decl *, SavedImportPathsForOneDecl, 32>;
    SavedImportPathsTy SavedImportPaths;

    /// The contexts we're importing to and from.
    ASTContext &ToContext, &FromContext;

    /// The file managers we're importing to and from.
    FileManager &ToFileManager, &FromFileManager;

    /// Whether to perform a minimal import.
    bool Minimal;

    ODRHandlingType ODRHandling;

    /// Whether the last diagnostic came from the "from" context.
    bool LastDiagFromFrom = false;

    /// Mapping from the already-imported types in the "from" context
    /// to the corresponding types in the "to" context.
    llvm::DenseMap<const Type *, const Type *> ImportedTypes;

    /// Mapping from the already-imported declarations in the "from"
    /// context to the corresponding declarations in the "to" context.
    llvm::DenseMap<Decl *, Decl *> ImportedDecls;

    /// Mapping from the already-imported declarations in the "from"
    /// context to the error status of the import of that declaration.
    /// This map contains only the declarations that were not correctly
    /// imported. The same declaration may or may not be included in
    /// ImportedDecls. This map is updated continuously during imports and never
    /// cleared (like ImportedDecls).
    llvm::DenseMap<Decl *, ImportError> ImportDeclErrors;

    /// Mapping from the already-imported declarations in the "to"
    /// context to the corresponding declarations in the "from" context.
    llvm::DenseMap<Decl *, Decl *> ImportedFromDecls;

    /// Mapping from the already-imported statements in the "from"
    /// context to the corresponding statements in the "to" context.
    llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;

    /// Mapping from the already-imported FileIDs in the "from" source
    /// manager to the corresponding FileIDs in the "to" source manager.
    llvm::DenseMap<FileID, FileID> ImportedFileIDs;

    /// Mapping from the already-imported CXXBasesSpecifier in
    ///  the "from" source manager to the corresponding CXXBasesSpecifier
    ///  in the "to" source manager.
    ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;

    /// Declaration (from, to) pairs that are known not to be equivalent
    /// (which we have already complained about).
    NonEquivalentDeclSet NonEquivalentDecls;

    using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
    FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);

    void AddToLookupTable(Decl *ToD);

  protected:
    /// Can be overwritten by subclasses to implement their own import logic.
    /// The overwritten method should call this method if it didn't import the
    /// decl on its own.
    virtual Expected<Decl *> ImportImpl(Decl *From);

    /// Used only in unittests to verify the behaviour of the error handling.
    virtual bool returnWithErrorInTest() { return false; };

  public:

    /// \param ToContext The context we'll be importing into.
    ///
    /// \param ToFileManager The file manager we'll be importing into.
    ///
    /// \param FromContext The context we'll be importing from.
    ///
    /// \param FromFileManager The file manager we'll be importing into.
    ///
    /// \param MinimalImport If true, the importer will attempt to import
    /// as little as it can, e.g., by importing declarations as forward
    /// declarations that can be completed at a later point.
    ///
    /// \param SharedState The importer specific lookup table which may be
    /// shared amongst several ASTImporter objects.
    /// If not set then the original C/C++ lookup is used.
    ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                ASTContext &FromContext, FileManager &FromFileManager,
                bool MinimalImport,
                std::shared_ptr<ASTImporterSharedState> SharedState = nullptr);

    virtual ~ASTImporter();

    /// Whether the importer will perform a minimal import, creating
    /// to-be-completed forward declarations when possible.
    bool isMinimalImport() const { return Minimal; }

    void setODRHandling(ODRHandlingType T) { ODRHandling = T; }

    /// \brief Import the given object, returns the result.
    ///
    /// \param To Import the object into this variable.
    /// \param From Object to import.
    /// \return Error information (success or error).
    template <typename ImportT>
    LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
      auto ToOrErr = Import(From);
      if (ToOrErr)
        To = *ToOrErr;
      return ToOrErr.takeError();
    }

    /// Import cleanup objects owned by ExprWithCleanup.
    llvm::Expected<ExprWithCleanups::CleanupObject>
    Import(ExprWithCleanups::CleanupObject From);

    /// Import the given type from the "from" context into the "to"
    /// context.
    ///
    /// \returns The equivalent type in the "to" context, or the import error.
    llvm::Expected<const Type *> Import(const Type *FromT);

    /// Import the given qualified type from the "from" context into the "to"
    /// context. A null type is imported as a null type (no error).
    ///
    /// \returns The equivalent type in the "to" context, or the import error.
    llvm::Expected<QualType> Import(QualType FromT);

    /// Import the given type source information from the
    /// "from" context into the "to" context.
    ///
    /// \returns The equivalent type source information in the "to"
    /// context, or the import error.
    llvm::Expected<TypeSourceInfo *> Import(TypeSourceInfo *FromTSI);

    /// Import the given attribute from the "from" context into the
    /// "to" context.
    ///
    /// \returns The equivalent attribute in the "to" context, or the import
    /// error.
    llvm::Expected<Attr *> Import(const Attr *FromAttr);

    /// Import the given declaration from the "from" context into the
    /// "to" context.
    ///
    /// \returns The equivalent declaration in the "to" context, or the import
    /// error.
    llvm::Expected<Decl *> Import(Decl *FromD);
    llvm::Expected<const Decl *> Import(const Decl *FromD) {
      return Import(const_cast<Decl *>(FromD));
    }

    llvm::Expected<InheritedConstructor>
    Import(const InheritedConstructor &From);

    /// Return the copy of the given declaration in the "to" context if
    /// it has already been imported from the "from" context.  Otherwise return
    /// nullptr.
    Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;

    /// Return the translation unit from where the declaration was
    /// imported. If it does not exist nullptr is returned.
    TranslationUnitDecl *GetFromTU(Decl *ToD);

    /// Return the declaration in the "from" context from which the declaration
    /// in the "to" context was imported. If it was not imported or of the wrong
    /// type a null value is returned.
    template <typename DeclT>
    llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
      auto FromI = ImportedFromDecls.find(ToD);
      if (FromI == ImportedFromDecls.end())
        return {};
      auto *FromD = dyn_cast<DeclT>(FromI->second);
      if (!FromD)
        return {};
      return FromD;
    }

    /// Import the given declaration context from the "from"
    /// AST context into the "to" AST context.
    ///
    /// \returns the equivalent declaration context in the "to"
    /// context, or error value.
    llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);

    /// Import the given expression from the "from" context into the
    /// "to" context.
    ///
    /// \returns The equivalent expression in the "to" context, or the import
    /// error.
    llvm::Expected<Expr *> Import(Expr *FromE);

    /// Import the given statement from the "from" context into the
    /// "to" context.
    ///
    /// \returns The equivalent statement in the "to" context, or the import
    /// error.
    llvm::Expected<Stmt *> Import(Stmt *FromS);

    /// Import the given nested-name-specifier from the "from"
    /// context into the "to" context.
    ///
    /// \returns The equivalent nested-name-specifier in the "to"
    /// context, or the import error.
    llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS);

    /// Import the given nested-name-specifier-loc from the "from"
    /// context into the "to" context.
    ///
    /// \returns The equivalent nested-name-specifier-loc in the "to"
    /// context, or the import error.
    llvm::Expected<NestedNameSpecifierLoc>
    Import(NestedNameSpecifierLoc FromNNS);

    /// Import the given template name from the "from" context into the
    /// "to" context, or the import error.
    llvm::Expected<TemplateName> Import(TemplateName From);

    /// Import the given source location from the "from" context into
    /// the "to" context.
    ///
    /// \returns The equivalent source location in the "to" context, or the
    /// import error.
    llvm::Expected<SourceLocation> Import(SourceLocation FromLoc);

    /// Import the given source range from the "from" context into
    /// the "to" context.
    ///
    /// \returns The equivalent source range in the "to" context, or the import
    /// error.
    llvm::Expected<SourceRange> Import(SourceRange FromRange);

    /// Import the given declaration name from the "from"
    /// context into the "to" context.
    ///
    /// \returns The equivalent declaration name in the "to" context, or the
    /// import error.
    llvm::Expected<DeclarationName> Import(DeclarationName FromName);

    /// Import the given identifier from the "from" context
    /// into the "to" context.
    ///
    /// \returns The equivalent identifier in the "to" context. Note: It
    /// returns nullptr only if the FromId was nullptr.
    IdentifierInfo *Import(const IdentifierInfo *FromId);

    /// Import the given Objective-C selector from the "from"
    /// context into the "to" context.
    ///
    /// \returns The equivalent selector in the "to" context, or the import
    /// error.
    llvm::Expected<Selector> Import(Selector FromSel);

    /// Import the given file ID from the "from" context into the
    /// "to" context.
    ///
    /// \returns The equivalent file ID in the source manager of the "to"
    /// context, or the import error.
    llvm::Expected<FileID> Import(FileID, bool IsBuiltin = false);

    /// Import the given C++ constructor initializer from the "from"
    /// context into the "to" context.
    ///
    /// \returns The equivalent initializer in the "to" context, or the import
    /// error.
    llvm::Expected<CXXCtorInitializer *> Import(CXXCtorInitializer *FromInit);

    /// Import the given CXXBaseSpecifier from the "from" context into
    /// the "to" context.
    ///
    /// \returns The equivalent CXXBaseSpecifier in the source manager of the
    /// "to" context, or the import error.
    llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec);

    /// Import the given APValue from the "from" context into
    /// the "to" context.
    ///
    /// \return the equivalent APValue in the "to" context or the import
    /// error.
    llvm::Expected<APValue> Import(const APValue &FromValue);

    /// Import the definition of the given declaration, including all of
    /// the declarations it contains.
    LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From);

    /// Cope with a name conflict when importing a declaration into the
    /// given context.
    ///
    /// This routine is invoked whenever there is a name conflict while
    /// importing a declaration. The returned name will become the name of the
    /// imported declaration. By default, the returned name is the same as the
    /// original name, leaving the conflict unresolve such that name lookup
    /// for this name is likely to find an ambiguity later.
    ///
    /// Subclasses may override this routine to resolve the conflict, e.g., by
    /// renaming the declaration being imported.
    ///
    /// \param Name the name of the declaration being imported, which conflicts
    /// with other declarations.
    ///
    /// \param DC the declaration context (in the "to" AST context) in which
    /// the name is being imported.
    ///
    /// \param IDNS the identifier namespace in which the name will be found.
    ///
    /// \param Decls the set of declarations with the same name as the
    /// declaration being imported.
    ///
    /// \param NumDecls the number of conflicting declarations in \p Decls.
    ///
    /// \returns the name that the newly-imported declaration should have. Or
    /// an error if we can't handle the name conflict.
    virtual Expected<DeclarationName>
    HandleNameConflict(DeclarationName Name, DeclContext *DC, unsigned IDNS,
                       NamedDecl **Decls, unsigned NumDecls);

    /// Retrieve the context that AST nodes are being imported into.
    ASTContext &getToContext() const { return ToContext; }

    /// Retrieve the context that AST nodes are being imported from.
    ASTContext &getFromContext() const { return FromContext; }

    /// Retrieve the file manager that AST nodes are being imported into.
    FileManager &getToFileManager() const { return ToFileManager; }

    /// Retrieve the file manager that AST nodes are being imported from.
    FileManager &getFromFileManager() const { return FromFileManager; }

    /// Report a diagnostic in the "to" context.
    DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);

    /// Report a diagnostic in the "from" context.
    DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);

    /// Return the set of declarations that we know are not equivalent.
    NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }

    /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
    /// Mark the Decl as complete, filling it in as much as possible.
    ///
    /// \param D A declaration in the "to" context.
    virtual void CompleteDecl(Decl* D);

    /// Subclasses can override this function to observe all of the \c From ->
    /// \c To declaration mappings as they are imported.
    virtual void Imported(Decl *From, Decl *To) {}

    void RegisterImportedDecl(Decl *FromD, Decl *ToD);

    /// Store and assign the imported declaration to its counterpart.
    /// It may happen that several decls from the 'from' context are mapped to
    /// the same decl in the 'to' context.
    Decl *MapImported(Decl *From, Decl *To);

    /// Called by StructuralEquivalenceContext.  If a RecordDecl is
    /// being compared to another RecordDecl as part of import, completing the
    /// other RecordDecl may trigger importation of the first RecordDecl. This
    /// happens especially for anonymous structs.  If the original of the second
    /// RecordDecl can be found, we can complete it without the need for
    /// importation, eliminating this loop.
    virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }

    /// Return if import of the given declaration has failed and if yes
    /// the kind of the problem. This gives the first error encountered with
    /// the node.
    llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *FromD) const;

    /// Mark (newly) imported declaration with error.
    void setImportDeclError(Decl *From, ImportError Error);

    /// Determine whether the given types are structurally
    /// equivalent.
    bool IsStructurallyEquivalent(QualType From, QualType To,
                                  bool Complain = true);

    /// Determine the index of a field in its parent record.
    /// F should be a field (or indirect field) declaration.
    /// \returns The index of the field in its parent context (starting from 0).
    /// On error `None` is returned (parent context is non-record).
    static llvm::Optional<unsigned> getFieldIndex(Decl *F);
  };

} // namespace clang

#endif // LLVM_CLANG_AST_ASTIMPORTER_H
