//===--- ImporterImpl.h - Import Clang Modules: Implementation --*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file provides the implementation class definitions for the Clang
// module loader.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_CLANG_IMPORTER_IMPL_H
#define SWIFT_CLANG_IMPORTER_IMPL_H

#include "ClangAdapter.h"
#include "ImportEnumInfo.h"
#include "ImportName.h"
#include "SwiftLookupTable.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/ClangImporter/ClangModule.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/LazyResolver.h"
#include "swift/AST/Module.h"
#include "swift/AST/Type.h"
#include "swift/AST/ForeignErrorConvention.h"
#include "swift/Basic/StringExtras.h"
#include "swift/Strings.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Path.h"
#include <set>

namespace llvm {

class SmallBitVector;

}

namespace clang {
class APValue;
class Decl;
class DeclarationName;
class EnumDecl;
class MacroInfo;
class MangleContext;
class NamedDecl;
class ObjCInterfaceDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl;
class ParmVarDecl;
class Parser;
class QualType;
class TypedefNameDecl;
}

namespace swift {

class ASTContext;
class ClassDecl;
class ConstructorDecl;
class Decl;
class DeclContext;
class Expr;
class ExtensionDecl;
class FuncDecl;
class Identifier;
class Pattern;
class SubscriptDecl;
class ValueDecl;

/// \brief Describes the kind of conversion to apply to a constant value.
enum class ConstantConvertKind {
  /// \brief No conversion required.
  None,
  /// \brief Coerce the constant to the given type.
  Coerce,
  /// \brief Construct the given type from the constant value.
  Construction,
  /// \brief Construct the given type from the constant value, using an
  /// optional initializer.
  ConstructionWithUnwrap,
  /// \brief Perform an unchecked downcast to the given type.
  Downcast
};

/// \brief Describes the kind of type import we're performing.
enum class ImportTypeKind {
  /// \brief Import a type in its most abstract form, without any adjustment.
  Abstract,

  /// \brief Import the underlying type of a typedef.
  Typedef,

  /// \brief Import the type of a literal value.
  Value,

  /// \brief Import the type of a literal value that can be bridged.
  BridgedValue,

  /// \brief Import the declared type of a variable.
  Variable,
  
  /// \brief Import the declared type of an audited variable.
  ///
  /// This is exactly like ImportTypeKind::Variable, except it
  /// disables wrapping CF class types in Unmanaged.
  AuditedVariable,

  /// \brief Import the declared type of a struct or union field.
  RecordField,
  
  /// \brief Import the result type of a function.
  ///
  /// This provides special treatment for 'void', among other things, and
  /// enables the conversion of bridged types.
  Result,

  /// \brief Import the result type of an audited function.
  ///
  /// This is exactly like ImportTypeKind::Result, except it
  /// disables wrapping CF class types in Unmanaged.
  AuditedResult,

  /// \brief Import the type of a function parameter.
  ///
  /// This provides special treatment for C++ references (which become
  /// [inout] parameters) and C pointers (which become magic [inout]-able types),
  /// among other things, and enables the conversion of bridged types.
  /// Parameters are always considered CF-audited.
  Parameter,

  /// \brief Import the type of a parameter declared with
  /// \c CF_RETURNS_RETAINED.
  ///
  /// This ensures that the parameter is not marked as Unmanaged.
  CFRetainedOutParameter,

  /// \brief Import the type of a parameter declared with
  /// \c CF_RETURNS_NON_RETAINED.
  ///
  /// This ensures that the parameter is not marked as Unmanaged.
  CFUnretainedOutParameter,

  /// \brief Import the type pointed to by a pointer or reference.
  ///
  /// This provides special treatment for pointer-to-ObjC-pointer
  /// types, which get imported as pointers to *checked* optional,
  /// *Pointer<NSFoo?>, instead of implicitly unwrapped optional as usual.
  Pointee,

  /// \brief Import the type of an ObjC property.
  ///
  /// This enables the conversion of bridged types. Properties are always
  /// considered CF-audited.
  Property,

  /// \brief Import the type of an ObjC property accessor marked 'weak',
  /// 'assign', or 'unsafe_unretained'.
  ///
  /// Like Property, but doesn't allow bridging to a value type, since that
  /// would discard the ownership.
  PropertyWithReferenceSemantics,

  /// \brief Import the underlying type of an enum.
  ///
  /// This provides special treatment for 'NSUInteger'.
  Enum
};

enum class Bridgeability {
  /// This context does not permit bridging at all.  For example, the
  /// target of a C pointer.
  None,

  /// This context permits all kinds of bridging.  For example, the
  /// imported result of a method declaration.
  Full
};

/// Controls whether a typedef for \p type should name the fully-bridged Swift
/// type or the original Clang type.
///
/// In either case we end up losing sugar at some uses sites, so this is more
/// about what the right default is.
static inline Bridgeability getTypedefBridgeability(
                                          const clang::TypedefNameDecl *decl,
                                          clang::QualType type) {
    return decl->hasAttr<clang::SwiftBridgedTypedefAttr>()
      ? Bridgeability::Full
        : type->isBlockPointerType()
        ? Bridgeability::Full
          : Bridgeability::None;
}

/// \brief Describes the kind of the C type that can be mapped to a stdlib
/// swift type.
enum class MappedCTypeKind {
  UnsignedInt,
  SignedInt,
  UnsignedWord,
  SignedWord,
  FloatIEEEsingle,
  FloatIEEEdouble,
  FloatX87DoubleExtended,
  VaList,
  ObjCBool,
  ObjCSel,
  ObjCId,
  ObjCClass,
  CGFloat,
  Block,
};

/// \brief Describes what to do with the C name of a type that can be mapped to
/// a Swift standard library type.
enum class MappedTypeNameKind {
  DoNothing,
  DefineOnly,
  DefineAndUse
};

/// \brief Describes certain kinds of methods that need to be specially
/// handled by the importer.
enum class SpecialMethodKind {
  Regular,
  Constructor,
  NSDictionarySubscriptGetter
};

#define SWIFT_NATIVE_ANNOTATION_STRING "__swift native"

#define SWIFT_PROTOCOL_SUFFIX "Protocol"
#define SWIFT_CFTYPE_SUFFIX "Ref"

/// Describes whether to classify a factory method as an initializer.
enum class FactoryAsInitKind {
  /// Infer based on name and type (the default).
  Infer,
  /// Treat as a class method.
  AsClassMethod,
  /// Treat as an initializer.
  AsInitializer
};

namespace importer {
struct PlatformAvailability {
  /// A predicate that indicates if the given platform should be
  /// considered for availability.
  std::function<bool(StringRef PlatformName)> filter;

