42#include "llvm/ADT/APInt.h"
43#include "llvm/ADT/APSInt.h"
44#include "llvm/ADT/ArrayRef.h"
45#include "llvm/ADT/FoldingSet.h"
46#include "llvm/ADT/SmallVector.h"
47#include "llvm/Support/Casting.h"
48#include "llvm/Support/ErrorHandling.h"
49#include "llvm/Support/MathExtras.h"
50#include "llvm/TargetParser/RISCVTargetParser.h"
61 return (*
this !=
Other) &&
88 getElementType().getBaseTypeIdentifier();
106 if (
T.isConstQualified())
110 return AT->getElementType().isConstant(Ctx);
115std::optional<QualType::NonConstantStorageReason>
118 if (!
isConstant(Ctx) && !(*this)->isReferenceType())
126 if (
Record->hasMutableFields())
128 if (!
Record->hasTrivialDestructor() && !ExcludeDtor)
148 et->getDependence() |
154 (tc == DependentSizedArray
164 const llvm::APInt &Sz,
const Expr *SzExpr,
166 bool NeedsExternalSize = SzExpr !=
nullptr || Sz.ugt(0x0FFFFFFFFFFFFFFF) ||
167 Sz.getBitWidth() > 0xFF;
168 if (!NeedsExternalSize)
170 ET, Can, Sz.getBitWidth(), Sz.getZExtValue(), SzMod, Qual);
172 auto *SzPtr =
new (Ctx,
alignof(ConstantArrayType::ExternalSize))
173 ConstantArrayType::ExternalSize(Sz, SzExpr);
180 const llvm::APInt &NumElements) {
189 if (llvm::isPowerOf2_64(ElementSize)) {
190 return NumElements.getActiveBits() + llvm::Log2_64(ElementSize);
195 if ((ElementSize >> 32) == 0 && NumElements.getBitWidth() <= 64 &&
196 (NumElements.getZExtValue() >> 32) == 0) {
197 uint64_t TotalSize = NumElements.getZExtValue() * ElementSize;
198 return llvm::bit_width(TotalSize);
202 llvm::APSInt SizeExtended(NumElements,
true);
204 SizeExtended = SizeExtended.extend(std::max(SizeTypeBits,
205 SizeExtended.getBitWidth()) * 2);
207 llvm::APSInt TotalSize(llvm::APInt(SizeExtended.getBitWidth(), ElementSize));
208 TotalSize *= SizeExtended;
210 return TotalSize.getActiveBits();
232 uint64_t ArraySize,
const Expr *SizeExpr,
235 ID.AddInteger(ArraySize);
236 ID.AddInteger(llvm::to_underlying(SizeMod));
237 ID.AddInteger(TypeQuals);
238 ID.AddBoolean(SizeExpr !=
nullptr);
240 SizeExpr->
Profile(ID, Context,
true);
247 :
ArrayType(DependentSizedArray, et, can, sm, tq, e), SizeExpr((
Stmt *)e),
248 Brackets(brackets) {}
257 ID.AddInteger(llvm::to_underlying(SizeMod));
258 ID.AddInteger(TypeQuals);
263DependentVectorType::DependentVectorType(
QualType ElementType,
266 :
Type(DependentVector, CanonType,
268 ElementType->getDependence() |
271 ElementType(ElementType), SizeExpr(SizeExpr),
Loc(
Loc) {
280 ID.AddInteger(llvm::to_underlying(VecKind));
281 SizeExpr->
Profile(ID, Context,
true);
284DependentSizedExtVectorType::DependentSizedExtVectorType(
QualType ElementType,
288 :
Type(DependentSizedExtVector, can,
290 ElementType->getDependence() |
293 SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {}
300 SizeExpr->
Profile(ID, Context,
true);
303DependentAddressSpaceType::DependentAddressSpaceType(
QualType PointeeType,
307 :
Type(DependentAddressSpace, can,
309 PointeeType->getDependence() |
312 AddrSpaceExpr(AddrSpaceExpr), PointeeType(PointeeType), loc(loc) {}
317 Expr *AddrSpaceExpr) {
319 AddrSpaceExpr->
Profile(ID, Context,
true);
323 const Expr *RowExpr,
const Expr *ColumnExpr)
324 :
Type(tc, canonType,
325 (RowExpr ? (matrixType->getDependence() |
TypeDependence::Dependent |
327 (matrixType->isVariablyModifiedType()
330 (matrixType->containsUnexpandedParameterPack() ||
332 RowExpr->containsUnexpandedParameterPack()) ||
334 ColumnExpr->containsUnexpandedParameterPack())
337 : matrixType->getDependence())),
338 ElementType(matrixType) {}
341 unsigned nColumns,
QualType canonType)
346 unsigned nRows,
unsigned nColumns,
348 :
MatrixType(tc, matrixType, canonType), NumRows(nRows),
349 NumColumns(nColumns) {}
351DependentSizedMatrixType::DependentSizedMatrixType(
QualType ElementType,
356 :
MatrixType(DependentSizedMatrix, ElementType, CanonicalType, RowExpr,
358 RowExpr(RowExpr), ColumnExpr(ColumnExpr), loc(loc) {}
365 RowExpr->
Profile(ID, CTX,
true);
366 ColumnExpr->
Profile(ID, CTX,
true);
375 :
Type(tc, canonType, vecType->getDependence()), ElementType(vecType) {
387 ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
390 return ExprAndUnsigned.getInt();
394 return ExprAndUnsigned.getPointer();
400 ID.AddBoolean(IsUnsigned);
401 NumBitsExpr->
Profile(ID, Context,
true);
407 return isa<FieldDecl>(Info.
getDecl());
413 bool CountInBytes,
bool OrNull) {
415 ID.AddBoolean(CountInBytes);
416 ID.AddBoolean(OrNull);
421 ID.AddPointer(CountExpr);
429 if (
const auto *ATy = dyn_cast<ArrayType>(
this))
430 return ATy->getElementType().getTypePtr();
433 if (!isa<ArrayType>(CanonicalType))
439 ->getElementType().getTypePtr();
463#define TYPE(CLASS, BASE) \
464 static_assert(!std::is_polymorphic<CLASS##Type>::value, \
465 #CLASS "Type should not be polymorphic!");
466#include "clang/AST/TypeNodes.inc"
471#define TYPE(CLASS, BASE) \
472 static_assert(std::is_trivially_destructible<CLASS##Type>::value, \
473 #CLASS "Type should be trivially destructible!");
474#include "clang/AST/TypeNodes.inc"
478#define ABSTRACT_TYPE(Class, Parent)
479#define TYPE(Class, Parent) \
480 case Type::Class: { \
481 const auto *ty = cast<Class##Type>(this); \
482 if (!ty->isSugared()) return QualType(ty, 0); \
483 return ty->desugar(); \
485#include "clang/AST/TypeNodes.inc"
487 llvm_unreachable(
"bad type kind!");
497#define ABSTRACT_TYPE(Class, Parent)
498#define TYPE(Class, Parent) \
499 case Type::Class: { \
500 const auto *Ty = cast<Class##Type>(CurTy); \
501 if (!Ty->isSugared()) \
502 return SplitQualType(Ty, Qs); \
503 Cur = Ty->desugar(); \
506#include "clang/AST/TypeNodes.inc"
526#define ABSTRACT_TYPE(Class, Parent)
527#define TYPE(Class, Parent) \
528 case Type::Class: { \
529 const auto *ty = cast<Class##Type>(split.Ty); \
530 if (!ty->isSugared()) goto done; \
531 next = ty->desugar(); \
534#include "clang/AST/TypeNodes.inc"
553 T = PT->getInnerType();
562 if (
const auto *Sugar = dyn_cast<T>(Cur))
565#define ABSTRACT_TYPE(Class, Parent)
566#define TYPE(Class, Parent) \
567 case Type::Class: { \
568 const auto *Ty = cast<Class##Type>(Cur); \
569 if (!Ty->isSugared()) return 0; \
570 Cur = Ty->desugar().getTypePtr(); \
573#include "clang/AST/TypeNodes.inc"
579 return getAsSugar<TypedefType>(
this);
583 return getAsSugar<UsingType>(
this);
587 return getAsSugar<TemplateSpecializationType>(
this);
591 return getAsSugar<AttributedType>(
this);
595 return getAsSugar<BoundsAttributedType>(
this);
599 return getAsSugar<CountAttributedType>(
this);
606 const Type *Cur =
this;
610#define ABSTRACT_TYPE(Class, Parent)
611#define TYPE(Class, Parent) \
613 const auto *Ty = cast<Class##Type>(Cur); \
614 if (!Ty->isSugared()) return Cur; \
615 Cur = Ty->desugar().getTypePtr(); \
618#include "clang/AST/TypeNodes.inc"
624 if (
const auto *RT = getAs<RecordType>())
625 return RT->getDecl()->isClass();
630 if (
const auto *RT = getAs<RecordType>())
631 return RT->getDecl()->isStruct();
636 if (
const auto *RT = getAs<RecordType>())
637 return RT->getDecl()->hasAttr<ObjCBoxableAttr>();
642 if (
const auto *RT = getAs<RecordType>())
643 return RT->getDecl()->isInterface();
648 if (
const auto *RT = getAs<RecordType>()) {
656 if (
const auto *PT = getAs<PointerType>())
657 return PT->getPointeeType()->isVoidType();
662 if (
const auto *RT = getAs<RecordType>())
663 return RT->getDecl()->isUnion();
668 if (
const auto *CT = dyn_cast<ComplexType>(CanonicalType))
669 return CT->getElementType()->isFloatingType();
679 if (
const auto *ET = getAs<EnumType>())
680 return ET->getDecl()->isScoped();
685 return getAs<CountAttributedType>();
689 if (
const auto *
Complex = getAs<ComplexType>())
690 if (
Complex->getElementType()->isIntegerType())
696 if (
const auto *PT = getAs<PointerType>())
698 if (
const auto *OPT = getAs<ObjCObjectPointerType>())
700 if (
const auto *BPT = getAs<BlockPointerType>())
702 if (
const auto *RT = getAs<ReferenceType>())
704 if (
const auto *MPT = getAs<MemberPointerType>())
706 if (
const auto *DT = getAs<DecayedType>())
713 if (
const auto *RT = dyn_cast<RecordType>(
this)) {
714 if (RT->getDecl()->isStruct())
719 if (
const auto *RT = dyn_cast<RecordType>(CanonicalType)) {
720 if (!RT->getDecl()->isStruct())
732 if (
const auto *RT = dyn_cast<RecordType>(
this)) {
733 if (RT->getDecl()->isUnion())
738 if (
const auto *RT = dyn_cast<RecordType>(CanonicalType)) {
739 if (!RT->getDecl()->isUnion())
754 const auto *OPT = getAs<ObjCObjectPointerType>();
759 if (OPT->isObjCIdType())
763 if (!OPT->isKindOfType())
767 if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType())
777 const auto *OPT = getAs<ObjCObjectPointerType>();
782 if (OPT->isObjCClassType())
786 if (!OPT->isKindOfType())
790 return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType();
804 :
Type(ObjCObject, Canonical,
Base->getDependence()), BaseType(
Base) {
809 "bitfield overflow in type argument count");
810 if (!typeArgs.empty())
811 memcpy(getTypeArgStorage(), typeArgs.data(),
812 typeArgs.size() *
sizeof(
QualType));
814 for (
auto typeArg : typeArgs) {
815 addDependence(typeArg->getDependence() & ~TypeDependence::VariablyModified);
828 if (
const auto objcObject =
getBaseType()->getAs<ObjCObjectType>()) {
830 if (isa<ObjCInterfaceType>(objcObject))
833 return objcObject->isSpecialized();
846 if (
const auto objcObject =
getBaseType()->getAs<ObjCObjectType>()) {
848 if (isa<ObjCInterfaceType>(objcObject))
851 return objcObject->getTypeArgs();
863 if (
const auto objcObject =
getBaseType()->getAs<ObjCObjectType>()) {
865 if (isa<ObjCInterfaceType>(objcObject))
868 return objcObject->isKindOfType();
884 baseType = baseObj->stripObjCKindOfTypeAndQuals(ctx);
887 splitBaseType.
Quals),
913template <
typename Derived>
914struct SimpleTransformVisitor :
public TypeVisitor<Derived, QualType> {
922 QualType result =
static_cast<Derived *
>(
this)->Visit(splitType.
Ty);
932 explicit SimpleTransformVisitor(
ASTContext &ctx) : Ctx(ctx) {}
936#define TYPE(Class, Base)
937#define DEPENDENT_TYPE(Class, Base) \
938 QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
939#include "clang/AST/TypeNodes.inc"
941#define TRIVIAL_TYPE_CLASS(Class) \
942 QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
943#define SUGARED_TYPE_CLASS(Class) \
944 QualType Visit##Class##Type(const Class##Type *T) { \
945 if (!T->isSugared()) \
946 return QualType(T, 0); \
947 QualType desugaredType = recurse(T->desugar()); \
948 if (desugaredType.isNull()) \
950 if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \
951 return QualType(T, 0); \
952 return desugaredType; \
958 QualType elementType = recurse(
T->getElementType());
962 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
991 QualType pointeeType = recurse(
T->getPointeeTypeAsWritten());
996 ==
T->getPointeeTypeAsWritten().getAsOpaquePtr())
1003 QualType pointeeType = recurse(
T->getPointeeTypeAsWritten());
1004 if (pointeeType.
isNull())
1008 ==
T->getPointeeTypeAsWritten().getAsOpaquePtr())
1016 if (pointeeType.
isNull())
1026 QualType elementType = recurse(
T->getElementType());
1027 if (elementType.
isNull())
1030 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
1034 T->getSizeModifier(),
1035 T->getIndexTypeCVRQualifiers());
1039 QualType elementType = recurse(
T->getElementType());
1040 if (elementType.
isNull())
1043 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
1047 T->getSizeModifier(),
1048 T->getIndexTypeCVRQualifiers(),
1049 T->getBracketsRange());
1053 QualType elementType = recurse(
T->getElementType());
1054 if (elementType.
isNull())
1057 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
1061 T->getIndexTypeCVRQualifiers());
1065 QualType elementType = recurse(
T->getElementType());
1066 if (elementType.
isNull())
1069 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
1073 T->getVectorKind());
1077 QualType elementType = recurse(
T->getElementType());
1078 if (elementType.
isNull())
1081 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
1088 QualType elementType = recurse(
T->getElementType());
1089 if (elementType.
isNull())
1091 if (elementType.
getAsOpaquePtr() ==
T->getElementType().getAsOpaquePtr())
1095 T->getNumColumns());
1116 bool paramChanged =
false;
1118 QualType newParamType = recurse(paramType);
1119 if (newParamType.
isNull())
1123 paramChanged =
true;
1125 paramTypes.push_back(newParamType);
1130 bool exceptionChanged =
false;
1134 QualType newExceptionType = recurse(exceptionType);
1135 if (newExceptionType.
isNull())
1138 if (newExceptionType.
getAsOpaquePtr() != exceptionType.getAsOpaquePtr())
1139 exceptionChanged =
true;
1141 exceptionTypes.push_back(newExceptionType);
1144 if (exceptionChanged) {
1151 !paramChanged && !exceptionChanged)
1158 QualType innerType = recurse(
T->getInnerType());
1173 QualType originalType = recurse(
T->getOriginalType());
1174 if (originalType.
isNull())
1177 QualType adjustedType = recurse(
T->getAdjustedType());
1178 if (adjustedType.
isNull())
1182 ==
T->getOriginalType().getAsOpaquePtr() &&
1183 adjustedType.
getAsOpaquePtr() ==
T->getAdjustedType().getAsOpaquePtr())
1190 QualType originalType = recurse(
T->getOriginalType());
1191 if (originalType.
isNull())
1195 ==
T->getOriginalType().getAsOpaquePtr())
1202 QualType ArrTy = VisitConstantArrayType(
T);
1220 QualType modifiedType = recurse(
T->getModifiedType());
1221 if (modifiedType.
isNull())
1224 QualType equivalentType = recurse(
T->getEquivalentType());
1225 if (equivalentType.
isNull())
1229 ==
T->getModifiedType().getAsOpaquePtr() &&
1231 ==
T->getEquivalentType().getAsOpaquePtr())
1239 QualType replacementType = recurse(
T->getReplacementType());
1240 if (replacementType.
isNull())
1244 ==
T->getReplacementType().getAsOpaquePtr())
1248 T->getAssociatedDecl(),
1249 T->getIndex(),
T->getPackIndex());
1256 if (!
T->isDeduced())
1259 QualType deducedType = recurse(
T->getDeducedType());
1260 if (deducedType.
isNull())
1264 ==
T->getDeducedType().getAsOpaquePtr())
1269 T->getTypeConstraintConcept(),
1270 T->getTypeConstraintArguments());
1274 QualType baseType = recurse(
T->getBaseType());
1279 bool typeArgChanged =
false;
1281 for (
auto typeArg :
T->getTypeArgsAsWritten()) {
1282 QualType newTypeArg = recurse(typeArg);
1287 typeArgChanged =
true;
1289 typeArgs.push_back(newTypeArg);
1299 T->isKindOfTypeAsWritten());
1306 if (pointeeType.
isNull())
1317 QualType valueType = recurse(
T->getValueType());
1322 ==
T->getValueType().getAsOpaquePtr())
1328#undef TRIVIAL_TYPE_CLASS
1329#undef SUGARED_TYPE_CLASS
1332struct SubstObjCTypeArgsVisitor
1333 :
public SimpleTransformVisitor<SubstObjCTypeArgsVisitor> {
1334 using BaseType = SimpleTransformVisitor<SubstObjCTypeArgsVisitor>;
1341 : BaseType(ctx), TypeArgs(typeArgs), SubstContext(context) {}
1348 if (!TypeArgs.empty()) {
1359 argType, protocolsToApply, hasError,
true);
1362 switch (SubstContext) {
1363 case ObjCSubstitutionContext::Ordinary:
1364 case ObjCSubstitutionContext::Parameter:
1365 case ObjCSubstitutionContext::Superclass:
1369 case ObjCSubstitutionContext::Result:
1370 case ObjCSubstitutionContext::Property: {
1372 const auto *objPtr =
1377 if (objPtr->isKindOfType() || objPtr->isObjCIdOrClassType())
1381 const auto *obj = objPtr->getObjectType();
1383 obj->getBaseType(), obj->getTypeArgsAsWritten(), obj->getProtocols(),
1390 llvm_unreachable(
"Unexpected ObjCSubstitutionContext!");
1399 Ctx, TypeArgs, ObjCSubstitutionContext::Result);
1405 if (isa<FunctionNoProtoType>(funcType)) {
1409 return BaseType::VisitFunctionType(funcType);
1415 const auto *funcProtoType = cast<FunctionProtoType>(funcType);
1419 bool paramChanged =
false;
1420 for (
auto paramType : funcProtoType->getParamTypes()) {
1422 Ctx, TypeArgs, ObjCSubstitutionContext::Parameter);
1423 if (newParamType.
isNull())
1427 paramChanged =
true;
1429 paramTypes.push_back(newParamType);
1434 bool exceptionChanged =
false;
1439 Ctx, TypeArgs, ObjCSubstitutionContext::Ordinary);
1440 if (newExceptionType.
isNull())
1443 if (newExceptionType.
getAsOpaquePtr() != exceptionType.getAsOpaquePtr())
1444 exceptionChanged =
true;
1446 exceptionTypes.push_back(newExceptionType);
1449 if (exceptionChanged) {
1456 funcProtoType->getReturnType().getAsOpaquePtr() &&
1457 !paramChanged && !exceptionChanged)
1458 return BaseType::VisitFunctionType(funcType);
1468 bool anyChanged =
false;
1471 Ctx, TypeArgs, ObjCSubstitutionContext::Ordinary);
1480 if (TypeArgs.empty() &&
1481 SubstContext != ObjCSubstitutionContext::Superclass) {
1490 newTypeArgs.push_back(newTypeArg);
1502 return BaseType::VisitObjCObjectType(objcObjectType);
1506 QualType newType = BaseType::VisitAttributedType(attrType);
1510 const auto *newAttrType = dyn_cast<AttributedType>(newType.
getTypePtr());
1511 if (!newAttrType || newAttrType->getAttrKind() != attr::ObjCKindOf)
1515 QualType newEquivType = newAttrType->getEquivalentType();
1527 objType->getBaseType(), objType->getTypeArgsAsWritten(),
1528 objType->getProtocols(),
1530 objType->isObjCUnqualifiedId() ?
false :
true);
1538 newAttrType->getModifiedType(), newEquivType);
1542struct StripObjCKindOfTypeVisitor
1543 :
public SimpleTransformVisitor<StripObjCKindOfTypeVisitor> {
1544 using BaseType = SimpleTransformVisitor<StripObjCKindOfTypeVisitor>;
1546 explicit StripObjCKindOfTypeVisitor(
ASTContext &ctx) : BaseType(ctx) {}
1550 return BaseType::VisitObjCObjectType(objType);
1571 case BuiltinType::Kind::Float16: {
1579 case BuiltinType::Kind::BFloat16: {
1599 SubstObjCTypeArgsVisitor visitor(ctx, typeArgs, context);
1600 return visitor.recurse(*
this);
1614 auto &ctx =
const_cast<ASTContext &
>(constCtx);
1615 StripObjCKindOfTypeVisitor visitor(ctx);
1616 return visitor.recurse(*
this);
1620 if (
const auto AT =
getTypePtr()->getAs<AtomicType>())
1621 return AT->getValueType().getUnqualifiedType();
1625std::optional<ArrayRef<QualType>>
1628 if (
const auto method = dyn_cast<ObjCMethodDecl>(dc))
1629 dc = method->getDeclContext();
1633 const auto *dcClassDecl = dyn_cast<ObjCInterfaceDecl>(dc);
1639 dcTypeParams = dcClassDecl->getTypeParamList();
1641 return std::nullopt;
1645 dcCategoryDecl = dyn_cast<ObjCCategoryDecl>(dc);
1646 if (!dcCategoryDecl)
1647 return std::nullopt;
1653 return std::nullopt;
1657 return std::nullopt;
1659 assert(dcTypeParams &&
"No substitutions to perform");
1660 assert(dcClassDecl &&
"No class context");
1664 if (
const auto *objectPointerType = getAs<ObjCObjectPointerType>()) {
1665 objectType = objectPointerType->getObjectType();
1666 }
else if (getAs<BlockPointerType>()) {
1671 objectType = getAs<ObjCObjectType>();
1677 if (!curClassDecl) {
1685 while (curClassDecl != dcClassDecl) {
1688 if (superType.
isNull()) {
1689 objectType =
nullptr;
1709 if (
auto *ID = IfaceT->getInterface()) {
1710 if (ID->getTypeParamList())
1724 CachedSuperClassType.setInt(
true);
1730 if (!superClassObjTy) {
1731 CachedSuperClassType.setInt(
true);
1736 if (!superClassDecl) {
1737 CachedSuperClassType.setInt(
true);
1743 QualType superClassType(superClassObjTy, 0);
1745 if (!superClassTypeParams) {
1746 CachedSuperClassType.setPointerAndInt(
1753 CachedSuperClassType.setPointerAndInt(superClassObjTy,
true);
1761 CachedSuperClassType.setPointerAndInt(
1772 CachedSuperClassType.setPointerAndInt(
1780 assert(typeArgs.size() == typeParams->
size());
1781 CachedSuperClassType.setPointerAndInt(
1790 return interfaceDecl->getASTContext().getObjCInterfaceType(interfaceDecl)
1799 if (superObjectType.
isNull())
1800 return superObjectType;
1810 if (
const auto *
T = getAs<ObjCObjectType>())
1811 if (
T->getNumProtocols() &&
T->getInterface())
1823 if (
const auto *OPT = getAs<ObjCObjectPointerType>()) {
1824 if (OPT->isObjCQualifiedIdType())
1833 if (
const auto *OPT = getAs<ObjCObjectPointerType>()) {
1834 if (OPT->isObjCQualifiedClassType())
1841 if (
const auto *OT = getAs<ObjCObjectType>()) {
1842 if (OT->getInterface())
1849 if (
const auto *OPT = getAs<ObjCObjectPointerType>()) {
1850 if (OPT->getInterfaceType())
1858 if (
const auto *PT = getAs<PointerType>())
1860 else if (
const auto *RT = getAs<ReferenceType>())
1866 return dyn_cast<CXXRecordDecl>(RT->getDecl());
1872 return dyn_cast_or_null<CXXRecordDecl>(
getAsTagDecl());
1880 if (
const auto *TT = getAs<TagType>())
1881 return TT->getDecl();
1882 if (
const auto *Injected = getAs<InjectedClassNameType>())
1883 return Injected->getDecl();
1889 const Type *Cur =
this;
1891 if (AT->getAttrKind() == AK)
1893 Cur = AT->getEquivalentType().getTypePtr();
1900 class GetContainedDeducedTypeVisitor :
1901 public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> {
1905 GetContainedDeducedTypeVisitor(
bool Syntactic =
false)
1906 : Syntactic(Syntactic) {}
1913 return Visit(
T.getTypePtr());
1923 return Visit(
T->getReplacementType());
1927 return Visit(
T->getNamedType());
1939 return Visit(
T->getPointeeTypeAsWritten());
1947 return Visit(
T->getElementType());
1950 Type *VisitDependentSizedExtVectorType(
1952 return Visit(
T->getElementType());
1956 return Visit(
T->getElementType());
1960 return Visit(
T->getElementType());
1964 return Visit(
T->getElementType());
1970 return VisitFunctionType(
T);
1978 return Visit(
T->getInnerType());
1982 return Visit(
T->getModifiedType());
1986 return Visit(
T->getUnderlyingType());
1990 return Visit(
T->getOriginalType());
1994 return Visit(
T->getPattern());
2001 return cast_or_null<DeducedType>(
2002 GetContainedDeducedTypeVisitor().Visit(
this));
2006 return isa_and_nonnull<FunctionType>(
2007 GetContainedDeducedTypeVisitor(
true).Visit(
this));
2011 if (
const auto *VT = dyn_cast<VectorType>(CanonicalType))
2012 return VT->getElementType()->isIntegerType();
2013 if (CanonicalType->isSveVLSBuiltinType()) {
2014 const auto *VT = cast<BuiltinType>(CanonicalType);
2015 return VT->getKind() == BuiltinType::SveBool ||
2016 (VT->getKind() >= BuiltinType::SveInt8 &&
2017 VT->getKind() <= BuiltinType::SveUint64);
2019 if (CanonicalType->isRVVVLSBuiltinType()) {
2020 const auto *VT = cast<BuiltinType>(CanonicalType);
2021 return (VT->getKind() >= BuiltinType::RvvInt8mf8 &&
2022 VT->getKind() <= BuiltinType::RvvUint64m8);
2048 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2049 return BT->getKind() >= BuiltinType::Bool &&
2050 BT->getKind() <= BuiltinType::Int128;
2054 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType))
2055 return ET->getDecl()->isComplete();
2061 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2062 return BT->getKind() >= BuiltinType::Bool &&
2063 BT->getKind() <= BuiltinType::Int128;
2072 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType))
2073 return !ET->getDecl()->isScoped();
2079 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2080 return BT->getKind() == BuiltinType::Char_U ||
2081 BT->getKind() == BuiltinType::UChar ||
2082 BT->getKind() == BuiltinType::Char_S ||
2083 BT->getKind() == BuiltinType::SChar;
2088 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2089 return BT->getKind() == BuiltinType::WChar_S ||
2090 BT->getKind() == BuiltinType::WChar_U;
2095 if (
const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
2096 return BT->getKind() == BuiltinType::Char8;
2101 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2102 return BT->getKind() == BuiltinType::Char16;
2107 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2108 return BT->getKind() == BuiltinType::Char32;
2115 const auto *BT = dyn_cast<BuiltinType>(CanonicalType);
2116 if (!BT)
return false;
2117 switch (BT->getKind()) {
2118 default:
return false;
2119 case BuiltinType::Char_U:
2120 case BuiltinType::UChar:
2121 case BuiltinType::WChar_U:
2122 case BuiltinType::Char8:
2123 case BuiltinType::Char16:
2124 case BuiltinType::Char32:
2125 case BuiltinType::Char_S:
2126 case BuiltinType::SChar:
2127 case BuiltinType::WChar_S:
2136 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
2137 return BT->getKind() >= BuiltinType::Char_S &&
2138 BT->getKind() <= BuiltinType::Int128;
2141 if (
const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
2144 if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
2148 if (
const auto *IT = dyn_cast<BitIntType>(CanonicalType))
2149 return IT->isSigned();
2150 if (
const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
2151 return IT->isSigned();
2157 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
2158 return BT->getKind() >= BuiltinType::Char_S &&
2159 BT->getKind() <= BuiltinType::Int128;
2162 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
2163 if (ET->getDecl()->isComplete())
2167 if (
const auto *IT = dyn_cast<BitIntType>(CanonicalType))
2168 return IT->isSigned();
2169 if (
const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
2170 return IT->isSigned();
2176 if (
const auto *VT = dyn_cast<VectorType>(CanonicalType))
2177 return VT->getElementType()->isSignedIntegerOrEnumerationType();
2186 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
2187 return BT->getKind() >= BuiltinType::Bool &&
2188 BT->getKind() <= BuiltinType::UInt128;
2191 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
2194 if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
2198 if (
const auto *IT = dyn_cast<BitIntType>(CanonicalType))
2199 return IT->isUnsigned();
2200 if (
const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
2201 return IT->isUnsigned();
2207 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
2208 return BT->getKind() >= BuiltinType::Bool &&
2209 BT->getKind() <= BuiltinType::UInt128;
2212 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
2213 if (ET->getDecl()->isComplete())
2217 if (
const auto *IT = dyn_cast<BitIntType>(CanonicalType))
2218 return IT->isUnsigned();
2219 if (
const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
2220 return IT->isUnsigned();
2226 if (
const auto *VT = dyn_cast<VectorType>(CanonicalType))
2227 return VT->getElementType()->isUnsignedIntegerOrEnumerationType();
2228 if (
const auto *VT = dyn_cast<MatrixType>(CanonicalType))
2229 return VT->getElementType()->isUnsignedIntegerOrEnumerationType();
2230 if (CanonicalType->isSveVLSBuiltinType()) {
2231 const auto *VT = cast<BuiltinType>(CanonicalType);
2232 return VT->getKind() >= BuiltinType::SveUint8 &&
2233 VT->getKind() <= BuiltinType::SveUint64;
2239 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2240 return BT->getKind() >= BuiltinType::Half &&
2241 BT->getKind() <= BuiltinType::Ibm128;
2242 if (
const auto *CT = dyn_cast<ComplexType>(CanonicalType))
2243 return CT->getElementType()->isFloatingType();
2248 if (
const auto *VT = dyn_cast<VectorType>(CanonicalType))
2249 return VT->getElementType()->isFloatingType();
2250 if (
const auto *MT = dyn_cast<MatrixType>(CanonicalType))
2251 return MT->getElementType()->isFloatingType();
2256 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2257 return BT->isFloatingPoint();
2262 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2263 return BT->getKind() >= BuiltinType::Bool &&
2264 BT->getKind() <= BuiltinType::Ibm128;
2265 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType))
2266 return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
2271 if (
const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
2272 return BT->getKind() >= BuiltinType::Bool &&
2273 BT->getKind() <= BuiltinType::Ibm128;
2274 if (
const auto *ET = dyn_cast<EnumType>(CanonicalType))
2281 return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete();
2282 return isa<ComplexType>(CanonicalType) ||
isBitIntType();
2288 const Type *
T = CanonicalType.getTypePtr();
2289 if (
const auto *BT = dyn_cast<BuiltinType>(
T)) {
2290 if (BT->getKind() == BuiltinType::Bool)
return STK_Bool;
2291 if (BT->getKind() == BuiltinType::NullPtr)
return STK_CPointer;
2295 llvm_unreachable(
"unknown scalar builtin type");
2296 }
else if (isa<PointerType>(
T)) {
2298 }
else if (isa<BlockPointerType>(
T)) {
2300 }
else if (isa<ObjCObjectPointerType>(
T)) {
2302 }
else if (isa<MemberPointerType>(
T)) {
2304 }
else if (isa<EnumType>(
T)) {
2305 assert(cast<EnumType>(
T)->getDecl()->isComplete());
2307 }
else if (
const auto *CT = dyn_cast<ComplexType>(
T)) {
2308 if (CT->getElementType()->isRealFloatingType())
2315 llvm_unreachable(
"unknown scalar type");
2328 if (
const auto *
Record = dyn_cast<RecordType>(CanonicalType)) {
2329 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(
Record->getDecl()))
2330 return ClassDecl->isAggregate();
2335 return isa<ArrayType>(CanonicalType);
2342 assert(!
isIncompleteType() &&
"This doesn't make sense for incomplete types");
2343 assert(!
isDependentType() &&
"This doesn't make sense for dependent types");
2345 return !isa<VariableArrayType>(CanonicalType);
2355 switch (CanonicalType->getTypeClass()) {
2356 default:
return false;
2362 EnumDecl *EnumD = cast<EnumType>(CanonicalType)->getDecl();
2370 RecordDecl *Rec = cast<RecordType>(CanonicalType)->getDecl();
2375 case InjectedClassName: {
2376 CXXRecordDecl *Rec = cast<InjectedClassNameType>(CanonicalType)->getDecl();
2389 return cast<ArrayType>(CanonicalType)->getElementType()
2390 ->isIncompleteType(Def);
2391 case IncompleteArray:
2394 case MemberPointer: {
2398 auto *MPTy = cast<MemberPointerType>(CanonicalType);
2399 const Type *ClassTy = MPTy->getClass();
2412 if (RD->
hasAttr<MSInheritanceAttr>())
2417 return cast<ObjCObjectType>(CanonicalType)->getBaseType()
2418 ->isIncompleteType(Def);
2419 case ObjCInterface: {
2422 = cast<ObjCInterfaceType>(CanonicalType)->getDecl();
2434 if (
const BuiltinType *BT = getAs<BuiltinType>()) {
2435 switch (BT->getKind()) {
2437#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2438#include "clang/Basic/WebAssemblyReferenceTypes.def"
2448 if (
const auto *BT = getAs<BuiltinType>())
2449 return BT->getKind() == BuiltinType::WasmExternRef;
2454 if (
const auto *ATy = dyn_cast<ArrayType>(
this))
2455 return ATy->getElementType().isWebAssemblyReferenceType();
2457 if (
const auto *PTy = dyn_cast<PointerType>(
this))
2458 return PTy->getPointeeType().isWebAssemblyReferenceType();
2470 if (
const BuiltinType *BT = getAs<BuiltinType>()) {
2471 switch (BT->getKind()) {
2473#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2474#include "clang/Basic/AArch64SVEACLETypes.def"
2484 if (
const BuiltinType *BT = getAs<BuiltinType>()) {
2485 switch (BT->getKind()) {
2486#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2487#include "clang/Basic/RISCVVTypes.def"
2497 if (
const BuiltinType *BT = getAs<BuiltinType>()) {
2498 switch (BT->getKind()) {
2499 case BuiltinType::SveInt8:
2500 case BuiltinType::SveInt16:
2501 case BuiltinType::SveInt32:
2502 case BuiltinType::SveInt64:
2503 case BuiltinType::SveUint8:
2504 case BuiltinType::SveUint16:
2505 case BuiltinType::SveUint32:
2506 case BuiltinType::SveUint64:
2507 case BuiltinType::SveFloat16:
2508 case BuiltinType::SveFloat32:
2509 case BuiltinType::SveFloat64:
2510 case BuiltinType::SveBFloat16:
2511 case BuiltinType::SveBool:
2512 case BuiltinType::SveBoolx2:
2513 case BuiltinType::SveBoolx4:
2531 llvm_unreachable(
"Unhandled type");
2538 if (BTy->
getKind() == BuiltinType::SveBool)
2548 if (
const BuiltinType *BT = getAs<BuiltinType>()) {
2549 switch (BT->getKind()) {
2550#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \
2552 case BuiltinType::Id: \
2554#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
2555 case BuiltinType::Id: \
2557#include "clang/Basic/RISCVVTypes.def"
2571#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
2572 case BuiltinType::Id: \
2573 return Ctx.UnsignedCharTy;
2576#include "clang/Basic/RISCVVTypes.def"
2579 llvm_unreachable(
"Unhandled type");
2597 if ((*this)->isIncompleteArrayType())
2600 if ((*this)->isIncompleteType())
2609 default:
return false;
2610 case Type::VariableArray:
2611 case Type::ConstantArray:
2615 case Type::ObjCObjectPointer:
2616 case Type::BlockPointer:
2620 case Type::MemberPointer:
2622 case Type::ExtVector:
2630 if (
const auto *ClassDecl =
2631 dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl()))
2632 return ClassDecl->isPOD();
2646 if ((*this)->isArrayType())
2649 if ((*this)->isSizelessBuiltinType())
2654 if ((*this)->isIncompleteType())
2673 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
2680 return ClassDecl->hasTrivialDefaultConstructor() &&
2681 !ClassDecl->hasNonTrivialDefaultConstructor() &&
2682 ClassDecl->isTriviallyCopyable();
2694 bool IsCopyConstructible) {
2695 if (
type->isArrayType())
2697 Context, IsCopyConstructible);
2699 if (
type.hasNonTrivialObjCLifetime())
2724 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
2725 if (IsCopyConstructible) {
2726 return ClassDecl->isTriviallyCopyConstructible();
2728 return ClassDecl->isTriviallyCopyable();
2756 return RD->canPassInRegisters();
2773 if (
Decl->isUnion())
2775 if (
Decl->isLambda())
2776 return Decl->isCapturelessLambda();
2779 return Function->getOverloadedOperator() ==
2780 OverloadedOperatorKind::OO_EqualEqual &&
2782 (
Function->getParamDecl(0)->getType()->isReferenceType() ||
2783 Decl->isTriviallyCopyable());
2786 if (llvm::none_of(
Decl->methods(), IsDefaultedOperatorEqualEqual) &&
2788 if (
NamedDecl *ND = Friend->getFriendDecl()) {
2790 IsDefaultedOperatorEqualEqual(ND->getAsFunction());
2796 return llvm::all_of(
Decl->bases(),
2798 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
2799 return HasNonDeletedDefaultedEqualityComparison(RD);
2803 auto Type = FD->getType();
2804 if (Type->isArrayType())
2805 Type = Type->getBaseElementTypeUnsafe()->getCanonicalTypeUnqualified();
2807 if (Type->isReferenceType() || Type->isEnumeralType())
2809 if (const auto *RD = Type->getAsCXXRecordDecl())
2810 return HasNonDeletedDefaultedEqualityComparison(RD);
2828 CanonicalType,
false);
2864 if (
const auto *RT =
2865 getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>())
2866 if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize())
2880 if (
const auto *RT =
2881 getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>())
2882 if (RT->getDecl()->isNonTrivialToPrimitiveCopy())
2918 assert(BaseTy &&
"NULL element type");
2948 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
2949 return ClassDecl->isLiteral();
2956 return AT->getValueType()->isLiteralType(Ctx);
2978 return RD->isStructural();
2991 assert(BaseTy &&
"NULL element type");
3001 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
3002 if (!ClassDecl->isStandardLayout())
3030 assert(BaseTy &&
"NULL element type");
3043 if (
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
3046 if (!ClassDecl->isTrivial())
return false;
3051 if (!ClassDecl->isStandardLayout())
return false;
3080 if (
const auto *ET = getAs<EnumType>()) {
3082 if (II && II->
isStr(
"align_val_t") && ET->getDecl()->isInStdNamespace())
3089 if (
const auto *ET = getAs<EnumType>()) {
3091 if (II && II->
isStr(
"byte") && ET->getDecl()->isInStdNamespace())
3107 case TemplateTypeParm:
3108 case SubstTemplateTypeParm:
3109 case TemplateSpecialization:
3112 case DependentTemplateSpecialization:
3156 llvm_unreachable(
"Type specifier is not a tag type kind.");
3173 llvm_unreachable(
"Unknown tag type kind.");
3191 llvm_unreachable(
"Elaborated type keyword is not a tag type kind.");
3193 llvm_unreachable(
"Unknown elaborated type keyword.");
3209 llvm_unreachable(
"Unknown elaborated type keyword.");
3223 return "__interface";
3230 llvm_unreachable(
"Unknown elaborated type keyword.");
3233DependentTemplateSpecializationType::DependentTemplateSpecializationType(
3240 NNS(NNS), Name(Name) {
3243 "DependentTemplateSpecializatonType requires dependent qualifier");
3244 auto *ArgBuffer =
const_cast<TemplateArgument *
>(template_arguments().data());
3247 TemplateArgumentDependence::UnexpandedPack));
3260 ID.AddInteger(llvm::to_underlying(Keyword));
3261 ID.AddPointer(Qualifier);
3262 ID.AddPointer(Name);
3264 Arg.Profile(ID, Context);
3269 if (
const auto *Elab = dyn_cast<ElaboratedType>(
this))
3270 Keyword = Elab->getKeyword();
3271 else if (
const auto *DepName = dyn_cast<DependentNameType>(
this))
3272 Keyword = DepName->getKeyword();
3273 else if (
const auto *DepTST =
3274 dyn_cast<DependentTemplateSpecializationType>(
this))
3275 Keyword = DepTST->getKeyword();
3284#define ABSTRACT_TYPE(Derived, Base)
3285#define TYPE(Derived, Base) case Derived: return #Derived;
3286#include "clang/AST/TypeNodes.inc"
3289 llvm_unreachable(
"Invalid type class.");
3297 return Policy.
Bool ?
"bool" :
"_Bool";
3303 return "signed char";
3315 return "unsigned char";
3317 return "unsigned short";
3319 return "unsigned int";
3321 return "unsigned long";
3323 return "unsigned long long";
3325 return "unsigned __int128";
3327 return Policy.
Half ?
"half" :
"__fp16";
3335 return "long double";
3337 return "short _Accum";
3341 return "long _Accum";
3343 return "unsigned short _Accum";
3345 return "unsigned _Accum";
3347 return "unsigned long _Accum";
3348 case BuiltinType::ShortFract:
3349 return "short _Fract";
3350 case BuiltinType::Fract:
3352 case BuiltinType::LongFract:
3353 return "long _Fract";
3354 case BuiltinType::UShortFract:
3355 return "unsigned short _Fract";
3356 case BuiltinType::UFract:
3357 return "unsigned _Fract";
3358 case BuiltinType::ULongFract:
3359 return "unsigned long _Fract";
3360 case BuiltinType::SatShortAccum:
3361 return "_Sat short _Accum";
3362 case BuiltinType::SatAccum:
3363 return "_Sat _Accum";
3364 case BuiltinType::SatLongAccum:
3365 return "_Sat long _Accum";
3366 case BuiltinType::SatUShortAccum:
3367 return "_Sat unsigned short _Accum";
3368 case BuiltinType::SatUAccum:
3369 return "_Sat unsigned _Accum";
3370 case BuiltinType::SatULongAccum:
3371 return "_Sat unsigned long _Accum";
3372 case BuiltinType::SatShortFract:
3373 return "_Sat short _Fract";
3374 case BuiltinType::SatFract:
3375 return "_Sat _Fract";
3376 case BuiltinType::SatLongFract:
3377 return "_Sat long _Fract";
3378 case BuiltinType::SatUShortFract:
3379 return "_Sat unsigned short _Fract";
3380 case BuiltinType::SatUFract:
3381 return "_Sat unsigned _Fract";
3382 case BuiltinType::SatULongFract:
3383 return "_Sat unsigned long _Fract";
3387 return "__float128";
3392 return Policy.
MSWChar ?
"__wchar_t" :
"wchar_t";
3402 return "<overloaded function type>";
3404 return "<bound member function type>";
3405 case UnresolvedTemplate:
3406 return "<unresolved template type>";
3408 return "<pseudo-object type>";
3410 return "<dependent type>";
3412 return "<unknown type>";
3413 case ARCUnbridgedCast:
3414 return "<ARC unbridged cast type>";
3416 return "<builtin fn type>";
3423#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3425 return "__" #Access " " #ImgType "_t";
3426#include "clang/Basic/OpenCLImageTypes.def"
3432 return "clk_event_t";
3436 return "reserve_id_t";
3437 case IncompleteMatrixIdx:
3438 return "<incomplete matrix index type>";
3440 return "<array section type>";
3441 case OMPArrayShaping:
3442 return "<OpenMP array shaping type>";
3444 return "<OpenMP iterator type>";
3445#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3448#include "clang/Basic/OpenCLExtensionTypes.def"
3449#define SVE_TYPE(Name, Id, SingletonId) \
3452#include "clang/Basic/AArch64SVEACLETypes.def"
3453#define PPC_VECTOR_TYPE(Name, Id, Size) \
3456#include "clang/Basic/PPCTypes.def"
3457#define RVV_TYPE(Name, Id, SingletonId) \
3460#include "clang/Basic/RISCVVTypes.def"
3461#define WASM_TYPE(Name, Id, SingletonId) \
3464#include "clang/Basic/WebAssemblyReferenceTypes.def"
3467 llvm_unreachable(
"Invalid builtin type.");
3472 if (
auto *PET = dyn_cast<PackExpansionType>(
getTypePtr()))
3473 return PET->getPattern();
3478 if (
const auto *RefType =
getTypePtr()->getAs<ReferenceType>())
3495 case CC_C:
return "cdecl";
3523 llvm_unreachable(
"Invalid calling convention.");
3541 assert(
getNumParams() == params.size() &&
"NumParams overflow!");
3549 auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
3556 auto &ArmTypeAttrs = *getTrailingObjects<FunctionTypeArmAttributes>();
3557 ArmTypeAttrs = FunctionTypeArmAttributes();
3560 auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
3561 ExtraBits.HasArmTypeAttributes =
true;
3565 auto *argSlot = getTrailingObjects<QualType>();
3568 ~TypeDependence::VariablyModified);
3569 argSlot[i] = params[i];
3574 auto &ArmTypeAttrs = *getTrailingObjects<FunctionTypeArmAttributes>();
3576 "Not enough bits to encode SME attributes");
3582 auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
3584 assert(NumExceptions <= 1023 &&
"Not enough bits to encode exceptions");
3585 ExtraBits.NumExceptionType = NumExceptions;
3587 assert(hasExtraBitfields() &&
"missing trailing extra bitfields!");
3589 reinterpret_cast<QualType *
>(getTrailingObjects<ExceptionType>());
3597 (TypeDependence::Instantiation | TypeDependence::UnexpandedPack));
3599 exnSlot[I++] = ExceptionType;
3613 (TypeDependence::Instantiation | TypeDependence::UnexpandedPack));
3619 auto **slot = getTrailingObjects<FunctionDecl *>();
3627 auto **slot = getTrailingObjects<FunctionDecl *>();
3646 auto *extParamInfos = getTrailingObjects<ExtParameterInfo>();
3653 *getTrailingObjects<Qualifiers>() = epi.
TypeQuals;
3660 auto &EllipsisLoc = *getTrailingObjects<SourceLocation>();
3667 return NE->isValueDependent();
3679 return NE->isInstantiationDependent();
3690 llvm_unreachable(
"should not call this with unresolved exception specs");
3716 llvm_unreachable(
"unexpected exception specification kind");
3720 for (
unsigned ArgIdx =
getNumParams(); ArgIdx; --ArgIdx)
3728 const QualType *ArgTys,
unsigned NumParams,
3729 const ExtProtoInfo &epi,
3751 ID.AddPointer(
Result.getAsOpaquePtr());
3752 for (
unsigned i = 0; i != NumParams; ++i)
3753 ID.AddPointer(ArgTys[i].getAsOpaquePtr());
3757 assert(!(
unsigned(epi.Variadic) & ~1) &&
3758 !(
unsigned(epi.RefQualifier) & ~3) &&
3759 !(
unsigned(epi.ExceptionSpec.Type) & ~15) &&
3760 "Values larger than expected.");
3761 ID.AddInteger(
unsigned(epi.Variadic) +
3762 (epi.RefQualifier << 1) +
3763 (epi.ExceptionSpec.Type << 3));
3764 ID.Add(epi.TypeQuals);
3766 for (
QualType Ex : epi.ExceptionSpec.Exceptions)
3769 epi.ExceptionSpec.NoexceptExpr->Profile(ID, Context, Canonical);
3772 ID.AddPointer(epi.ExceptionSpec.SourceDecl->getCanonicalDecl());
3774 if (epi.ExtParameterInfos) {
3775 for (
unsigned i = 0; i != NumParams; ++i)
3776 ID.AddInteger(epi.ExtParameterInfos[i].getOpaqueValue());
3779 epi.ExtInfo.Profile(ID);
3780 ID.AddInteger((epi.AArch64SMEAttributes << 1) | epi.HasTrailingReturn);
3790 :
Data(D, Deref << DerefShift) {}
3793 return Data.getInt() & DerefMask;
3798 return Data.getOpaqueValue();
3805 Data.setFromOpaqueValue(
V);
3810 :
Type(TC, Canon, Wrapped->getDependence()), WrappedTy(Wrapped) {}
3812CountAttributedType::CountAttributedType(
3816 CountExpr(CountExpr) {
3820 auto *DeclSlot = getTrailingObjects<TypeCoupledDeclRefInfo>();
3822 for (
unsigned i = 0; i != CoupledDecls.size(); ++i)
3823 DeclSlot[i] = CoupledDecls[i];
3830 assert(!isa<TypedefType>(can) &&
"Invalid canonical type");
3832 if (!typeMatchesDecl())
3833 *getTrailingObjects<QualType>() = Underlying;
3838 : *getTrailingObjects<QualType>();
3847 *getTrailingObjects<QualType>() = Underlying;
3853 cast<TypeDecl>(Found->
getTargetDecl())->getTypeForDecl(), 0)
3854 : *getTrailingObjects<QualType>();
3863 while (
auto *InnerMQT = dyn_cast<MacroQualifiedType>(Inner)) {
3866 Inner = InnerMQT->getModifiedType();
3876 ? Can.getAtomicUnqualifiedType()
3879 (E->getType()->getDependence() &
3900 E->
Profile(ID, Context,
true);
3901 ID.AddBoolean(IsUnqual);
3908 :
Type(Decltype, can,
3912 (E->getType()->getDependence() &
3914 E(E), UnderlyingType(underlyingType) {}
3930 E->
Profile(ID, Context,
true);
3937 :
Type(PackIndexing, Canonical,
3939 Context(Context), Pattern(Pattern), IndexExpr(IndexExpr),
3940 Size(Expansions.size()) {
3942 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
3943 getTrailingObjects<QualType>());
3948 return std::nullopt;
3952 return std::nullopt;
3954 assert(Index.isNonNegative() &&
"Invalid index");
3955 return static_cast<unsigned>(Index.getExtValue());
3959PackIndexingType::computeDependence(
QualType Pattern,
Expr *IndexExpr,
3964 ? TypeDependence::DependentInstantiation
3965 : TypeDependence::None);
3966 if (Expansions.empty())
3967 TD |= Pattern->
getDependence() & TypeDependence::DependentInstantiation;
3972 if (!(IndexD & TypeDependence::UnexpandedPack))
3973 TD &= ~TypeDependence::UnexpandedPack;
3978 TD |= TypeDependence::Error | TypeDependence::DependentInstantiation;
3987 E->
Profile(ID, Context,
true);
3993 :
Type(UnaryTransform, CanonicalType, BaseType->getDependence()),
3994 BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {}
4008 for (
auto *I :
decl->redecls()) {
4009 if (I->isCompleteDefinition() || I->isBeingDefined())
4025 std::vector<const RecordType*> RecordTypeList;
4026 RecordTypeList.push_back(
this);
4027 unsigned NextToCheckIndex = 0;
4029 while (RecordTypeList.size() > NextToCheckIndex) {
4031 RecordTypeList[NextToCheckIndex]->
getDecl()->fields()) {
4037 if (!llvm::is_contained(RecordTypeList, FieldRecTy))
4038 RecordTypeList.push_back(FieldRecTy);
4053 case attr::ObjCOwnership:
4054 case attr::ObjCInertUnsafeUnretained:
4055 case attr::TypeNonNull:
4056 case attr::TypeNullable:
4057 case attr::TypeNullableResult:
4058 case attr::TypeNullUnspecified:
4059 case attr::LifetimeBound:
4060 case attr::AddressSpace:
4073 default:
return false;
4080 llvm_unreachable(
"invalid attr kind");
4090 default:
return false;
4093 case attr::FastCall:
4095 case attr::ThisCall:
4097 case attr::SwiftCall:
4098 case attr::SwiftAsyncCall:
4099 case attr::VectorCall:
4100 case attr::AArch64VectorPcs:
4101 case attr::AArch64SVEPcs:
4102 case attr::AMDGPUKernelCall:
4106 case attr::IntelOclBicc:
4107 case attr::PreserveMost:
4108 case attr::PreserveAll:
4110 case attr::PreserveNone:
4111 case attr::RISCVVectorCC:
4114 llvm_unreachable(
"invalid attr kind");
4127 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
4129 return cast<TemplateTypeParmDecl>(
4133SubstTemplateTypeParmType::SubstTemplateTypeParmType(
4134 QualType Replacement,
Decl *AssociatedDecl,
unsigned Index,
4135 std::optional<unsigned> PackIndex)
4136 :
Type(SubstTemplateTypeParm, Replacement.getCanonicalType(),
4137 Replacement->getDependence()),
4138 AssociatedDecl(AssociatedDecl) {
4139 SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType =
4140 Replacement != getCanonicalTypeInternal();
4141 if (SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType)
4142 *getTrailingObjects<QualType>() = Replacement;
4144 SubstTemplateTypeParmTypeBits.Index = Index;
4145 SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0;
4146 assert(AssociatedDecl !=
nullptr);
4154SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType(
4155 QualType Canon,
Decl *AssociatedDecl,
unsigned Index,
bool Final,
4157 :
Type(SubstTemplateTypeParmPack, Canon,
4160 Arguments(ArgPack.pack_begin()),
4161 AssociatedDeclAndFinal(AssociatedDecl, Final) {
4164 assert(AssociatedDecl !=
nullptr);
4168 return AssociatedDeclAndFinal.getPointer();
4172 return AssociatedDeclAndFinal.getInt();
4193 const Decl *AssociatedDecl,
4194 unsigned Index,
bool Final,
4196 ID.AddPointer(AssociatedDecl);
4197 ID.AddInteger(Index);
4198 ID.AddBoolean(Final);
4201 ID.AddPointer(
P.getAsType().getAsOpaquePtr());
4212 if (Arg.isDependent())
4220 if (ArgLoc.getArgument().isInstantiationDependent())
4226TemplateSpecializationType::TemplateSpecializationType(
4229 :
Type(TemplateSpecialization, Canon.isNull() ?
QualType(this, 0) : Canon,
4239 assert(!
T.getAsDependentTemplateName() &&
4240 "Use DependentTemplateSpecializationType for dependent template-name");
4245 "Unexpected template name for TemplateSpecializationType");
4258 ~TypeDependence::Dependent);
4261 TypeDependence::VariablyModified);
4268 *
reinterpret_cast<QualType *
>(
Begin + Args.size()) = AliasedType;
4273 assert(
isTypeAlias() &&
"not a type alias template specialization");
4291 Arg.Profile(ID, Context);
4316 ID.AddInteger(typeArgs.size());
4317 for (
auto typeArg : typeArgs)
4318 ID.AddPointer(typeArg.getAsOpaquePtr());
4319 ID.AddInteger(protocols.size());
4320 for (
auto *proto : protocols)
4321 ID.AddPointer(proto);
4322 ID.AddBoolean(isKindOf);
4335 ID.AddPointer(OTPDecl);
4337 ID.AddInteger(protocols.size());
4338 for (
auto *proto : protocols)
4339 ID.AddPointer(proto);
4350class CachedProperties {
4355 CachedProperties(
Linkage L,
bool local) : L(L), local(local) {}
4357 Linkage getLinkage()
const {
return L; }
4358 bool hasLocalOrUnnamedType()
const {
return local; }
4360 friend CachedProperties merge(CachedProperties L, CachedProperties R) {
4362 return CachedProperties(MergedLinkage, L.hasLocalOrUnnamedType() ||
4363 R.hasLocalOrUnnamedType());
4379 return get(
T.getTypePtr());
4384 return CachedProperties(
T->
TypeBits.getLinkage(),
4426#define TYPE(Class,Base)
4427#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
4428#include "clang/AST/TypeNodes.inc"
4429 llvm_unreachable(
"didn't expect a non-canonical type here");
4431#define TYPE(Class,Base)
4432#define DEPENDENT_TYPE(Class,Base) case Type::Class:
4433#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
4434#include "clang/AST/TypeNodes.inc"
4441 case Type::DeducedTemplateSpecialization:
4455 const TagDecl *Tag = cast<TagType>(
T)->getDecl();
4462 bool IsLocalOrUnnamed =
4465 return CachedProperties(L, IsLocalOrUnnamed);
4472 return Cache::get(cast<ComplexType>(
T)->getElementType());
4474 return Cache::get(cast<PointerType>(
T)->getPointeeType());
4475 case Type::BlockPointer:
4476 return Cache::get(cast<BlockPointerType>(
T)->getPointeeType());
4477 case Type::LValueReference:
4478 case Type::RValueReference:
4479 return Cache::get(cast<ReferenceType>(
T)->getPointeeType());
4480 case Type::MemberPointer: {
4481 const auto *MPT = cast<MemberPointerType>(
T);
4485 case Type::ConstantArray:
4486 case Type::IncompleteArray:
4487 case Type::VariableArray:
4488 case Type::ArrayParameter:
4489 return Cache::get(cast<ArrayType>(
T)->getElementType());
4491 case Type::ExtVector:
4492 return Cache::get(cast<VectorType>(
T)->getElementType());
4493 case Type::ConstantMatrix:
4494 return Cache::get(cast<ConstantMatrixType>(
T)->getElementType());
4495 case Type::FunctionNoProto:
4496 return Cache::get(cast<FunctionType>(
T)->getReturnType());
4497 case Type::FunctionProto: {
4498 const auto *FPT = cast<FunctionProtoType>(
T);
4499 CachedProperties result =
Cache::get(FPT->getReturnType());
4500 for (
const auto &ai : FPT->param_types())
4504 case Type::ObjCInterface: {
4505 Linkage L = cast<ObjCInterfaceType>(
T)->getDecl()->getLinkageInternal();
4506 return CachedProperties(L,
false);
4508 case Type::ObjCObject:
4509 return Cache::get(cast<ObjCObjectType>(
T)->getBaseType());
4510 case Type::ObjCObjectPointer:
4511 return Cache::get(cast<ObjCObjectPointerType>(
T)->getPointeeType());
4513 return Cache::get(cast<AtomicType>(
T)->getValueType());
4515 return Cache::get(cast<PipeType>(
T)->getElementType());
4518 llvm_unreachable(
"unhandled type class");
4529 return TypeBits.hasLocalOrUnnamedType();
4534#define TYPE(Class,Base)
4535#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
4536#include "clang/AST/TypeNodes.inc"
4537 llvm_unreachable(
"didn't expect a non-canonical type here");
4539#define TYPE(Class,Base)
4540#define DEPENDENT_TYPE(Class,Base) case Type::Class:
4541#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
4542#include "clang/AST/TypeNodes.inc"
4552 case Type::DeducedTemplateSpecialization:
4563 case Type::BlockPointer:
4565 case Type::LValueReference:
4566 case Type::RValueReference:
4568 case Type::MemberPointer: {
4569 const auto *MPT = cast<MemberPointerType>(
T);
4574 case Type::ConstantArray:
4575 case Type::IncompleteArray:
4576 case Type::VariableArray:
4577 case Type::ArrayParameter:
4580 case Type::ExtVector:
4582 case Type::ConstantMatrix:
4584 cast<ConstantMatrixType>(
T)->getElementType());
4585 case Type::FunctionNoProto:
4587 case Type::FunctionProto: {
4588 const auto *FPT = cast<FunctionProtoType>(
T);
4590 for (
const auto &ai : FPT->param_types())
4594 case Type::ObjCInterface:
4596 case Type::ObjCObject:
4598 case Type::ObjCObjectPointer:
4600 cast<ObjCObjectPointerType>(
T)->getPointeeType());
4607 llvm_unreachable(
"unhandled type class");
4638 if (
auto Nullability = AT->getImmediateNullability())
4641 Type = AT->getEquivalentType();
4643 return std::nullopt;
4649 switch (
type->getTypeClass()) {
4651#define NON_CANONICAL_TYPE(Class, Parent) \
4653 llvm_unreachable("non-canonical type");
4654#define TYPE(Class, Parent)
4655#include "clang/AST/TypeNodes.inc"
4659 case Type::BlockPointer:
4660 case Type::MemberPointer:
4661 case Type::ObjCObjectPointer:
4665 case Type::UnresolvedUsing:
4666 case Type::TypeOfExpr:
4668 case Type::Decltype:
4669 case Type::PackIndexing:
4670 case Type::UnaryTransform:
4671 case Type::TemplateTypeParm:
4672 case Type::SubstTemplateTypeParmPack:
4673 case Type::DependentName:
4674 case Type::DependentTemplateSpecialization:
4676 return ResultIfUnknown;
4679 case Type::TemplateSpecialization:
4682 cast<TemplateSpecializationType>(
type.getTypePtr())
4684 .getAsTemplateDecl())
4685 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(templateDecl))
4686 return CTD->getTemplatedDecl()->hasAttr<TypeNullableAttr>();
4687 return ResultIfUnknown;
4690 switch (cast<BuiltinType>(
type.getTypePtr())->getKind()) {
4692#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
4693#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
4694#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
4695#define BUILTIN_TYPE(Id, SingletonId)
4696#include "clang/AST/BuiltinTypes.def"
4699 case BuiltinType::UnresolvedTemplate:
4701 case BuiltinType::Dependent:
4702 case BuiltinType::Overload:
4703 case BuiltinType::BoundMember:
4704 case BuiltinType::PseudoObject:
4705 case BuiltinType::UnknownAny:
4706 case BuiltinType::ARCUnbridgedCast:
4707 return ResultIfUnknown;
4709 case BuiltinType::Void:
4710 case BuiltinType::ObjCId:
4711 case BuiltinType::ObjCClass:
4712 case BuiltinType::ObjCSel:
4713#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
4714 case BuiltinType::Id:
4715#include "clang/Basic/OpenCLImageTypes.def"
4716#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
4717 case BuiltinType::Id:
4718#include "clang/Basic/OpenCLExtensionTypes.def"
4719 case BuiltinType::OCLSampler:
4720 case BuiltinType::OCLEvent:
4721 case BuiltinType::OCLClkEvent:
4722 case BuiltinType::OCLQueue:
4723 case BuiltinType::OCLReserveID:
4724#define SVE_TYPE(Name, Id, SingletonId) \
4725 case BuiltinType::Id:
4726#include "clang/Basic/AArch64SVEACLETypes.def"
4727#define PPC_VECTOR_TYPE(Name, Id, Size) \
4728 case BuiltinType::Id:
4729#include "clang/Basic/PPCTypes.def"
4730#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
4731#include "clang/Basic/RISCVVTypes.def"
4732#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
4733#include "clang/Basic/WebAssemblyReferenceTypes.def"
4734 case BuiltinType::BuiltinFn:
4735 case BuiltinType::NullPtr:
4736 case BuiltinType::IncompleteMatrixIdx:
4737 case BuiltinType::ArraySection:
4738 case BuiltinType::OMPArrayShaping:
4739 case BuiltinType::OMPIterator:
4742 llvm_unreachable(
"unknown builtin type");
4744 case Type::Record: {
4748 if (
const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
4749 return CTSD->getSpecializedTemplate()
4750 ->getTemplatedDecl()
4751 ->
hasAttr<TypeNullableAttr>();
4752 return RD->
hasAttr<TypeNullableAttr>();
4757 case Type::LValueReference:
4758 case Type::RValueReference:
4759 case Type::ConstantArray:
4760 case Type::IncompleteArray:
4761 case Type::VariableArray:
4762 case Type::DependentSizedArray:
4763 case Type::DependentVector:
4764 case Type::DependentSizedExtVector:
4766 case Type::ExtVector:
4767 case Type::ConstantMatrix:
4768 case Type::DependentSizedMatrix:
4769 case Type::DependentAddressSpace:
4770 case Type::FunctionProto:
4771 case Type::FunctionNoProto:
4772 case Type::DeducedTemplateSpecialization:
4774 case Type::InjectedClassName:
4775 case Type::PackExpansion:
4776 case Type::ObjCObject:
4777 case Type::ObjCInterface:
4781 case Type::DependentBitInt:
4782 case Type::ArrayParameter:
4785 llvm_unreachable(
"bad type kind!");
4797 return std::nullopt;
4800std::optional<NullabilityKind>
4803 if (
auto MacroTy = dyn_cast<MacroQualifiedType>(
T))
4804 AttrTy = MacroTy->getUnderlyingType();
4806 if (
auto attributed = dyn_cast<AttributedType>(AttrTy)) {
4807 if (
auto nullability = attributed->getImmediateNullability()) {
4808 T = attributed->getModifiedType();
4813 return std::nullopt;
4817 const auto *objcPtr = getAs<ObjCObjectPointerType>();
4821 if (objcPtr->isObjCIdType()) {
4832 }
else if (objcPtr->isObjCQualifiedIdType()) {
4857 "cannot query implicit lifetime for non-inferrable type");
4862 while (
const auto *array = dyn_cast<ArrayType>(canon))
4863 canon = array->getElementType().getTypePtr();
4865 if (
const auto *opt = dyn_cast<ObjCObjectPointerType>(canon)) {
4867 if (opt->getObjectType()->isObjCClass())
4875 if (
const auto *
typedefType = getAs<TypedefType>())
4876 return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>();
4881 if (
const auto *
typedefType = getAs<TypedefType>())
4882 return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>();
4895 if (
const auto *OPT = getAs<PointerType>())
4896 return OPT->getPointeeType()->isObjCIndirectLifetimeType();
4897 if (
const auto *Ref = getAs<ReferenceType>())
4898 return Ref->getPointeeType()->isObjCIndirectLifetimeType();
4899 if (
const auto *MemPtr = getAs<MemberPointerType>())
4900 return MemPtr->getPointeeType()->isObjCIndirectLifetimeType();
4908 while (
const ArrayType *array =
type->getAsArrayTypeUnsafe())
4909 type = array->getElementType().getTypePtr();
4910 return type->isObjCRetainableType();
4921 const auto *
Pointer = getAs<PointerType>();
4931 if (
const auto *RT = getAs<RecordType>())
4932 return RT->getDecl()->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>();
4938 if (
const auto *RT = getAs<RecordType>())
4939 return RT->getDecl()->hasAttr<CUDADeviceBuiltinTextureTypeAttr>();
4946 if (
const auto *ptr = getAs<PointerType>())
4947 return ptr->getPointeeType()->hasSizedVLAType();
4948 if (
const auto *ref = getAs<ReferenceType>())
4949 return ref->getPointeeType()->hasSizedVLAType();
4951 if (isa<VariableArrayType>(arr) &&
4952 cast<VariableArrayType>(arr)->getSizeExpr())
4955 return arr->getElementType()->hasSizedVLAType();
4962 switch (
type.getObjCLifetime()) {
4974 if (
const auto *RT =
4977 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4979 if (CXXRD->hasDefinition() && !CXXRD->hasTrivialDestructor())
4997 llvm::APSInt Val,
unsigned Scale) {
4998 llvm::FixedPointSemantics FXSema(Val.getBitWidth(), Scale, Val.isSigned(),
5001 llvm::APFixedPoint(Val, FXSema).toString(Str);
5009 AutoTypeBits.Keyword = llvm::to_underlying(Keyword);
5010 AutoTypeBits.NumArgs = TypeConstraintArgs.size();
5011 this->TypeConstraintConcept = TypeConstraintConcept;
5012 assert(TypeConstraintConcept || AutoTypeBits.NumArgs == 0);
5013 if (TypeConstraintConcept) {
5032 ID.AddInteger((
unsigned)Keyword);
5033 ID.AddBoolean(IsDependent);
5036 Arg.Profile(ID, Context);
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Record Record
static bool isRecordType(QualType T)
Defines various enumerations that describe declaration and type specifiers.
Defines the TargetCXXABI class, which abstracts details of the C++ ABI that we're targeting.
static TagDecl * getInterestingTagDecl(TagDecl *decl)
#define SUGARED_TYPE_CLASS(Class)
static bool HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl)
static const TemplateTypeParmDecl * getReplacedParameter(Decl *D, unsigned Index)
static bool isTriviallyCopyableTypeImpl(const QualType &type, const ASTContext &Context, bool IsCopyConstructible)
static const T * getAsSugar(const Type *Cur)
This will check for a T (which should be a Type which can act as sugar, such as a TypedefType) by rem...
#define TRIVIAL_TYPE_CLASS(Class)
static CachedProperties computeCachedProperties(const Type *T)
C Language Family Type Representation.
Defines the clang::Visibility enumeration and various utility functions.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
BuiltinVectorTypeInfo getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const
Returns the element type, element count and number of vectors (in case of tuple) for a builtin vector...
QualType getAtomicType(QualType T) const
Return the uniqued reference to the atomic type for the specified type.
QualType getParenType(QualType NamedType) const
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) const
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent, bool IsPack=false, ConceptDecl *TypeConstraintConcept=nullptr, ArrayRef< TemplateArgument > TypeConstraintArgs={}) const
C++11 deduced auto type.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getBlockPointerType(QualType T) const
Return the uniqued reference to the type for a block of the specified type.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type.
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
QualType getArrayParameterType(QualType Ty) const
Return the uniqued reference to a specified array parameter type from the original array type.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
QualType applyObjCProtocolQualifiers(QualType type, ArrayRef< ObjCProtocolDecl * > protocols, bool &hasError, bool allowOnPointerType=false) const
Apply Objective-C protocol qualifiers to the given type.
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
bool hasUniqueObjectRepresentations(QualType Ty, bool CheckIfTriviallyCopyable=true) const
Return true if the specified type has unique object representations according to (C++17 [meta....
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType ObjCBuiltinIdTy
IdentifierInfo * getNSObjectName() const
Retrieve the identifier 'NSObject'.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getAdjustedType(QualType Orig, QualType New) const
Return the uniqued reference to a type adjusted from the original type to a new type.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const
Legacy interface: cannot provide type arguments or __kindof.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedCharTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, unsigned Index, std::optional< unsigned > PackIndex) const
Retrieve a substitution-result type.
QualType getIncompleteArrayType(QualType EltTy, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return a unique reference to the type for an incomplete array of the specified element type.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
IdentifierInfo * getNSCopyingName()
Retrieve the identifier 'NSCopying'.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, unsigned tq, const Expr *sz=nullptr)
An attributed type is a type to which a type attribute has been applied.
bool isCallingConv() const
std::optional< NullabilityKind > getImmediateNullability() const
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
bool isMSTypeSpec() const
bool isWebAssemblyFuncrefSpec() const
bool isQualifier() const
Does this attribute behave like a type qualifier?
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
ConceptDecl * getTypeConstraintConcept() const
AutoTypeKeyword getKeyword() const
BitIntType(bool isUnsigned, unsigned NumBits)
[BoundsSafety] Represents a parent type class for CountAttributedType and similar sugar types that wi...
BoundsAttributedType(TypeClass TC, QualType Wrapped, QualType Canon)
decl_range dependent_decls() const
bool referencesFieldDecls() const
ArrayRef< TypeCoupledDeclRefInfo > Decls
This class is used for builtin types like 'int'.
StringRef getName(const PrintingPolicy &Policy) const
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
bool mayBeNonDynamicClass() const
CXXRecordDecl * getMostRecentNonInjectedDecl()
bool mayBeDynamicClass() const
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Complex values, per C99 6.2.5p11.
Declaration of a C++20 concept.
Represents the canonical version of C arrays with a specified constant size.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
llvm::APInt getSize() const
Return the constant array size as an APInt.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
llvm::APSInt getResultAsAPSInt() const
Represents a concrete matrix type with constant number of rows and columns.
ConstantMatrixType(QualType MatrixElementType, unsigned NRows, unsigned NColumns, QualType CanonElementType)
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
void Profile(llvm::FoldingSetNodeID &ID)
Represents a pointer type decayed from an array or function type.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
ASTContext & getParentASTContext() const
bool isFunctionOrMethod() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
ASTContext & getASTContext() const LLVM_READONLY
DeclContext * getDeclContext()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Represents the type decltype(expr) (C++11).
QualType desugar() const
Remove a single level of sugar.
bool isSugared() const
Returns whether this type directly provides sugar.
DecltypeType(Expr *E, QualType underlyingType, QualType can=QualType())
QualType getUnderlyingType() const
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
Expr * getNumBitsExpr() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
DependentBitIntType(bool IsUnsigned, Expr *NumBits)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
DependentDecltypeType(Expr *E, QualType UnderlyingTpe)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
Represents an extended vector type where either the type or size is dependent.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context)
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
bool isComplete() const
Returns true if this can be considered a complete type.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
ExprDependence getDependence() const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Represents a function declaration or definition.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
bool hasDependentExceptionSpec() const
Return whether this function has a dependent exception spec.
param_type_iterator param_type_begin() const
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
bool isTemplateVariadic() const
Determines whether this function prototype contains a parameter pack at the end.
unsigned getNumParams() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
QualType getParamType(unsigned i) const
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
unsigned getNumExceptions() const
Return the number of types in the exception specification.
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
ExtProtoInfo getExtProtoInfo() const
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > exceptions() const
bool hasInstantiationDependentExceptionSpec() const
Return whether this function has an instantiation-dependent exception spec.
A class which abstracts out some details necessary for making a call.
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
static StringRef getNameForCallConv(CallingConv CC)
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Represents a C array with an unspecified size.
CXXRecordDecl * getDecl() const
An lvalue reference type, per C++11 [dcl.ref].
LinkageInfo computeTypeLinkageInfo(const Type *T)
LinkageInfo getTypeLinkageAndVisibility(const Type *T)
LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D)
static LinkageInfo external()
Linkage getLinkage() const
void merge(LinkageInfo other)
Merge both linkage and visibility.
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
QualType getModifiedType() const
Return this attributed type's modified type with no qualifiers attached to it.
QualType getUnderlyingType() const
const IdentifierInfo * getMacroIdentifier() const
Represents a matrix type, as defined in the Matrix Types clang extensions.
MatrixType(QualType ElementTy, QualType CanonElementTy)
QualType ElementType
The element type of the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
const Type * getClass() const
This represents a decl that may have a name.
Linkage getLinkageInternal() const
Determine what kind of linkage this entity has.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameter list associated with this category or extension.
Represents an ObjC class declaration.
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Represents a pointer to an Objective C object.
const ObjCObjectPointerType * stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const
Strip off the Objective-C "kindof" type and (with it) any protocol qualifiers.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
QualType getSuperClassType() const
Retrieve the type of the superclass of this object pointer type.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
bool isKindOfType() const
Whether this is a "__kindof" type.
void Profile(llvm::FoldingSetNodeID &ID)
Represents a class type in Objective C.
bool isKindOfTypeAsWritten() const
Whether this is a "__kindof" type as written.
bool isSpecialized() const
Determine whether this object type is "specialized", meaning that it has type arguments.
ObjCObjectType(QualType Canonical, QualType Base, ArrayRef< QualType > typeArgs, ArrayRef< ObjCProtocolDecl * > protocols, bool isKindOf)
ArrayRef< QualType > getTypeArgsAsWritten() const
Retrieve the type arguments of this object type as they were written.
QualType getBaseType() const
Gets the base type of this object type.
bool isKindOfType() const
Whether this ia a "__kindof" type (semantically).
bool isSpecializedAsWritten() const
Determine whether this object type was written with type arguments.
ArrayRef< QualType > getTypeArgs() const
Retrieve the type arguments of this object type (semantically).
bool isUnspecialized() const
Determine whether this object type is "unspecialized", meaning that it has no type arguments.
QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const
Strip off the Objective-C "kindof" type and (with it) any protocol qualifiers.
void computeSuperClassTypeSlow() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
QualType getSuperClassType() const
Retrieve the type of the superclass of this object type.
Represents an Objective-C protocol declaration.
void initialize(ArrayRef< ObjCProtocolDecl * > protocols)
ArrayRef< ObjCProtocolDecl * > getProtocols() const
Retrieve all of the protocol qualifiers.
unsigned getNumProtocols() const
Return the number of qualifying protocols in this type, or 0 if there are none.
qual_iterator qual_end() const
qual_iterator qual_begin() const
Represents the declaration of an Objective-C type parameter.
unsigned getIndex() const
Retrieve the index into its type parameter list.
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
unsigned size() const
Determine the number of type parameters in this list.
Represents a type parameter type in Objective C.
void Profile(llvm::FoldingSetNodeID &ID)
ObjCTypeParamDecl * getDecl() const
Represents a pack expansion of types.
PackIndexingType(const ASTContext &Context, QualType Canonical, QualType Pattern, Expr *IndexExpr, ArrayRef< QualType > Expansions={})
void Profile(llvm::FoldingSetNodeID &ID)
Expr * getIndexExpr() const
std::optional< unsigned > getSelectedIndex() const
Sugar for parentheses used when specifying types.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
QualType withFastQualifiers(unsigned TQs) const
bool hasNonTrivialToPrimitiveCopyCUnion() const
Check if this is or contains a C union that is non-trivial to copy, which is a union that has a membe...
bool isWebAssemblyFuncrefType() const
Returns true if it is a WebAssembly Funcref Type.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
@ DK_objc_strong_lifetime
PrimitiveDefaultInitializeKind
@ PDIK_ARCWeak
The type is an Objective-C retainable pointer type that is qualified with the ARC __weak qualifier.
@ PDIK_Trivial
The type does not fall into any of the following categories.
@ PDIK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
@ PDIK_Struct
The type is a struct containing a field whose type is not PCK_Trivial.
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const
const IdentifierInfo * getBaseTypeIdentifier() const
Retrieves a pointer to the name of the base type.
void Profile(llvm::FoldingSetNodeID &ID) const
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isTriviallyCopyConstructibleType(const ASTContext &Context) const
Return true if this is a trivially copyable type.
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const
Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...
bool isTriviallyRelocatableType(const ASTContext &Context) const
Return true if this is a trivially relocatable type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
bool hasNonTrivialToPrimitiveDestructCUnion() const
Check if this is or contains a C union that is non-trivial to destruct, which is a union that has a m...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isCXX98PODType(const ASTContext &Context) const
Return true if this is a POD type according to the rules of the C++98 standard, regardless of the cur...
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType stripObjCKindOfType(const ASTContext &ctx) const
Strip Objective-C "__kindof" types from the given type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isTriviallyEqualityComparableType(const ASTContext &Context) const
Return true if this is a trivially equality comparable type.
QualType substObjCMemberType(QualType objectType, const DeclContext *dc, ObjCSubstitutionContext context) const
Substitute type arguments from an object type for the Objective-C type parameters used in the subject...
bool isWebAssemblyReferenceType() const
Returns true if it is a WebAssembly Reference Type.
SplitQualType getSplitDesugaredType() const
std::optional< NonConstantStorageReason > isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Determine whether instances of this type can be placed in immutable storage.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
bool UseExcessPrecision(const ASTContext &Ctx)
PrimitiveDefaultInitializeKind isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C struct types.
void * getAsOpaquePtr() const
bool isWebAssemblyExternrefType() const
Returns true if it is a WebAssembly Externref Type.
QualType getNonPackExpansionType() const
Remove an outer pack expansion type (if any) from this type.
bool isCXX11PODType(const ASTContext &Context) const
Return true if this is a POD type according to the more relaxed rules of the C++11 standard,...
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
bool isConstQualified() const
Determine whether this type is const-qualified.
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool hasNonTrivialObjCLifetime() const
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const
Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...
@ NonConstNonReferenceType
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
@ PCK_Trivial
The type does not fall into any of the following categories.
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
@ PCK_VolatileTrivial
The type would be trivial except that it is volatile-qualified.
@ PCK_ARCWeak
The type is an Objective-C retainable pointer type that is qualified with the ARC __weak qualifier.
bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const
Check if this is or contains a C union that is non-trivial to default-initialize, which is a union th...
A qualifier set is used to build a set of qualifiers.
const Type * strip(QualType type)
Collect any qualifiers on the given type and return an unqualified type.
QualType apply(const ASTContext &Context, QualType QT) const
Apply the collected qualifiers to the given type.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool isStrictSupersetOf(Qualifiers Other) const
Determine whether this set of qualifiers is a strict superset of another set of qualifiers,...
bool hasNonFastQualifiers() const
Return true if the set contains any qualifiers which require an ExtQuals node to be allocated.
void addConsistentQualifiers(Qualifiers qs)
Add the qualifiers from the given set to this set, given that they don't conflict.
bool hasAddressSpace() const
unsigned getFastQualifiers() const
bool hasObjCGCAttr() const
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
LangAS getAddressSpace() const
An rvalue reference type, per C++11 [dcl.ref].
Represents a struct/union/class.
bool hasNonTrivialToPrimitiveDestructCUnion() const
bool hasNonTrivialToPrimitiveCopyCUnion() const
bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const
bool isNonTrivialToPrimitiveDestroy() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
bool hasConstFields() const
Recursively check all fields in the record for const-ness.
Base for LValueReferenceType and RValueReferenceType.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
IdentifierInfo * getIdentifier() const
TemplateArgument getArgumentPack() const
void Profile(llvm::FoldingSetNodeID &ID)
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
unsigned getNumArgs() const
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
Represents the result of substituting a type for a template type parameter.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
Represents the declaration of a struct/union/class/enum.
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool hasNameForLinkage() const
Is this tag type named, either directly or via being defined in a typedef of this type?
TagType(TypeClass TC, const TagDecl *D, QualType can)
TagDecl * getDecl() const
bool isBeingDefined() const
Determines whether this type is in the process of being defined.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
Exposes information about the current target.
virtual bool hasLegalHalfType() const
Determine whether _Float16 is supported on this target.
virtual bool hasFullBFloat16Type() const
Determine whether the BFloat type is fully supported on this target, i.e arithemtic operations.
virtual bool hasFloat16Type() const
Determine whether the _Float16 type is supported on this target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual bool hasBFloat16Type() const
Determine whether the _BFloat16 type is supported on this target.
A convenient class for passing around template argument information.
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
Represents a template argument.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Represents a C++ template name within the type system.
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
@ Template
A single template declaration.
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Represents a type template specialization; the template must be a class template, a type alias templa...
QualType getAliasedType() const
Get the aliased type, if this is a specialization of a type alias template.
ArrayRef< TemplateArgument > template_arguments() const
bool isTypeAlias() const
Determine if this template specialization type is for a type alias template that has been substituted...
static bool anyInstantiationDependentTemplateArguments(ArrayRef< TemplateArgumentLoc > Args)
static bool anyDependentTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, ArrayRef< TemplateArgument > Converted)
Determine whether any of the given template arguments are dependent.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Declaration of a template type parameter.
TemplateTypeParmDecl * getDecl() const
IdentifierInfo * getIdentifier() const
[BoundsSafety] Represents information of declarations referenced by the arguments of the counted_by a...
ValueDecl * getDecl() const
bool operator==(const TypeCoupledDeclRefInfo &Other) const
void * getOpaqueValue() const
TypeCoupledDeclRefInfo(ValueDecl *D=nullptr, bool Deref=false)
D is to a declaration referenced by the argument of attribute.
void setFromOpaqueValue(void *V)
TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can=QualType())
bool isSugared() const
Returns whether this type directly provides sugar.
Expr * getUnderlyingExpr() const
QualType desugar() const
Remove a single level of sugar.
static void ensure(const Type *T)
static CachedProperties get(QualType T)
static CachedProperties get(const Type *T)
A helper class for Type nodes having an ElaboratedTypeKeyword.
static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec)
Converts a type specifier (DeclSpec::TST) into an elaborated type keyword.
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)
Converts an elaborated type keyword into a TagTypeKind.
static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword)
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag)
Converts a TagTypeKind into an elaborated type keyword.
static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec)
Converts a type specifier (DeclSpec::TST) into a tag type kind.
The base class of the type hierarchy.
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
bool isStructureType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
const ObjCObjectPointerType * getAsObjCQualifiedClassType() const
bool isLinkageValid() const
True if the computed linkage is valid.
TypedefBitfields TypedefBits
const ObjCObjectType * getAsObjCQualifiedInterfaceType() const
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool hasAttr(attr::Kind AK) const
Determine whether this type had the specified attribute applied to it (looking through top-level type...
QualType getRVVEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an RVV builtin type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
ArrayTypeBitfields ArrayTypeBits
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
VectorTypeBitfields VectorTypeBits
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
const ComplexType * getAsComplexIntegerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isObjCARCBridgableType() const
Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...
bool isArithmeticType() const
bool isPointerType() const
TypeOfBitfields TypeOfBits
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isSVESizelessBuiltinType() const
Returns true for SVE scalable vector types.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
void addDependence(TypeDependence D)
bool isObjCNSObjectType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isInterfaceType() const
bool isVariableArrayType() const
bool isSizelessBuiltinType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool isElaboratedTypeSpecifier() const
Determine wither this type is a C++ elaborated-type-specifier.
CountAttributedTypeBitfields CountAttributedTypeBits
const Type * getArrayElementTypeNoTypeQual() const
If this is an array type, return the element type of the array, potentially with type qualifiers miss...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
LinkageInfo getLinkageAndVisibility() const
Determine the linkage and visibility of this type.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
bool isWebAssemblyExternrefType() const
Check if this is a WebAssembly Externref Type.
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
bool isLValueReferenceType() const
bool isBitIntType() const
bool isStructuralType() const
Determine if this type is a structural type, per C++20 [temp.param]p7.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
bool isChar16Type() const
bool isAnyComplexType() const
DependentTemplateSpecializationTypeBitfields DependentTemplateSpecializationTypeBits
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
ScalarTypeKind getScalarTypeKind() const
Given that this is a scalar type, classify it.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
const RecordType * getAsStructureType() const
const char * getTypeClassName() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isObjCBoxableRecordType() const
bool isChar32Type() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isComplexIntegerType() const
bool isUnscopedEnumerationType() const
bool isStdByteType() const
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const
bool isObjCClassOrClassKindOfType() const
Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isObjectType() const
Determine whether this type is an object type.
bool isObjCIndirectLifetimeType() const
bool hasUnnamedOrLocalType() const
Whether this type is or contains a local or unnamed type.
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const
Return the implicit lifetime for this type, which must not be dependent.
FunctionTypeBitfields FunctionTypeBits
bool isObjCQualifiedInterfaceType() const
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
TypeDependence getDependence() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRVVVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'riscv_rvv_vector_bits' type attribute,...
bool isRealFloatingType() const
Floating point categories.
bool isRVVSizelessBuiltinType() const
Returns true for RVV scalable vector types.
std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const
Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...
Linkage getLinkage() const
Determine the linkage of this type.
ObjCObjectTypeBitfields ObjCObjectTypeBits
bool isFloatingType() const
const ObjCObjectType * getAsObjCInterfaceType() const
bool isWideCharType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool hasSizedVLAType() const
Whether this type involves a variable-length array type with a definite size.
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
bool hasAutoForTrailingReturnType() const
Determine whether this type was written with a leading 'auto' corresponding to a trailing return type...
bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, const ObjCObjectType *&bound) const
Whether the type is Objective-C 'id' or a __kindof type of an object type, e.g., __kindof NSView * or...
const T * getAs() const
Member-template getAs<specific type>'.
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
bool isObjCARCImplicitlyUnretainedType() const
Determines if this type, which must satisfy isObjCLifetimeType(), is implicitly __unsafe_unretained r...
bool isRecordType() const
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isObjCIndependentClassType() const
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool isScopedEnumeralType() const
Determine whether this type is a scoped enumeration type.
bool acceptsObjCTypeParams() const
Determines if this is an ObjC interface type that may accept type parameters.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
bool typeMatchesDecl() const
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
QualType getUnderlyingType() const
bool typeMatchesDecl() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
VectorType(QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind)
QualType getElementType() const
Defines the Linkage enumeration and various utility functions.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< TypedefType > typedefType
Matches typedef types.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
AutoTypeKeyword
Which keyword(s) were used to create an AutoType.
CanThrowResult
Possible results from evaluation of a noexcept expression.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
Linkage minLinkage(Linkage L1, Linkage L2)
Compute the minimum linkage given two linkages.
@ Nullable
Values of this type can be null.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
ExprDependence computeDependence(FullExpr *E)
TypeOfKind
The kind of 'typeof' expression we're after.
TypeDependence toTypeDependence(ExprDependence D)
ExprDependence turnValueToTypeDependence(ExprDependence D)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
ObjCSubstitutionContext
The kind of type we are substituting Objective-C type arguments into.
@ Superclass
The superclass of a type.
@ Result
The result type of a method or function.
ArraySizeModifier
Capture whether this is a normal array (e.g.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
@ Interface
The "__interface" keyword.
@ Struct
The "struct" keyword.
@ Class
The "class" keyword.
@ Union
The "union" keyword.
@ Enum
The "enum" keyword.
void FixedPointValueToString(SmallVectorImpl< char > &Str, llvm::APSInt Val, unsigned Scale)
const FunctionProtoType * T
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ None
The alignment was not explicit in code.
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ None
No keyword precedes the qualified type name.
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Union
The "union" keyword introduces the elaborated-type-specifier.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
TypeDependence toSemanticDependence(TypeDependence D)
TypeDependence toSyntacticDependence(TypeDependence D)
@ Other
Other implicit parameter.
@ EST_DependentNoexcept
noexcept(expression), value-dependent
@ EST_Uninstantiated
not instantiated yet
@ EST_Unparsed
not parsed yet
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_None
no exception specification
@ EST_MSAny
Microsoft throw(...) extension.
@ EST_BasicNoexcept
noexcept
@ EST_NoexceptFalse
noexcept(expression), evals to 'false'
@ EST_Unevaluated
not evaluated yet, for special member function
@ EST_NoexceptTrue
noexcept(expression), evals to 'true'
@ EST_Dynamic
throw(T1, T2)
FunctionDecl * SourceDecl
The function whose exception specification this is, for EST_Unevaluated and EST_Uninstantiated.
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
ExceptionSpecificationType Type
The kind of exception specification this is.
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Extra information about a function prototype.
ExceptionSpecInfo ExceptionSpec
bool requiresFunctionProtoTypeArmAttributes() const
unsigned AArch64SMEAttributes
SourceLocation EllipsisLoc
const ExtParameterInfo * ExtParameterInfos
RefQualifierKind RefQualifier
unsigned HasTrailingReturn
bool requiresFunctionProtoTypeExtraBitfields() const
Describes how types, statements, expressions, and declarations should be printed.
unsigned Bool
Whether we can use 'bool' rather than '_Bool' (even if the language doesn't actually have 'bool',...
unsigned NullptrTypeInNamespace
Whether 'nullptr_t' is in namespace 'std' or not.
unsigned Half
When true, print the half-precision floating-point type as 'half' instead of '__fp16'.
unsigned MSWChar
When true, print the built-in wchar_t type as __wchar_t.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
const Type * Ty
The locally-unqualified type.
Qualifiers Quals
The local qualifiers.