//===- ASTContext.h - Context to hold long-lived AST nodes ------*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines the clang::ASTContext interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H

#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/ComparisonCategories.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/NoSanitizeList.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/ProfileList.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/XRayLists.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TypeSize.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

namespace llvm {

class APFixedPoint;
class FixedPointSemantics;
struct fltSemantics;
template <typename T, unsigned N> class SmallPtrSet;

} // namespace llvm

namespace clang {

class APValue;
class ASTMutationListener;
class ASTRecordLayout;
class AtomicExpr;
class BlockExpr;
class BuiltinTemplateDecl;
class CharUnits;
class ConceptDecl;
class CXXABI;
class CXXConstructorDecl;
class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
class ParentMapContext;
class DynTypedNode;
class DynTypedNodeList;
class Expr;
enum class FloatModeKind;
class GlobalDecl;
class ItaniumMangleContext;
class MangleContext;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
class MemberSpecializationInfo;
class Module;
struct MSGuidDeclParts;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
class ObjCImplDecl;
class ObjCImplementationDecl;
class ObjCInterfaceDecl;
class ObjCIvarDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl;
class ObjCPropertyImplDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
class OMPTraitInfo;
struct ParsedTargetAttr;
class Preprocessor;
class Stmt;
class StoredDeclsMap;
class TargetAttr;
class TargetInfo;
class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
class UnresolvedSetIterator;
class UsingShadowDecl;
class VarTemplateDecl;
class VTableContextBase;
struct BlockVarCopyInit;

namespace Builtin {

class Context;

} // namespace Builtin

enum BuiltinTemplateKind : int;
enum OpenCLTypeKind : uint8_t;

namespace comments {

class FullComment;

} // namespace comments

namespace interp {

class Context;

} // namespace interp

namespace serialization {
template <class> class AbstractTypeReader;
} // namespace serialization

enum class AlignRequirementKind {
  /// The alignment was not explicit in code.
  None,

  /// The alignment comes from an alignment attribute on a typedef.
  RequiredByTypedef,

  /// The alignment comes from an alignment attribute on a record type.
  RequiredByRecord,

  /// The alignment comes from an alignment attribute on a enum type.
  RequiredByEnum,
};

struct TypeInfo {
  uint64_t Width = 0;
  unsigned Align = 0;
  AlignRequirementKind AlignRequirement;

  TypeInfo() : AlignRequirement(AlignRequirementKind::None) {}
  TypeInfo(uint64_t Width, unsigned Align,
           AlignRequirementKind AlignRequirement)
      : Width(Width), Align(Align), AlignRequirement(AlignRequirement) {}
  bool isAlignRequired() {
    return AlignRequirement != AlignRequirementKind::None;
  }
};

struct TypeInfoChars {
  CharUnits Width;
  CharUnits Align;
  AlignRequirementKind AlignRequirement;

  TypeInfoChars() : AlignRequirement(AlignRequirementKind::None) {}
  TypeInfoChars(CharUnits Width, CharUnits Align,
                AlignRequirementKind AlignRequirement)
      : Width(Width), Align(Align), AlignRequirement(AlignRequirement) {}
  bool isAlignRequired() {
    return AlignRequirement != AlignRequirementKind::None;
  }
};

/// Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
  friend class NestedNameSpecifier;

  mutable SmallVector<Type *, 0> Types;
  mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
  mutable llvm::FoldingSet<ComplexType> ComplexTypes;
  mutable llvm::FoldingSet<PointerType> PointerTypes;
  mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
  mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
  mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
  mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
  mutable llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
  mutable llvm::ContextualFoldingSet<ConstantArrayType, ASTContext &>
      ConstantArrayTypes;
  mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
  mutable std::vector<VariableArrayType*> VariableArrayTypes;
  mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
  mutable llvm::FoldingSet<DependentSizedExtVectorType>
    DependentSizedExtVectorTypes;
  mutable llvm::FoldingSet<DependentAddressSpaceType>
      DependentAddressSpaceTypes;
  mutable llvm::FoldingSet<VectorType> VectorTypes;
  mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
  mutable llvm::FoldingSet<ConstantMatrixType> MatrixTypes;
  mutable llvm::FoldingSet<DependentSizedMatrixType> DependentSizedMatrixTypes;
  mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
  mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
    FunctionProtoTypes;
  mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
  mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
  mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
  mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
  mutable llvm::FoldingSet<SubstTemplateTypeParmType>
    SubstTemplateTypeParmTypes;
  mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
    SubstTemplateTypeParmPackTypes;
  mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
    TemplateSpecializationTypes;
  mutable llvm::FoldingSet<ParenType> ParenTypes;
  mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
  mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
  mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
                                     ASTContext&>
    DependentTemplateSpecializationTypes;
  llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
  mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
  mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
  mutable llvm::FoldingSet<DependentUnaryTransformType>
    DependentUnaryTransformTypes;
  mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
  mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
    DeducedTemplateSpecializationTypes;
  mutable llvm::FoldingSet<AtomicType> AtomicTypes;
  llvm::FoldingSet<AttributedType> AttributedTypes;
  mutable llvm::FoldingSet<PipeType> PipeTypes;
  mutable llvm::FoldingSet<BitIntType> BitIntTypes;
  mutable llvm::FoldingSet<DependentBitIntType> DependentBitIntTypes;

  mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
  mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
  mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
    SubstTemplateTemplateParms;
  mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
                                     ASTContext&>
    SubstTemplateTemplateParmPacks;

  /// The set of nested name specifiers.
  ///
  /// This set is managed by the NestedNameSpecifier class.
  mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
  mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;

  /// A cache mapping from RecordDecls to ASTRecordLayouts.
  ///
  /// This is lazily created.  This is intentionally not serialized.
  mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>
    ASTRecordLayouts;
  mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
    ObjCLayouts;

  /// A cache from types to size and alignment information.
  using TypeInfoMap = llvm::DenseMap<const Type *, struct TypeInfo>;
  mutable TypeInfoMap MemoizedTypeInfo;

  /// A cache from types to unadjusted alignment information. Only ARM and
  /// AArch64 targets need this information, keeping it separate prevents
  /// imposing overhead on TypeInfo size.
  using UnadjustedAlignMap = llvm::DenseMap<const Type *, unsigned>;
  mutable UnadjustedAlignMap MemoizedUnadjustedAlign;

  /// A cache mapping from CXXRecordDecls to key functions.
  llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;

  /// Mapping from ObjCContainers to their ObjCImplementations.
  llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;

  /// Mapping from ObjCMethod to its duplicate declaration in the same
  /// interface.
  llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;

  /// Mapping from __block VarDecls to BlockVarCopyInit.
  llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;

  /// Mapping from GUIDs to the corresponding MSGuidDecl.
  mutable llvm::FoldingSet<MSGuidDecl> MSGuidDecls;

  /// Mapping from APValues to the corresponding TemplateParamObjects.
  mutable llvm::FoldingSet<TemplateParamObjectDecl> TemplateParamObjectDecls;

  /// A cache mapping a string value to a StringLiteral object with the same
  /// value.
  ///
  /// This is lazily created.  This is intentionally not serialized.
  mutable llvm::StringMap<StringLiteral *> StringLiteralCache;

  /// MD5 hash of CUID. It is calculated when first used and cached by this
  /// data member.
  mutable std::string CUIDHash;

  /// Representation of a "canonical" template template parameter that
  /// is used in canonical template names.
  class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
    TemplateTemplateParmDecl *Parm;

  public:
    CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
        : Parm(Parm) {}

    TemplateTemplateParmDecl *getParam() const { return Parm; }

    void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
      Profile(ID, C, Parm);
    }

    static void Profile(llvm::FoldingSetNodeID &ID,
                        const ASTContext &C,
                        TemplateTemplateParmDecl *Parm);
  };
  mutable llvm::ContextualFoldingSet<CanonicalTemplateTemplateParm,
                                     const ASTContext&>
    CanonTemplateTemplateParms;

  TemplateTemplateParmDecl *
    getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;

  /// The typedef for the __int128_t type.
  mutable TypedefDecl *Int128Decl = nullptr;

  /// The typedef for the __uint128_t type.
  mutable TypedefDecl *UInt128Decl = nullptr;

  /// The typedef for the target specific predefined
  /// __builtin_va_list type.
  mutable TypedefDecl *BuiltinVaListDecl = nullptr;

  /// The typedef for the predefined \c __builtin_ms_va_list type.
  mutable TypedefDecl *BuiltinMSVaListDecl = nullptr;

  /// The typedef for the predefined \c id type.
  mutable TypedefDecl *ObjCIdDecl = nullptr;

  /// The typedef for the predefined \c SEL type.
  mutable TypedefDecl *ObjCSelDecl = nullptr;

  /// The typedef for the predefined \c Class type.
  mutable TypedefDecl *ObjCClassDecl = nullptr;

  /// The typedef for the predefined \c Protocol class in Objective-C.
  mutable ObjCInterfaceDecl *ObjCProtocolClassDecl = nullptr;

  /// The typedef for the predefined 'BOOL' type.
  mutable TypedefDecl *BOOLDecl = nullptr;

  // Typedefs which may be provided defining the structure of Objective-C
  // pseudo-builtins
  QualType ObjCIdRedefinitionType;
  QualType ObjCClassRedefinitionType;
  QualType ObjCSelRedefinitionType;

  /// The identifier 'bool'.
  mutable IdentifierInfo *BoolName = nullptr;

  /// The identifier 'NSObject'.
  mutable IdentifierInfo *NSObjectName = nullptr;

  /// The identifier 'NSCopying'.
  IdentifierInfo *NSCopyingName = nullptr;

  /// The identifier '__make_integer_seq'.
  mutable IdentifierInfo *MakeIntegerSeqName = nullptr;

  /// The identifier '__type_pack_element'.
  mutable IdentifierInfo *TypePackElementName = nullptr;

  QualType ObjCConstantStringType;
  mutable RecordDecl *CFConstantStringTagDecl = nullptr;
  mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;

  mutable QualType ObjCSuperType;

  QualType ObjCNSStringType;

  /// The typedef declaration for the Objective-C "instancetype" type.
  TypedefDecl *ObjCInstanceTypeDecl = nullptr;

  /// The type for the C FILE type.
  TypeDecl *FILEDecl = nullptr;

  /// The type for the C jmp_buf type.
  TypeDecl *jmp_bufDecl = nullptr;

  /// The type for the C sigjmp_buf type.
  TypeDecl *sigjmp_bufDecl = nullptr;

  /// The type for the C ucontext_t type.
  TypeDecl *ucontext_tDecl = nullptr;

  /// Type for the Block descriptor for Blocks CodeGen.
  ///
  /// Since this is only used for generation of debug info, it is not
  /// serialized.
  mutable RecordDecl *BlockDescriptorType = nullptr;

  /// Type for the Block descriptor for Blocks CodeGen.
  ///
  /// Since this is only used for generation of debug info, it is not
  /// serialized.
  mutable RecordDecl *BlockDescriptorExtendedType = nullptr;

  /// Declaration for the CUDA cudaConfigureCall function.
  FunctionDecl *cudaConfigureCallDecl = nullptr;

  /// Keeps track of all declaration attributes.
  ///
  /// Since so few decls have attrs, we keep them in a hash map instead of
  /// wasting space in the Decl class.
  llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;

  /// A mapping from non-redeclarable declarations in modules that were
  /// merged with other declarations to the canonical declaration that they were
  /// merged into.
  llvm::DenseMap<Decl*, Decl*> MergedDecls;

  /// A mapping from a defining declaration to a list of modules (other
  /// than the owning module of the declaration) that contain merged
  /// definitions of that entity.
  llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;

  /// Initializers for a module, in order. Each Decl will be either
  /// something that has a semantic effect on startup (such as a variable with
  /// a non-constant initializer), or an ImportDecl (which recursively triggers
  /// initialization of another module).
  struct PerModuleInitializers {
    llvm::SmallVector<Decl*, 4> Initializers;
    llvm::SmallVector<uint32_t, 4> LazyInitializers;

    void resolve(ASTContext &Ctx);
  };
  llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;

  ASTContext &this_() { return *this; }

public:
  /// A type synonym for the TemplateOrInstantiation mapping.
  using TemplateOrSpecializationInfo =
      llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>;