  /// A predicate that indicates if the given platform version should
  /// should be included in the cutoff of deprecated APIs marked unavailable.
  std::function<bool(unsigned major, llvm::Optional<unsigned> minor)>
      deprecatedAsUnavailableFilter;

  /// The message to embed for implicitly unavailability if a deprecated
  /// API is now unavailable.
  std::string deprecatedAsUnavailableMessage;

  PlatformAvailability(LangOptions &opts);

private:
  PlatformAvailability(const PlatformAvailability&) = delete;
  PlatformAvailability &operator=(const PlatformAvailability &) = delete;
};
}

using LookupTableMap = llvm::StringMap<std::unique_ptr<SwiftLookupTable>>;

/// The result of importing a clang type. It holds both the Swift Type
/// as well as a bool in which 'true' indicates either:
///   This is an Optional type.
///   This is a function type where the result type is an Optional.
/// It is otherwise 'false'.
class ImportedType {
  Type type;
  bool isIUO;

public:
  ImportedType() {
    type = Type();
    isIUO = false;
  }

  ImportedType(Type ty, bool implicitlyUnwrap)
      : type(ty), isIUO(implicitlyUnwrap) {
#if !defined(NDEBUG)
    if (implicitlyUnwrap) {
      assert(ty->getOptionalObjectType() || ty->getAs<AnyFunctionType>());
      if (!ty->getOptionalObjectType()) {
        auto fnTy = ty->castTo<AnyFunctionType>();
        assert(fnTy->getResult()->getOptionalObjectType());
      }
    }
#endif
  }

  Type getType() const { return type; }

  bool isImplicitlyUnwrapped() const { return isIUO; }

