llvm/clang/lib/AST/Type.cpp

//===- Type.cpp - Type representation and manipulation --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements type-related functionality.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Type.h"
#include "Linkage.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DependenceFlags.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/NonTrivialTypeVisitor.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <optional>
#include <type_traits>

usingnamespaceclang;

bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {}

const IdentifierInfo* QualType::getBaseTypeIdentifier() const {}

bool QualType::mayBeDynamicClass() const {}

bool QualType::mayBeNotDynamicClass() const {}

bool QualType::isConstant(QualType T, const ASTContext &Ctx) {}

std::optional<QualType::NonConstantStorageReason>
QualType::isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
                            bool ExcludeDtor) {}

// C++ [temp.dep.type]p1:
//   A type is dependent if it is...
//     - an array type constructed from any dependent type or whose
//       size is specified by a constant expression that is
//       value-dependent,
ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
                     ArraySizeModifier sm, unsigned tq, const Expr *sz)
    // Note, we need to check for DependentSizedArrayType explicitly here
    // because we use a DependentSizedArrayType with no size expression as the
    // type of a dependent array of unknown bound with a dependent braced
    // initializer:
    //
    //   template<int ...N> int arr[] = {N...};
    :{}

ConstantArrayType *
ConstantArrayType::Create(const ASTContext &Ctx, QualType ET, QualType Can,
                          const llvm::APInt &Sz, const Expr *SzExpr,
                          ArraySizeModifier SzMod, unsigned Qual) {}

unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
                                                 QualType ElementType,
                                               const llvm::APInt &NumElements) {}

unsigned
ConstantArrayType::getNumAddressingBits(const ASTContext &Context) const {}

unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) {}

void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID,
                                const ASTContext &Context, QualType ET,
                                uint64_t ArraySize, const Expr *SizeExpr,
                                ArraySizeModifier SizeMod, unsigned TypeQuals) {}

DependentSizedArrayType::DependentSizedArrayType(QualType et, QualType can,
                                                 Expr *e, ArraySizeModifier sm,
                                                 unsigned tq,
                                                 SourceRange brackets)
    :{}

void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
                                      const ASTContext &Context,
                                      QualType ET,
                                      ArraySizeModifier SizeMod,
                                      unsigned TypeQuals,
                                      Expr *E) {}

DependentVectorType::DependentVectorType(QualType ElementType,
                                         QualType CanonType, Expr *SizeExpr,
                                         SourceLocation Loc, VectorKind VecKind)
    :{}

void DependentVectorType::Profile(llvm::FoldingSetNodeID &ID,
                                  const ASTContext &Context,
                                  QualType ElementType, const Expr *SizeExpr,
                                  VectorKind VecKind) {}

DependentSizedExtVectorType::DependentSizedExtVectorType(QualType ElementType,
                                                         QualType can,
                                                         Expr *SizeExpr,
                                                         SourceLocation loc)
    :{}

void
DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
                                     const ASTContext &Context,
                                     QualType ElementType, Expr *SizeExpr) {}

DependentAddressSpaceType::DependentAddressSpaceType(QualType PointeeType,
                                                     QualType can,
                                                     Expr *AddrSpaceExpr,
                                                     SourceLocation loc)
    :{}

void DependentAddressSpaceType::Profile(llvm::FoldingSetNodeID &ID,
                                        const ASTContext &Context,
                                        QualType PointeeType,
                                        Expr *AddrSpaceExpr) {}

MatrixType::MatrixType(TypeClass tc, QualType matrixType, QualType canonType,
                       const Expr *RowExpr, const Expr *ColumnExpr)
    :{}

ConstantMatrixType::ConstantMatrixType(QualType matrixType, unsigned nRows,
                                       unsigned nColumns, QualType canonType)
    :{}

ConstantMatrixType::ConstantMatrixType(TypeClass tc, QualType matrixType,
                                       unsigned nRows, unsigned nColumns,
                                       QualType canonType)
    :{}

DependentSizedMatrixType::DependentSizedMatrixType(QualType ElementType,
                                                   QualType CanonicalType,
                                                   Expr *RowExpr,
                                                   Expr *ColumnExpr,
                                                   SourceLocation loc)
    :{}