private:
  friend class ASTDeclReader;
  friend class ASTReader;
  friend class ASTWriter;
  template <class> friend class serialization::AbstractTypeReader;
  friend class CXXRecordDecl;
  friend class IncrementalParser;

  /// A mapping to contain the template or declaration that
  /// a variable declaration describes or was instantiated from,
  /// respectively.
  ///
  /// For non-templates, this value will be NULL. For variable
  /// declarations that describe a variable template, this will be a
  /// pointer to a VarTemplateDecl. For static data members
  /// of class template specializations, this will be the
  /// MemberSpecializationInfo referring to the member variable that was
  /// instantiated or specialized. Thus, the mapping will keep track of
  /// the static data member templates from which static data members of
  /// class template specializations were instantiated.
  ///
  /// Given the following example:
  ///
  /// \code
  /// template<typename T>
  /// struct X {
  ///   static T value;
  /// };
  ///
  /// template<typename T>
  ///   T X<T>::value = T(17);
  ///
  /// int *x = &X<int>::value;
  /// \endcode
  ///
  /// This mapping will contain an entry that maps from the VarDecl for
  /// X<int>::value to the corresponding VarDecl for X<T>::value (within the
  /// class template X) and will be marked TSK_ImplicitInstantiation.
  llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
  TemplateOrInstantiation;

  /// Keeps track of the declaration from which a using declaration was
  /// created during instantiation.
  ///
  /// The source and target declarations are always a UsingDecl, an
  /// UnresolvedUsingValueDecl, or an UnresolvedUsingTypenameDecl.
  ///
  /// For example:
  /// \code
  /// template<typename T>
  /// struct A {
  ///   void f();
  /// };
  ///
  /// template<typename T>
  /// struct B : A<T> {
  ///   using A<T>::f;
  /// };
  ///
  /// template struct B<int>;
  /// \endcode
  ///
  /// This mapping will contain an entry that maps from the UsingDecl in
  /// B<int> to the UnresolvedUsingDecl in B<T>.
  llvm::DenseMap<NamedDecl *, NamedDecl *> InstantiatedFromUsingDecl;

  /// Like InstantiatedFromUsingDecl, but for using-enum-declarations. Maps
  /// from the instantiated using-enum to the templated decl from whence it
  /// came.
  /// Note that using-enum-declarations cannot be dependent and
  /// thus will never be instantiated from an "unresolved"
  /// version thereof (as with using-declarations), so each mapping is from
  /// a (resolved) UsingEnumDecl to a (resolved) UsingEnumDecl.
  llvm::DenseMap<UsingEnumDecl *, UsingEnumDecl *>
      InstantiatedFromUsingEnumDecl;

  /// Simlarly maps instantiated UsingShadowDecls to their origin.
  llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
    InstantiatedFromUsingShadowDecl;

  llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;

  /// Mapping that stores the methods overridden by a given C++
  /// member function.
  ///
  /// Since most C++ member functions aren't virtual and therefore
  /// don't override anything, we store the overridden functions in
  /// this map on the side rather than within the CXXMethodDecl structure.
  using CXXMethodVector = llvm::TinyPtrVector<const CXXMethodDecl *>;
  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;

  /// Mapping from each declaration context to its corresponding
  /// mangling numbering context (used for constructs like lambdas which
  /// need to be consistently numbered for the mangler).
  llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
      MangleNumberingContexts;
  llvm::DenseMap<const Decl *, std::unique_ptr<MangleNumberingContext>>
      ExtraMangleNumberingContexts;

  /// Side-table of mangling numbers for declarations which rarely
  /// need them (like static local vars).
  llvm::MapVector<const NamedDecl *, unsigned> MangleNumbers;
  llvm::MapVector<const VarDecl *, unsigned> StaticLocalNumbers;
  /// Mapping the associated device lambda mangling number if present.
  mutable llvm::DenseMap<const CXXRecordDecl *, unsigned>
      DeviceLambdaManglingNumbers;

  /// Mapping that stores parameterIndex values for ParmVarDecls when
  /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
  using ParameterIndexTable = llvm::DenseMap<const VarDecl *, unsigned>;
  ParameterIndexTable ParamIndices;

  ImportDecl *FirstLocalImport = nullptr;
  ImportDecl *LastLocalImport = nullptr;

  TranslationUnitDecl *TUDecl = nullptr;
  mutable ExternCContextDecl *ExternCContext = nullptr;
  mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
  mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;

  /// The associated SourceManager object.
  SourceManager &SourceMgr;

  /// The language options used to create the AST associated with
  ///  this ASTContext object.
  LangOptions &LangOpts;

  /// NoSanitizeList object that is used by sanitizers to decide which
  /// entities should not be instrumented.
  std::unique_ptr<NoSanitizeList> NoSanitizeL;

  /// Function filtering mechanism to determine whether a given function
  /// should be imbued with the XRay "always" or "never" attributes.
  std::unique_ptr<XRayFunctionFilter> XRayFilter;

  /// ProfileList object that is used by the profile instrumentation
  /// to decide which entities should be instrumented.
  std::unique_ptr<ProfileList> ProfList;

  /// The allocator used to create AST objects.
  ///
  /// AST objects are never destructed; rather, all memory associated with the
  /// AST objects will be released when the ASTContext itself is destroyed.
  mutable llvm::BumpPtrAllocator BumpAlloc;

  /// Allocator for partial diagnostics.
  PartialDiagnostic::DiagStorageAllocator DiagAllocator;

  /// The current C++ ABI.
  std::unique_ptr<CXXABI> ABI;
  CXXABI *createCXXABI(const TargetInfo &T);

  /// The logical -> physical address space map.
  const LangASMap *AddrSpaceMap = nullptr;

  /// Address space map mangling must be used with language specific
  /// address spaces (e.g. OpenCL/CUDA)
  bool AddrSpaceMapMangling;

  const TargetInfo *Target = nullptr;
  const TargetInfo *AuxTarget = nullptr;
  clang::PrintingPolicy PrintingPolicy;
  std::unique_ptr<interp::Context> InterpContext;
  std::unique_ptr<ParentMapContext> ParentMapCtx;

  /// Keeps track of the deallocated DeclListNodes for future reuse.
  DeclListNode *ListNodeFreeList = nullptr;

public:
  IdentifierTable &Idents;
  SelectorTable &Selectors;
  Builtin::Context &BuiltinInfo;
  const TranslationUnitKind TUKind;
  mutable DeclarationNameTable DeclarationNames;
  IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
  ASTMutationListener *Listener = nullptr;

  /// Returns the clang bytecode interpreter context.
  interp::Context &getInterpContext();

  /// Returns the dynamic AST node parent map context.
  ParentMapContext &getParentMapContext();

  // A traversal scope limits the parts of the AST visible to certain analyses.
  // RecursiveASTVisitor only visits specified children of TranslationUnitDecl.
  // getParents() will only observe reachable parent edges.
  //
  // The scope is defined by a set of "top-level" declarations which will be
  // visible under the TranslationUnitDecl.
  // Initially, it is the entire TU, represented by {getTranslationUnitDecl()}.
  //
  // After setTraversalScope({foo, bar}), the exposed AST looks like:
  // TranslationUnitDecl
  //  - foo
  //    - ...
  //  - bar
  //    - ...
  // All other siblings of foo and bar are pruned from the tree.
  // (However they are still accessible via TranslationUnitDecl->decls())
  //
  // Changing the scope clears the parent cache, which is expensive to rebuild.
  std::vector<Decl *> getTraversalScope() const { return TraversalScope; }
  void setTraversalScope(const std::vector<Decl *> &);

  /// Forwards to get node parents from the ParentMapContext. New callers should
  /// use ParentMapContext::getParents() directly.
  template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);

  const clang::PrintingPolicy &getPrintingPolicy() const {
    return PrintingPolicy;
  }

  void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
    PrintingPolicy = Policy;
  }

  SourceManager& getSourceManager() { return SourceMgr; }
  const SourceManager& getSourceManager() const { return SourceMgr; }

  // Cleans up some of the data structures. This allows us to do cleanup
  // normally done in the destructor earlier. Renders much of the ASTContext
  // unusable, mostly the actual AST nodes, so should be called when we no
  // longer need access to the AST.
  void cleanup();

  llvm::BumpPtrAllocator &getAllocator() const {
    return BumpAlloc;
  }

  void *Allocate(size_t Size, unsigned Align = 8) const {
    return BumpAlloc.Allocate(Size, Align);
  }
  template <typename T> T *Allocate(size_t Num = 1) const {
    return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
  }
  void Deallocate(void *Ptr) const {}

  /// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList
  /// pool.
  DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) {
    if (DeclListNode *Alloc = ListNodeFreeList) {
      ListNodeFreeList = Alloc->Rest.dyn_cast<DeclListNode*>();
      Alloc->D = ND;
      Alloc->Rest = nullptr;
      return Alloc;
    }
    return new (*this) DeclListNode(ND);
  }
  /// Deallcates a \c DeclListNode by returning it to the \c ListNodeFreeList
  /// pool.
  void DeallocateDeclListNode(DeclListNode *N) {
    N->Rest = ListNodeFreeList;
    ListNodeFreeList = N;
  }

  /// Return the total amount of physical memory allocated for representing
  /// AST nodes and type information.
  size_t getASTAllocatedMemory() const {
    return BumpAlloc.getTotalMemory();
  }

  /// Return the total memory used for various side tables.
  size_t getSideTableAllocatedMemory() const;

  PartialDiagnostic::DiagStorageAllocator &getDiagAllocator() {
    return DiagAllocator;
  }

  const TargetInfo &getTargetInfo() const { return *Target; }
  const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }

  /// getIntTypeForBitwidth -
  /// sets integer QualTy according to specified details:
  /// bitwidth, signed/unsigned.
  /// Returns empty type if there is no appropriate target types.
  QualType getIntTypeForBitwidth(unsigned DestWidth,
                                 unsigned Signed) const;

  /// getRealTypeForBitwidth -
  /// sets floating point QualTy according to specified bitwidth.
  /// Returns empty type if there is no appropriate target types.
  QualType getRealTypeForBitwidth(unsigned DestWidth,
                                  FloatModeKind ExplicitType) const;

  bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;

  const LangOptions& getLangOpts() const { return LangOpts; }

  // If this condition is false, typo correction must be performed eagerly
  // rather than delayed in many places, as it makes use of dependent types.
  // the condition is false for clang's C-only codepath, as it doesn't support
  // dependent types yet.
  bool isDependenceAllowed() const {
    return LangOpts.CPlusPlus || LangOpts.RecoveryAST;
  }

  const NoSanitizeList &getNoSanitizeList() const { return *NoSanitizeL; }

  const XRayFunctionFilter &getXRayFilter() const {
    return *XRayFilter;
  }

  const ProfileList &getProfileList() const { return *ProfList; }

  DiagnosticsEngine &getDiagnostics() const;

  FullSourceLoc getFullLoc(SourceLocation Loc) const {
    return FullSourceLoc(Loc,SourceMgr);
  }

  /// Return the C++ ABI kind that should be used. The C++ ABI can be overriden
  /// at compile time with `-fc++-abi=`. If this is not provided, we instead use
  /// the default ABI set by the target.
  TargetCXXABI::Kind getCXXABIKind() const;

  /// All comments in this translation unit.
  RawCommentList Comments;

  /// True if comments are already loaded from ExternalASTSource.
  mutable bool CommentsLoaded = false;

  /// Mapping from declaration to directly attached comment.
  ///
  /// Raw comments are owned by Comments list.  This mapping is populated
  /// lazily.
  mutable llvm::DenseMap<const Decl *, const RawComment *> DeclRawComments;

  /// Mapping from canonical declaration to the first redeclaration in chain
  /// that has a comment attached.
  ///
  /// Raw comments are owned by Comments list.  This mapping is populated
  /// lazily.
  mutable llvm::DenseMap<const Decl *, const Decl *> RedeclChainComments;

  /// Keeps track of redeclaration chains that don't have any comment attached.
  /// Mapping from canonical declaration to redeclaration chain that has no
  /// comments attached to any redeclaration. Specifically it's mapping to
  /// the last redeclaration we've checked.
  ///
  /// Shall not contain declarations that have comments attached to any
  /// redeclaration in their chain.
  mutable llvm::DenseMap<const Decl *, const Decl *> CommentlessRedeclChains;

  /// Mapping from declarations to parsed comments attached to any
  /// redeclaration.
  mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;

  /// Attaches \p Comment to \p OriginalD and to its redeclaration chain
  /// and removes the redeclaration chain from the set of commentless chains.
  ///
  /// Don't do anything if a comment has already been attached to \p OriginalD
  /// or its redeclaration chain.
  void cacheRawCommentForDecl(const Decl &OriginalD,
                              const RawComment &Comment) const;

  /// \returns searches \p CommentsInFile for doc comment for \p D.
  ///
  /// \p RepresentativeLocForDecl is used as a location for searching doc
  /// comments. \p CommentsInFile is a mapping offset -> comment of files in the
  /// same file where \p RepresentativeLocForDecl is.
  RawComment *getRawCommentForDeclNoCacheImpl(
      const Decl *D, const SourceLocation RepresentativeLocForDecl,
      const std::map<unsigned, RawComment *> &CommentsInFile) const;

  /// Return the documentation comment attached to a given declaration,
  /// without looking into cache.
  RawComment *getRawCommentForDeclNoCache(const Decl *D) const;

public:
  void addComment(const RawComment &RC);

  /// Return the documentation comment attached to a given declaration.
  /// Returns nullptr if no comment is attached.
  ///
  /// \param OriginalDecl if not nullptr, is set to declaration AST node that
  /// had the comment, if the comment we found comes from a redeclaration.
  const RawComment *
  getRawCommentForAnyRedecl(const Decl *D,
                            const Decl **OriginalDecl = nullptr) const;

  /// Searches existing comments for doc comments that should be attached to \p
  /// Decls. If any doc comment is found, it is parsed.
  ///
  /// Requirement: All \p Decls are in the same file.
  ///
  /// If the last comment in the file is already attached we assume
  /// there are not comments left to be attached to \p Decls.
  void attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls,
                                       const Preprocessor *PP);

  /// Return parsed documentation comment attached to a given declaration.
  /// Returns nullptr if no comment is attached.
  ///
  /// \param PP the Preprocessor used with this TU.  Could be nullptr if
  /// preprocessor is not available.
  comments::FullComment *getCommentForDecl(const Decl *D,
                                           const Preprocessor *PP) const;

  /// Return parsed documentation comment attached to a given declaration.
  /// Returns nullptr if no comment is attached. Does not look at any
  /// redeclarations of the declaration.
  comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;

  comments::FullComment *cloneFullComment(comments::FullComment *FC,
                                         const Decl *D) const;

private:
  mutable comments::CommandTraits CommentCommandTraits;

  /// Iterator that visits import declarations.
  class import_iterator {
    ImportDecl *Import = nullptr;

  public:
    using value_type = ImportDecl *;
    using reference = ImportDecl *;
    using pointer = ImportDecl *;
    using difference_type = int;
    using iterator_category = std::forward_iterator_tag;

    import_iterator() = default;
    explicit import_iterator(ImportDecl *Import) : Import(Import) {}

    reference operator*() const { return Import; }
    pointer operator->() const { return Import; }

    import_iterator &operator++() {
      Import = ASTContext::getNextLocalImport(Import);
      return *this;
    }

    import_iterator operator++(int) {
      import_iterator Other(*this);
      ++(*this);
      return Other;
    }

    friend bool operator==(import_iterator X, import_iterator Y) {
      return X.Import == Y.Import;
    }

    friend bool operator!=(import_iterator X, import_iterator Y) {
      return X.Import != Y.Import;
    }
  };

