//===- 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 DynTypedNodeList;
class Expr;
enum class FloatModeKind;
class GlobalDecl;
class MangleContext;
class MangleNumberingContext;
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 StoredDeclsMap;
class TargetAttr;
class TargetInfo;
class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
class TypeConstraint;
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{GeneralTypesLog2InitSize};
  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{GeneralTypesLog2InitSize};
  mutable llvm::FoldingSet<UsingType> UsingTypes;
  mutable llvm::FoldingSet<TypedefType> TypedefTypes;
  mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes{
      GeneralTypesLog2InitSize};
  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;
  mutable llvm::FoldingSet<AttributedType> AttributedTypes;
  mutable llvm::FoldingSet<PipeType> PipeTypes;
  mutable llvm::FoldingSet<BitIntType> BitIntTypes;
  mutable llvm::FoldingSet<DependentBitIntType> DependentBitIntTypes;
  llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;

  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 UnnamedGlobalConstantDecl.
  mutable llvm::FoldingSet<UnnamedGlobalConstantDecl>
      UnnamedGlobalConstantDecls;

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

  /// For module code-gen cases, this is the top-level module we are building.
  Module *TopLevelModule = nullptr;

  static constexpr unsigned ConstantArrayTypesLog2InitSize = 8;
  static constexpr unsigned GeneralTypesLog2InitSize = 9;
  static constexpr unsigned FunctionProtoTypesLog2InitSize = 12;

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

  struct CUDAConstantEvalContext {
    /// Do not allow wrong-sided variables in constant expressions.
    bool NoWrongSidedVars = false;
  } CUDAConstantEvalCtx;
  struct CUDAConstantEvalContextRAII {
    ASTContext &Ctx;
    CUDAConstantEvalContext SavedCtx;
    CUDAConstantEvalContextRAII(ASTContext &Ctx_, bool NoWrongSidedVars)
        : Ctx(Ctx_), SavedCtx(Ctx_.CUDAConstantEvalCtx) {
      Ctx_.CUDAConstantEvalCtx.NoWrongSidedVars = NoWrongSidedVars;
    }
    ~CUDAConstantEvalContextRAII() { Ctx.CUDAConstantEvalCtx = SavedCtx; }
  };

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

  /// Set the (C++20) module we are building.
  void setModuleForCodeGen(Module *M) { TopLevelModule = M; }

  /// Get module under construction, nullptr if this is not a C++20 module.
  Module *getModuleForCodeGen() const { return TopLevelModule; }

  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;

  /// Keep track of CUDA/HIP external kernels or device variables ODR-used by
  /// host code.
  llvm::DenseSet<const ValueDecl *> CUDAExternalDeviceDeclODRUsedByHost;

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

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

  /// 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 a specified decay from the original
  /// type to the decayed type.
  QualType getDecayedType(QualType Orig, QualType Decayed) const;

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

  QualType getUsingType(const UsingShadowDecl *Found,
                        QualType Underlying) const;

  /// 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
  getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;

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

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

  QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
                                   QualType Wrapped);

  QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
                                        QualType Replacement,
                                        Optional<unsigned> PackIndex) 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,
                                         ArrayRef<TemplateArgumentLoc> 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;

  /// C2x feature and GCC extension.
  QualType getTypeOfExprType(Expr *E, TypeOfKind Kind) const;
  QualType getTypeOfType(QualType QT, TypeOfKind Kind) 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,
                                        TemplateName 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);
  }

  /// Determine whether the given expressions \p X and \p Y are equivalent.
  bool hasSameExpr(const Expr *X, const Expr *Y) const;

  /// 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.has_value() == SuperTnullability.has_value()) {
      // 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(const TemplateName &Name) const;

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

  /// Determine whether two Friend functions are different because constraints
  /// that refer to an enclosing template, according to [temp.friend] p9.
  bool FriendsDifferByConstraints(const FunctionDecl *X,
                                  const FunctionDecl *Y) const;

  /// Determine whether the two declarations refer to the same entity.
  bool isSameEntity(const NamedDecl *X, const NamedDecl *Y) const;

  /// Determine whether two template parameter lists are similar enough
  /// that they may be used in declarations of the same template.
  bool isSameTemplateParameterList(const TemplateParameterList *X,
                                   const TemplateParameterList *Y) const;

  /// Determine whether two template parameters are similar enough
  /// that they may be used in declarations of the same template.
  bool isSameTemplateParameter(const NamedDecl *X, const NamedDecl *Y) const;

  /// Determine whether two 'requires' expressions are similar enough that they
  /// may be used in re-declarations.
  ///
  /// Use of 'requires' isn't mandatory, works with constraints expressed in
  /// other ways too.
  bool isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const;

  /// Determine whether two type contraint are similar enough that they could
  /// used in declarations of the same template.
  bool isSameTypeConstraint(const TypeConstraint *XTC,
                            const TypeConstraint *YTC) const;

  /// Determine whether two default template arguments are similar enough
  /// that they may be used in declarations of the same template.
  bool isSameDefaultTemplateArgument(const NamedDecl *X,
                                     const NamedDecl *Y) const;

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

  /// Return number of elements initialized in an ArrayInitLoopExpr.
  uint64_t
  getArrayInitLoopExprElementCount(const ArrayInitLoopExpr *AILE) 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;

  unsigned getTargetAddressSpace(QualType T) const;

  unsigned getTargetAddressSpace(Qualifiers Q) const;

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

  // Merges two exception specifications, such that the resulting
  // exception spec is the union of both. For example, if either
  // of them can throw something, the result can throw it as well.
  FunctionProtoType::ExceptionSpecInfo
  mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,
                      FunctionProtoType::ExceptionSpecInfo ESI2,
                      SmallVectorImpl<QualType> &ExceptionTypeStorage,
                      bool AcceptDependent);

  // For two "same" types, return a type which has
  // the common sugar between them. If Unqualified is true,
  // both types need only be the same unqualified type.
  // The result will drop the qualifiers which do not occur
  // in both types.
  QualType getCommonSugaredType(QualType X, QualType Y,
                                bool Unqualified = false);

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 {
    if (const auto *ET = dyn_cast<ElaboratedType>(T))
      T = ET->getNamedType();
    return T == getObjCIdType();
  }

  bool isObjCClassType(QualType T) const {
    if (const auto *ET = dyn_cast<ElaboratedType>(T))
      T = ET->getNamedType();
    return T == getObjCClassType();
  }

  bool isObjCSelType(QualType T) const {
    if (const auto *ET = dyn_cast<ElaboratedType>(T))
      T = ET->getNamedType();
    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,
                             bool ForAuxTarget = false) 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 a declaration for a uniquified anonymous global constant
  /// corresponding to a given APValue.
  UnnamedGlobalConstantDecl *
  getUnnamedGlobalConstantDecl(QualType Ty, const APValue &Value) 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

    [[nodiscard]] ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
      return Bits & Mask.Bits;
    }

    [[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 or CUDA/HIP kernel may be externalized.
  bool mayExternalize(const Decl *D) const;

  /// Whether a C++ static variable or CUDA/HIP kernel should be externalized.
  bool shouldExternalize(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