  // Allow a direct test in boolean contexts. It makes sense to base
  // this entirely on the type as the isIUO is meaningless for a null
  // type.
  explicit operator bool() const { return type.getPointer() != nullptr; }
};

/// \brief Implementation of the Clang importer.
class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation 
  : public LazyMemberLoader,
    public LazyConformanceLoader
{
  friend class ClangImporter;
  using Version = importer::ImportNameVersion;

public:
  Implementation(ASTContext &ctx, const ClangImporterOptions &opts);
  ~Implementation();

  /// \brief Swift AST context.
  ASTContext &SwiftContext;

  const bool ImportForwardDeclarations;
  const bool InferImportAsMember;
  const bool DisableSwiftBridgeAttr;
  const bool BridgingHeaderExplicitlyRequested;
  const bool DisableAdapterModules;

  bool IsReadingBridgingPCH;
  llvm::SmallVector<clang::serialization::SubmoduleID, 2> PCHImportedSubmodules;

  const Version CurrentVersion;

  constexpr static const char * const moduleImportBufferName =
    "<swift-imported-modules>";
  constexpr static const char * const bridgingHeaderBufferName =
    "<bridging-header-import>";

private:
  /// The Swift lookup table for the bridging header.
  std::unique_ptr<SwiftLookupTable> BridgingHeaderLookupTable;

  /// The Swift lookup tables, per module.
  ///
  /// Annoyingly, we list this table early so that it gets torn down after
  /// the underlying Clang instances that reference it
  /// (through the Swift name lookup module file extension).
  LookupTableMap LookupTables;

  /// \brief The fake buffer used to import modules.
  ///
  /// \see getNextIncludeLoc
  clang::FileID DummyIncludeBuffer;

  /// \brief A count of the number of load module operations.
  ///
  /// \see getNextIncludeLoc
  unsigned IncludeCounter = 0;

  /// Generate a dummy Clang source location for header includes and module
  /// imports.
  ///
  /// These have to be unique and valid or Clang gets very confused.
  clang::SourceLocation getNextIncludeLoc();

  /// \brief Used to avoid running the AST verifier over the same declarations.
  size_t VerifiedDeclsCounter = 0;

  /// \brief Clang compiler invocation.
  std::shared_ptr<clang::CompilerInvocation> Invocation;

  /// \brief Clang compiler instance, which is used to actually load Clang
  /// modules.
  std::unique_ptr<clang::CompilerInstance> Instance;

  /// \brief Clang compiler action, which is used to actually run the
  /// parser.
  std::unique_ptr<clang::FrontendAction> Action;

  /// \brief Clang parser, which is used to load textual headers.
  std::unique_ptr<clang::Parser> Parser;

  /// \brief Clang parser, which is used to load textual headers.
  std::unique_ptr<clang::MangleContext> Mangler;

  /// The active type checker, or null if there is no active type checker.
  ///
  /// The flag is \c true if there has ever been a type resolver assigned, i.e.
  /// if type checking has begun.
  llvm::PointerIntPair<LazyResolver *, 1, bool> typeResolver;

public:
  /// \brief Mapping of already-imported declarations.
  llvm::DenseMap<std::pair<const clang::Decl *, Version>, Decl *> ImportedDecls;

  /// \brief The set of "special" typedef-name declarations, which are
  /// mapped to specific Swift types.
  ///
  /// Normal typedef-name declarations imported into Swift will maintain
  /// equality between the imported declaration's underlying type and the
  /// import of the underlying type. A typedef-name declaration is special
  /// when this is not the case, e.g., Objective-C's "BOOL" has an underlying
  /// type of "signed char", but is mapped to a special Swift struct type
  /// ObjCBool.
  llvm::SmallDenseMap<const clang::TypedefNameDecl *, MappedTypeNameKind, 16>
    SpecialTypedefNames;

  /// \brief Provide a single extension point for any given type per clang
  /// submodule
  llvm::DenseMap<std::pair<NominalTypeDecl *, const clang::Module *>,
                 ExtensionDecl *> extensionPoints;

  /// \brief Typedefs that we should not be importing.  We should be importing
  /// underlying decls instead.
  llvm::DenseSet<const clang::Decl *> SuperfluousTypedefs;

  /// Tag decls whose typedefs were imported instead.
  ///
  /// \sa SuperfluousTypedefs
  llvm::DenseSet<const clang::Decl *> DeclsWithSuperfluousTypedefs;

  /// \brief Mapping of already-imported declarations from protocols, which
  /// can (and do) get replicated into classes.
  llvm::DenseMap<std::tuple<const clang::Decl *, DeclContext *, Version>,
                 Decl *> ImportedProtocolDecls;

  /// Mapping from identifiers to the set of macros that have that name along
  /// with their corresponding Swift declaration.
  ///
  /// Multiple macro definitions can map to the same declaration if the
  /// macros are identically defined.
  llvm::DenseMap<Identifier,
                 SmallVector<std::pair<const clang::MacroInfo *, ValueDecl *>,
                             2>>
    ImportedMacros;

  // Mapping from macro to value for macros that expand to constant values.
  llvm::DenseMap<const clang::MacroInfo *, std::pair<clang::APValue, Type>>
    ImportedMacroConstants;

  /// Keeps track of active selector-based lookups, so that we don't infinitely
  /// recurse when checking whether a method with a given selector has already
  /// been imported.
  llvm::DenseMap<std::pair<ObjCSelector, char>, unsigned>
    ActiveSelectors;

  clang::CompilerInstance *getClangInstance() {
    return Instance.get();
  }

private:
  /// \brief Generation number that is used for crude versioning.
  ///
  /// This value is incremented every time a new module is imported.
  unsigned Generation = 1;

  void bumpGeneration() {
    ++Generation;
    SwiftContext.bumpGeneration();
  }

public:
  /// \brief Keep track of subscript declarations based on getter/setter
  /// pairs.
  llvm::DenseMap<std::pair<FuncDecl *, FuncDecl *>, SubscriptDecl *> Subscripts;

  /// Keeps track of the Clang functions that have been turned into
  /// properties.
  llvm::DenseMap<const clang::FunctionDecl *, VarDecl *> FunctionsAsProperties;

  importer::EnumInfo getEnumInfo(const clang::EnumDecl *decl) {
    return getNameImporter().getEnumInfo(decl);
  }
  importer::EnumKind getEnumKind(const clang::EnumDecl *decl) {
    return getNameImporter().getEnumKind(decl);
  }

  // TODO: drop this accessor as soon as we further de-couple the swift name
  // lookup tables from the Impl.
  LookupTableMap &getLookupTables() { return LookupTables; }

private:
  /// A mapping from imported declarations to their "alternate" declarations,
  /// for cases where a single Clang declaration is imported to two
  /// different Swift declarations.
  llvm::DenseMap<Decl *, TinyPtrVector<ValueDecl *>> AlternateDecls;

public:
  /// \brief Keep track of initializer declarations that correspond to
  /// imported methods.
  llvm::DenseMap<
      std::tuple<const clang::ObjCMethodDecl *, DeclContext *, Version>,
      ConstructorDecl *> Constructors;

  /// Retrieve the alternative declaration for the given imported
  /// Swift declaration.
  ArrayRef<ValueDecl *> getAlternateDecls(Decl *decl) {
    auto known = AlternateDecls.find(decl);
    if (known == AlternateDecls.end()) return {};
    return known->second;
  }

  /// Add an alternative decl
  void addAlternateDecl(Decl *forDecl, ValueDecl *altDecl) {
    auto &vec = AlternateDecls[forDecl];
    for (auto alt : vec)
      if (alt == altDecl)
        return;
    vec.push_back(altDecl);
  }

private:
  /// \brief NSObject, imported into Swift.
  Type NSObjectTy;

  /// A pair containing a ClangModuleUnit,
  /// and whether the adapters of its re-exported modules have all been forced
  /// to load already.
  using ModuleInitPair = llvm::PointerIntPair<ClangModuleUnit *, 1, bool>;

public:
  /// A map from Clang modules to their Swift wrapper modules.
  llvm::SmallDenseMap<const clang::Module *, ModuleInitPair, 16> ModuleWrappers;

  /// The module unit that contains declarations from imported headers.
  ClangModuleUnit *ImportedHeaderUnit = nullptr;

  /// The modules re-exported by imported headers.
  llvm::SmallVector<clang::Module *, 8> ImportedHeaderExports;

  /// The modules that requested imported headers.
  ///
  /// These are used to look up Swift classes forward-declared with \@class.
  TinyPtrVector<ModuleDecl *> ImportedHeaderOwners;

  /// \brief Clang's objectAtIndexedSubscript: selector.
  clang::Selector objectAtIndexedSubscript;

  /// \brief Clang's setObjectAt:indexedSubscript: selector.
  clang::Selector setObjectAtIndexedSubscript;

  /// \brief Clang's objectForKeyedSubscript: selector.
  clang::Selector objectForKeyedSubscript;

  /// \brief Clang's setObject:forKeyedSubscript: selector.
  clang::Selector setObjectForKeyedSubscript;

private:
  /// Records those modules that we have looked up.
  llvm::DenseMap<Identifier, ModuleDecl *> checkedModules;

  /// Mapping from delayed conformance IDs to the set of delayed
  /// protocol conformances.
  llvm::DenseMap<unsigned, SmallVector<ProtocolConformance *, 4>>
    DelayedConformances;

  /// The next delayed conformance ID to use with \c DelayedConformances.
  unsigned NextDelayedConformanceID = 0;

  /// The set of imported protocols for a declaration, used only to
  /// load all members of the declaration.
  llvm::DenseMap<const Decl *, SmallVector<ProtocolDecl *, 4>>
    ImportedProtocols;

  void startedImportingEntity();

public:
  importer::PlatformAvailability platformAvailability;

private:
  /// For importing names. This is initialized by the ClangImporter::create()
  /// after having set up a suitable Clang instance.
  std::unique_ptr<importer::NameImporter> nameImporter = nullptr;

  /// If there is a single .PCH file imported into the __ObjC module, this
  /// is the filename of that PCH. When other files are imported, this should
  /// be llvm::None.
  Optional<std::string> SinglePCHImport = None;

public:
  importer::NameImporter &getNameImporter() {
    assert(nameImporter && "haven't finished initialization");
    return *nameImporter;
  }

  /// Tracks top level decls from the bridging header.
  std::vector<clang::Decl *> BridgeHeaderTopLevelDecls;
  std::vector<llvm::PointerUnion<clang::ImportDecl *, ImportDecl *>>
    BridgeHeaderTopLevelImports;

  /// Tracks macro definitions from the bridging header.
  std::vector<clang::IdentifierInfo *> BridgeHeaderMacros;
  /// Tracks included headers from the bridging header.
  llvm::DenseSet<const clang::FileEntry *> BridgeHeaderFiles;

  void addBridgeHeaderTopLevelDecls(clang::Decl *D);
  bool shouldIgnoreBridgeHeaderTopLevelDecl(clang::Decl *D);

public:
  void registerExternalDecl(Decl *D) {
    if (!hasFinishedTypeChecking())
      SwiftContext.addExternalDecl(D);
  }

  void recordImplicitUnwrapForDecl(Decl *decl, bool isIUO) {
#if !defined(NDEBUG)
    Type ty;
    if (auto *FD = dyn_cast<FuncDecl>(decl)) {
      assert(FD->getInterfaceType());
      ty = FD->getResultInterfaceType();
    } else if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
      assert(CD->getInterfaceType());
      ty = CD->getResultInterfaceType();
    } else if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
      ty = SD->getElementInterfaceType();
    } else {
      auto *VD = cast<VarDecl>(decl);
      ty = VD->getInterfaceType()->getReferenceStorageReferent();
    }
#endif