public:
  comments::CommandTraits &getCommentCommandTraits() const {
    return CommentCommandTraits;
  }

  /// Retrieve the attributes for the given declaration.
  AttrVec& getDeclAttrs(const Decl *D);

  /// Erase the attributes corresponding to the given declaration.
  void eraseDeclAttrs(const Decl *D);

  /// If this variable is an instantiated static data member of a
  /// class template specialization, returns the templated static data member
  /// from which it was instantiated.
  // FIXME: Remove ?
  MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
                                                           const VarDecl *Var);

  /// Note that the static data member \p Inst is an instantiation of
  /// the static data member template \p Tmpl of a class template.
  void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
                                           TemplateSpecializationKind TSK,
                        SourceLocation PointOfInstantiation = SourceLocation());

  TemplateOrSpecializationInfo
  getTemplateOrSpecializationInfo(const VarDecl *Var);

  void setTemplateOrSpecializationInfo(VarDecl *Inst,
                                       TemplateOrSpecializationInfo TSI);

  /// If the given using decl \p Inst is an instantiation of
  /// another (possibly unresolved) using decl, return it.
  NamedDecl *getInstantiatedFromUsingDecl(NamedDecl *Inst);

  /// Remember that the using decl \p Inst is an instantiation
  /// of the using decl \p Pattern of a class template.
  void setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern);

  /// If the given using-enum decl \p Inst is an instantiation of
  /// another using-enum decl, return it.
  UsingEnumDecl *getInstantiatedFromUsingEnumDecl(UsingEnumDecl *Inst);

  /// Remember that the using enum decl \p Inst is an instantiation
  /// of the using enum decl \p Pattern of a class template.
  void setInstantiatedFromUsingEnumDecl(UsingEnumDecl *Inst,
                                        UsingEnumDecl *Pattern);

  UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst);
  void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
                                          UsingShadowDecl *Pattern);

  FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);

  void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);

  // Access to the set of methods overridden by the given C++ method.
  using overridden_cxx_method_iterator = CXXMethodVector::const_iterator;
  overridden_cxx_method_iterator
  overridden_methods_begin(const CXXMethodDecl *Method) const;

  overridden_cxx_method_iterator
  overridden_methods_end(const CXXMethodDecl *Method) const;

  unsigned overridden_methods_size(const CXXMethodDecl *Method) const;

  using overridden_method_range =
      llvm::iterator_range<overridden_cxx_method_iterator>;

  overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;

  /// Note that the given C++ \p Method overrides the given \p
  /// Overridden method.
  void addOverriddenMethod(const CXXMethodDecl *Method,
                           const CXXMethodDecl *Overridden);

  /// Return C++ or ObjC overridden methods for the given \p Method.
  ///
  /// An ObjC method is considered to override any method in the class's
  /// base classes, its protocols, or its categories' protocols, that has
  /// the same selector and is of the same kind (class or instance).
  /// A method in an implementation is not considered as overriding the same
  /// method in the interface or its categories.
  void getOverriddenMethods(
                        const NamedDecl *Method,
                        SmallVectorImpl<const NamedDecl *> &Overridden) const;

  /// Notify the AST context that a new import declaration has been
  /// parsed or implicitly created within this translation unit.
  void addedLocalImportDecl(ImportDecl *Import);

  static ImportDecl *getNextLocalImport(ImportDecl *Import) {
    return Import->getNextLocalImport();
  }

  using import_range = llvm::iterator_range<import_iterator>;

  import_range local_imports() const {
    return import_range(import_iterator(FirstLocalImport), import_iterator());
  }

  Decl *getPrimaryMergedDecl(Decl *D) {
    Decl *Result = MergedDecls.lookup(D);
    return Result ? Result : D;
  }
  void setPrimaryMergedDecl(Decl *D, Decl *Primary) {
    MergedDecls[D] = Primary;
  }

  /// Note that the definition \p ND has been merged into module \p M,
  /// and should be visible whenever \p M is visible.
  void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
                                 bool NotifyListeners = true);

  /// Clean up the merged definition list. Call this if you might have
  /// added duplicates into the list.
  void deduplicateMergedDefinitonsFor(NamedDecl *ND);

  /// Get the additional modules in which the definition \p Def has
  /// been merged.
  ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def);

  /// Add a declaration to the list of declarations that are initialized
  /// for a module. This will typically be a global variable (with internal
  /// linkage) that runs module initializers, such as the iostream initializer,
  /// or an ImportDecl nominating another module that has initializers.
  void addModuleInitializer(Module *M, Decl *Init);

  void addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs);

  /// Get the initializations to perform when importing a module, if any.
  ArrayRef<Decl*> getModuleInitializers(Module *M);

  TranslationUnitDecl *getTranslationUnitDecl() const {
    return TUDecl->getMostRecentDecl();
  }
  void addTranslationUnitDecl() {
    assert(!TUDecl || TUKind == TU_Incremental);
    TranslationUnitDecl *NewTUDecl = TranslationUnitDecl::Create(*this);
    if (TraversalScope.empty() || TraversalScope.back() == TUDecl)
      TraversalScope = {NewTUDecl};
    if (TUDecl)
      NewTUDecl->setPreviousDecl(TUDecl);
    TUDecl = NewTUDecl;
  }

  ExternCContextDecl *getExternCContextDecl() const;
  BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
  BuiltinTemplateDecl *getTypePackElementDecl() const;

  // Builtin Types.
  CanQualType VoidTy;
  CanQualType BoolTy;
  CanQualType CharTy;
  CanQualType WCharTy;  // [C++ 3.9.1p5].
  CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
  CanQualType WIntTy;   // [C99 7.24.1], integer type unchanged by default promotions.
  CanQualType Char8Ty;  // [C++20 proposal]
  CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
  CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
  CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
  CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
  CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
  CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty, Ibm128Ty;
  CanQualType ShortAccumTy, AccumTy,
      LongAccumTy;  // ISO/IEC JTC1 SC22 WG14 N1169 Extension
  CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
  CanQualType ShortFractTy, FractTy, LongFractTy;
  CanQualType UnsignedShortFractTy, UnsignedFractTy, UnsignedLongFractTy;
  CanQualType SatShortAccumTy, SatAccumTy, SatLongAccumTy;
  CanQualType SatUnsignedShortAccumTy, SatUnsignedAccumTy,
      SatUnsignedLongAccumTy;
  CanQualType SatShortFractTy, SatFractTy, SatLongFractTy;
  CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy,
      SatUnsignedLongFractTy;
  CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
  CanQualType BFloat16Ty;
  CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
  CanQualType VoidPtrTy, NullPtrTy;
  CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
  CanQualType BuiltinFnTy;
  CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
  CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
  CanQualType ObjCBuiltinBoolTy;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
  CanQualType SingletonId;
#include "clang/Basic/OpenCLImageTypes.def"
  CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
  CanQualType OCLQueueTy, OCLReserveIDTy;
  CanQualType IncompleteMatrixIdxTy;
  CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy;
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
  CanQualType Id##Ty;
#include "clang/Basic/OpenCLExtensionTypes.def"
#define SVE_TYPE(Name, Id, SingletonId) \
  CanQualType SingletonId;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define PPC_VECTOR_TYPE(Name, Id, Size) \
  CanQualType Id##Ty;
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) \
  CanQualType SingletonId;
#include "clang/Basic/RISCVVTypes.def"

  // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
  mutable QualType AutoDeductTy;     // Deduction against 'auto'.
  mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.

  // Decl used to help define __builtin_va_list for some targets.
  // The decl is built when constructing 'BuiltinVaListDecl'.
  mutable Decl *VaListTagDecl = nullptr;

  // Implicitly-declared type 'struct _GUID'.
  mutable TagDecl *MSGuidTagDecl = nullptr;

  /// Keep track of CUDA/HIP device-side variables ODR-used by host code.
  llvm::DenseSet<const VarDecl *> CUDADeviceVarODRUsedByHost;

  ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
             SelectorTable &sels, Builtin::Context &builtins,
             TranslationUnitKind TUKind);
  ASTContext(const ASTContext &) = delete;
  ASTContext &operator=(const ASTContext &) = delete;
  ~ASTContext();

  /// Attach an external AST source to the AST context.
  ///
  /// The external AST source provides the ability to load parts of
  /// the abstract syntax tree as needed from some external storage,
  /// e.g., a precompiled header.
  void setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source);

  /// Retrieve a pointer to the external AST source associated
  /// with this AST context, if any.
  ExternalASTSource *getExternalSource() const {
    return ExternalSource.get();
  }

  /// Attach an AST mutation listener to the AST context.
  ///
  /// The AST mutation listener provides the ability to track modifications to
  /// the abstract syntax tree entities committed after they were initially
  /// created.
  void setASTMutationListener(ASTMutationListener *Listener) {
    this->Listener = Listener;
  }

  /// Retrieve a pointer to the AST mutation listener associated
  /// with this AST context, if any.
  ASTMutationListener *getASTMutationListener() const { return Listener; }

  void PrintStats() const;
  const SmallVectorImpl<Type *>& getTypes() const { return Types; }

  BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
                                                const IdentifierInfo *II) const;

  /// Create a new implicit TU-level CXXRecordDecl or RecordDecl
  /// declaration.
  RecordDecl *buildImplicitRecord(StringRef Name,
                                  RecordDecl::TagKind TK = TTK_Struct) const;

  /// Create a new implicit TU-level typedef declaration.
  TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;

  /// Retrieve the declaration for the 128-bit signed integer type.
  TypedefDecl *getInt128Decl() const;

  /// Retrieve the declaration for the 128-bit unsigned integer type.
  TypedefDecl *getUInt128Decl() const;

  //===--------------------------------------------------------------------===//
  //                           Type Constructors
  //===--------------------------------------------------------------------===//

private:
  /// Return a type with extended qualifiers.
  QualType getExtQualType(const Type *Base, Qualifiers Quals) const;

  QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;

  QualType getPipeType(QualType T, bool ReadOnly) const;