void DependentSizedMatrixType::Profile(llvm::FoldingSetNodeID &ID,
                                       const ASTContext &CTX,
                                       QualType ElementType, Expr *RowExpr,
                                       Expr *ColumnExpr) {}

VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType,
                       VectorKind vecKind)
    :{}

VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
                       QualType canonType, VectorKind vecKind)
    :{}

BitIntType::BitIntType(bool IsUnsigned, unsigned NumBits)
    :{}

DependentBitIntType::DependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr)
    :{}

bool DependentBitIntType::isUnsigned() const {}

clang::Expr *DependentBitIntType::getNumBitsExpr() const {}

void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID,
                                  const ASTContext &Context, bool IsUnsigned,
                                  Expr *NumBitsExpr) {}

bool BoundsAttributedType::referencesFieldDecls() const {}

void CountAttributedType::Profile(llvm::FoldingSetNodeID &ID,
                                  QualType WrappedTy, Expr *CountExpr,
                                  bool CountInBytes, bool OrNull) {}

/// getArrayElementTypeNoTypeQual - If this is an array type, return the
/// element type of the array, potentially with type qualifiers missing.
/// This method should never be used when type qualifiers are meaningful.
const Type *Type::getArrayElementTypeNoTypeQual() const {}

/// getDesugaredType - Return the specified type with any "sugar" removed from
/// the type.  This takes off typedefs, typeof's etc.  If the outer level of
/// the type is already concrete, it returns it unmodified.  This is similar
/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
/// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
/// concrete.
QualType QualType::getDesugaredType(QualType T, const ASTContext &Context) {}

QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
                                                  const ASTContext &Context) {}

// Check that no type class is polymorphic. LLVM style RTTI should be used
// instead. If absolutely needed an exception can still be added here by
// defining the appropriate macro (but please don't do this).
#define TYPE
#include "clang/AST/TypeNodes.inc"

// Check that no type class has a non-trival destructor. Types are
// allocated with the BumpPtrAllocator from ASTContext and therefore
// their destructor is not executed.
#define TYPE
#include "clang/AST/TypeNodes.inc"

QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const {}

SplitQualType QualType::getSplitDesugaredType(QualType T) {}

SplitQualType QualType::getSplitUnqualifiedTypeImpl(QualType type) {}

QualType QualType::IgnoreParens(QualType T) {}

/// This will check for a T (which should be a Type which can act as
/// sugar, such as a TypedefType) by removing any existing sugar until it
/// reaches a T or a non-sugared type.
template<typename T> static const T *getAsSugar(const Type *Cur) {}

template <> const TypedefType *Type::getAs() const {}

template <> const UsingType *Type::getAs() const {}

template <> const TemplateSpecializationType *Type::getAs() const {}

template <> const AttributedType *Type::getAs() const {}

template <> const BoundsAttributedType *Type::getAs() const {}

template <> const CountAttributedType *Type::getAs() const {}

/// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic
/// sugar off the given type.  This should produce an object of the
/// same dynamic type as the canonical type.
const Type *Type::getUnqualifiedDesugaredType() const {}

bool Type::isClassType() const {}

bool Type::isStructureType() const {}

bool Type::isStructureTypeWithFlexibleArrayMember() const {}

bool Type::isObjCBoxableRecordType() const {}

bool Type::isInterfaceType() const {}

bool Type::isStructureOrClassType() const {}

bool Type::isVoidPointerType() const {}

bool Type::isUnionType() const {}

bool Type::isComplexType() const {}

bool Type::isComplexIntegerType() const {}

bool Type::isScopedEnumeralType() const {}

bool Type::isCountAttributedType() const {}

const ComplexType *Type::getAsComplexIntegerType() const {}

QualType Type::getPointeeType() const {}

const RecordType *Type::getAsStructureType() const {}

const RecordType *Type::getAsUnionType() const {}

bool Type::isObjCIdOrObjectKindOfType(const ASTContext &ctx,
                                      const ObjCObjectType *&bound) const {}

bool Type::isObjCClassOrClassKindOfType() const {}

ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D, QualType can,
                                     ArrayRef<ObjCProtocolDecl *> protocols)
    :{}

ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
                               ArrayRef<QualType> typeArgs,
                               ArrayRef<ObjCProtocolDecl *> protocols,
                               bool isKindOf)
    :{}