    if (!isIUO)
      return;

    assert(ty->getOptionalObjectType());

    auto *IUOAttr = new (SwiftContext)
        ImplicitlyUnwrappedOptionalAttr(/* implicit= */ true);
    decl->getAttrs().add(IUOAttr);
  }

  /// \brief Retrieve the Clang AST context.
  clang::ASTContext &getClangASTContext() const {
    return Instance->getASTContext();
  }

  /// \brief Retrieve the Clang Sema object.
  clang::Sema &getClangSema() const {
    return Instance->getSema();
  }

  /// \brief Retrieve the Clang AST context.
  clang::Preprocessor &getClangPreprocessor() const {
    return Instance->getPreprocessor();
  }
  
  clang::CodeGenOptions &getClangCodeGenOpts() const {
    return Instance->getCodeGenOpts();
  }

  /// Imports the given header contents into the Clang context.
  bool importHeader(ModuleDecl *adapter, StringRef headerName,
                    SourceLoc diagLoc, bool trackParsedSymbols,
                    std::unique_ptr<llvm::MemoryBuffer> contents,
                    bool implicitImport);

  /// \brief Retrieve the imported module that should contain the given
  /// Clang decl.
  ClangModuleUnit *getClangModuleForDecl(const clang::Decl *D,
                                         bool allowForwardDeclaration = false);

  /// Returns the module \p MI comes from, or \c None if \p MI does not have
  /// a valid associated module.
  ///
  /// The returned module may be null (but not \c None) if \p MI comes from
  /// an imported header.
  const clang::Module *getClangOwningModule(ClangNode Node) const;

  /// Whether NSUInteger can be imported as Int in certain contexts. If false,
  /// should always be imported as UInt.
  static bool shouldAllowNSUIntegerAsInt(bool isFromSystemModule,
                                         const clang::NamedDecl *decl);

  /// \brief Converts the given Swift identifier for Clang.
  clang::DeclarationName exportName(Identifier name);

  /// Imports the full name of the given Clang declaration into Swift.
  ///
  /// Note that this may result in a name very different from the Clang name,
  /// so it should not be used when referencing Clang symbols.
  ///
  /// \param D The Clang declaration whose name should be imported.
  importer::ImportedName importFullName(const clang::NamedDecl *D,
                                        Version version,
                                        clang::DeclarationName givenName =
                                          clang::DeclarationName()) {
    return getNameImporter().importName(D, version, givenName);
  }

  /// Print an imported name as a string suitable for the swift_name attribute,
  /// or the 'Rename' field of AvailableAttr.
  void printSwiftName(importer::ImportedName name,
                      importer::ImportNameVersion version,
                      bool fullyQualified,
                      llvm::raw_ostream &os);

  /// \brief Import the given Clang identifier into Swift.
  ///
  /// \param identifier The Clang identifier to map into Swift.
  ///
  /// \param removePrefix The prefix to remove from the Clang name to produce
  /// the Swift name. If the Clang name does not start with this prefix,
  /// nothing is removed.
  Identifier importIdentifier(const clang::IdentifierInfo *identifier,
                              StringRef removePrefix = "");

  /// Import an Objective-C selector.
  ObjCSelector importSelector(clang::Selector selector);

  /// Import a Swift name as a Clang selector.
  clang::Selector exportSelector(DeclName name, bool allowSimpleName = true);

  /// Export a Swift Objective-C selector as a Clang Objective-C selector.
  clang::Selector exportSelector(ObjCSelector selector);

  /// \brief Import the given Swift source location into Clang.
  clang::SourceLocation exportSourceLoc(SourceLoc loc);

  /// \brief Import the given Clang source location into Swift.
  SourceLoc importSourceLoc(clang::SourceLocation loc);

  /// \brief Import the given Clang source range into Swift.
  SourceRange importSourceRange(clang::SourceRange loc);

  /// \brief Import the given Clang preprocessor macro as a Swift value decl.
  ///
  /// \p macroNode must be a MacroInfo or a ModuleMacro.
  ///
  /// \returns The imported declaration, or null if the macro could not be
  /// translated into Swift.
  ValueDecl *importMacro(Identifier name, ClangNode macroNode);

  /// Map a Clang identifier name to its imported Swift equivalent.
  StringRef getSwiftNameFromClangName(StringRef name);

  /// Import attributes from the given Clang declaration to its Swift
  /// equivalent.
  ///
  /// \param ClangDecl The decl being imported.
  /// \param MappedDecl The decl to attach attributes to.
  /// \param NewContext If present, the Clang node for the context the decl is
  /// being imported into, which may affect info from API notes.
  void importAttributes(const clang::NamedDecl *ClangDecl, Decl *MappedDecl,
                        const clang::ObjCContainerDecl *NewContext = nullptr);

  /// If we already imported a given decl, return the corresponding Swift decl.
  /// Otherwise, return nullptr.
  Decl *importDeclCached(const clang::NamedDecl *ClangDecl, Version version);

  Decl *importDeclImpl(const clang::NamedDecl *ClangDecl, Version version,
                       bool &TypedefIsSuperfluous, bool &HadForwardDeclaration);

  Decl *importDeclAndCacheImpl(const clang::NamedDecl *ClangDecl,
                               Version version,
                               bool SuperfluousTypedefsAreTransparent);

  /// \brief Same as \c importDeclReal, but for use inside importer
  /// implementation.
  ///
  /// Unlike \c importDeclReal, this function for convenience transparently
  /// looks through superfluous typedefs and returns the imported underlying
  /// decl in that case.
  Decl *importDecl(const clang::NamedDecl *ClangDecl, Version version) {
    return importDeclAndCacheImpl(ClangDecl, version,
                                  /*SuperfluousTypedefsAreTransparent=*/true);
  }

  /// \brief Import the given Clang declaration into Swift.  Use this function
  /// outside of the importer implementation, when importing a decl requested by
  /// Swift code.
  ///
  /// \returns The imported declaration, or null if this declaration could
  /// not be represented in Swift.
  Decl *importDeclReal(const clang::NamedDecl *ClangDecl, Version version) {
    return importDeclAndCacheImpl(ClangDecl, version,
                                  /*SuperfluousTypedefsAreTransparent=*/false);
  }

  /// \brief Import a cloned version of the given declaration, which is part of
  /// an Objective-C protocol and currently must be a method or property, into
  /// the given declaration context.
  ///
  /// \returns The imported declaration, or null if this declaration could not
  /// be represented in Swift.
  Decl *importMirroredDecl(const clang::NamedDecl *decl, DeclContext *dc,
                           Version version, ProtocolDecl *proto);

  /// \brief Utility function for building simple generic signatures.
  GenericSignature *buildGenericSignature(GenericParamList *genericParams,
                                          DeclContext *dc);

  /// \brief Utility function for building simple generic environments.
  GenericEnvironment *buildGenericEnvironment(GenericParamList *genericParams,
                                              DeclContext *dc);

  /// \brief Import the given Clang declaration context into Swift.
  ///
  /// Usually one will use \c importDeclContextOf instead.
  ///
  /// \returns The imported declaration context, or null if it could not
  /// be converted.
  DeclContext *importDeclContextImpl(const clang::DeclContext *dc);

  /// \brief Import the declaration context of a given Clang declaration into
  /// Swift.
  ///
  /// \param context The effective context as determined by importFullName.
  ///
  /// \returns The imported declaration context, or null if it could not
  /// be converted.
  DeclContext *importDeclContextOf(const clang::Decl *D,
                                   EffectiveClangContext context);

  /// \brief Create a new named constant with the given value.
  ///
  /// \param name The name of the constant.
  /// \param dc The declaration context into which the name will be introduced.
  /// \param type The type of the named constant.
  /// \param value The value of the named constant.
  /// \param convertKind How to convert the constant to the given type.
  /// \param isStatic Whether the constant should be a static member of \p dc.
  ValueDecl *createConstant(Identifier name, DeclContext *dc,
                            Type type, const clang::APValue &value,
                            ConstantConvertKind convertKind,
                            bool isStatic,
                            ClangNode ClangN);

  /// \brief Create a new named constant with the given value.
  ///
  /// \param name The name of the constant.
  /// \param dc The declaration context into which the name will be introduced.
  /// \param type The type of the named constant.
  /// \param value The value of the named constant.
  /// \param convertKind How to convert the constant to the given type.
  /// \param isStatic Whether the constant should be a static member of \p dc.
  ValueDecl *createConstant(Identifier name, DeclContext *dc,
                            Type type, StringRef value,
                            ConstantConvertKind convertKind,
                            bool isStatic,
                            ClangNode ClangN);

  /// \brief Create a new named constant using the given expression.
  ///
  /// \param name The name of the constant.
  /// \param dc The declaration context into which the name will be introduced.
  /// \param type The type of the named constant.
  /// \param valueExpr An expression to use as the value of the constant.
  /// \param convertKind How to convert the constant to the given type.
  /// \param isStatic Whether the constant should be a static member of \p dc.
  ValueDecl *createConstant(Identifier name, DeclContext *dc,
                            Type type, Expr *valueExpr,
                            ConstantConvertKind convertKind,
                            bool isStatic,
                            ClangNode ClangN);

  /// Determine whether the given declaration is considered
  /// 'unavailable' in Swift.
  bool isUnavailableInSwift(const clang::Decl *decl) {
    return importer::isUnavailableInSwift(
        decl, platformAvailability, SwiftContext.LangOpts.EnableObjCInterop);
  }

  /// \brief Add "Unavailable" annotation to the swift declaration.
  void markUnavailable(ValueDecl *decl, StringRef unavailabilityMsg);

  /// \brief Create a decl with error type and an "unavailable" attribute on it
  /// with the specified message.
  ValueDecl *createUnavailableDecl(Identifier name, DeclContext *dc,
                                   Type type, StringRef UnavailableMessage,
                                   bool isStatic, ClangNode ClangN);

  /// \brief Retrieve the standard library module.
  ModuleDecl *getStdlibModule();

  /// \brief Retrieve the named module.
  ///
  /// \param name The name of the module.
  ///
  /// \returns The named module, or null if the module has not been imported.
  ModuleDecl *getNamedModule(StringRef name);

  /// \brief Returns the "Foundation" module, if it can be loaded.
  ///
  /// After this has been called, the Foundation module will or won't be loaded
  /// into the ASTContext.
  ModuleDecl *tryLoadFoundationModule();

  /// \brief Returns the "SIMD" module, if it can be loaded.
  ///
  /// After this has been called, the SIMD module will or won't be loaded
  /// into the ASTContext.
  ModuleDecl *tryLoadSIMDModule();

  /// \brief Retrieves the Swift wrapper for the given Clang module, creating
  /// it if necessary.
  ClangModuleUnit *getWrapperForModule(const clang::Module *underlying);

  /// \brief Constructs a Swift module for the given Clang module.
  ModuleDecl *finishLoadingClangModule(const clang::Module *clangModule,
                                       bool preferAdapter);

  /// \brief Call finishLoadingClangModule on each deferred import collected
  /// while scanning a bridging header or PCH.
  void handleDeferredImports();

  /// \brief Retrieve the named Swift type, e.g., Int32.
  ///
  /// \param moduleName The name of the module in which the type should occur.
  ///
  /// \param name The name of the type to find.
  ///
  /// \returns The named type, or null if the type could not be found.
  Type getNamedSwiftType(StringRef moduleName, StringRef name);

  /// \brief Retrieve the named Swift type, e.g., Int32.
  ///
  /// \param module The module in which the type should occur.
  ///
  /// \param name The name of the type to find.
  ///
  /// \returns The named type, or null if the type could not be found.
  Type getNamedSwiftType(ModuleDecl *module, StringRef name);

  /// \brief Retrieve a specialization of the named Swift type, e.g.,
  /// UnsafeMutablePointer<T>.
  ///
  /// \param module The name of the module in which the type should occur.
  ///
  /// \param name The name of the type to find.
  ///
  /// \param args The arguments to use in the specialization.
  ///
  /// \returns The named type, or null if the type could not be found.
  Type getNamedSwiftTypeSpecialization(ModuleDecl *module, StringRef name,
                                       ArrayRef<Type> args);

  /// \brief Retrieve the NSObject type.
  Type getNSObjectType();

  /// \brief Retrieve the NSObject protocol type.
  Type getNSObjectProtocolType();

  /// \brief Retrieve the NSCopying protocol type.
  Type getNSCopyingType();

  /// \brief Retrieve a sugared referenece to the given (imported) type.
  Type getSugaredTypeReference(TypeDecl *type);

  /// \brief Determines whether the given type matches an implicit type
  /// bound of "Hashable", which is used to validate NSDictionary/NSSet.
  bool matchesHashableBound(Type type);

  /// \brief Look up and attempt to import a Clang declaration with
  /// the given name.
  Decl *importDeclByName(StringRef name);

  /// \brief Import the given Clang type into Swift.
  ///
  /// \param type The Clang type to import.
  ///
  /// \param kind A classification of the immediate context in which this type
  ///   will be used. Different contexts result in the type being imported
  ///   differently; for example, CF types are normally considered Unmanaged,
  ///   but in parameter position they are known to always be passed at +0.
  ///   See also the \p topLevelBridgeability parameter.
  ///
  /// \param allowNSUIntegerAsInt If true, NSUInteger will be imported as Int
  ///   in certain contexts. If false, it will always be imported as UInt.
  ///
  /// \param topLevelBridgeability A classification of the top-level context in
  ///   which this type will be used. This and \p kind are used together to
  ///   determine whether a type can be imported in a more Swifty way than
  ///   a naive translation of its C type. Full bridgeability requires that SIL
  ///   can get back to the original Clang type if it needs to, which implies
  ///   that this type is part of a top-level declaration where we do bridging.
  ///   Without full bridgeability, we can still do some Swifty importing (e.g.
  ///   mapping NSString to String) if we're in an immediate context \p kind
  ///   that allows bridging, but only in cases where Swift's default mapping
  ///   "back" to C is the correct one. If the original type has something
  ///   funny going on, we either have to use a less lossy version of the type
  ///   (ObjCBool rather than Bool) or refuse to import it at all (a block with
  ///   the \c ns_returns_retained attribute).
  ///
  /// \param optional If the imported type was a pointer-like type in C, this
  ///   optionality is applied to the resulting Swift type.
  ///
  /// \param resugarNSErrorPointer If true, Objective-C's `NSError **` is
  ///   imported as Foundation.NSErrorPointer rather than
  ///   AutoreleasingUnsafeMutablePointer<...>. This is usually desirable
  ///   behavior, but isn't necessary when we use Swift's \c throws anyway.
  ///   Strictly speaking, though, this is a hack used to break cyclic
  ///   dependencies.
  ///
  /// \returns An ImportedType value which holds the imported type. If
  ///          this type is an Optional, it also has a flag which
  ///          indicates if the Optional is implicitly unwrapped. If
  ///          the type cannot be represented in Swift, then the type
  ///          field will be null.
  ImportedType
  importType(clang::QualType type, ImportTypeKind kind,
             bool allowNSUIntegerAsInt, Bridgeability topLevelBridgeability,
             OptionalTypeKind optional = OTK_ImplicitlyUnwrappedOptional,
             bool resugarNSErrorPointer = true);

  /// \brief Import the given Clang type into Swift.
  ///
  /// For a description of parameters, see importType(). This differs
  /// only in that it returns a Type rather than ImportedType, which
  /// means that we do not retain the information of whether the type
  /// returned might be an implicitly unwrapped optional.
  ///
  /// \returns The imported type, or null if this type could not be
  ///   represented in Swift.
  Type importTypeIgnoreIUO(
      clang::QualType type, ImportTypeKind kind, bool allowNSUIntegerAsInt,
      Bridgeability topLevelBridgeability,
      OptionalTypeKind optional = OTK_ImplicitlyUnwrappedOptional,
      bool resugarNSErrorPointer = true);

  /// \brief Import the given Clang type into Swift, returning the
  /// Swift type and whether we should treat it as an optional that is
  /// implicitly unwrapped.
  ///
  /// \returns A pair of the imported type and whether we should treat
  /// it as an optional that is implicitly unwrapped. The returned
  /// type is null if it cannot be represented in Swift.

  /// \brief Import the given function type.
  ///
  /// This routine should be preferred when importing function types for
  /// which we have actual function parameters, e.g., when dealing with a
  /// function declaration, because it produces a function type whose input
  /// tuple has argument names.
  ///
  /// \param dc The context the function is being imported into.
  /// \param clangDecl The underlying declaration, if any; should only be
  ///   considered for any attributes it might carry.
  /// \param params The parameter types to the function.
  /// \param isVariadic Whether the function is variadic.
  /// \param isFromSystemModule Whether to apply special rules that only apply
  ///   to system APIs.
  /// \param name The name of the function.
  /// \param[out] parameterList The parameters visible inside the function body.
  ///
  /// \returns the imported function type, or null if the type cannot be
  /// imported.
  ImportedType importFunctionType(DeclContext *dc,
                                  const clang::FunctionDecl *clangDecl,
                                  ArrayRef<const clang::ParmVarDecl *> params,
                                  bool isVariadic, bool isFromSystemModule,
                                  DeclName name, ParameterList *&parameterList);

  /// \brief Import the given function return type.
  ///
  /// \param dc The context the function is being imported into.
  /// \param clangDecl The underlying declaration, if any; should only be
  ///   considered for any attributes it might carry.
  /// \param allowNSUIntegerAsInt If true, NSUInteger will be imported as Int
  ///        in certain contexts. If false, it will always be imported as UInt.
  ///
  /// \returns the imported function return type, or null if the type cannot be
  /// imported.
  ImportedType importFunctionReturnType(DeclContext *dc,
                                        const clang::FunctionDecl *clangDecl,
                                        bool allowNSUIntegerAsInt);

  /// \brief Import the parameter list for a function
  ///
  /// \param clangDecl The underlying declaration, if any; should only be
  ///   considered for any attributes it might carry.
  /// \param params The parameter types to the function.
  /// \param isVariadic Whether the function is variadic.
  /// \param allowNSUIntegerAsInt If true, NSUInteger will be imported as Int
  ///        in certain contexts. If false, it will always be imported as UInt.
  /// \param argNames The argument names
  ///
  /// \returns The imported parameter list on success, or null on failure
  ParameterList *
  importFunctionParameterList(DeclContext *dc,
                              const clang::FunctionDecl *clangDecl,
                              ArrayRef<const clang::ParmVarDecl *> params,
                              bool isVariadic, bool allowNSUIntegerAsInt,
                              ArrayRef<Identifier> argNames);

  ImportedType importPropertyType(const clang::ObjCPropertyDecl *clangDecl,
                                  bool isFromSystemModule);

  /// Attempt to infer a default argument for a parameter with the
  /// given Clang \c type, \c baseName, and optionality.
  static DefaultArgumentKind
  inferDefaultArgument(clang::QualType type, OptionalTypeKind clangOptionality,
                       DeclBaseName baseName, unsigned numParams,
                       StringRef argumentLabel, bool isFirstParameter,
                       bool isLastParameter, importer::NameImporter &);

  /// Import the type of an Objective-C method.
  ///
  /// Note that this is not appropriate to use for property accessor methods.
  /// Use #importAccessorMethodType instead.
  ///
  /// \param dc The context the method is being imported into.
  /// \param clangDecl The underlying declaration.
  /// \param params The parameter types to the function. Note that this may not
  ///   include all parameters defined on the ObjCMethodDecl.
  /// \param isVariadic Whether the function is variadic.
  /// \param isFromSystemModule Whether to apply special rules that only apply
  ///   to system APIs.
  /// \param[out] bodyParams The patterns visible inside the function body.
  /// \param importedName How to import the name of the method.
  /// \param[out] errorConvention Whether and how the method throws NSErrors.
  /// \param kind Controls whether we're building a type for a method that
  ///   needs special handling.
  ///
  /// \returns the imported function type, or null if the type cannot be
  /// imported.
  ImportedType
  importMethodType(const DeclContext *dc,
                   const clang::ObjCMethodDecl *clangDecl,
                   ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,
                   bool isFromSystemModule, ParameterList **bodyParams,
                   importer::ImportedName importedName,
                   Optional<ForeignErrorConvention> &errorConvention,
                   SpecialMethodKind kind);

  /// Import the type of an Objective-C method that will be imported as an
  /// accessor for \p property.
  ///
  /// \param dc The context the method is being imported into.
  /// \param property The property the method will be an accessor for.
  /// \param clangDecl The underlying declaration.
  /// \param isFromSystemModule Whether to apply special rules that only apply
  ///   to system APIs.
  /// \param importedName How to import the name of the method. This is still
  ///   important to satisfy the AST verifier, even though the method is an
  ///   accessor.
  /// \param[out] params The patterns visible inside the function body.
  ///
  /// \returns the imported function type, or null if the type cannot be
  /// imported.
  ImportedType importAccessorMethodType(const DeclContext *dc,
                                        const clang::ObjCPropertyDecl *property,
                                        const clang::ObjCMethodDecl *clangDecl,
                                        bool isFromSystemModule,
                                        importer::ImportedName importedName,
                                        ParameterList **params);

  /// \brief Determine whether the given typedef-name is "special", meaning
  /// that it has performed some non-trivial mapping of its underlying type
  /// based on the name of the typedef.
  Optional<MappedTypeNameKind>
  getSpecialTypedefKind(clang::TypedefNameDecl *decl);

  /// \brief Look up a name, accepting only typedef results.
  const clang::TypedefNameDecl *lookupTypedef(clang::DeclarationName);

  /// \brief Return whether a global of the given type should be imported as a
  /// 'let' declaration as opposed to 'var'.
  bool shouldImportGlobalAsLet(clang::QualType type);

  LazyResolver *getTypeResolver() const {
    return typeResolver.getPointer();
  }
  void setTypeResolver(LazyResolver *newResolver) {
    assert((!typeResolver.getPointer() || !newResolver) &&
           "already have a type resolver");
    typeResolver.setPointerAndInt(newResolver, true);
  }
  bool hasBegunTypeChecking() const { return typeResolver.getInt(); }
  bool hasFinishedTypeChecking() const {
    return hasBegunTypeChecking() && !getTypeResolver();
  }

  /// Allocate a new delayed conformance ID with the given set of
  /// conformances.
  unsigned allocateDelayedConformance(
             SmallVector<ProtocolConformance *, 4> &&conformances) {
    unsigned id = NextDelayedConformanceID++;
    DelayedConformances[id] = std::move(conformances);
    return id;
  }

  /// Take the delayed conformances associated with the given id.
  SmallVector<ProtocolConformance *, 4> takeDelayedConformance(unsigned id) {
    auto conformances = DelayedConformances.find(id);
    SmallVector<ProtocolConformance *, 4> result
      = std::move(conformances->second);
    DelayedConformances.erase(conformances);
    return result;
  }

  /// Record the set of imported protocols for the given declaration,
  /// to be used by member loading.
  ///
  /// FIXME: This is all a hack; we should have lazier deserialization
  /// of protocols separate from their conformances.
  void recordImportedProtocols(const Decl *decl,
                               ArrayRef<ProtocolDecl *> protocols) {
    if (protocols.empty())
      return;

    auto &recorded = ImportedProtocols[decl];
    recorded.insert(recorded.end(), protocols.begin(), protocols.end());
  }

  /// Retrieve the imported protocols for the given declaration.
  SmallVector<ProtocolDecl *, 4> takeImportedProtocols(const Decl *decl) {
    SmallVector<ProtocolDecl *, 4> result;

    auto known = ImportedProtocols.find(decl);
    if (known != ImportedProtocols.end()) {
      result = std::move(known->second);
      ImportedProtocols.erase(known);
    }

    return result;
  }

  virtual void
  loadAllMembers(Decl *D, uint64_t unused) override;

  virtual Optional<TinyPtrVector<ValueDecl *>>
  loadNamedMembers(const IterableDeclContext *IDC, DeclBaseName N,
                   uint64_t contextData) override;