public:
  /// Return the uniqued reference to the type for an address space
  /// qualified type with the specified type and address space.
  ///
  /// The resulting type has a union of the qualifiers from T and the address
  /// space. If T already has an address space specifier, it is silently
  /// replaced.
  QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const;

  /// Remove any existing address space on the type and returns the type
  /// with qualifiers intact (or that's the idea anyway)
  ///
  /// The return type should be T with all prior qualifiers minus the address
  /// space.
  QualType removeAddrSpaceQualType(QualType T) const;

  /// Apply Objective-C protocol qualifiers to the given type.
  /// \param allowOnPointerType specifies if we can apply protocol
  /// qualifiers on ObjCObjectPointerType. It can be set to true when
  /// constructing the canonical type of a Objective-C type parameter.
  QualType applyObjCProtocolQualifiers(QualType type,
      ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
      bool allowOnPointerType = false) const;

  /// Return the uniqued reference to the type for an Objective-C
  /// gc-qualified type.
  ///
  /// The resulting type has a union of the qualifiers from T and the gc
  /// attribute.
  QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;

  /// Remove the existing address space on the type if it is a pointer size
  /// address space and return the type with qualifiers intact.
  QualType removePtrSizeAddrSpace(QualType T) const;

  /// Return the uniqued reference to the type for a \c restrict
  /// qualified type.
  ///
  /// The resulting type has a union of the qualifiers from \p T and
  /// \c restrict.
  QualType getRestrictType(QualType T) const {
    return T.withFastQualifiers(Qualifiers::Restrict);
  }

  /// Return the uniqued reference to the type for a \c volatile
  /// qualified type.
  ///
  /// The resulting type has a union of the qualifiers from \p T and
  /// \c volatile.
  QualType getVolatileType(QualType T) const {
    return T.withFastQualifiers(Qualifiers::Volatile);
  }

  /// Return the uniqued reference to the type for a \c const
  /// qualified type.
  ///
  /// The resulting type has a union of the qualifiers from \p T and \c const.
  ///
  /// It can be reasonably expected that this will always be equivalent to
  /// calling T.withConst().
  QualType getConstType(QualType T) const { return T.withConst(); }

  /// Change the ExtInfo on a function type.
  const FunctionType *adjustFunctionType(const FunctionType *Fn,
                                         FunctionType::ExtInfo EInfo);

  /// Adjust the given function result type.
  CanQualType getCanonicalFunctionResultType(QualType ResultType) const;

  /// Change the result type of a function type once it is deduced.
  void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);

  /// Get a function type and produce the equivalent function type with the
  /// specified exception specification. Type sugar that can be present on a
  /// declaration of a function with an exception specification is permitted
  /// and preserved. Other type sugar (for instance, typedefs) is not.
  QualType getFunctionTypeWithExceptionSpec(
      QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI);

  /// Determine whether two function types are the same, ignoring
  /// exception specifications in cases where they're part of the type.
  bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);

  /// Change the exception specification on a function once it is
  /// delay-parsed, instantiated, or computed.
  void adjustExceptionSpec(FunctionDecl *FD,
                           const FunctionProtoType::ExceptionSpecInfo &ESI,
                           bool AsWritten = false);

  /// Get a function type and produce the equivalent function type where
  /// pointer size address spaces in the return type and parameter tyeps are
  /// replaced with the default address space.
  QualType getFunctionTypeWithoutPtrSizes(QualType T);

  /// Determine whether two function types are the same, ignoring pointer sizes
  /// in the return type and parameter types.
  bool hasSameFunctionTypeIgnoringPtrSizes(QualType T, QualType U);

  /// Return the uniqued reference to the type for a complex
  /// number with the specified element type.
  QualType getComplexType(QualType T) const;
  CanQualType getComplexType(CanQualType T) const {
    return CanQualType::CreateUnsafe(getComplexType((QualType) T));
  }

  /// Return the uniqued reference to the type for a pointer to
  /// the specified type.
  QualType getPointerType(QualType T) const;
  CanQualType getPointerType(CanQualType T) const {
    return CanQualType::CreateUnsafe(getPointerType((QualType) T));
  }

  /// Return the uniqued reference to a type adjusted from the original
  /// type to a new type.
  QualType getAdjustedType(QualType Orig, QualType New) const;
  CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
    return CanQualType::CreateUnsafe(
        getAdjustedType((QualType)Orig, (QualType)New));
  }

  /// Return the uniqued reference to the decayed version of the given
  /// type.  Can only be called on array and function types which decay to
  /// pointer types.
  QualType getDecayedType(QualType T) const;
  CanQualType getDecayedType(CanQualType T) const {
    return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
  }

  /// Return the uniqued reference to the atomic type for the specified
  /// type.
  QualType getAtomicType(QualType T) const;

  /// Return the uniqued reference to the type for a block of the
  /// specified type.
  QualType getBlockPointerType(QualType T) const;

  /// Gets the struct used to keep track of the descriptor for pointer to
  /// blocks.
  QualType getBlockDescriptorType() const;

  /// Return a read_only pipe type for the specified type.
  QualType getReadPipeType(QualType T) const;

  /// Return a write_only pipe type for the specified type.
  QualType getWritePipeType(QualType T) const;

  /// Return a bit-precise integer type with the specified signedness and bit
  /// count.
  QualType getBitIntType(bool Unsigned, unsigned NumBits) const;

  /// Return a dependent bit-precise integer type with the specified signedness
  /// and bit count.
  QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const;

  /// Gets the struct used to keep track of the extended descriptor for
  /// pointer to blocks.
  QualType getBlockDescriptorExtendedType() const;

  /// Map an AST Type to an OpenCLTypeKind enum value.
  OpenCLTypeKind getOpenCLTypeKind(const Type *T) const;

  /// Get address space for OpenCL type.
  LangAS getOpenCLTypeAddrSpace(const Type *T) const;

  /// Returns default address space based on OpenCL version and enabled features
  inline LangAS getDefaultOpenCLPointeeAddrSpace() {
    return LangOpts.OpenCLGenericAddressSpace ? LangAS::opencl_generic
                                              : LangAS::opencl_private;
  }

  void setcudaConfigureCallDecl(FunctionDecl *FD) {
    cudaConfigureCallDecl = FD;
  }

  FunctionDecl *getcudaConfigureCallDecl() {
    return cudaConfigureCallDecl;
  }

  /// Returns true iff we need copy/dispose helpers for the given type.
  bool BlockRequiresCopying(QualType Ty, const VarDecl *D);

  /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout
  /// is set to false in this case. If HasByrefExtendedLayout returns true,
  /// byref variable has extended lifetime.
  bool getByrefLifetime(QualType Ty,
                        Qualifiers::ObjCLifetime &Lifetime,
                        bool &HasByrefExtendedLayout) const;

  /// Return the uniqued reference to the type for an lvalue reference
  /// to the specified type.
  QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
    const;

  /// Return the uniqued reference to the type for an rvalue reference
  /// to the specified type.
  QualType getRValueReferenceType(QualType T) const;

  /// Return the uniqued reference to the type for a member pointer to
  /// the specified type in the specified class.
  ///
  /// The class \p Cls is a \c Type because it could be a dependent name.
  QualType getMemberPointerType(QualType T, const Type *Cls) const;

  /// Return a non-unique reference to the type for a variable array of
  /// the specified element type.
  QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
                                ArrayType::ArraySizeModifier ASM,
                                unsigned IndexTypeQuals,
                                SourceRange Brackets) const;

  /// Return a non-unique reference to the type for a dependently-sized
  /// array of the specified element type.
  ///
  /// FIXME: We will need these to be uniqued, or at least comparable, at some
  /// point.
  QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
                                      ArrayType::ArraySizeModifier ASM,
                                      unsigned IndexTypeQuals,
                                      SourceRange Brackets) const;

  /// Return a unique reference to the type for an incomplete array of
  /// the specified element type.
  QualType getIncompleteArrayType(QualType EltTy,
                                  ArrayType::ArraySizeModifier ASM,
                                  unsigned IndexTypeQuals) const;

  /// Return the unique reference to the type for a constant array of
  /// the specified element type.
  QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
                                const Expr *SizeExpr,
                                ArrayType::ArraySizeModifier ASM,
                                unsigned IndexTypeQuals) const;

  /// Return a type for a constant array for a string literal of the
  /// specified element type and length.
  QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const;

  /// Returns a vla type where known sizes are replaced with [*].
  QualType getVariableArrayDecayedType(QualType Ty) const;

  // Convenience struct to return information about a builtin vector type.
  struct BuiltinVectorTypeInfo {
    QualType ElementType;
    llvm::ElementCount EC;
    unsigned NumVectors;
    BuiltinVectorTypeInfo(QualType ElementType, llvm::ElementCount EC,
                          unsigned NumVectors)
        : ElementType(ElementType), EC(EC), NumVectors(NumVectors) {}
  };

  /// Returns the element type, element count and number of vectors
  /// (in case of tuple) for a builtin vector type.
  BuiltinVectorTypeInfo
  getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const;

  /// Return the unique reference to a scalable vector type of the specified
  /// element type and scalable number of elements.
  ///
  /// \pre \p EltTy must be a built-in type.
  QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const;

  /// Return the unique reference to a vector type of the specified
  /// element type and size.
  ///
  /// \pre \p VectorType must be a built-in type.
  QualType getVectorType(QualType VectorType, unsigned NumElts,
                         VectorType::VectorKind VecKind) const;
  /// Return the unique reference to the type for a dependently sized vector of
  /// the specified element type.
  QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr,
                                  SourceLocation AttrLoc,
                                  VectorType::VectorKind VecKind) const;

  /// Return the unique reference to an extended vector type
  /// of the specified element type and size.
  ///
  /// \pre \p VectorType must be a built-in type.
  QualType getExtVectorType(QualType VectorType, unsigned NumElts) const;

  /// \pre Return a non-unique reference to the type for a dependently-sized
  /// vector of the specified element type.
  ///
  /// FIXME: We will need these to be uniqued, or at least comparable, at some
  /// point.
  QualType getDependentSizedExtVectorType(QualType VectorType,
                                          Expr *SizeExpr,
                                          SourceLocation AttrLoc) const;

  /// Return the unique reference to the matrix type of the specified element
  /// type and size
  ///
  /// \pre \p ElementType must be a valid matrix element type (see
  /// MatrixType::isValidElementType).
  QualType getConstantMatrixType(QualType ElementType, unsigned NumRows,
                                 unsigned NumColumns) const;

  /// Return the unique reference to the matrix type of the specified element
  /// type and size
  QualType getDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
                                       Expr *ColumnExpr,
                                       SourceLocation AttrLoc) const;

  QualType getDependentAddressSpaceType(QualType PointeeType,
                                        Expr *AddrSpaceExpr,
                                        SourceLocation AttrLoc) const;

  /// Return a K&R style C function type like 'int()'.
  QualType getFunctionNoProtoType(QualType ResultTy,
                                  const FunctionType::ExtInfo &Info) const;

  QualType getFunctionNoProtoType(QualType ResultTy) const {
    return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
  }

  /// Return a normal function type with a typed argument list.
  QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
                           const FunctionProtoType::ExtProtoInfo &EPI) const {
    return getFunctionTypeInternal(ResultTy, Args, EPI, false);
  }

  QualType adjustStringLiteralBaseType(QualType StrLTy) const;

private:
  /// Return a normal function type with a typed argument list.
  QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
                                   const FunctionProtoType::ExtProtoInfo &EPI,
                                   bool OnlyWantCanonical) const;
  QualType
  getAutoTypeInternal(QualType DeducedType, AutoTypeKeyword Keyword,
                      bool IsDependent, bool IsPack = false,
                      ConceptDecl *TypeConstraintConcept = nullptr,
                      ArrayRef<TemplateArgument> TypeConstraintArgs = {},
                      bool IsCanon = false) const;