bool ObjCObjectType::isSpecialized() const {}

ArrayRef<QualType> ObjCObjectType::getTypeArgs() const {}

bool ObjCObjectType::isKindOfType() const {}

QualType ObjCObjectType::stripObjCKindOfTypeAndQuals(
           const ASTContext &ctx) const {}

ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {}

const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals(
                               const ASTContext &ctx) const {}

namespace {

/// Visitor used to perform a simple type transformation that does not change
/// the semantics of the type.
template <typename Derived>
struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {};

struct SubstObjCTypeArgsVisitor
    : public SimpleTransformVisitor<SubstObjCTypeArgsVisitor> {};

struct StripObjCKindOfTypeVisitor
    : public SimpleTransformVisitor<StripObjCKindOfTypeVisitor> {};

} // namespace

bool QualType::UseExcessPrecision(const ASTContext &Ctx) {}

/// Substitute the given type arguments for Objective-C type
/// parameters within the given type, recursively.
QualType QualType::substObjCTypeArgs(ASTContext &ctx,
                                     ArrayRef<QualType> typeArgs,
                                     ObjCSubstitutionContext context) const {}

QualType QualType::substObjCMemberType(QualType objectType,
                                       const DeclContext *dc,
                                       ObjCSubstitutionContext context) const {}

QualType QualType::stripObjCKindOfType(const ASTContext &constCtx) const {}

QualType QualType::getAtomicUnqualifiedType() const {}

std::optional<ArrayRef<QualType>>
Type::getObjCSubstitutions(const DeclContext *dc) const {}

bool Type::acceptsObjCTypeParams() const {}

void ObjCObjectType::computeSuperClassTypeSlow() const {}

const ObjCInterfaceType *ObjCObjectPointerType::getInterfaceType() const {}

QualType ObjCObjectPointerType::getSuperClassType() const {}

const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const {}

bool Type::isObjCQualifiedInterfaceType() const {}

const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {}

const ObjCObjectPointerType *Type::getAsObjCQualifiedClassType() const {}

const ObjCObjectType *Type::getAsObjCInterfaceType() const {}

const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {}

const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const {}

CXXRecordDecl *Type::getAsCXXRecordDecl() const {}

RecordDecl *Type::getAsRecordDecl() const {}

TagDecl *Type::getAsTagDecl() const {}

bool Type::hasAttr(attr::Kind AK) const {}

namespace {

  class GetContainedDeducedTypeVisitor :
    public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> {};

} // namespace

DeducedType *Type::getContainedDeducedType() const {}

bool Type::hasAutoForTrailingReturnType() const {}

bool Type::hasIntegerRepresentation() const {}

/// Determine whether this type is an integral type.
///
/// This routine determines whether the given type is an integral type per
/// C++ [basic.fundamental]p7. Although the C standard does not define the
/// term "integral type", it has a similar term "integer type", and in C++
/// the two terms are equivalent. However, C's "integer type" includes
/// enumeration types, while C++'s "integer type" does not. The \c ASTContext
/// parameter is used to determine whether we should be following the C or
/// C++ rules when determining whether this type is an integral/integer type.
///
/// For cases where C permits "an integer type" and C++ permits "an integral
/// type", use this routine.
///
/// For cases where C permits "an integer type" and C++ permits "an integral
/// or enumeration type", use \c isIntegralOrEnumerationType() instead.
///
/// \param Ctx The context in which this type occurs.
///
/// \returns true if the type is considered an integral type, false otherwise.
bool Type::isIntegralType(const ASTContext &Ctx) const {}

bool Type::isIntegralOrUnscopedEnumerationType() const {}

bool Type::isUnscopedEnumerationType() const {}

bool Type::isCharType() const {}

bool Type::isWideCharType() const {}

bool Type::isChar8Type() const {}

bool Type::isChar16Type() const {}

bool Type::isChar32Type() const {}

/// Determine whether this type is any of the built-in character
/// types.
bool Type::isAnyCharacterType() const {}