private:
  void
  loadAllMembersOfObjcContainer(Decl *D,
                                const clang::ObjCContainerDecl *objcContainer);
  void collectMembersToAdd(const clang::ObjCContainerDecl *objcContainer,
                           Decl *D, DeclContext *DC,
                           SmallVectorImpl<Decl *> &members);
  void insertMembersAndAlternates(const clang::NamedDecl *nd,
                                  SmallVectorImpl<Decl *> &members);
  void loadAllMembersIntoExtension(Decl *D, uint64_t extra);

  /// Imports \p decl under \p nameVersion with the name \p newName, and adds
  /// it and its alternates to \p ext.
  ///
  /// \returns true if \p decl was successfully imported, whether or not it was
  /// ultimately added to \p ext. This matches the behavior of
  /// forEachDistinctName's callback.
  bool addMemberAndAlternatesToExtension(
      clang::NamedDecl *decl, importer::ImportedName newName,
      importer::ImportNameVersion nameVersion, ExtensionDecl *ext);

public:
  void
  loadAllConformances(
    const Decl *D, uint64_t contextData,
    SmallVectorImpl<ProtocolConformance *> &Conformances) override;

  void finishNormalConformance(NormalProtocolConformance *conformance,
                               uint64_t unused) override;
  
  /// Returns the default definition type for \p ATD.
  TypeLoc loadAssociatedTypeDefault(const AssociatedTypeDecl *ATD,
                                            uint64_t contextData) override {
    llvm_unreachable("unimplemented for ClangImporter");
  }
  
  /// Returns the generic environment.
  virtual GenericEnvironment *loadGenericEnvironment(const DeclContext *decl,
                                                     uint64_t contextData) override {
    llvm_unreachable("unimplemented for ClangImporter");
  }

  template <typename DeclTy, typename ...Targs>
  DeclTy *createDeclWithClangNode(ClangNode ClangN, AccessLevel access,
                                  Targs &&... Args) {
    assert(ClangN);
    void *DeclPtr = allocateMemoryForDecl<DeclTy>(SwiftContext, sizeof(DeclTy),
                                                  true);
    auto D = ::new (DeclPtr) DeclTy(std::forward<Targs>(Args)...);
    D->setClangNode(ClangN);
    D->setEarlyAttrValidation(true);
    D->setAccess(access);
    if (auto ASD = dyn_cast<AbstractStorageDecl>(D))
      ASD->setSetterAccess(access);
    // All imported decls are constructed fully validated.
    D->setValidationStarted();
    if (auto AFD = dyn_cast<AbstractFunctionDecl>(static_cast<Decl *>(D)))
      AFD->setNeedsNewVTableEntry(false);
    return D;
  }

  /// Find the lookup table that corresponds to the given Clang module.
  ///
  /// \param clangModule The module, or null to indicate that we're talking
  /// about the directly-parsed headers.
  SwiftLookupTable *findLookupTable(const clang::Module *clangModule);

  /// Visit each of the lookup tables in some deterministic order.
  ///
  /// \param fn Invoke the given visitor for each table. If the
  /// visitor returns true, stop early.
  ///
  /// \returns \c true if the \c visitor ever returns \c true, \c
  /// false otherwise.
  bool forEachLookupTable(llvm::function_ref<bool(SwiftLookupTable &table)> fn);

  /// Look for namespace-scope values with the given name in the given
  /// Swift lookup table.
  void lookupValue(SwiftLookupTable &table, DeclName name,
                   VisibleDeclConsumer &consumer);

  /// Look for namespace-scope values in the given Swift lookup table.
  void lookupVisibleDecls(SwiftLookupTable &table,
                          VisibleDeclConsumer &consumer);

  /// Look for Objective-C members with the given name in the given
  /// Swift lookup table.
  void lookupObjCMembers(SwiftLookupTable &table, DeclName name,
                         VisibleDeclConsumer &consumer);

  /// Look for all Objective-C members in the given Swift lookup table.
  void lookupAllObjCMembers(SwiftLookupTable &table,
                            VisibleDeclConsumer &consumer);

  /// Determine the effective Clang context for the given Swift nominal type.
  EffectiveClangContext
  getEffectiveClangContext(const NominalTypeDecl *nominal);

  /// Attempts to import the name of \p decl with each possible
  /// ImportNameVersion. \p action will be called with each unique name.
  ///
  /// In this case, "unique" means either the full name is distinct or the
  /// effective context is distinct. This method does not attempt to handle
  /// "unresolved" contexts in any special way---if one name references a
  /// particular Clang declaration and the other has an unresolved context that
  /// will eventually reference that declaration, the contexts will still be
  /// considered distinct.
  ///
  /// If \p action returns false, the current name will \e not be added to the
  /// set of seen names.
  ///
  /// The active name is always first, followed by the other names in the order
  /// of ImportNameVersion::forEachOtherImportNameVersion.
  void forEachDistinctName(
      const clang::NamedDecl *decl,
      llvm::function_ref<bool(importer::ImportedName,
                              importer::ImportNameVersion)> action);

  /// Dump the Swift-specific name lookup tables we generate.
  void dumpSwiftLookupTables();

  void setSinglePCHImport(Optional<std::string> PCHFilename) {
    if (PCHFilename.hasValue()) {
      assert(llvm::sys::path::extension(PCHFilename.getValue())
                 .endswith(PCH_EXTENSION) &&
             "Single PCH imported filename doesn't have .pch extension!");
    }
    SinglePCHImport = PCHFilename;
  }

  /// If there was is a single .pch bridging header without other imported
  /// files, we can provide the PCH filename for declaration caching,
  /// especially in code completion.
  StringRef getSinglePCHImport() const {
    if (SinglePCHImport.hasValue())
      return *SinglePCHImport;
    return StringRef();
  }
};