public:
  /// Return the unique reference to the type for the specified type
  /// declaration.
  QualType getTypeDeclType(const TypeDecl *Decl,
                           const TypeDecl *PrevDecl = nullptr) const {
    assert(Decl && "Passed null for Decl param");
    if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);

    if (PrevDecl) {
      assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
      Decl->TypeForDecl = PrevDecl->TypeForDecl;
      return QualType(PrevDecl->TypeForDecl, 0);
    }

    return getTypeDeclTypeSlow(Decl);
  }

  /// Return the unique reference to the type for the specified
  /// typedef-name decl.
  QualType getTypedefType(const TypedefNameDecl *Decl,
                          QualType Underlying = QualType()) const;

  QualType getRecordType(const RecordDecl *Decl) const;

  QualType getEnumType(const EnumDecl *Decl) const;

  QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;

  QualType getAttributedType(attr::Kind attrKind,
                             QualType modifiedType,
                             QualType equivalentType);

  QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
                                        QualType Replacement) const;
  QualType getSubstTemplateTypeParmPackType(
                                          const TemplateTypeParmType *Replaced,
                                            const TemplateArgument &ArgPack);

  QualType
  getTemplateTypeParmType(unsigned Depth, unsigned Index,
                          bool ParameterPack,
                          TemplateTypeParmDecl *ParmDecl = nullptr) const;

  QualType getTemplateSpecializationType(TemplateName T,
                                         ArrayRef<TemplateArgument> Args,
                                         QualType Canon = QualType()) const;

  QualType
  getCanonicalTemplateSpecializationType(TemplateName T,
                                         ArrayRef<TemplateArgument> Args) const;

  QualType getTemplateSpecializationType(TemplateName T,
                                         const TemplateArgumentListInfo &Args,
                                         QualType Canon = QualType()) const;

  TypeSourceInfo *
  getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
                                    const TemplateArgumentListInfo &Args,
                                    QualType Canon = QualType()) const;

  QualType getParenType(QualType NamedType) const;

  QualType getMacroQualifiedType(QualType UnderlyingTy,
                                 const IdentifierInfo *MacroII) const;

  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
                             NestedNameSpecifier *NNS, QualType NamedType,
                             TagDecl *OwnedTagDecl = nullptr) const;
  QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
                                NestedNameSpecifier *NNS,
                                const IdentifierInfo *Name,
                                QualType Canon = QualType()) const;

  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
                                                  NestedNameSpecifier *NNS,
                                                  const IdentifierInfo *Name,
                                    const TemplateArgumentListInfo &Args) const;
  QualType getDependentTemplateSpecializationType(
      ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
      const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;

  TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl);

  /// Get a template argument list with one argument per template parameter
  /// in a template parameter list, such as for the injected class name of
  /// a class template.
  void getInjectedTemplateArgs(const TemplateParameterList *Params,
                               SmallVectorImpl<TemplateArgument> &Args);

  /// Form a pack expansion type with the given pattern.
  /// \param NumExpansions The number of expansions for the pack, if known.
  /// \param ExpectPackInType If \c false, we should not expect \p Pattern to
  ///        contain an unexpanded pack. This only makes sense if the pack
  ///        expansion is used in a context where the arity is inferred from
  ///        elsewhere, such as if the pattern contains a placeholder type or
  ///        if this is the canonical type of another pack expansion type.
  QualType getPackExpansionType(QualType Pattern,
                                Optional<unsigned> NumExpansions,
                                bool ExpectPackInType = true);

  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
                                ObjCInterfaceDecl *PrevDecl = nullptr) const;

  /// Legacy interface: cannot provide type arguments or __kindof.
  QualType getObjCObjectType(QualType Base,
                             ObjCProtocolDecl * const *Protocols,
                             unsigned NumProtocols) const;

  QualType getObjCObjectType(QualType Base,
                             ArrayRef<QualType> typeArgs,
                             ArrayRef<ObjCProtocolDecl *> protocols,
                             bool isKindOf) const;

  QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
                                ArrayRef<ObjCProtocolDecl *> protocols) const;
  void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,
                                    ObjCTypeParamDecl *New) const;

  bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);

  /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
  /// QT's qualified-id protocol list adopt all protocols in IDecl's list
  /// of protocols.
  bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
                                            ObjCInterfaceDecl *IDecl);

  /// Return a ObjCObjectPointerType type for the given ObjCObjectType.
  QualType getObjCObjectPointerType(QualType OIT) const;

  /// GCC extension.
  QualType getTypeOfExprType(Expr *e) const;
  QualType getTypeOfType(QualType t) const;

  QualType getReferenceQualifiedType(const Expr *e) const;

  /// C++11 decltype.
  QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;

  /// Unary type transforms
  QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
                                 UnaryTransformType::UTTKind UKind) const;

  /// C++11 deduced auto type.
  QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
                       bool IsDependent, bool IsPack = false,
                       ConceptDecl *TypeConstraintConcept = nullptr,
                       ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;

  /// C++11 deduction pattern for 'auto' type.
  QualType getAutoDeductType() const;

  /// C++11 deduction pattern for 'auto &&' type.
  QualType getAutoRRefDeductType() const;

  /// C++17 deduced class template specialization type.
  QualType getDeducedTemplateSpecializationType(TemplateName Template,
                                                QualType DeducedType,
                                                bool IsDependent) const;

  /// Return the unique reference to the type for the specified TagDecl
  /// (struct/union/class/enum) decl.
  QualType getTagDeclType(const TagDecl *Decl) const;

  /// Return the unique type for "size_t" (C99 7.17), defined in
  /// <stddef.h>.
  ///
  /// The sizeof operator requires this (C99 6.5.3.4p4).
  CanQualType getSizeType() const;

  /// Return the unique signed counterpart of
  /// the integer type corresponding to size_t.
  CanQualType getSignedSizeType() const;

  /// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
  /// <stdint.h>.
  CanQualType getIntMaxType() const;

  /// Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in
  /// <stdint.h>.
  CanQualType getUIntMaxType() const;

  /// Return the unique wchar_t type available in C++ (and available as
  /// __wchar_t as a Microsoft extension).
  QualType getWCharType() const { return WCharTy; }

  /// Return the type of wide characters. In C++, this returns the
  /// unique wchar_t type. In C99, this returns a type compatible with the type
  /// defined in <stddef.h> as defined by the target.
  QualType getWideCharType() const { return WideCharTy; }

  /// Return the type of "signed wchar_t".
  ///
  /// Used when in C++, as a GCC extension.
  QualType getSignedWCharType() const;

  /// Return the type of "unsigned wchar_t".
  ///
  /// Used when in C++, as a GCC extension.
  QualType getUnsignedWCharType() const;

  /// In C99, this returns a type compatible with the type
  /// defined in <stddef.h> as defined by the target.
  QualType getWIntType() const { return WIntTy; }

  /// Return a type compatible with "intptr_t" (C99 7.18.1.4),
  /// as defined by the target.
  QualType getIntPtrType() const;

  /// Return a type compatible with "uintptr_t" (C99 7.18.1.4),
  /// as defined by the target.
  QualType getUIntPtrType() const;

  /// Return the unique type for "ptrdiff_t" (C99 7.17) defined in
  /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
  QualType getPointerDiffType() const;

  /// Return the unique unsigned counterpart of "ptrdiff_t"
  /// integer type. The standard (C11 7.21.6.1p7) refers to this type
  /// in the definition of %tu format specifier.
  QualType getUnsignedPointerDiffType() const;

  /// Return the unique type for "pid_t" defined in
  /// <sys/types.h>. We need this to compute the correct type for vfork().
  QualType getProcessIDType() const;

  /// Return the C structure type used to represent constant CFStrings.
  QualType getCFConstantStringType() const;

  /// Returns the C struct type for objc_super
  QualType getObjCSuperType() const;
  void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }

  /// Get the structure type used to representation CFStrings, or NULL
  /// if it hasn't yet been built.
  QualType getRawCFConstantStringType() const {
    if (CFConstantStringTypeDecl)
      return getTypedefType(CFConstantStringTypeDecl);
    return QualType();
  }
  void setCFConstantStringType(QualType T);
  TypedefDecl *getCFConstantStringDecl() const;
  RecordDecl *getCFConstantStringTagDecl() const;

  // This setter/getter represents the ObjC type for an NSConstantString.
  void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
  QualType getObjCConstantStringInterface() const {
    return ObjCConstantStringType;
  }

  QualType getObjCNSStringType() const {
    return ObjCNSStringType;
  }

  void setObjCNSStringType(QualType T) {
    ObjCNSStringType = T;
  }

  /// Retrieve the type that \c id has been defined to, which may be
  /// different from the built-in \c id if \c id has been typedef'd.
  QualType getObjCIdRedefinitionType() const {
    if (ObjCIdRedefinitionType.isNull())
      return getObjCIdType();
    return ObjCIdRedefinitionType;
  }

  /// Set the user-written type that redefines \c id.
  void setObjCIdRedefinitionType(QualType RedefType) {
    ObjCIdRedefinitionType = RedefType;
  }

  /// Retrieve the type that \c Class has been defined to, which may be
  /// different from the built-in \c Class if \c Class has been typedef'd.
  QualType getObjCClassRedefinitionType() const {
    if (ObjCClassRedefinitionType.isNull())
      return getObjCClassType();
    return ObjCClassRedefinitionType;
  }

  /// Set the user-written type that redefines 'SEL'.
  void setObjCClassRedefinitionType(QualType RedefType) {
    ObjCClassRedefinitionType = RedefType;
  }

  /// Retrieve the type that 'SEL' has been defined to, which may be
  /// different from the built-in 'SEL' if 'SEL' has been typedef'd.
  QualType getObjCSelRedefinitionType() const {
    if (ObjCSelRedefinitionType.isNull())
      return getObjCSelType();
    return ObjCSelRedefinitionType;
  }

  /// Set the user-written type that redefines 'SEL'.
  void setObjCSelRedefinitionType(QualType RedefType) {
    ObjCSelRedefinitionType = RedefType;
  }

  /// Retrieve the identifier 'NSObject'.
  IdentifierInfo *getNSObjectName() const {
    if (!NSObjectName) {
      NSObjectName = &Idents.get("NSObject");
    }

    return NSObjectName;
  }

  /// Retrieve the identifier 'NSCopying'.
  IdentifierInfo *getNSCopyingName() {
    if (!NSCopyingName) {
      NSCopyingName = &Idents.get("NSCopying");
    }

    return NSCopyingName;
  }

  CanQualType getNSUIntegerType() const;

  CanQualType getNSIntegerType() const;

  /// Retrieve the identifier 'bool'.
  IdentifierInfo *getBoolName() const {
    if (!BoolName)
      BoolName = &Idents.get("bool");
    return BoolName;
  }

  IdentifierInfo *getMakeIntegerSeqName() const {
    if (!MakeIntegerSeqName)
      MakeIntegerSeqName = &Idents.get("__make_integer_seq");
    return MakeIntegerSeqName;
  }

  IdentifierInfo *getTypePackElementName() const {
    if (!TypePackElementName)
      TypePackElementName = &Idents.get("__type_pack_element");
    return TypePackElementName;
  }

  /// Retrieve the Objective-C "instancetype" type, if already known;
  /// otherwise, returns a NULL type;
  QualType getObjCInstanceType() {
    return getTypeDeclType(getObjCInstanceTypeDecl());
  }

  /// Retrieve the typedef declaration corresponding to the Objective-C
  /// "instancetype" type.
  TypedefDecl *getObjCInstanceTypeDecl();

  /// Set the type for the C FILE type.
  void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }

  /// Retrieve the C FILE type.
  QualType getFILEType() const {
    if (FILEDecl)
      return getTypeDeclType(FILEDecl);
    return QualType();
  }

  /// Set the type for the C jmp_buf type.
  void setjmp_bufDecl(TypeDecl *jmp_bufDecl) {
    this->jmp_bufDecl = jmp_bufDecl;
  }

  /// Retrieve the C jmp_buf type.
  QualType getjmp_bufType() const {
    if (jmp_bufDecl)
      return getTypeDeclType(jmp_bufDecl);
    return QualType();
  }

  /// Set the type for the C sigjmp_buf type.
  void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) {
    this->sigjmp_bufDecl = sigjmp_bufDecl;
  }

  /// Retrieve the C sigjmp_buf type.
  QualType getsigjmp_bufType() const {
    if (sigjmp_bufDecl)
      return getTypeDeclType(sigjmp_bufDecl);
    return QualType();
  }

  /// Set the type for the C ucontext_t type.
  void setucontext_tDecl(TypeDecl *ucontext_tDecl) {
    this->ucontext_tDecl = ucontext_tDecl;
  }

  /// Retrieve the C ucontext_t type.
  QualType getucontext_tType() const {
    if (ucontext_tDecl)
      return getTypeDeclType(ucontext_tDecl);
    return QualType();
  }

  /// The result type of logical operations, '<', '>', '!=', etc.
  QualType getLogicalOperationType() const {
    return getLangOpts().CPlusPlus ? BoolTy : IntTy;
  }

  /// Emit the Objective-CC type encoding for the given type \p T into
  /// \p S.
  ///
  /// If \p Field is specified then record field names are also encoded.
  void getObjCEncodingForType(QualType T, std::string &S,
                              const FieldDecl *Field=nullptr,
                              QualType *NotEncodedT=nullptr) const;

  /// Emit the Objective-C property type encoding for the given
  /// type \p T into \p S.
  void getObjCEncodingForPropertyType(QualType T, std::string &S) const;

  void getLegacyIntegralTypeEncoding(QualType &t) const;

  /// Put the string version of the type qualifiers \p QT into \p S.
  void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
                                       std::string &S) const;

  /// Emit the encoded type for the function \p Decl into \p S.
  ///
  /// This is in the same format as Objective-C method encodings.
  ///
  /// \returns true if an error occurred (e.g., because one of the parameter
  /// types is incomplete), false otherwise.
  std::string getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const;

  /// Emit the encoded type for the method declaration \p Decl into
  /// \p S.
  std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
                                           bool Extended = false) const;

  /// Return the encoded type for this block declaration.
  std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;

  /// getObjCEncodingForPropertyDecl - Return the encoded type for
  /// this method declaration. If non-NULL, Container must be either
  /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
  /// only be NULL when getting encodings for protocol properties.
  std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
                                             const Decl *Container) const;

  bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
                                      ObjCProtocolDecl *rProto) const;

  ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
                                                  const ObjCPropertyDecl *PD,
                                                  const Decl *Container) const;

  /// Return the size of type \p T for Objective-C encoding purpose,
  /// in characters.
  CharUnits getObjCEncodingTypeSize(QualType T) const;

  /// Retrieve the typedef corresponding to the predefined \c id type
  /// in Objective-C.
  TypedefDecl *getObjCIdDecl() const;

  /// Represents the Objective-CC \c id type.
  ///
  /// This is set up lazily, by Sema.  \c id is always a (typedef for a)
  /// pointer type, a pointer to a struct.
  QualType getObjCIdType() const {
    return getTypeDeclType(getObjCIdDecl());
  }

  /// Retrieve the typedef corresponding to the predefined 'SEL' type
  /// in Objective-C.
  TypedefDecl *getObjCSelDecl() const;

  /// Retrieve the type that corresponds to the predefined Objective-C
  /// 'SEL' type.
  QualType getObjCSelType() const {
    return getTypeDeclType(getObjCSelDecl());
  }

  /// Retrieve the typedef declaration corresponding to the predefined
  /// Objective-C 'Class' type.
  TypedefDecl *getObjCClassDecl() const;

  /// Represents the Objective-C \c Class type.
  ///
  /// This is set up lazily, by Sema.  \c Class is always a (typedef for a)
  /// pointer type, a pointer to a struct.
  QualType getObjCClassType() const {
    return getTypeDeclType(getObjCClassDecl());
  }

  /// Retrieve the Objective-C class declaration corresponding to
  /// the predefined \c Protocol class.
  ObjCInterfaceDecl *getObjCProtocolDecl() const;

  /// Retrieve declaration of 'BOOL' typedef
  TypedefDecl *getBOOLDecl() const {
    return BOOLDecl;
  }

  /// Save declaration of 'BOOL' typedef
  void setBOOLDecl(TypedefDecl *TD) {
    BOOLDecl = TD;
  }

  /// type of 'BOOL' type.
  QualType getBOOLType() const {
    return getTypeDeclType(getBOOLDecl());
  }

  /// Retrieve the type of the Objective-C \c Protocol class.
  QualType getObjCProtoType() const {
    return getObjCInterfaceType(getObjCProtocolDecl());
  }

  /// Retrieve the C type declaration corresponding to the predefined
  /// \c __builtin_va_list type.
  TypedefDecl *getBuiltinVaListDecl() const;

  /// Retrieve the type of the \c __builtin_va_list type.
  QualType getBuiltinVaListType() const {
    return getTypeDeclType(getBuiltinVaListDecl());
  }

  /// Retrieve the C type declaration corresponding to the predefined
  /// \c __va_list_tag type used to help define the \c __builtin_va_list type
  /// for some targets.
  Decl *getVaListTagDecl() const;

  /// Retrieve the C type declaration corresponding to the predefined
  /// \c __builtin_ms_va_list type.
  TypedefDecl *getBuiltinMSVaListDecl() const;

  /// Retrieve the type of the \c __builtin_ms_va_list type.
  QualType getBuiltinMSVaListType() const {
    return getTypeDeclType(getBuiltinMSVaListDecl());
  }

  /// Retrieve the implicitly-predeclared 'struct _GUID' declaration.
  TagDecl *getMSGuidTagDecl() const { return MSGuidTagDecl; }

  /// Retrieve the implicitly-predeclared 'struct _GUID' type.
  QualType getMSGuidType() const {
    assert(MSGuidTagDecl && "asked for GUID type but MS extensions disabled");
    return getTagDeclType(MSGuidTagDecl);
  }

  /// Return whether a declaration to a builtin is allowed to be
  /// overloaded/redeclared.
  bool canBuiltinBeRedeclared(const FunctionDecl *) const;

  /// Return a type with additional \c const, \c volatile, or
  /// \c restrict qualifiers.
  QualType getCVRQualifiedType(QualType T, unsigned CVR) const {
    return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
  }

  /// Un-split a SplitQualType.
  QualType getQualifiedType(SplitQualType split) const {
    return getQualifiedType(split.Ty, split.Quals);
  }

  /// Return a type with additional qualifiers.
  QualType getQualifiedType(QualType T, Qualifiers Qs) const {
    if (!Qs.hasNonFastQualifiers())
      return T.withFastQualifiers(Qs.getFastQualifiers());
    QualifierCollector Qc(Qs);
    const Type *Ptr = Qc.strip(T);
    return getExtQualType(Ptr, Qc);
  }

  /// Return a type with additional qualifiers.
  QualType getQualifiedType(const Type *T, Qualifiers Qs) const {
    if (!Qs.hasNonFastQualifiers())
      return QualType(T, Qs.getFastQualifiers());
    return getExtQualType(T, Qs);
  }

  /// Return a type with the given lifetime qualifier.
  ///
  /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None.
  QualType getLifetimeQualifiedType(QualType type,
                                    Qualifiers::ObjCLifetime lifetime) {
    assert(type.getObjCLifetime() == Qualifiers::OCL_None);
    assert(lifetime != Qualifiers::OCL_None);

    Qualifiers qs;
    qs.addObjCLifetime(lifetime);
    return getQualifiedType(type, qs);
  }

  /// getUnqualifiedObjCPointerType - Returns version of
  /// Objective-C pointer type with lifetime qualifier removed.
  QualType getUnqualifiedObjCPointerType(QualType type) const {
    if (!type.getTypePtr()->isObjCObjectPointerType() ||
        !type.getQualifiers().hasObjCLifetime())
      return type;
    Qualifiers Qs = type.getQualifiers();
    Qs.removeObjCLifetime();
    return getQualifiedType(type.getUnqualifiedType(), Qs);
  }

  unsigned char getFixedPointScale(QualType Ty) const;
  unsigned char getFixedPointIBits(QualType Ty) const;
  llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
  llvm::APFixedPoint getFixedPointMax(QualType Ty) const;
  llvm::APFixedPoint getFixedPointMin(QualType Ty) const;

  DeclarationNameInfo getNameForTemplate(TemplateName Name,
                                         SourceLocation NameLoc) const;

  TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
                                         UnresolvedSetIterator End) const;
  TemplateName getAssumedTemplateName(DeclarationName Name) const;

  TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
                                        bool TemplateKeyword,
                                        TemplateDecl *Template) const;

  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
                                        const IdentifierInfo *Name) const;
  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
                                        OverloadedOperatorKind Operator) const;
  TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
                                            TemplateName replacement) const;
  TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
                                        const TemplateArgument &ArgPack) const;

  enum GetBuiltinTypeError {
    /// No error
    GE_None,

    /// Missing a type
    GE_Missing_type,

    /// Missing a type from <stdio.h>
    GE_Missing_stdio,

    /// Missing a type from <setjmp.h>
    GE_Missing_setjmp,

    /// Missing a type from <ucontext.h>
    GE_Missing_ucontext
  };

  QualType DecodeTypeStr(const char *&Str, const ASTContext &Context,
                         ASTContext::GetBuiltinTypeError &Error,
                         bool &RequireICE, bool AllowTypeModifiers) const;

  /// Return the type for the specified builtin.
  ///
  /// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of
  /// arguments to the builtin that are required to be integer constant
  /// expressions.
  QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
                          unsigned *IntegerConstantArgs = nullptr) const;

  /// Types and expressions required to build C++2a three-way comparisons
  /// using operator<=>, including the values return by builtin <=> operators.
  ComparisonCategories CompCategories;