/// isSignedIntegerType - Return true if this is an integer type that is
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
/// an enum decl which has a signed representation
bool Type::isSignedIntegerType() const {}

bool Type::isSignedIntegerOrEnumerationType() const {}

bool Type::hasSignedIntegerRepresentation() const {}

/// isUnsignedIntegerType - Return true if this is an integer type that is
/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
/// decl which has an unsigned representation
bool Type::isUnsignedIntegerType() const {}

bool Type::isUnsignedIntegerOrEnumerationType() const {}

bool Type::hasUnsignedIntegerRepresentation() const {}

bool Type::isFloatingType() const {}

bool Type::hasFloatingRepresentation() const {}

bool Type::isRealFloatingType() const {}

bool Type::isRealType() const {}

bool Type::isArithmeticType() const {}

Type::ScalarTypeKind Type::getScalarTypeKind() const {}

/// Determines whether the type is a C++ aggregate type or C
/// aggregate or union type.
///
/// An aggregate type is an array or a class type (struct, union, or
/// class) that has no user-declared constructors, no private or
/// protected non-static data members, no base classes, and no virtual
/// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type
/// subsumes the notion of C aggregates (C99 6.2.5p21) because it also
/// includes union types.
bool Type::isAggregateType() const {}

/// isConstantSizeType - Return true if this is not a variable sized type,
/// according to the rules of C99 6.7.5p3.  It is not legal to call this on
/// incomplete types or dependent types.
bool Type::isConstantSizeType() const {}

/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
/// - a type that can describe objects, but which lacks information needed to
/// determine its size.
bool Type::isIncompleteType(NamedDecl **Def) const {}

bool Type::isSizelessBuiltinType() const {}

bool Type::isWebAssemblyExternrefType() const {}

bool Type::isWebAssemblyTableType() const {}

bool Type::isSizelessType() const {}

bool Type::isSizelessVectorType() const {}

bool Type::isSVESizelessBuiltinType() const {}

bool Type::isRVVSizelessBuiltinType() const {}

bool Type::isSveVLSBuiltinType() const {}

QualType Type::getSizelessVectorEltType(const ASTContext &Ctx) const {}

QualType Type::getSveEltType(const ASTContext &Ctx) const {}

bool Type::isRVVVLSBuiltinType() const {}

QualType Type::getRVVEltType(const ASTContext &Ctx) const {}

bool QualType::isPODType(const ASTContext &Context) const {}

bool QualType::isCXX98PODType(const ASTContext &Context) const {}

bool QualType::isTrivialType(const ASTContext &Context) const {}

static bool isTriviallyCopyableTypeImpl(const QualType &type,
                                        const ASTContext &Context,
                                        bool IsCopyConstructible) {}

bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {}

// FIXME: each call will trigger a full computation, cache the result.
bool QualType::isBitwiseCloneableType(const ASTContext &Context) const {}

bool QualType::isTriviallyCopyConstructibleType(
    const ASTContext &Context) const {}

bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {}

bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {}

bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD) {}

bool QualType::hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD) {}

bool QualType::hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD) {}

bool QualType::isWebAssemblyReferenceType() const {}

bool QualType::isWebAssemblyExternrefType() const {}

bool QualType::isWebAssemblyFuncrefType() const {}

QualType::PrimitiveDefaultInitializeKind
QualType::isNonTrivialToPrimitiveDefaultInitialize() const {}

QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const {}

QualType::PrimitiveCopyKind
QualType::isNonTrivialToPrimitiveDestructiveMove() const {}

bool Type::isLiteralType(const ASTContext &Ctx) const {}

bool Type::isStructuralType() const {}

bool Type::isStandardLayoutType() const {}

// This is effectively the intersection of isTrivialType and
// isStandardLayoutType. We implement it directly to avoid redundant
// conversions from a type to a CXXRecordDecl.
bool QualType::isCXX11PODType(const ASTContext &Context) const {}

bool Type::isNothrowT() const {}

bool Type::isAlignValT() const {}

bool Type::isStdByteType() const {}

bool Type::isSpecifierType() const {}

ElaboratedTypeKeyword
TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {}

TagTypeKind
TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {}

ElaboratedTypeKeyword
TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {}

TagTypeKind
TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {}