namespace importer {

/// Whether we should suppress the import of the given Clang declaration.
bool shouldSuppressDeclImport(const clang::Decl *decl);

/// Finds a particular kind of nominal by looking through typealiases.
template <typename T>
static T *dynCastIgnoringCompatibilityAlias(Decl *D) {
  static_assert(std::is_base_of<NominalTypeDecl, T>::value,
                "only meant for use with NominalTypeDecl and subclasses");
  if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(D)) {
    if (!alias->isCompatibilityAlias())
      return nullptr;
    D = alias->getDeclaredInterfaceType()->getAnyNominal();
  }
  return dyn_cast_or_null<T>(D);
}

/// Finds a particular kind of nominal by looking through typealiases.
template <typename T>
static T *castIgnoringCompatibilityAlias(Decl *D) {
  static_assert(std::is_base_of<NominalTypeDecl, T>::value,
                "only meant for use with NominalTypeDecl and subclasses");
  if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(D)) {
    assert(alias->isCompatibilityAlias() &&
           "non-compatible typealias found where nominal was expected");
    D = alias->getDeclaredInterfaceType()->getAnyNominal();
  }
  return cast_or_null<T>(D);
}

class SwiftNameLookupExtension : public clang::ModuleFileExtension {
  std::unique_ptr<SwiftLookupTable> &pchLookupTable;
  LookupTableMap &lookupTables;
  ASTContext &swiftCtx;
  const PlatformAvailability &availability;
  const bool inferImportAsMember;

public:
  SwiftNameLookupExtension(std::unique_ptr<SwiftLookupTable> &pchLookupTable,
                           LookupTableMap &tables, ASTContext &ctx,
                           const PlatformAvailability &avail, bool inferIAM)
      : pchLookupTable(pchLookupTable), lookupTables(tables), swiftCtx(ctx),
        availability(avail), inferImportAsMember(inferIAM) {}

  clang::ModuleFileExtensionMetadata getExtensionMetadata() const override;
  llvm::hash_code hashExtension(llvm::hash_code code) const override;

  std::unique_ptr<clang::ModuleFileExtensionWriter>
  createExtensionWriter(clang::ASTWriter &writer) override;

  std::unique_ptr<clang::ModuleFileExtensionReader>
  createExtensionReader(const clang::ModuleFileExtensionMetadata &metadata,
                        clang::ASTReader &reader,
                        clang::serialization::ModuleFile &mod,
                        const llvm::BitstreamCursor &stream) override;
};

}
}

#endif