private:
  CanQualType getFromTargetType(unsigned Type) const;
  TypeInfo getTypeInfoImpl(const Type *T) const;

  //===--------------------------------------------------------------------===//
  //                         Type Predicates.
  //===--------------------------------------------------------------------===//

public:
  /// Return one of the GCNone, Weak or Strong Objective-C garbage
  /// collection attributes.
  Qualifiers::GC getObjCGCAttrKind(QualType Ty) const;

  /// Return true if the given vector types are of the same unqualified
  /// type or if they are equivalent to the same GCC vector type.
  ///
  /// \note This ignores whether they are target-specific (AltiVec or Neon)
  /// types.
  bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);

  /// Return true if the given types are an SVE builtin and a VectorType that
  /// is a fixed-length representation of the SVE builtin for a specific
  /// vector-length.
  bool areCompatibleSveTypes(QualType FirstType, QualType SecondType);

  /// Return true if the given vector types are lax-compatible SVE vector types,
  /// false otherwise.
  bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);

  /// Return true if the type has been explicitly qualified with ObjC ownership.
  /// A type may be implicitly qualified with ownership under ObjC ARC, and in
  /// some cases the compiler treats these differently.
  bool hasDirectOwnershipQualifier(QualType Ty) const;

  /// Return true if this is an \c NSObject object with its \c NSObject
  /// attribute set.
  static bool isObjCNSObjectType(QualType Ty) {
    return Ty->isObjCNSObjectType();
  }

  //===--------------------------------------------------------------------===//
  //                         Type Sizing and Analysis
  //===--------------------------------------------------------------------===//

  /// Return the APFloat 'semantics' for the specified scalar floating
  /// point type.
  const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;

  /// Get the size and alignment of the specified complete type in bits.
  TypeInfo getTypeInfo(const Type *T) const;
  TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); }

  /// Get default simd alignment of the specified complete type in bits.
  unsigned getOpenMPDefaultSimdAlign(QualType T) const;

  /// Return the size of the specified (complete) type \p T, in bits.
  uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; }
  uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; }

  /// Return the size of the character type, in bits.
  uint64_t getCharWidth() const {
    return getTypeSize(CharTy);
  }

  /// Convert a size in bits to a size in characters.
  CharUnits toCharUnitsFromBits(int64_t BitSize) const;

  /// Convert a size in characters to a size in bits.
  int64_t toBits(CharUnits CharSize) const;

  /// Return the size of the specified (complete) type \p T, in
  /// characters.
  CharUnits getTypeSizeInChars(QualType T) const;
  CharUnits getTypeSizeInChars(const Type *T) const;

  Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
    if (Ty->isIncompleteType() || Ty->isDependentType())
      return None;
    return getTypeSizeInChars(Ty);
  }

  Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
    return getTypeSizeInCharsIfKnown(QualType(Ty, 0));
  }

  /// Return the ABI-specified alignment of a (complete) type \p T, in
  /// bits.
  unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
  unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }

  /// Return the ABI-specified natural alignment of a (complete) type \p T,
  /// before alignment adjustments, in bits.
  ///
  /// This alignment is curently used only by ARM and AArch64 when passing
  /// arguments of a composite type.
  unsigned getTypeUnadjustedAlign(QualType T) const {
    return getTypeUnadjustedAlign(T.getTypePtr());
  }
  unsigned getTypeUnadjustedAlign(const Type *T) const;

  /// Return the alignment of a type, in bits, or 0 if
  /// the type is incomplete and we cannot determine the alignment (for
  /// example, from alignment attributes). The returned alignment is the
  /// Preferred alignment if NeedsPreferredAlignment is true, otherwise is the
  /// ABI alignment.
  unsigned getTypeAlignIfKnown(QualType T,
                               bool NeedsPreferredAlignment = false) const;

  /// Return the ABI-specified alignment of a (complete) type \p T, in
  /// characters.
  CharUnits getTypeAlignInChars(QualType T) const;
  CharUnits getTypeAlignInChars(const Type *T) const;

  /// Return the PreferredAlignment of a (complete) type \p T, in
  /// characters.
  CharUnits getPreferredTypeAlignInChars(QualType T) const {
    return toCharUnitsFromBits(getPreferredTypeAlign(T));
  }

  /// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a type,
  /// in characters, before alignment adjustments. This method does not work on
  /// incomplete types.
  CharUnits getTypeUnadjustedAlignInChars(QualType T) const;
  CharUnits getTypeUnadjustedAlignInChars(const Type *T) const;

  // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
  // type is a record, its data size is returned.
  TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const;

  TypeInfoChars getTypeInfoInChars(const Type *T) const;
  TypeInfoChars getTypeInfoInChars(QualType T) const;

  /// Determine if the alignment the type has was required using an
  /// alignment attribute.
  bool isAlignmentRequired(const Type *T) const;
  bool isAlignmentRequired(QualType T) const;

  /// Return the "preferred" alignment of the specified type \p T for
  /// the current target, in bits.
  ///
  /// This can be different than the ABI alignment in cases where it is
  /// beneficial for performance or backwards compatibility preserving to
  /// overalign a data type. (Note: despite the name, the preferred alignment
  /// is ABI-impacting, and not an optimization.)
  unsigned getPreferredTypeAlign(QualType T) const {
    return getPreferredTypeAlign(T.getTypePtr());
  }
  unsigned getPreferredTypeAlign(const Type *T) const;

  /// Return the default alignment for __attribute__((aligned)) on
  /// this target, to be used if no alignment value is specified.
  unsigned getTargetDefaultAlignForAttributeAligned() const;

  /// Return the alignment in bits that should be given to a
  /// global variable with type \p T.
  unsigned getAlignOfGlobalVar(QualType T) const;

  /// Return the alignment in characters that should be given to a
  /// global variable with type \p T.
  CharUnits getAlignOfGlobalVarInChars(QualType T) const;

  /// Return a conservative estimate of the alignment of the specified
  /// decl \p D.
  ///
  /// \pre \p D must not be a bitfield type, as bitfields do not have a valid
  /// alignment.
  ///
  /// If \p ForAlignof, references are treated like their underlying type
  /// and  large arrays don't get any special treatment. If not \p ForAlignof
  /// it computes the value expected by CodeGen: references are treated like
  /// pointers and large arrays get extra alignment.
  CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;

  /// Return the alignment (in bytes) of the thrown exception object. This is
  /// only meaningful for targets that allocate C++ exceptions in a system
  /// runtime, such as those using the Itanium C++ ABI.
  CharUnits getExnObjectAlignment() const;

  /// Get or compute information about the layout of the specified
  /// record (struct/union/class) \p D, which indicates its size and field
  /// position information.
  const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;

  /// Get or compute information about the layout of the specified
  /// Objective-C interface.
  const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D)
    const;

  void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
                        bool Simple = false) const;

  /// Get or compute information about the layout of the specified
  /// Objective-C implementation.
  ///
  /// This may differ from the interface if synthesized ivars are present.
  const ASTRecordLayout &
  getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;

  /// Get our current best idea for the key function of the
  /// given record decl, or nullptr if there isn't one.
  ///
  /// The key function is, according to the Itanium C++ ABI section 5.2.3:
  ///   ...the first non-pure virtual function that is not inline at the
  ///   point of class definition.
  ///
  /// Other ABIs use the same idea.  However, the ARM C++ ABI ignores
  /// virtual functions that are defined 'inline', which means that
  /// the result of this computation can change.
  const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD);

  /// Observe that the given method cannot be a key function.
  /// Checks the key-function cache for the method's class and clears it
  /// if matches the given declaration.
  ///
  /// This is used in ABIs where out-of-line definitions marked
  /// inline are not considered to be key functions.
  ///
  /// \param method should be the declaration from the class definition
  void setNonKeyFunction(const CXXMethodDecl *method);

  /// Loading virtual member pointers using the virtual inheritance model
  /// always results in an adjustment using the vbtable even if the index is
  /// zero.
  ///
  /// This is usually OK because the first slot in the vbtable points
  /// backwards to the top of the MDC.  However, the MDC might be reusing a
  /// vbptr from an nv-base.  In this case, the first slot in the vbtable
  /// points to the start of the nv-base which introduced the vbptr and *not*
  /// the MDC.  Modify the NonVirtualBaseAdjustment to account for this.
  CharUnits getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const;

  /// Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
  uint64_t getFieldOffset(const ValueDecl *FD) const;

  /// Get the offset of an ObjCIvarDecl in bits.
  uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID,
                                const ObjCImplementationDecl *ID,
                                const ObjCIvarDecl *Ivar) const;

  /// Find the 'this' offset for the member path in a pointer-to-member
  /// APValue.
  CharUnits getMemberPointerPathAdjustment(const APValue &MP) const;

  bool isNearlyEmpty(const CXXRecordDecl *RD) const;

  VTableContextBase *getVTableContext();

  /// If \p T is null pointer, assume the target in ASTContext.
  MangleContext *createMangleContext(const TargetInfo *T = nullptr);

  /// Creates a device mangle context to correctly mangle lambdas in a mixed
  /// architecture compile by setting the lambda mangling number source to the
  /// DeviceLambdaManglingNumber. Currently this asserts that the TargetInfo
  /// (from the AuxTargetInfo) is a an itanium target.
  MangleContext *createDeviceMangleContext(const TargetInfo &T);

  void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
                            SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;

  unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
  void CollectInheritedProtocols(const Decl *CDecl,
                          llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);

  /// Return true if the specified type has unique object representations
  /// according to (C++17 [meta.unary.prop]p9)
  bool hasUniqueObjectRepresentations(QualType Ty) const;

  //===--------------------------------------------------------------------===//
  //                            Type Operators
  //===--------------------------------------------------------------------===//

  /// Return the canonical (structural) type corresponding to the
  /// specified potentially non-canonical type \p T.
  ///
  /// The non-canonical version of a type may have many "decorated" versions of
  /// types.  Decorators can include typedefs, 'typeof' operators, etc. The
  /// returned type is guaranteed to be free of any of these, allowing two
  /// canonical types to be compared for exact equality with a simple pointer
  /// comparison.
  CanQualType getCanonicalType(QualType T) const {
    return CanQualType::CreateUnsafe(T.getCanonicalType());
  }

  const Type *getCanonicalType(const Type *T) const {
    return T->getCanonicalTypeInternal().getTypePtr();
  }

  /// Return the canonical parameter type corresponding to the specific
  /// potentially non-canonical one.
  ///
  /// Qualifiers are stripped off, functions are turned into function
  /// pointers, and arrays decay one level into pointers.
  CanQualType getCanonicalParamType(QualType T) const;

  /// Determine whether the given types \p T1 and \p T2 are equivalent.
  bool hasSameType(QualType T1, QualType T2) const {
    return getCanonicalType(T1) == getCanonicalType(T2);
  }
  bool hasSameType(const Type *T1, const Type *T2) const {
    return getCanonicalType(T1) == getCanonicalType(T2);
  }

  /// Return this type as a completely-unqualified array type,
  /// capturing the qualifiers in \p Quals.
  ///
  /// This will remove the minimal amount of sugaring from the types, similar
  /// to the behavior of QualType::getUnqualifiedType().
  ///
  /// \param T is the qualified type, which may be an ArrayType
  ///
  /// \param Quals will receive the full set of qualifiers that were
  /// applied to the array.
  ///
  /// \returns if this is an array type, the completely unqualified array type
  /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
  QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);

  /// Determine whether the given types are equivalent after
  /// cvr-qualifiers have been removed.
  bool hasSameUnqualifiedType(QualType T1, QualType T2) const {
    return getCanonicalType(T1).getTypePtr() ==
           getCanonicalType(T2).getTypePtr();
  }

  bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT,
                                       bool IsParam) const {
    auto SubTnullability = SubT->getNullability(*this);
    auto SuperTnullability = SuperT->getNullability(*this);
    if (SubTnullability.hasValue() == SuperTnullability.hasValue()) {
      // Neither has nullability; return true
      if (!SubTnullability)
        return true;
      // Both have nullability qualifier.
      if (*SubTnullability == *SuperTnullability ||
          *SubTnullability == NullabilityKind::Unspecified ||
          *SuperTnullability == NullabilityKind::Unspecified)
        return true;

      if (IsParam) {
        // Ok for the superclass method parameter to be "nonnull" and the subclass
        // method parameter to be "nullable"
        return (*SuperTnullability == NullabilityKind::NonNull &&
                *SubTnullability == NullabilityKind::Nullable);
      }
      // For the return type, it's okay for the superclass method to specify
      // "nullable" and the subclass method specify "nonnull"
      return (*SuperTnullability == NullabilityKind::Nullable &&
              *SubTnullability == NullabilityKind::NonNull);
    }
    return true;
  }

  bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
                           const ObjCMethodDecl *MethodImp);

  bool UnwrapSimilarTypes(QualType &T1, QualType &T2,
                          bool AllowPiMismatch = true);
  void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2,
                               bool AllowPiMismatch = true);

  /// Determine if two types are similar, according to the C++ rules. That is,
  /// determine if they are the same other than qualifiers on the initial
  /// sequence of pointer / pointer-to-member / array (and in Clang, object
  /// pointer) types and their element types.
  ///
  /// Clang offers a number of qualifiers in addition to the C++ qualifiers;
  /// those qualifiers are also ignored in the 'similarity' check.
  bool hasSimilarType(QualType T1, QualType T2);

  /// Determine if two types are similar, ignoring only CVR qualifiers.
  bool hasCvrSimilarType(QualType T1, QualType T2);

  /// Retrieves the "canonical" nested name specifier for a
  /// given nested name specifier.
  ///
  /// The canonical nested name specifier is a nested name specifier
  /// that uniquely identifies a type or namespace within the type
  /// system. For example, given:
  ///
  /// \code
  /// namespace N {
  ///   struct S {
  ///     template<typename T> struct X { typename T* type; };
  ///   };
  /// }
  ///
  /// template<typename T> struct Y {
  ///   typename N::S::X<T>::type member;
  /// };
  /// \endcode
  ///
  /// Here, the nested-name-specifier for N::S::X<T>:: will be
  /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
  /// by declarations in the type system and the canonical type for
  /// the template type parameter 'T' is template-param-0-0.
  NestedNameSpecifier *
  getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;

  /// Retrieves the default calling convention for the current target.
  CallingConv getDefaultCallingConvention(bool IsVariadic,
                                          bool IsCXXMethod,
                                          bool IsBuiltin = false) const;

  /// Retrieves the "canonical" template name that refers to a
  /// given template.
  ///
  /// The canonical template name is the simplest expression that can
  /// be used to refer to a given template. For most templates, this
  /// expression is just the template declaration itself. For example,
  /// the template std::vector can be referred to via a variety of
  /// names---std::vector, \::std::vector, vector (if vector is in
  /// scope), etc.---but all of these names map down to the same
  /// TemplateDecl, which is used to form the canonical template name.
  ///
  /// Dependent template names are more interesting. Here, the
  /// template name could be something like T::template apply or
  /// std::allocator<T>::template rebind, where the nested name
  /// specifier itself is dependent. In this case, the canonical
  /// template name uses the shortest form of the dependent
  /// nested-name-specifier, which itself contains all canonical
  /// types, values, and templates.
  TemplateName getCanonicalTemplateName(TemplateName Name) const;

  /// Determine whether the given template names refer to the same
  /// template.
  bool hasSameTemplateName(TemplateName X, TemplateName Y);

  /// Retrieve the "canonical" template argument.
  ///
  /// The canonical template argument is the simplest template argument
  /// (which may be a type, value, expression, or declaration) that
  /// expresses the value of the argument.
  TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg)
    const;

  /// Type Query functions.  If the type is an instance of the specified class,
  /// return the Type pointer for the underlying maximally pretty type.  This
  /// is a member of ASTContext because this may need to do some amount of
  /// canonicalization, e.g. to move type qualifiers into the element type.
  const ArrayType *getAsArrayType(QualType T) const;
  const ConstantArrayType *getAsConstantArrayType(QualType T) const {
    return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
  }
  const VariableArrayType *getAsVariableArrayType(QualType T) const {
    return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
  }
  const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const {
    return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
  }
  const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T)
    const {
    return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
  }

  /// Return the innermost element type of an array type.
  ///
  /// For example, will return "int" for int[m][n]
  QualType getBaseElementType(const ArrayType *VAT) const;

  /// Return the innermost element type of a type (which needn't
  /// actually be an array type).
  QualType getBaseElementType(QualType QT) const;

  /// Return number of constant array elements.
  uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;

  /// Perform adjustment on the parameter type of a function.
  ///
  /// This routine adjusts the given parameter type @p T to the actual
  /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
  /// C++ [dcl.fct]p3). The adjusted parameter type is returned.
  QualType getAdjustedParameterType(QualType T) const;

  /// Retrieve the parameter type as adjusted for use in the signature
  /// of a function, decaying array and function types and removing top-level
  /// cv-qualifiers.
  QualType getSignatureParameterType(QualType T) const;

  QualType getExceptionObjectType(QualType T) const;

  /// Return the properly qualified result of decaying the specified
  /// array type to a pointer.
  ///
  /// This operation is non-trivial when handling typedefs etc.  The canonical
  /// type of \p T must be an array type, this returns a pointer to a properly
  /// qualified element of the array.
  ///
  /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
  QualType getArrayDecayedType(QualType T) const;

  /// Return the type that \p PromotableType will promote to: C99
  /// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type.
  QualType getPromotedIntegerType(QualType PromotableType) const;

  /// Recurses in pointer/array types until it finds an Objective-C
  /// retainable type and returns its ownership.
  Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;

  /// Whether this is a promotable bitfield reference according
  /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
  ///
  /// \returns the type this bit-field will promote to, or NULL if no
  /// promotion occurs.
  QualType isPromotableBitField(Expr *E) const;

  /// Return the highest ranked integer type, see C99 6.3.1.8p1.
  ///
  /// If \p LHS > \p RHS, returns 1.  If \p LHS == \p RHS, returns 0.  If
  /// \p LHS < \p RHS, return -1.
  int getIntegerTypeOrder(QualType LHS, QualType RHS) const;

  /// Compare the rank of the two specified floating point types,
  /// ignoring the domain of the type (i.e. 'double' == '_Complex double').
  ///
  /// If \p LHS > \p RHS, returns 1.  If \p LHS == \p RHS, returns 0.  If
  /// \p LHS < \p RHS, return -1.
  int getFloatingTypeOrder(QualType LHS, QualType RHS) const;

  /// Compare the rank of two floating point types as above, but compare equal
  /// if both types have the same floating-point semantics on the target (i.e.
  /// long double and double on AArch64 will return 0).
  int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const;

  /// Return a real floating point or a complex type (based on
  /// \p typeDomain/\p typeSize).
  ///
  /// \param typeDomain a real floating point or complex type.
  /// \param typeSize a real floating point or complex type.
  QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
                                             QualType typeDomain) const;

  unsigned getTargetAddressSpace(QualType T) const {
    return getTargetAddressSpace(T.getQualifiers());
  }

  unsigned getTargetAddressSpace(Qualifiers Q) const {
    return getTargetAddressSpace(Q.getAddressSpace());
  }

  unsigned getTargetAddressSpace(LangAS AS) const;

  LangAS getLangASForBuiltinAddressSpace(unsigned AS) const;

  /// Get target-dependent integer value for null pointer which is used for
  /// constant folding.
  uint64_t getTargetNullPointerValue(QualType QT) const;

  bool addressSpaceMapManglingFor(LangAS AS) const {
    return AddrSpaceMapMangling || isTargetAddressSpace(AS);
  }