bool
TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {}

StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {}

DependentTemplateSpecializationType::DependentTemplateSpecializationType(
    ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
    const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args, QualType Canon)
    :{}

void
DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
                                             const ASTContext &Context,
                                             ElaboratedTypeKeyword Keyword,
                                             NestedNameSpecifier *Qualifier,
                                             const IdentifierInfo *Name,
                                             ArrayRef<TemplateArgument> Args) {}

bool Type::isElaboratedTypeSpecifier() const {}

const char *Type::getTypeClassName() const {}

StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {}

QualType QualType::getNonPackExpansionType() const {}

QualType QualType::getNonLValueExprType(const ASTContext &Context) const {}

StringRef FunctionType::getNameForCallConv(CallingConv CC) {}

void FunctionProtoType::ExceptionSpecInfo::instantiate() {}

FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
                                     QualType canonical,
                                     const ExtProtoInfo &epi)
    :{}

bool FunctionProtoType::hasDependentExceptionSpec() const {}

bool FunctionProtoType::hasInstantiationDependentExceptionSpec() const {}

CanThrowResult FunctionProtoType::canThrow() const {}

bool FunctionProtoType::isTemplateVariadic() const {}

void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
                                const QualType *ArgTys, unsigned NumParams,
                                const ExtProtoInfo &epi,
                                const ASTContext &Context, bool Canonical) {}

void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
                                const ASTContext &Ctx) {}

TypeCoupledDeclRefInfo::TypeCoupledDeclRefInfo(ValueDecl *D, bool Deref)
    :{}

bool TypeCoupledDeclRefInfo::isDeref() const {}
ValueDecl *TypeCoupledDeclRefInfo::getDecl() const {}
unsigned TypeCoupledDeclRefInfo::getInt() const {}
void *TypeCoupledDeclRefInfo::getOpaqueValue() const {}
bool TypeCoupledDeclRefInfo::operator==(
    const TypeCoupledDeclRefInfo &Other) const {}
void TypeCoupledDeclRefInfo::setFromOpaqueValue(void *V) {}

BoundsAttributedType::BoundsAttributedType(TypeClass TC, QualType Wrapped,
                                           QualType Canon)
    :{}

CountAttributedType::CountAttributedType(
    QualType Wrapped, QualType Canon, Expr *CountExpr, bool CountInBytes,
    bool OrNull, ArrayRef<TypeCoupledDeclRefInfo> CoupledDecls)
    :{}

TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D,
                         QualType Underlying, QualType can)
    :{}

QualType TypedefType::desugar() const {}

UsingType::UsingType(const UsingShadowDecl *Found, QualType Underlying,
                     QualType Canon)
    :{}

QualType UsingType::getUnderlyingType() const {}

QualType MacroQualifiedType::desugar() const {}

QualType MacroQualifiedType::getModifiedType() const {}

TypeOfExprType::TypeOfExprType(const ASTContext &Context, Expr *E,
                               TypeOfKind Kind, QualType Can)
    :{}

bool TypeOfExprType::isSugared() const {}

QualType TypeOfExprType::desugar() const {}

void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
                                      const ASTContext &Context, Expr *E,
                                      bool IsUnqual) {}

TypeOfType::TypeOfType(const ASTContext &Context, QualType T, QualType Can,
                       TypeOfKind Kind)
    :{}

QualType TypeOfType::desugar() const {}

DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
    // C++11 [temp.type]p2: "If an expression e involves a template parameter,
    // decltype(e) denotes a unique dependent type." Hence a decltype type is
    // type-dependent even if its expression is only instantiation-dependent.
    :{}

bool DecltypeType::isSugared() const {}

QualType DecltypeType::desugar() const {}

DependentDecltypeType::DependentDecltypeType(Expr *E, QualType UnderlyingType)
    :{}

void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
                                    const ASTContext &Context, Expr *E) {}

PackIndexingType::PackIndexingType(const ASTContext &Context,
                                   QualType Canonical, QualType Pattern,
                                   Expr *IndexExpr, bool ExpandsToEmptyPack,
                                   ArrayRef<QualType> Expansions)
    :{}

std::optional<unsigned> PackIndexingType::getSelectedIndex() const {}

