//===- 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/DeclBase.h"
#include "clang/AST/DeclarationName.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(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 *>;
    using FileIDImportHandlerType =
        std::function<void(FileID /*ToID*/, FileID /*FromID*/)>;

    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:
    FileIDImportHandlerType FileIDImportHandler;

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

    /// Set a callback function for FileID import handling.
    /// The function is invoked when a FileID is imported from the From context.
    /// The imported FileID in the To context and the original FileID in the
    /// From context is passed to it.
    void setFileIDImportHandler(FileIDImportHandlerType H) {
      FileIDImportHandler = H;
    }

    /// 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 the given 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));
    }

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