private:
  // Helper for integer ordering
  unsigned getIntegerRank(const Type *T) const;

public:
  //===--------------------------------------------------------------------===//
  //                    Type Compatibility Predicates
  //===--------------------------------------------------------------------===//

  /// Compatibility predicates used to check assignment expressions.
  bool typesAreCompatible(QualType T1, QualType T2,
                          bool CompareUnqualified = false); // C99 6.2.7p1

  bool propertyTypesAreCompatible(QualType, QualType);
  bool typesAreBlockPointerCompatible(QualType, QualType);

  bool isObjCIdType(QualType T) const {
    return T == getObjCIdType();
  }

  bool isObjCClassType(QualType T) const {
    return T == getObjCClassType();
  }

  bool isObjCSelType(QualType T) const {
    return T == getObjCSelType();
  }

  bool ObjCQualifiedIdTypesAreCompatible(const ObjCObjectPointerType *LHS,
                                         const ObjCObjectPointerType *RHS,
                                         bool ForCompare);

  bool ObjCQualifiedClassTypesAreCompatible(const ObjCObjectPointerType *LHS,
                                            const ObjCObjectPointerType *RHS);

  // Check the safety of assignment from LHS to RHS
  bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
                               const ObjCObjectPointerType *RHSOPT);
  bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
                               const ObjCObjectType *RHS);
  bool canAssignObjCInterfacesInBlockPointer(
                                          const ObjCObjectPointerType *LHSOPT,
                                          const ObjCObjectPointerType *RHSOPT,
                                          bool BlockReturnType);
  bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
  QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
                                   const ObjCObjectPointerType *RHSOPT);
  bool canBindObjCObjectType(QualType To, QualType From);

  // Functions for calculating composite types
  QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
                      bool Unqualified = false, bool BlockReturnType = false);
  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
                              bool Unqualified = false, bool AllowCXX = false);
  QualType mergeFunctionParameterTypes(QualType, QualType,
                                       bool OfBlockPointer = false,
                                       bool Unqualified = false);
  QualType mergeTransparentUnionType(QualType, QualType,
                                     bool OfBlockPointer=false,
                                     bool Unqualified = false);

  QualType mergeObjCGCQualifiers(QualType, QualType);

  /// This function merges the ExtParameterInfo lists of two functions. It
  /// returns true if the lists are compatible. The merged list is returned in
  /// NewParamInfos.
  ///
  /// \param FirstFnType The type of the first function.
  ///
  /// \param SecondFnType The type of the second function.
  ///
  /// \param CanUseFirst This flag is set to true if the first function's
  /// ExtParameterInfo list can be used as the composite list of
  /// ExtParameterInfo.
  ///
  /// \param CanUseSecond This flag is set to true if the second function's
  /// ExtParameterInfo list can be used as the composite list of
  /// ExtParameterInfo.
  ///
  /// \param NewParamInfos The composite list of ExtParameterInfo. The list is
  /// empty if none of the flags are set.
  ///
  bool mergeExtParameterInfo(
      const FunctionProtoType *FirstFnType,
      const FunctionProtoType *SecondFnType,
      bool &CanUseFirst, bool &CanUseSecond,
      SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos);

  void ResetObjCLayout(const ObjCContainerDecl *CD);

  //===--------------------------------------------------------------------===//
  //                    Integer Predicates
  //===--------------------------------------------------------------------===//

  // The width of an integer, as defined in C99 6.2.6.2. This is the number
  // of bits in an integer type excluding any padding bits.
  unsigned getIntWidth(QualType T) const;

  // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
  // unsigned integer type.  This method takes a signed type, and returns the
  // corresponding unsigned integer type.
  // With the introduction of fixed point types in ISO N1169, this method also
  // accepts fixed point types and returns the corresponding unsigned type for
  // a given fixed point type.
  QualType getCorrespondingUnsignedType(QualType T) const;

  // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
  // unsigned integer type.  This method takes an unsigned type, and returns the
  // corresponding signed integer type.
  // With the introduction of fixed point types in ISO N1169, this method also
  // accepts fixed point types and returns the corresponding signed type for
  // a given fixed point type.
  QualType getCorrespondingSignedType(QualType T) const;

  // Per ISO N1169, this method accepts fixed point types and returns the
  // corresponding saturated type for a given fixed point type.
  QualType getCorrespondingSaturatedType(QualType Ty) const;

  // This method accepts fixed point types and returns the corresponding signed
  // type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned
  // fixed point types because there are unsigned integer types like bool and
  // char8_t that don't have signed equivalents.
  QualType getCorrespondingSignedFixedPointType(QualType Ty) const;

  //===--------------------------------------------------------------------===//
  //                    Integer Values
  //===--------------------------------------------------------------------===//

  /// Make an APSInt of the appropriate width and signedness for the
  /// given \p Value and integer \p Type.
  llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
    // If Type is a signed integer type larger than 64 bits, we need to be sure
    // to sign extend Res appropriately.
    llvm::APSInt Res(64, !Type->isSignedIntegerOrEnumerationType());
    Res = Value;
    unsigned Width = getIntWidth(Type);
    if (Width != Res.getBitWidth())
      return Res.extOrTrunc(Width);
    return Res;
  }

  bool isSentinelNullExpr(const Expr *E);

  /// Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if
  /// none exists.
  ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);

  /// Get the implementation of the ObjCCategoryDecl \p D, or nullptr if
  /// none exists.
  ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);

  /// Return true if there is at least one \@implementation in the TU.
  bool AnyObjCImplementation() {
    return !ObjCImpls.empty();
  }

  /// Set the implementation of ObjCInterfaceDecl.
  void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
                             ObjCImplementationDecl *ImplD);

  /// Set the implementation of ObjCCategoryDecl.
  void setObjCImplementation(ObjCCategoryDecl *CatD,
                             ObjCCategoryImplDecl *ImplD);

  /// Get the duplicate declaration of a ObjCMethod in the same
  /// interface, or null if none exists.
  const ObjCMethodDecl *
  getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const;

  void setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
                                  const ObjCMethodDecl *Redecl);

  /// Returns the Objective-C interface that \p ND belongs to if it is
  /// an Objective-C method/property/ivar etc. that is part of an interface,
  /// otherwise returns null.
  const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;

  /// Set the copy initialization expression of a block var decl. \p CanThrow
  /// indicates whether the copy expression can throw or not.
  void setBlockVarCopyInit(const VarDecl* VD, Expr *CopyExpr, bool CanThrow);

  /// Get the copy initialization expression of the VarDecl \p VD, or
  /// nullptr if none exists.
  BlockVarCopyInit getBlockVarCopyInit(const VarDecl* VD) const;

  /// Allocate an uninitialized TypeSourceInfo.
  ///
  /// The caller should initialize the memory held by TypeSourceInfo using
  /// the TypeLoc wrappers.
  ///
  /// \param T the type that will be the basis for type source info. This type
  /// should refer to how the declarator was written in source code, not to
  /// what type semantic analysis resolved the declarator to.
  ///
  /// \param Size the size of the type info to create, or 0 if the size
  /// should be calculated based on the type.
  TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const;

  /// Allocate a TypeSourceInfo where all locations have been
  /// initialized to a given location, which defaults to the empty
  /// location.
  TypeSourceInfo *
  getTrivialTypeSourceInfo(QualType T,
                           SourceLocation Loc = SourceLocation()) const;

  /// Add a deallocation callback that will be invoked when the
  /// ASTContext is destroyed.
  ///
  /// \param Callback A callback function that will be invoked on destruction.
  ///
  /// \param Data Pointer data that will be provided to the callback function
  /// when it is called.
  void AddDeallocation(void (*Callback)(void *), void *Data) const;

  /// If T isn't trivially destructible, calls AddDeallocation to register it
  /// for destruction.
  template <typename T> void addDestruction(T *Ptr) const {
    if (!std::is_trivially_destructible<T>::value) {
      auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
      AddDeallocation(DestroyPtr, Ptr);
    }
  }

  GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
  GVALinkage GetGVALinkageForVariable(const VarDecl *VD);

  /// Determines if the decl can be CodeGen'ed or deserialized from PCH
  /// lazily, only when used; this is only relevant for function or file scoped
  /// var definitions.
  ///
  /// \returns true if the function/var must be CodeGen'ed/deserialized even if
  /// it is not used.
  bool DeclMustBeEmitted(const Decl *D);

  /// Visits all versions of a multiversioned function with the passed
  /// predicate.
  void forEachMultiversionedFunctionVersion(
      const FunctionDecl *FD,
      llvm::function_ref<void(FunctionDecl *)> Pred) const;

  const CXXConstructorDecl *
  getCopyConstructorForExceptionObject(CXXRecordDecl *RD);

  void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
                                            CXXConstructorDecl *CD);

  void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND);

  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD);

  void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD);

  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD);

  void setManglingNumber(const NamedDecl *ND, unsigned Number);
  unsigned getManglingNumber(const NamedDecl *ND) const;

  void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
  unsigned getStaticLocalNumber(const VarDecl *VD) const;

  /// Retrieve the context for computing mangling numbers in the given
  /// DeclContext.
  MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
  enum NeedExtraManglingDecl_t { NeedExtraManglingDecl };
  MangleNumberingContext &getManglingNumberContext(NeedExtraManglingDecl_t,
                                                   const Decl *D);

  std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;

  /// Used by ParmVarDecl to store on the side the
  /// index of the parameter when it exceeds the size of the normal bitfield.
  void setParameterIndex(const ParmVarDecl *D, unsigned index);

  /// Used by ParmVarDecl to retrieve on the side the
  /// index of the parameter when it exceeds the size of the normal bitfield.
  unsigned getParameterIndex(const ParmVarDecl *D) const;

  /// Return a string representing the human readable name for the specified
  /// function declaration or file name. Used by SourceLocExpr and
  /// PredefinedExpr to cache evaluated results.
  StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const;

  /// Return a declaration for the global GUID object representing the given
  /// GUID value.
  MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const;

  /// Return the template parameter object of the given type with the given
  /// value.
  TemplateParamObjectDecl *getTemplateParamObjectDecl(QualType T,
                                                      const APValue &V) const;

  /// Parses the target attributes passed in, and returns only the ones that are
  /// valid feature names.
  ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;

  void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
                             const FunctionDecl *) const;
  void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
                             GlobalDecl GD) const;

  //===--------------------------------------------------------------------===//
  //                    Statistics
  //===--------------------------------------------------------------------===//

  /// The number of implicitly-declared default constructors.
  unsigned NumImplicitDefaultConstructors = 0;

  /// The number of implicitly-declared default constructors for
  /// which declarations were built.
  unsigned NumImplicitDefaultConstructorsDeclared = 0;

  /// The number of implicitly-declared copy constructors.
  unsigned NumImplicitCopyConstructors = 0;

  /// The number of implicitly-declared copy constructors for
  /// which declarations were built.
  unsigned NumImplicitCopyConstructorsDeclared = 0;

  /// The number of implicitly-declared move constructors.
  unsigned NumImplicitMoveConstructors = 0;

  /// The number of implicitly-declared move constructors for
  /// which declarations were built.
  unsigned NumImplicitMoveConstructorsDeclared = 0;

  /// The number of implicitly-declared copy assignment operators.
  unsigned NumImplicitCopyAssignmentOperators = 0;

  /// The number of implicitly-declared copy assignment operators for
  /// which declarations were built.
  unsigned NumImplicitCopyAssignmentOperatorsDeclared = 0;

  /// The number of implicitly-declared move assignment operators.
  unsigned NumImplicitMoveAssignmentOperators = 0;

  /// The number of implicitly-declared move assignment operators for
  /// which declarations were built.
  unsigned NumImplicitMoveAssignmentOperatorsDeclared = 0;

  /// The number of implicitly-declared destructors.
  unsigned NumImplicitDestructors = 0;

  /// The number of implicitly-declared destructors for which
  /// declarations were built.
  unsigned NumImplicitDestructorsDeclared = 0;