TypeDependence
PackIndexingType::computeDependence(QualType Pattern, Expr *IndexExpr,
                                    ArrayRef<QualType> Expansions) {}

void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID,
                               const ASTContext &Context, QualType Pattern,
                               Expr *E, bool ExpandsToEmptyPack) {}

UnaryTransformType::UnaryTransformType(QualType BaseType,
                                       QualType UnderlyingType, UTTKind UKind,
                                       QualType CanonicalType)
    :{}

DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C,
                                                         QualType BaseType,
                                                         UTTKind UKind)
     :{}

TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
    :{}

static TagDecl *getInterestingTagDecl(TagDecl *decl) {}

TagDecl *TagType::getDecl() const {}

bool TagType::isBeingDefined() const {}

bool RecordType::hasConstFields() const {}

bool AttributedType::isQualifier() const {}

bool AttributedType::isMSTypeSpec() const {}

bool AttributedType::isWebAssemblyFuncrefSpec() const {}

bool AttributedType::isCallingConv() const {}

CXXRecordDecl *InjectedClassNameType::getDecl() const {}

IdentifierInfo *TemplateTypeParmType::getIdentifier() const {}

static const TemplateTypeParmDecl *getReplacedParameter(Decl *D,
                                                        unsigned Index) {}

SubstTemplateTypeParmType::SubstTemplateTypeParmType(
    QualType Replacement, Decl *AssociatedDecl, unsigned Index,
    std::optional<unsigned> PackIndex)
    :{}

const TemplateTypeParmDecl *
SubstTemplateTypeParmType::getReplacedParameter() const {}

SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType(
    QualType Canon, Decl *AssociatedDecl, unsigned Index, bool Final,
    const TemplateArgument &ArgPack)
    :{}

Decl *SubstTemplateTypeParmPackType::getAssociatedDecl() const {}

bool SubstTemplateTypeParmPackType::getFinal() const {}

const TemplateTypeParmDecl *
SubstTemplateTypeParmPackType::getReplacedParameter() const {}

IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const {}

TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {}

void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {}

void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
                                            const Decl *AssociatedDecl,
                                            unsigned Index, bool Final,
                                            const TemplateArgument &ArgPack) {}

bool TemplateSpecializationType::anyDependentTemplateArguments(
    const TemplateArgumentListInfo &Args, ArrayRef<TemplateArgument> Converted) {}

bool TemplateSpecializationType::anyDependentTemplateArguments(
    ArrayRef<TemplateArgumentLoc> Args, ArrayRef<TemplateArgument> Converted) {}

bool TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
      ArrayRef<TemplateArgumentLoc> Args) {}

TemplateSpecializationType::TemplateSpecializationType(
    TemplateName T, ArrayRef<TemplateArgument> Args, QualType Canon,
    QualType AliasedType)
    :{}

QualType TemplateSpecializationType::getAliasedType() const {}

void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
                                         const ASTContext &Ctx) {}

void
TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
                                    TemplateName T,
                                    ArrayRef<TemplateArgument> Args,
                                    const ASTContext &Context) {}

QualType
QualifierCollector::apply(const ASTContext &Context, QualType QT) const {}

QualType
QualifierCollector::apply(const ASTContext &Context, const Type *T) const {}

void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID,
                                 QualType BaseType,
                                 ArrayRef<QualType> typeArgs,
                                 ArrayRef<ObjCProtocolDecl *> protocols,
                                 bool isKindOf) {}

void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {}

void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID,
                                const ObjCTypeParamDecl *OTPDecl,
                                QualType CanonicalType,
                                ArrayRef<ObjCProtocolDecl *> protocols) {}

void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID) {}

namespace {

/// The cached properties of a type.
class CachedProperties {};

} // namespace

static CachedProperties computeCachedProperties(const Type *T);

namespace clang {

/// The type-property cache.  This is templated so as to be
/// instantiated at an internal type to prevent unnecessary symbol
/// leakage.
template <class Private> class TypePropertyCache {};

} // namespace clang

// Instantiate the friend template at a private class.  In a
// reasonable implementation, these symbols will be internal.
// It is terrible that this is the best way to accomplish this.
namespace {

class Private {};

} // namespace