public:
  /// Initialize built-in types.
  ///
  /// This routine may only be invoked once for a given ASTContext object.
  /// It is normally invoked after ASTContext construction.
  ///
  /// \param Target The target
  void InitBuiltinTypes(const TargetInfo &Target,
                        const TargetInfo *AuxTarget = nullptr);

private:
  void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);

  class ObjCEncOptions {
    unsigned Bits;

    ObjCEncOptions(unsigned Bits) : Bits(Bits) {}

  public:
    ObjCEncOptions() : Bits(0) {}
    ObjCEncOptions(const ObjCEncOptions &RHS) : Bits(RHS.Bits) {}

#define OPT_LIST(V)                                                            \
  V(ExpandPointedToStructures, 0)                                              \
  V(ExpandStructures, 1)                                                       \
  V(IsOutermostType, 2)                                                        \
  V(EncodingProperty, 3)                                                       \
  V(IsStructField, 4)                                                          \
  V(EncodeBlockParameters, 5)                                                  \
  V(EncodeClassNames, 6)                                                       \

#define V(N,I) ObjCEncOptions& set##N() { Bits |= 1 << I; return *this; }
OPT_LIST(V)
#undef V

#define V(N,I) bool N() const { return Bits & 1 << I; }
OPT_LIST(V)
#undef V

#undef OPT_LIST

    LLVM_NODISCARD ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
      return Bits & Mask.Bits;
    }

    LLVM_NODISCARD ObjCEncOptions forComponentType() const {
      ObjCEncOptions Mask = ObjCEncOptions()
                                .setIsOutermostType()
                                .setIsStructField();
      return Bits & ~Mask.Bits;
    }
  };

  // Return the Objective-C type encoding for a given type.
  void getObjCEncodingForTypeImpl(QualType t, std::string &S,
                                  ObjCEncOptions Options,
                                  const FieldDecl *Field,
                                  QualType *NotEncodedT = nullptr) const;

  // Adds the encoding of the structure's members.
  void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
                                       const FieldDecl *Field,
                                       bool includeVBases = true,
                                       QualType *NotEncodedT=nullptr) const;

public:
  // Adds the encoding of a method parameter or return type.
  void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
                                         QualType T, std::string& S,
                                         bool Extended) const;

  /// Returns true if this is an inline-initialized static data member
  /// which is treated as a definition for MSVC compatibility.
  bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;

  enum class InlineVariableDefinitionKind {
    /// Not an inline variable.
    None,

    /// Weak definition of inline variable.
    Weak,

    /// Weak for now, might become strong later in this TU.
    WeakUnknown,

    /// Strong definition.
    Strong
  };

  /// Determine whether a definition of this inline variable should
  /// be treated as a weak or strong definition. For compatibility with
  /// C++14 and before, for a constexpr static data member, if there is an
  /// out-of-line declaration of the member, we may promote it from weak to
  /// strong.
  InlineVariableDefinitionKind
  getInlineVariableDefinitionKind(const VarDecl *VD) const;

private:
  friend class DeclarationNameTable;
  friend class DeclContext;

  const ASTRecordLayout &
  getObjCLayout(const ObjCInterfaceDecl *D,
                const ObjCImplementationDecl *Impl) const;

  /// A set of deallocations that should be performed when the
  /// ASTContext is destroyed.
  // FIXME: We really should have a better mechanism in the ASTContext to
  // manage running destructors for types which do variable sized allocation
  // within the AST. In some places we thread the AST bump pointer allocator
  // into the datastructures which avoids this mess during deallocation but is
  // wasteful of memory, and here we require a lot of error prone book keeping
  // in order to track and run destructors while we're tearing things down.
  using DeallocationFunctionsAndArguments =
      llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>;
  mutable DeallocationFunctionsAndArguments Deallocations;

  // FIXME: This currently contains the set of StoredDeclMaps used
  // by DeclContext objects.  This probably should not be in ASTContext,
  // but we include it here so that ASTContext can quickly deallocate them.
  llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;

  std::vector<Decl *> TraversalScope;

  std::unique_ptr<VTableContextBase> VTContext;

  void ReleaseDeclContextMaps();

public:
  enum PragmaSectionFlag : unsigned {
    PSF_None = 0,
    PSF_Read = 0x1,
    PSF_Write = 0x2,
    PSF_Execute = 0x4,
    PSF_Implicit = 0x8,
    PSF_ZeroInit = 0x10,
    PSF_Invalid = 0x80000000U,
  };

  struct SectionInfo {
    NamedDecl *Decl;
    SourceLocation PragmaSectionLocation;
    int SectionFlags;

    SectionInfo() = default;
    SectionInfo(NamedDecl *Decl, SourceLocation PragmaSectionLocation,
                int SectionFlags)
        : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation),
          SectionFlags(SectionFlags) {}
  };

  llvm::StringMap<SectionInfo> SectionInfos;

  /// Return a new OMPTraitInfo object owned by this context.
  OMPTraitInfo &getNewOMPTraitInfo();

  /// Whether a C++ static variable may be externalized.
  bool mayExternalizeStaticVar(const Decl *D) const;

  /// Whether a C++ static variable should be externalized.
  bool shouldExternalizeStaticVar(const Decl *D) const;

  StringRef getCUIDHash() const;

private:
  /// All OMPTraitInfo objects live in this collection, one per
  /// `pragma omp [begin] declare variant` directive.
  SmallVector<std::unique_ptr<OMPTraitInfo>, 4> OMPTraitInfoVector;
};

/// Insertion operator for diagnostics.
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
                                      const ASTContext::SectionInfo &Section);

/// Utility function for constructing a nullary selector.
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
  IdentifierInfo* II = &Ctx.Idents.get(name);
  return Ctx.Selectors.getSelector(0, &II);
}

/// Utility function for constructing an unary selector.
inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
  IdentifierInfo* II = &Ctx.Idents.get(name);
  return Ctx.Selectors.getSelector(1, &II);
}

} // namespace clang

// operator new and delete aren't allowed inside namespaces.

/// Placement new for using the ASTContext's allocator.
///
/// This placement form of operator new uses the ASTContext's allocator for
/// obtaining memory.
///
/// IMPORTANT: These are also declared in clang/AST/ASTContextAllocate.h!
/// Any changes here need to also be made there.
///
/// We intentionally avoid using a nothrow specification here so that the calls
/// to this operator will not perform a null check on the result -- the
/// underlying allocator never returns null pointers.
///
/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
/// @code
/// // Default alignment (8)
/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
/// // Specific alignment
/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
/// @endcode
/// Memory allocated through this placement new operator does not need to be
/// explicitly freed, as ASTContext will free all of this memory when it gets
/// destroyed. Please note that you cannot use delete on the pointer.
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The ASTContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
///                  allocator supports it).
/// @return The allocated memory. Could be nullptr.
inline void *operator new(size_t Bytes, const clang::ASTContext &C,
                          size_t Alignment /* = 8 */) {
  return C.Allocate(Bytes, Alignment);
}

/// Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
/// invoking it directly; see the new operator for more details. This operator
/// is called implicitly by the compiler if a placement new expression using
/// the ASTContext throws in the object constructor.
inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
  C.Deallocate(Ptr);
}

/// This placement form of operator new[] uses the ASTContext's allocator for
/// obtaining memory.
///
/// We intentionally avoid using a nothrow specification here so that the calls
/// to this operator will not perform a null check on the result -- the
/// underlying allocator never returns null pointers.
///
/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
/// @code
/// // Default alignment (8)
/// char *data = new (Context) char[10];
/// // Specific alignment
/// char *data = new (Context, 4) char[10];
/// @endcode
/// Memory allocated through this placement new[] operator does not need to be
/// explicitly freed, as ASTContext will free all of this memory when it gets
/// destroyed. Please note that you cannot use delete on the pointer.
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The ASTContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
///                  allocator supports it).
/// @return The allocated memory. Could be nullptr.
inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
                            size_t Alignment /* = 8 */) {
  return C.Allocate(Bytes, Alignment);
}

/// Placement delete[] companion to the new[] above.
///
/// This operator is just a companion to the new[] above. There is no way of
/// invoking it directly; see the new[] operator for more details. This operator
/// is called implicitly by the compiler if a placement new[] expression using
/// the ASTContext throws in the object constructor.
inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
  C.Deallocate(Ptr);
}

/// Create the representation of a LazyGenerationalUpdatePtr.
template <typename Owner, typename T,
          void (clang::ExternalASTSource::*Update)(Owner)>
typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
    clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
        const clang::ASTContext &Ctx, T Value) {
  // Note, this is implemented here so that ExternalASTSource.h doesn't need to
  // include ASTContext.h. We explicitly instantiate it for all relevant types
  // in ASTContext.cpp.
  if (auto *Source = Ctx.getExternalSource())
    return new (Ctx) LazyData(Source, Value);
  return Value;
}

#endif // LLVM_CLANG_AST_ASTCONTEXT_H