Cache;

static CachedProperties computeCachedProperties(const Type *T) {}

/// Determine the linkage of this type.
Linkage Type::getLinkage() const {}

bool Type::hasUnnamedOrLocalType() const {}

LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {}

bool Type::isLinkageValid() const {}

LinkageInfo LinkageComputer::getTypeLinkageAndVisibility(const Type *T) {}

LinkageInfo Type::getLinkageAndVisibility() const {}

std::optional<NullabilityKind> Type::getNullability() const {}

bool Type::canHaveNullability(bool ResultIfUnknown) const {}

std::optional<NullabilityKind> AttributedType::getImmediateNullability() const {}

std::optional<NullabilityKind>
AttributedType::stripOuterNullability(QualType &T) {}

bool Type::isBlockCompatibleObjCPointerType(ASTContext &ctx) const {}

Qualifiers::ObjCLifetime Type::getObjCARCImplicitLifetime() const {}

bool Type::isObjCARCImplicitlyUnretainedType() const {}

bool Type::isObjCNSObjectType() const {}

bool Type::isObjCIndependentClassType() const {}

bool Type::isObjCRetainableType() const {}

bool Type::isObjCIndirectLifetimeType() const {}

/// Returns true if objects of this type have lifetime semantics under
/// ARC.
bool Type::isObjCLifetimeType() const {}

/// Determine whether the given type T is a "bridgable" Objective-C type,
/// which is either an Objective-C object pointer type or an
bool Type::isObjCARCBridgableType() const {}

/// Determine whether the given type T is a "bridgeable" C type.
bool Type::isCARCBridgableType() const {}

/// Check if the specified type is the CUDA device builtin surface type.
bool Type::isCUDADeviceBuiltinSurfaceType() const {}

/// Check if the specified type is the CUDA device builtin texture type.
bool Type::isCUDADeviceBuiltinTextureType() const {}

bool Type::hasSizedVLAType() const {}

QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {}

CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {}

void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
                                    llvm::APSInt Val, unsigned Scale) {}

AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
                   TypeDependence ExtraDependence, QualType Canon,
                   ConceptDecl *TypeConstraintConcept,
                   ArrayRef<TemplateArgument> TypeConstraintArgs)
    :{}

void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
                      QualType Deduced, AutoTypeKeyword Keyword,
                      bool IsDependent, ConceptDecl *CD,
                      ArrayRef<TemplateArgument> Arguments) {}

void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {}

FunctionEffect::Kind FunctionEffect::oppositeKind() const {}

StringRef FunctionEffect::name() const {}

std::optional<FunctionEffect> FunctionEffect::effectProhibitingInference(
    const Decl &Callee, FunctionEffectKindSet CalleeFX) const {}

bool FunctionEffect::shouldDiagnoseFunctionCall(
    bool Direct, FunctionEffectKindSet CalleeFX) const {}

// =====

bool FunctionEffectSet::insert(const FunctionEffectWithCondition &NewEC,
                               Conflicts &Errs) {}

bool FunctionEffectSet::insert(const FunctionEffectsRef &Set, Conflicts &Errs) {}

FunctionEffectSet FunctionEffectSet::getIntersection(FunctionEffectsRef LHS,
                                                     FunctionEffectsRef RHS) {}

FunctionEffectSet FunctionEffectSet::getUnion(FunctionEffectsRef LHS,
                                              FunctionEffectsRef RHS,
                                              Conflicts &Errs) {}

namespace clang {

raw_ostream &operator<<(raw_ostream &OS,
                        const FunctionEffectWithCondition &CFE) {}

} // namespace clang

LLVM_DUMP_METHOD void FunctionEffectsRef::dump(llvm::raw_ostream &OS) const {}

LLVM_DUMP_METHOD void FunctionEffectSet::dump(llvm::raw_ostream &OS) const {}

LLVM_DUMP_METHOD void FunctionEffectKindSet::dump(llvm::raw_ostream &OS) const {}

FunctionEffectsRef
FunctionEffectsRef::create(ArrayRef<FunctionEffect> FX,
                           ArrayRef<EffectConditionExpr> Conds) {}

std::string FunctionEffectWithCondition::description() const {}