File indexing completed on 2026-05-10 08:36:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_CLANG_AST_TYPE_H
0018 #define LLVM_CLANG_AST_TYPE_H
0019
0020 #include "clang/AST/DependenceFlags.h"
0021 #include "clang/AST/NestedNameSpecifier.h"
0022 #include "clang/AST/TemplateName.h"
0023 #include "clang/Basic/AddressSpaces.h"
0024 #include "clang/Basic/AttrKinds.h"
0025 #include "clang/Basic/Diagnostic.h"
0026 #include "clang/Basic/ExceptionSpecificationType.h"
0027 #include "clang/Basic/LLVM.h"
0028 #include "clang/Basic/LangOptions.h"
0029 #include "clang/Basic/Linkage.h"
0030 #include "clang/Basic/PartialDiagnostic.h"
0031 #include "clang/Basic/PointerAuthOptions.h"
0032 #include "clang/Basic/SourceLocation.h"
0033 #include "clang/Basic/Specifiers.h"
0034 #include "clang/Basic/Visibility.h"
0035 #include "llvm/ADT/APInt.h"
0036 #include "llvm/ADT/APSInt.h"
0037 #include "llvm/ADT/ArrayRef.h"
0038 #include "llvm/ADT/FoldingSet.h"
0039 #include "llvm/ADT/PointerIntPair.h"
0040 #include "llvm/ADT/PointerUnion.h"
0041 #include "llvm/ADT/STLForwardCompat.h"
0042 #include "llvm/ADT/StringRef.h"
0043 #include "llvm/ADT/Twine.h"
0044 #include "llvm/ADT/iterator_range.h"
0045 #include "llvm/Support/Casting.h"
0046 #include "llvm/Support/Compiler.h"
0047 #include "llvm/Support/DXILABI.h"
0048 #include "llvm/Support/ErrorHandling.h"
0049 #include "llvm/Support/PointerLikeTypeTraits.h"
0050 #include "llvm/Support/TrailingObjects.h"
0051 #include "llvm/Support/type_traits.h"
0052 #include <bitset>
0053 #include <cassert>
0054 #include <cstddef>
0055 #include <cstdint>
0056 #include <cstring>
0057 #include <optional>
0058 #include <string>
0059 #include <type_traits>
0060 #include <utility>
0061
0062 namespace clang {
0063
0064 class BTFTypeTagAttr;
0065 class ExtQuals;
0066 class QualType;
0067 class ConceptDecl;
0068 class ValueDecl;
0069 class TagDecl;
0070 class TemplateParameterList;
0071 class Type;
0072 class Attr;
0073
0074 enum {
0075 TypeAlignmentInBits = 4,
0076 TypeAlignment = 1 << TypeAlignmentInBits
0077 };
0078
0079 namespace serialization {
0080 template <class T> class AbstractTypeReader;
0081 template <class T> class AbstractTypeWriter;
0082 }
0083
0084 }
0085
0086 namespace llvm {
0087
0088 template <typename T>
0089 struct PointerLikeTypeTraits;
0090 template<>
0091 struct PointerLikeTypeTraits< ::clang::Type*> {
0092 static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
0093
0094 static inline ::clang::Type *getFromVoidPointer(void *P) {
0095 return static_cast< ::clang::Type*>(P);
0096 }
0097
0098 static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
0099 };
0100
0101 template<>
0102 struct PointerLikeTypeTraits< ::clang::ExtQuals*> {
0103 static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
0104
0105 static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
0106 return static_cast< ::clang::ExtQuals*>(P);
0107 }
0108
0109 static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
0110 };
0111
0112 }
0113
0114 namespace clang {
0115
0116 class ASTContext;
0117 template <typename> class CanQual;
0118 class CXXRecordDecl;
0119 class DeclContext;
0120 class EnumDecl;
0121 class Expr;
0122 class ExtQualsTypeCommonBase;
0123 class FunctionDecl;
0124 class FunctionEffectsRef;
0125 class FunctionEffectKindSet;
0126 class FunctionEffectSet;
0127 class IdentifierInfo;
0128 class NamedDecl;
0129 class ObjCInterfaceDecl;
0130 class ObjCProtocolDecl;
0131 class ObjCTypeParamDecl;
0132 struct PrintingPolicy;
0133 class RecordDecl;
0134 class Stmt;
0135 class TagDecl;
0136 class TemplateArgument;
0137 class TemplateArgumentListInfo;
0138 class TemplateArgumentLoc;
0139 class TemplateTypeParmDecl;
0140 class TypedefNameDecl;
0141 class UnresolvedUsingTypenameDecl;
0142 class UsingShadowDecl;
0143
0144 using CanQualType = CanQual<Type>;
0145
0146
0147 #define TYPE(Class, Base) class Class##Type;
0148 #include "clang/AST/TypeNodes.inc"
0149
0150
0151 class PointerAuthQualifier {
0152 enum : uint32_t {
0153 EnabledShift = 0,
0154 EnabledBits = 1,
0155 EnabledMask = 1 << EnabledShift,
0156 AddressDiscriminatedShift = EnabledShift + EnabledBits,
0157 AddressDiscriminatedBits = 1,
0158 AddressDiscriminatedMask = 1 << AddressDiscriminatedShift,
0159 AuthenticationModeShift =
0160 AddressDiscriminatedShift + AddressDiscriminatedBits,
0161 AuthenticationModeBits = 2,
0162 AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1)
0163 << AuthenticationModeShift,
0164 IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits,
0165 IsaPointerBits = 1,
0166 IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift,
0167 AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits,
0168 AuthenticatesNullValuesBits = 1,
0169 AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1)
0170 << AuthenticatesNullValuesShift,
0171 KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits,
0172 KeyBits = 10,
0173 KeyMask = ((1 << KeyBits) - 1) << KeyShift,
0174 DiscriminatorShift = KeyShift + KeyBits,
0175 DiscriminatorBits = 16,
0176 DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift,
0177 };
0178
0179
0180
0181
0182
0183 uint32_t Data = 0;
0184
0185
0186
0187 static_assert((EnabledBits + AddressDiscriminatedBits +
0188 AuthenticationModeBits + IsaPointerBits +
0189 AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) ==
0190 32,
0191 "PointerAuthQualifier should be exactly 32 bits");
0192 static_assert((EnabledMask + AddressDiscriminatedMask +
0193 AuthenticationModeMask + IsaPointerMask +
0194 AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) ==
0195 0xFFFFFFFF,
0196 "All masks should cover the entire bits");
0197 static_assert((EnabledMask ^ AddressDiscriminatedMask ^
0198 AuthenticationModeMask ^ IsaPointerMask ^
0199 AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) ==
0200 0xFFFFFFFF,
0201 "All masks should cover the entire bits");
0202
0203 PointerAuthQualifier(unsigned Key, bool IsAddressDiscriminated,
0204 unsigned ExtraDiscriminator,
0205 PointerAuthenticationMode AuthenticationMode,
0206 bool IsIsaPointer, bool AuthenticatesNullValues)
0207 : Data(EnabledMask |
0208 (IsAddressDiscriminated
0209 ? llvm::to_underlying(AddressDiscriminatedMask)
0210 : 0) |
0211 (Key << KeyShift) |
0212 (llvm::to_underlying(AuthenticationMode)
0213 << AuthenticationModeShift) |
0214 (ExtraDiscriminator << DiscriminatorShift) |
0215 (IsIsaPointer << IsaPointerShift) |
0216 (AuthenticatesNullValues << AuthenticatesNullValuesShift)) {
0217 assert(Key <= KeyNoneInternal);
0218 assert(ExtraDiscriminator <= MaxDiscriminator);
0219 assert((Data == 0) ==
0220 (getAuthenticationMode() == PointerAuthenticationMode::None));
0221 }
0222
0223 public:
0224 enum {
0225 KeyNoneInternal = (1u << KeyBits) - 1,
0226
0227
0228 MaxKey = KeyNoneInternal - 1,
0229
0230
0231 MaxDiscriminator = (1u << DiscriminatorBits) - 1
0232 };
0233
0234 public:
0235 PointerAuthQualifier() = default;
0236
0237 static PointerAuthQualifier
0238 Create(unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator,
0239 PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer,
0240 bool AuthenticatesNullValues) {
0241 if (Key == PointerAuthKeyNone)
0242 Key = KeyNoneInternal;
0243 assert(Key <= KeyNoneInternal && "out-of-range key value");
0244 return PointerAuthQualifier(Key, IsAddressDiscriminated, ExtraDiscriminator,
0245 AuthenticationMode, IsIsaPointer,
0246 AuthenticatesNullValues);
0247 }
0248
0249 bool isPresent() const {
0250 assert((Data == 0) ==
0251 (getAuthenticationMode() == PointerAuthenticationMode::None));
0252 return Data != 0;
0253 }
0254
0255 explicit operator bool() const { return isPresent(); }
0256
0257 unsigned getKey() const {
0258 assert(isPresent());
0259 return (Data & KeyMask) >> KeyShift;
0260 }
0261
0262 bool hasKeyNone() const { return isPresent() && getKey() == KeyNoneInternal; }
0263
0264 bool isAddressDiscriminated() const {
0265 assert(isPresent());
0266 return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift;
0267 }
0268
0269 unsigned getExtraDiscriminator() const {
0270 assert(isPresent());
0271 return (Data >> DiscriminatorShift);
0272 }
0273
0274 PointerAuthenticationMode getAuthenticationMode() const {
0275 return PointerAuthenticationMode((Data & AuthenticationModeMask) >>
0276 AuthenticationModeShift);
0277 }
0278
0279 bool isIsaPointer() const {
0280 assert(isPresent());
0281 return (Data & IsaPointerMask) >> IsaPointerShift;
0282 }
0283
0284 bool authenticatesNullValues() const {
0285 assert(isPresent());
0286 return (Data & AuthenticatesNullValuesMask) >> AuthenticatesNullValuesShift;
0287 }
0288
0289 PointerAuthQualifier withoutKeyNone() const {
0290 return hasKeyNone() ? PointerAuthQualifier() : *this;
0291 }
0292
0293 friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
0294 return Lhs.Data == Rhs.Data;
0295 }
0296 friend bool operator!=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
0297 return Lhs.Data != Rhs.Data;
0298 }
0299
0300 bool isEquivalent(PointerAuthQualifier Other) const {
0301 return withoutKeyNone() == Other.withoutKeyNone();
0302 }
0303
0304 uint32_t getAsOpaqueValue() const { return Data; }
0305
0306
0307 static PointerAuthQualifier fromOpaqueValue(uint32_t Opaque) {
0308 PointerAuthQualifier Result;
0309 Result.Data = Opaque;
0310 assert((Result.Data == 0) ==
0311 (Result.getAuthenticationMode() == PointerAuthenticationMode::None));
0312 return Result;
0313 }
0314
0315 void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Data); }
0316 };
0317
0318
0319
0320
0321
0322
0323
0324 class Qualifiers {
0325 public:
0326 Qualifiers() = default;
0327 enum TQ : uint64_t {
0328
0329 Const = 0x1,
0330 Restrict = 0x2,
0331 Volatile = 0x4,
0332 CVRMask = Const | Volatile | Restrict
0333 };
0334
0335 enum GC {
0336 GCNone = 0,
0337 Weak,
0338 Strong
0339 };
0340
0341 enum ObjCLifetime {
0342
0343 OCL_None,
0344
0345
0346
0347 OCL_ExplicitNone,
0348
0349
0350
0351
0352
0353
0354 OCL_Strong,
0355
0356
0357 OCL_Weak,
0358
0359
0360 OCL_Autoreleasing
0361 };
0362
0363 enum : uint64_t {
0364
0365
0366 MaxAddressSpace = 0x7fffffu,
0367
0368
0369 FastWidth = 3,
0370
0371
0372 FastMask = (1 << FastWidth) - 1
0373 };
0374
0375
0376
0377 static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
0378 Qualifiers Q;
0379 PointerAuthQualifier LPtrAuth = L.getPointerAuth();
0380 if (LPtrAuth.isPresent() &&
0381 LPtrAuth.getKey() != PointerAuthQualifier::KeyNoneInternal &&
0382 LPtrAuth == R.getPointerAuth()) {
0383 Q.setPointerAuth(LPtrAuth);
0384 PointerAuthQualifier Empty;
0385 L.setPointerAuth(Empty);
0386 R.setPointerAuth(Empty);
0387 }
0388
0389
0390 if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
0391 Q.Mask = L.Mask & R.Mask;
0392 L.Mask &= ~Q.Mask;
0393 R.Mask &= ~Q.Mask;
0394 return Q;
0395 }
0396
0397 unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
0398 Q.addCVRQualifiers(CommonCRV);
0399 L.removeCVRQualifiers(CommonCRV);
0400 R.removeCVRQualifiers(CommonCRV);
0401
0402 if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
0403 Q.setObjCGCAttr(L.getObjCGCAttr());
0404 L.removeObjCGCAttr();
0405 R.removeObjCGCAttr();
0406 }
0407
0408 if (L.getObjCLifetime() == R.getObjCLifetime()) {
0409 Q.setObjCLifetime(L.getObjCLifetime());
0410 L.removeObjCLifetime();
0411 R.removeObjCLifetime();
0412 }
0413
0414 if (L.getAddressSpace() == R.getAddressSpace()) {
0415 Q.setAddressSpace(L.getAddressSpace());
0416 L.removeAddressSpace();
0417 R.removeAddressSpace();
0418 }
0419 return Q;
0420 }
0421
0422 static Qualifiers fromFastMask(unsigned Mask) {
0423 Qualifiers Qs;
0424 Qs.addFastQualifiers(Mask);
0425 return Qs;
0426 }
0427
0428 static Qualifiers fromCVRMask(unsigned CVR) {
0429 Qualifiers Qs;
0430 Qs.addCVRQualifiers(CVR);
0431 return Qs;
0432 }
0433
0434 static Qualifiers fromCVRUMask(unsigned CVRU) {
0435 Qualifiers Qs;
0436 Qs.addCVRUQualifiers(CVRU);
0437 return Qs;
0438 }
0439
0440
0441 static Qualifiers fromOpaqueValue(uint64_t opaque) {
0442 Qualifiers Qs;
0443 Qs.Mask = opaque;
0444 return Qs;
0445 }
0446
0447
0448 uint64_t getAsOpaqueValue() const { return Mask; }
0449
0450 bool hasConst() const { return Mask & Const; }
0451 bool hasOnlyConst() const { return Mask == Const; }
0452 void removeConst() { Mask &= ~Const; }
0453 void addConst() { Mask |= Const; }
0454 Qualifiers withConst() const {
0455 Qualifiers Qs = *this;
0456 Qs.addConst();
0457 return Qs;
0458 }
0459
0460 bool hasVolatile() const { return Mask & Volatile; }
0461 bool hasOnlyVolatile() const { return Mask == Volatile; }
0462 void removeVolatile() { Mask &= ~Volatile; }
0463 void addVolatile() { Mask |= Volatile; }
0464 Qualifiers withVolatile() const {
0465 Qualifiers Qs = *this;
0466 Qs.addVolatile();
0467 return Qs;
0468 }
0469
0470 bool hasRestrict() const { return Mask & Restrict; }
0471 bool hasOnlyRestrict() const { return Mask == Restrict; }
0472 void removeRestrict() { Mask &= ~Restrict; }
0473 void addRestrict() { Mask |= Restrict; }
0474 Qualifiers withRestrict() const {
0475 Qualifiers Qs = *this;
0476 Qs.addRestrict();
0477 return Qs;
0478 }
0479
0480 bool hasCVRQualifiers() const { return getCVRQualifiers(); }
0481 unsigned getCVRQualifiers() const { return Mask & CVRMask; }
0482 unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); }
0483
0484 void setCVRQualifiers(unsigned mask) {
0485 assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
0486 Mask = (Mask & ~CVRMask) | mask;
0487 }
0488 void removeCVRQualifiers(unsigned mask) {
0489 assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
0490 Mask &= ~static_cast<uint64_t>(mask);
0491 }
0492 void removeCVRQualifiers() {
0493 removeCVRQualifiers(CVRMask);
0494 }
0495 void addCVRQualifiers(unsigned mask) {
0496 assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
0497 Mask |= mask;
0498 }
0499 void addCVRUQualifiers(unsigned mask) {
0500 assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits");
0501 Mask |= mask;
0502 }
0503
0504 bool hasUnaligned() const { return Mask & UMask; }
0505 void setUnaligned(bool flag) {
0506 Mask = (Mask & ~UMask) | (flag ? UMask : 0);
0507 }
0508 void removeUnaligned() { Mask &= ~UMask; }
0509 void addUnaligned() { Mask |= UMask; }
0510
0511 bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
0512 GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
0513 void setObjCGCAttr(GC type) {
0514 Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
0515 }
0516 void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
0517 void addObjCGCAttr(GC type) {
0518 assert(type);
0519 setObjCGCAttr(type);
0520 }
0521 Qualifiers withoutObjCGCAttr() const {
0522 Qualifiers qs = *this;
0523 qs.removeObjCGCAttr();
0524 return qs;
0525 }
0526 Qualifiers withoutObjCLifetime() const {
0527 Qualifiers qs = *this;
0528 qs.removeObjCLifetime();
0529 return qs;
0530 }
0531 Qualifiers withoutAddressSpace() const {
0532 Qualifiers qs = *this;
0533 qs.removeAddressSpace();
0534 return qs;
0535 }
0536
0537 bool hasObjCLifetime() const { return Mask & LifetimeMask; }
0538 ObjCLifetime getObjCLifetime() const {
0539 return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
0540 }
0541 void setObjCLifetime(ObjCLifetime type) {
0542 Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
0543 }
0544 void removeObjCLifetime() { setObjCLifetime(OCL_None); }
0545 void addObjCLifetime(ObjCLifetime type) {
0546 assert(type);
0547 assert(!hasObjCLifetime());
0548 Mask |= (type << LifetimeShift);
0549 }
0550
0551
0552 bool hasNonTrivialObjCLifetime() const {
0553 ObjCLifetime lifetime = getObjCLifetime();
0554 return (lifetime > OCL_ExplicitNone);
0555 }
0556
0557
0558 bool hasStrongOrWeakObjCLifetime() const {
0559 ObjCLifetime lifetime = getObjCLifetime();
0560 return (lifetime == OCL_Strong || lifetime == OCL_Weak);
0561 }
0562
0563 bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
0564 LangAS getAddressSpace() const {
0565 return static_cast<LangAS>(Mask >> AddressSpaceShift);
0566 }
0567 bool hasTargetSpecificAddressSpace() const {
0568 return isTargetAddressSpace(getAddressSpace());
0569 }
0570
0571 unsigned getAddressSpaceAttributePrintValue() const {
0572 auto Addr = getAddressSpace();
0573
0574
0575
0576 assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace());
0577 if (Addr != LangAS::Default)
0578 return toTargetAddressSpace(Addr);
0579
0580
0581
0582 return 0;
0583 }
0584 void setAddressSpace(LangAS space) {
0585 assert((unsigned)space <= MaxAddressSpace);
0586 Mask = (Mask & ~AddressSpaceMask)
0587 | (((uint32_t) space) << AddressSpaceShift);
0588 }
0589 void removeAddressSpace() { setAddressSpace(LangAS::Default); }
0590 void addAddressSpace(LangAS space) {
0591 assert(space != LangAS::Default);
0592 setAddressSpace(space);
0593 }
0594
0595 bool hasPointerAuth() const { return Mask & PtrAuthMask; }
0596 PointerAuthQualifier getPointerAuth() const {
0597 return PointerAuthQualifier::fromOpaqueValue(Mask >> PtrAuthShift);
0598 }
0599 void setPointerAuth(PointerAuthQualifier Q) {
0600 Mask = (Mask & ~PtrAuthMask) |
0601 (uint64_t(Q.getAsOpaqueValue()) << PtrAuthShift);
0602 }
0603 void removePointerAuth() { Mask &= ~PtrAuthMask; }
0604 void addPointerAuth(PointerAuthQualifier Q) {
0605 assert(Q.isPresent());
0606 setPointerAuth(Q);
0607 }
0608
0609
0610
0611 bool hasFastQualifiers() const { return getFastQualifiers(); }
0612 unsigned getFastQualifiers() const { return Mask & FastMask; }
0613 void setFastQualifiers(unsigned mask) {
0614 assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
0615 Mask = (Mask & ~FastMask) | mask;
0616 }
0617 void removeFastQualifiers(unsigned mask) {
0618 assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
0619 Mask &= ~static_cast<uint64_t>(mask);
0620 }
0621 void removeFastQualifiers() {
0622 removeFastQualifiers(FastMask);
0623 }
0624 void addFastQualifiers(unsigned mask) {
0625 assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
0626 Mask |= mask;
0627 }
0628
0629
0630
0631 bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
0632 Qualifiers getNonFastQualifiers() const {
0633 Qualifiers Quals = *this;
0634 Quals.setFastQualifiers(0);
0635 return Quals;
0636 }
0637
0638
0639 bool hasQualifiers() const { return Mask; }
0640 bool empty() const { return !Mask; }
0641
0642
0643 void addQualifiers(Qualifiers Q) {
0644
0645
0646 if (!(Q.Mask & ~CVRMask))
0647 Mask |= Q.Mask;
0648 else {
0649 Mask |= (Q.Mask & CVRMask);
0650 if (Q.hasAddressSpace())
0651 addAddressSpace(Q.getAddressSpace());
0652 if (Q.hasObjCGCAttr())
0653 addObjCGCAttr(Q.getObjCGCAttr());
0654 if (Q.hasObjCLifetime())
0655 addObjCLifetime(Q.getObjCLifetime());
0656 if (Q.hasPointerAuth())
0657 addPointerAuth(Q.getPointerAuth());
0658 }
0659 }
0660
0661
0662 void removeQualifiers(Qualifiers Q) {
0663
0664
0665 if (!(Q.Mask & ~CVRMask))
0666 Mask &= ~Q.Mask;
0667 else {
0668 Mask &= ~(Q.Mask & CVRMask);
0669 if (getObjCGCAttr() == Q.getObjCGCAttr())
0670 removeObjCGCAttr();
0671 if (getObjCLifetime() == Q.getObjCLifetime())
0672 removeObjCLifetime();
0673 if (getAddressSpace() == Q.getAddressSpace())
0674 removeAddressSpace();
0675 if (getPointerAuth() == Q.getPointerAuth())
0676 removePointerAuth();
0677 }
0678 }
0679
0680
0681
0682 void addConsistentQualifiers(Qualifiers qs) {
0683 assert(getAddressSpace() == qs.getAddressSpace() ||
0684 !hasAddressSpace() || !qs.hasAddressSpace());
0685 assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
0686 !hasObjCGCAttr() || !qs.hasObjCGCAttr());
0687 assert(getObjCLifetime() == qs.getObjCLifetime() ||
0688 !hasObjCLifetime() || !qs.hasObjCLifetime());
0689 assert(!hasPointerAuth() || !qs.hasPointerAuth() ||
0690 getPointerAuth() == qs.getPointerAuth());
0691 Mask |= qs.Mask;
0692 }
0693
0694
0695
0696
0697
0698
0699
0700
0701 static bool isAddressSpaceSupersetOf(LangAS A, LangAS B,
0702 const ASTContext &Ctx) {
0703
0704 return A == B || isTargetAddressSpaceSupersetOf(A, B, Ctx);
0705 }
0706
0707 static bool isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
0708 const ASTContext &Ctx);
0709
0710
0711
0712 bool isAddressSpaceSupersetOf(Qualifiers other, const ASTContext &Ctx) const {
0713 return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace(),
0714 Ctx);
0715 }
0716
0717
0718
0719
0720 bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const {
0721 return isAddressSpaceSupersetOf(other, Ctx) &&
0722
0723
0724 (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() ||
0725 !other.hasObjCGCAttr()) &&
0726
0727 getPointerAuth() == other.getPointerAuth() &&
0728
0729 getObjCLifetime() == other.getObjCLifetime() &&
0730
0731 (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) &&
0732
0733 (!other.hasUnaligned() || hasUnaligned());
0734 }
0735
0736
0737
0738
0739
0740
0741
0742
0743 bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
0744 if (getObjCLifetime() == other.getObjCLifetime())
0745 return true;
0746
0747 if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
0748 return false;
0749
0750 if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None)
0751 return true;
0752
0753 return hasConst();
0754 }
0755
0756
0757
0758 bool isStrictSupersetOf(Qualifiers Other) const;
0759
0760 bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
0761 bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
0762
0763 explicit operator bool() const { return hasQualifiers(); }
0764
0765 Qualifiers &operator+=(Qualifiers R) {
0766 addQualifiers(R);
0767 return *this;
0768 }
0769
0770
0771
0772 friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
0773 L += R;
0774 return L;
0775 }
0776
0777 Qualifiers &operator-=(Qualifiers R) {
0778 removeQualifiers(R);
0779 return *this;
0780 }
0781
0782
0783 friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
0784 L -= R;
0785 return L;
0786 }
0787
0788 std::string getAsString() const;
0789 std::string getAsString(const PrintingPolicy &Policy) const;
0790
0791 static std::string getAddrSpaceAsString(LangAS AS);
0792
0793 bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
0794 void print(raw_ostream &OS, const PrintingPolicy &Policy,
0795 bool appendSpaceIfNonEmpty = false) const;
0796
0797 void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Mask); }
0798
0799 private:
0800
0801
0802 uint64_t Mask = 0;
0803 static_assert(sizeof(PointerAuthQualifier) == sizeof(uint32_t),
0804 "PointerAuthQualifier must be 32 bits");
0805
0806 static constexpr uint64_t UMask = 0x8;
0807 static constexpr uint64_t UShift = 3;
0808 static constexpr uint64_t GCAttrMask = 0x30;
0809 static constexpr uint64_t GCAttrShift = 4;
0810 static constexpr uint64_t LifetimeMask = 0x1C0;
0811 static constexpr uint64_t LifetimeShift = 6;
0812 static constexpr uint64_t AddressSpaceMask =
0813 ~(CVRMask | UMask | GCAttrMask | LifetimeMask);
0814 static constexpr uint64_t AddressSpaceShift = 9;
0815 static constexpr uint64_t PtrAuthShift = 32;
0816 static constexpr uint64_t PtrAuthMask = uint64_t(0xffffffff) << PtrAuthShift;
0817 };
0818
0819 class QualifiersAndAtomic {
0820 Qualifiers Quals;
0821 bool HasAtomic;
0822
0823 public:
0824 QualifiersAndAtomic() : HasAtomic(false) {}
0825 QualifiersAndAtomic(Qualifiers Quals, bool HasAtomic)
0826 : Quals(Quals), HasAtomic(HasAtomic) {}
0827
0828 operator Qualifiers() const { return Quals; }
0829
0830 bool hasVolatile() const { return Quals.hasVolatile(); }
0831 bool hasConst() const { return Quals.hasConst(); }
0832 bool hasRestrict() const { return Quals.hasRestrict(); }
0833 bool hasAtomic() const { return HasAtomic; }
0834
0835 void addVolatile() { Quals.addVolatile(); }
0836 void addConst() { Quals.addConst(); }
0837 void addRestrict() { Quals.addRestrict(); }
0838 void addAtomic() { HasAtomic = true; }
0839
0840 void removeVolatile() { Quals.removeVolatile(); }
0841 void removeConst() { Quals.removeConst(); }
0842 void removeRestrict() { Quals.removeRestrict(); }
0843 void removeAtomic() { HasAtomic = false; }
0844
0845 QualifiersAndAtomic withVolatile() {
0846 return {Quals.withVolatile(), HasAtomic};
0847 }
0848 QualifiersAndAtomic withConst() { return {Quals.withConst(), HasAtomic}; }
0849 QualifiersAndAtomic withRestrict() {
0850 return {Quals.withRestrict(), HasAtomic};
0851 }
0852 QualifiersAndAtomic withAtomic() { return {Quals, true}; }
0853
0854 QualifiersAndAtomic &operator+=(Qualifiers RHS) {
0855 Quals += RHS;
0856 return *this;
0857 }
0858 };
0859
0860
0861
0862 struct SplitQualType {
0863
0864 const Type *Ty = nullptr;
0865
0866
0867 Qualifiers Quals;
0868
0869 SplitQualType() = default;
0870 SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
0871
0872 SplitQualType getSingleStepDesugaredType() const;
0873
0874
0875 std::pair<const Type *,Qualifiers> asPair() const {
0876 return std::pair<const Type *, Qualifiers>(Ty, Quals);
0877 }
0878
0879 friend bool operator==(SplitQualType a, SplitQualType b) {
0880 return a.Ty == b.Ty && a.Quals == b.Quals;
0881 }
0882 friend bool operator!=(SplitQualType a, SplitQualType b) {
0883 return a.Ty != b.Ty || a.Quals != b.Quals;
0884 }
0885 };
0886
0887
0888
0889
0890
0891
0892 enum class ObjCSubstitutionContext {
0893
0894 Ordinary,
0895
0896
0897 Result,
0898
0899
0900 Parameter,
0901
0902
0903 Property,
0904
0905
0906 Superclass,
0907 };
0908
0909
0910 enum class TypeOfKind : uint8_t {
0911 Qualified,
0912 Unqualified,
0913 };
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929 class QualType {
0930 friend class QualifierCollector;
0931
0932
0933 llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>,
0934 Qualifiers::FastWidth> Value;
0935
0936 const ExtQuals *getExtQualsUnsafe() const {
0937 return cast<const ExtQuals *>(Value.getPointer());
0938 }
0939
0940 const Type *getTypePtrUnsafe() const {
0941 return cast<const Type *>(Value.getPointer());
0942 }
0943
0944 const ExtQualsTypeCommonBase *getCommonPtr() const {
0945 assert(!isNull() && "Cannot retrieve a NULL type pointer");
0946 auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
0947 CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
0948 return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
0949 }
0950
0951 public:
0952 QualType() = default;
0953 QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {}
0954 QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {}
0955
0956 unsigned getLocalFastQualifiers() const { return Value.getInt(); }
0957 void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
0958
0959 bool UseExcessPrecision(const ASTContext &Ctx);
0960
0961
0962
0963
0964
0965 const Type *getTypePtr() const;
0966
0967 const Type *getTypePtrOrNull() const;
0968
0969
0970 const IdentifierInfo *getBaseTypeIdentifier() const;
0971
0972
0973
0974 SplitQualType split() const;
0975
0976 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
0977
0978 static QualType getFromOpaquePtr(const void *Ptr) {
0979 QualType T;
0980 T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
0981 return T;
0982 }
0983
0984 const Type &operator*() const {
0985 return *getTypePtr();
0986 }
0987
0988 const Type *operator->() const {
0989 return getTypePtr();
0990 }
0991
0992 bool isCanonical() const;
0993 bool isCanonicalAsParam() const;
0994
0995
0996 bool isNull() const {
0997 return Value.getPointer().isNull();
0998 }
0999
1000
1001 bool isReferenceable() const;
1002
1003
1004
1005
1006 bool isLocalConstQualified() const {
1007 return (getLocalFastQualifiers() & Qualifiers::Const);
1008 }
1009
1010
1011 bool isConstQualified() const;
1012
1013 enum class NonConstantStorageReason {
1014 MutableField,
1015 NonConstNonReferenceType,
1016 NonTrivialCtor,
1017 NonTrivialDtor,
1018 };
1019
1020
1021
1022
1023
1024 std::optional<NonConstantStorageReason>
1025 isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
1026 bool ExcludeDtor);
1027
1028 bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
1029 bool ExcludeDtor) {
1030 return !isNonConstantStorage(Ctx, ExcludeCtor, ExcludeDtor);
1031 }
1032
1033
1034
1035
1036 bool isLocalRestrictQualified() const {
1037 return (getLocalFastQualifiers() & Qualifiers::Restrict);
1038 }
1039
1040
1041 bool isRestrictQualified() const;
1042
1043
1044
1045
1046 bool isLocalVolatileQualified() const {
1047 return (getLocalFastQualifiers() & Qualifiers::Volatile);
1048 }
1049
1050
1051 bool isVolatileQualified() const;
1052
1053
1054
1055
1056 bool hasLocalQualifiers() const {
1057 return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
1058 }
1059
1060
1061 bool hasQualifiers() const;
1062
1063
1064
1065
1066 bool hasLocalNonFastQualifiers() const {
1067 return isa<const ExtQuals *>(Value.getPointer());
1068 }
1069
1070
1071
1072
1073 Qualifiers getLocalQualifiers() const;
1074
1075
1076 Qualifiers getQualifiers() const;
1077
1078
1079
1080
1081 unsigned getLocalCVRQualifiers() const {
1082 return getLocalFastQualifiers();
1083 }
1084
1085
1086
1087 unsigned getCVRQualifiers() const;
1088
1089 bool isConstant(const ASTContext& Ctx) const {
1090 return QualType::isConstant(*this, Ctx);
1091 }
1092
1093
1094 bool isPODType(const ASTContext &Context) const;
1095
1096
1097
1098 bool isCXX98PODType(const ASTContext &Context) const;
1099
1100
1101
1102
1103
1104 bool isCXX11PODType(const ASTContext &Context) const;
1105
1106
1107 bool isTrivialType(const ASTContext &Context) const;
1108
1109
1110 bool isTriviallyCopyableType(const ASTContext &Context) const;
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124 bool isBitwiseCloneableType(const ASTContext &Context) const;
1125
1126
1127 bool isTriviallyCopyConstructibleType(const ASTContext &Context) const;
1128
1129
1130 bool isTriviallyRelocatableType(const ASTContext &Context) const;
1131
1132
1133 bool mayBeDynamicClass() const;
1134
1135
1136 bool mayBeNotDynamicClass() const;
1137
1138
1139 bool isWebAssemblyReferenceType() const;
1140
1141
1142 bool isWebAssemblyExternrefType() const;
1143
1144
1145 bool isWebAssemblyFuncrefType() const;
1146
1147
1148
1149
1150
1151 void addConst() {
1152 addFastQualifiers(Qualifiers::Const);
1153 }
1154 QualType withConst() const {
1155 return withFastQualifiers(Qualifiers::Const);
1156 }
1157
1158
1159 void addVolatile() {
1160 addFastQualifiers(Qualifiers::Volatile);
1161 }
1162 QualType withVolatile() const {
1163 return withFastQualifiers(Qualifiers::Volatile);
1164 }
1165
1166
1167 void addRestrict() {
1168 addFastQualifiers(Qualifiers::Restrict);
1169 }
1170 QualType withRestrict() const {
1171 return withFastQualifiers(Qualifiers::Restrict);
1172 }
1173
1174 QualType withCVRQualifiers(unsigned CVR) const {
1175 return withFastQualifiers(CVR);
1176 }
1177
1178 void addFastQualifiers(unsigned TQs) {
1179 assert(!(TQs & ~Qualifiers::FastMask)
1180 && "non-fast qualifier bits set in mask!");
1181 Value.setInt(Value.getInt() | TQs);
1182 }
1183
1184 void removeLocalConst();
1185 void removeLocalVolatile();
1186 void removeLocalRestrict();
1187
1188 void removeLocalFastQualifiers() { Value.setInt(0); }
1189 void removeLocalFastQualifiers(unsigned Mask) {
1190 assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
1191 Value.setInt(Value.getInt() & ~Mask);
1192 }
1193
1194
1195
1196 QualType withFastQualifiers(unsigned TQs) const {
1197 QualType T = *this;
1198 T.addFastQualifiers(TQs);
1199 return T;
1200 }
1201
1202
1203
1204 QualType withExactLocalFastQualifiers(unsigned TQs) const {
1205 return withoutLocalFastQualifiers().withFastQualifiers(TQs);
1206 }
1207
1208
1209 QualType withoutLocalFastQualifiers() const {
1210 QualType T = *this;
1211 T.removeLocalFastQualifiers();
1212 return T;
1213 }
1214
1215 QualType getCanonicalType() const;
1216
1217
1218
1219
1220 QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244 inline QualType getUnqualifiedType() const;
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255 inline SplitQualType getSplitUnqualifiedType() const;
1256
1257
1258
1259 bool isMoreQualifiedThan(QualType Other, const ASTContext &Ctx) const;
1260
1261
1262
1263 bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const;
1264
1265 QualType getNonReferenceType() const;
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275 QualType getNonLValueExprType(const ASTContext &Context) const;
1276
1277
1278
1279
1280
1281 QualType getNonPackExpansionType() const;
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291 QualType getDesugaredType(const ASTContext &Context) const {
1292 return getDesugaredType(*this, Context);
1293 }
1294
1295 SplitQualType getSplitDesugaredType() const {
1296 return getSplitDesugaredType(*this);
1297 }
1298
1299
1300
1301
1302
1303
1304 QualType getSingleStepDesugaredType(const ASTContext &Context) const {
1305 return getSingleStepDesugaredTypeImpl(*this, Context);
1306 }
1307
1308
1309
1310 QualType IgnoreParens() const {
1311 if (isa<ParenType>(*this))
1312 return QualType::IgnoreParens(*this);
1313 return *this;
1314 }
1315
1316
1317 friend bool operator==(const QualType &LHS, const QualType &RHS) {
1318 return LHS.Value == RHS.Value;
1319 }
1320 friend bool operator!=(const QualType &LHS, const QualType &RHS) {
1321 return LHS.Value != RHS.Value;
1322 }
1323 friend bool operator<(const QualType &LHS, const QualType &RHS) {
1324 return LHS.Value < RHS.Value;
1325 }
1326
1327 static std::string getAsString(SplitQualType split,
1328 const PrintingPolicy &Policy) {
1329 return getAsString(split.Ty, split.Quals, Policy);
1330 }
1331 static std::string getAsString(const Type *ty, Qualifiers qs,
1332 const PrintingPolicy &Policy);
1333
1334 std::string getAsString() const;
1335 std::string getAsString(const PrintingPolicy &Policy) const;
1336
1337 void print(raw_ostream &OS, const PrintingPolicy &Policy,
1338 const Twine &PlaceHolder = Twine(),
1339 unsigned Indentation = 0) const;
1340
1341 static void print(SplitQualType split, raw_ostream &OS,
1342 const PrintingPolicy &policy, const Twine &PlaceHolder,
1343 unsigned Indentation = 0) {
1344 return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation);
1345 }
1346
1347 static void print(const Type *ty, Qualifiers qs,
1348 raw_ostream &OS, const PrintingPolicy &policy,
1349 const Twine &PlaceHolder,
1350 unsigned Indentation = 0);
1351
1352 void getAsStringInternal(std::string &Str,
1353 const PrintingPolicy &Policy) const;
1354
1355 static void getAsStringInternal(SplitQualType split, std::string &out,
1356 const PrintingPolicy &policy) {
1357 return getAsStringInternal(split.Ty, split.Quals, out, policy);
1358 }
1359
1360 static void getAsStringInternal(const Type *ty, Qualifiers qs,
1361 std::string &out,
1362 const PrintingPolicy &policy);
1363
1364 class StreamedQualTypeHelper {
1365 const QualType &T;
1366 const PrintingPolicy &Policy;
1367 const Twine &PlaceHolder;
1368 unsigned Indentation;
1369
1370 public:
1371 StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
1372 const Twine &PlaceHolder, unsigned Indentation)
1373 : T(T), Policy(Policy), PlaceHolder(PlaceHolder),
1374 Indentation(Indentation) {}
1375
1376 friend raw_ostream &operator<<(raw_ostream &OS,
1377 const StreamedQualTypeHelper &SQT) {
1378 SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation);
1379 return OS;
1380 }
1381 };
1382
1383 StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
1384 const Twine &PlaceHolder = Twine(),
1385 unsigned Indentation = 0) const {
1386 return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation);
1387 }
1388
1389 void dump(const char *s) const;
1390 void dump() const;
1391 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
1392
1393 void Profile(llvm::FoldingSetNodeID &ID) const {
1394 ID.AddPointer(getAsOpaquePtr());
1395 }
1396
1397
1398 inline bool hasAddressSpace() const;
1399
1400
1401 inline LangAS getAddressSpace() const;
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411 bool isAddressSpaceOverlapping(QualType T, const ASTContext &Ctx) const {
1412 Qualifiers Q = getQualifiers();
1413 Qualifiers TQ = T.getQualifiers();
1414
1415 return Q.isAddressSpaceSupersetOf(TQ, Ctx) ||
1416 TQ.isAddressSpaceSupersetOf(Q, Ctx);
1417 }
1418
1419
1420 inline Qualifiers::GC getObjCGCAttr() const;
1421
1422
1423 bool isObjCGCWeak() const {
1424 return getObjCGCAttr() == Qualifiers::Weak;
1425 }
1426
1427
1428 bool isObjCGCStrong() const {
1429 return getObjCGCAttr() == Qualifiers::Strong;
1430 }
1431
1432
1433 Qualifiers::ObjCLifetime getObjCLifetime() const {
1434 return getQualifiers().getObjCLifetime();
1435 }
1436
1437 bool hasNonTrivialObjCLifetime() const {
1438 return getQualifiers().hasNonTrivialObjCLifetime();
1439 }
1440
1441 bool hasStrongOrWeakObjCLifetime() const {
1442 return getQualifiers().hasStrongOrWeakObjCLifetime();
1443 }
1444
1445
1446 bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
1447
1448 PointerAuthQualifier getPointerAuth() const {
1449 return getQualifiers().getPointerAuth();
1450 }
1451
1452 enum PrimitiveDefaultInitializeKind {
1453
1454
1455
1456 PDIK_Trivial,
1457
1458
1459
1460 PDIK_ARCStrong,
1461
1462
1463
1464 PDIK_ARCWeak,
1465
1466
1467 PDIK_Struct
1468 };
1469
1470
1471
1472
1473
1474
1475 PrimitiveDefaultInitializeKind
1476 isNonTrivialToPrimitiveDefaultInitialize() const;
1477
1478 enum PrimitiveCopyKind {
1479
1480
1481
1482 PCK_Trivial,
1483
1484
1485
1486
1487 PCK_VolatileTrivial,
1488
1489
1490
1491 PCK_ARCStrong,
1492
1493
1494
1495 PCK_ARCWeak,
1496
1497
1498
1499
1500
1501
1502
1503 PCK_Struct
1504 };
1505
1506
1507
1508
1509 PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const;
1510
1511
1512
1513
1514
1515
1516
1517 PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const;
1518
1519 enum DestructionKind {
1520 DK_none,
1521 DK_cxx_destructor,
1522 DK_objc_strong_lifetime,
1523 DK_objc_weak_lifetime,
1524 DK_nontrivial_c_struct
1525 };
1526
1527
1528
1529
1530
1531 DestructionKind isDestructedType() const {
1532 return isDestructedTypeImpl(*this);
1533 }
1534
1535
1536
1537
1538
1539 bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const;
1540
1541
1542
1543
1544 bool hasNonTrivialToPrimitiveDestructCUnion() const;
1545
1546
1547
1548
1549 bool hasNonTrivialToPrimitiveCopyCUnion() const;
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561 bool isCForbiddenLValueType() const;
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577 QualType substObjCTypeArgs(ASTContext &ctx,
1578 ArrayRef<QualType> typeArgs,
1579 ObjCSubstitutionContext context) const;
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601 QualType substObjCMemberType(QualType objectType,
1602 const DeclContext *dc,
1603 ObjCSubstitutionContext context) const;
1604
1605
1606 QualType stripObjCKindOfType(const ASTContext &ctx) const;
1607
1608
1609
1610
1611
1612
1613 QualType getAtomicUnqualifiedType() const;
1614
1615 private:
1616
1617
1618
1619 static bool isConstant(QualType T, const ASTContext& Ctx);
1620 static QualType getDesugaredType(QualType T, const ASTContext &Context);
1621 static SplitQualType getSplitDesugaredType(QualType T);
1622 static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
1623 static QualType getSingleStepDesugaredTypeImpl(QualType type,
1624 const ASTContext &C);
1625 static QualType IgnoreParens(QualType T);
1626 static DestructionKind isDestructedTypeImpl(QualType type);
1627
1628
1629 static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD);
1630 static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD);
1631 static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD);
1632 };
1633
1634 raw_ostream &operator<<(raw_ostream &OS, QualType QT);
1635
1636 }
1637
1638 namespace llvm {
1639
1640
1641
1642 template<> struct simplify_type< ::clang::QualType> {
1643 using SimpleType = const ::clang::Type *;
1644
1645 static SimpleType getSimplifiedValue(::clang::QualType Val) {
1646 return Val.getTypePtr();
1647 }
1648 };
1649
1650
1651 template<>
1652 struct PointerLikeTypeTraits<clang::QualType> {
1653 static inline void *getAsVoidPointer(clang::QualType P) {
1654 return P.getAsOpaquePtr();
1655 }
1656
1657 static inline clang::QualType getFromVoidPointer(void *P) {
1658 return clang::QualType::getFromOpaquePtr(P);
1659 }
1660
1661
1662 static constexpr int NumLowBitsAvailable = 0;
1663 };
1664
1665 }
1666
1667 namespace clang {
1668
1669
1670
1671
1672 class ExtQualsTypeCommonBase {
1673 friend class ExtQuals;
1674 friend class QualType;
1675 friend class Type;
1676 friend class ASTReader;
1677
1678
1679
1680
1681
1682
1683 const Type *const BaseType;
1684
1685
1686 QualType CanonicalType;
1687
1688 ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
1689 : BaseType(baseType), CanonicalType(canon) {}
1690 };
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702 class alignas(TypeAlignment) ExtQuals : public ExtQualsTypeCommonBase,
1703 public llvm::FoldingSetNode {
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719 Qualifiers Quals;
1720
1721 ExtQuals *this_() { return this; }
1722
1723 public:
1724 ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
1725 : ExtQualsTypeCommonBase(baseType,
1726 canon.isNull() ? QualType(this_(), 0) : canon),
1727 Quals(quals) {
1728 assert(Quals.hasNonFastQualifiers()
1729 && "ExtQuals created with no fast qualifiers");
1730 assert(!Quals.hasFastQualifiers()
1731 && "ExtQuals created with fast qualifiers");
1732 }
1733
1734 Qualifiers getQualifiers() const { return Quals; }
1735
1736 bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
1737 Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
1738
1739 bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
1740 Qualifiers::ObjCLifetime getObjCLifetime() const {
1741 return Quals.getObjCLifetime();
1742 }
1743
1744 bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
1745 LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
1746
1747 const Type *getBaseType() const { return BaseType; }
1748
1749 public:
1750 void Profile(llvm::FoldingSetNodeID &ID) const {
1751 Profile(ID, getBaseType(), Quals);
1752 }
1753
1754 static void Profile(llvm::FoldingSetNodeID &ID,
1755 const Type *BaseType,
1756 Qualifiers Quals) {
1757 assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
1758 ID.AddPointer(BaseType);
1759 Quals.Profile(ID);
1760 }
1761 };
1762
1763
1764
1765
1766 enum RefQualifierKind {
1767
1768 RQ_None = 0,
1769
1770
1771 RQ_LValue,
1772
1773
1774 RQ_RValue
1775 };
1776
1777
1778 enum class AutoTypeKeyword {
1779
1780 Auto,
1781
1782
1783 DecltypeAuto,
1784
1785
1786 GNUAutoType
1787 };
1788
1789 enum class SubstTemplateTypeParmTypeFlag {
1790 None,
1791
1792
1793
1794
1795 ExpandPacksInPlace,
1796 };
1797
1798 enum class ArraySizeModifier;
1799 enum class ElaboratedTypeKeyword;
1800 enum class VectorKind;
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828 class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
1829 public:
1830 enum TypeClass {
1831 #define TYPE(Class, Base) Class,
1832 #define LAST_TYPE(Class) TypeLast = Class
1833 #define ABSTRACT_TYPE(Class, Base)
1834 #include "clang/AST/TypeNodes.inc"
1835 };
1836
1837 private:
1838
1839 class TypeBitfields {
1840 friend class Type;
1841 template <class T> friend class TypePropertyCache;
1842
1843
1844 LLVM_PREFERRED_TYPE(TypeClass)
1845 unsigned TC : 8;
1846
1847
1848 LLVM_PREFERRED_TYPE(TypeDependence)
1849 unsigned Dependence : llvm::BitWidth<TypeDependence>;
1850
1851
1852
1853 LLVM_PREFERRED_TYPE(bool)
1854 mutable unsigned CacheValid : 1;
1855
1856
1857 LLVM_PREFERRED_TYPE(Linkage)
1858 mutable unsigned CachedLinkage : 3;
1859
1860
1861 LLVM_PREFERRED_TYPE(bool)
1862 mutable unsigned CachedLocalOrUnnamed : 1;
1863
1864
1865 LLVM_PREFERRED_TYPE(bool)
1866 mutable unsigned FromAST : 1;
1867
1868 bool isCacheValid() const {
1869 return CacheValid;
1870 }
1871
1872 Linkage getLinkage() const {
1873 assert(isCacheValid() && "getting linkage from invalid cache");
1874 return static_cast<Linkage>(CachedLinkage);
1875 }
1876
1877 bool hasLocalOrUnnamedType() const {
1878 assert(isCacheValid() && "getting linkage from invalid cache");
1879 return CachedLocalOrUnnamed;
1880 }
1881 };
1882 enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 };
1883
1884 protected:
1885
1886
1887
1888 class ArrayTypeBitfields {
1889 friend class ArrayType;
1890
1891 LLVM_PREFERRED_TYPE(TypeBitfields)
1892 unsigned : NumTypeBits;
1893
1894
1895
1896 LLVM_PREFERRED_TYPE(Qualifiers)
1897 unsigned IndexTypeQuals : 3;
1898
1899
1900
1901 LLVM_PREFERRED_TYPE(ArraySizeModifier)
1902 unsigned SizeModifier : 3;
1903 };
1904 enum { NumArrayTypeBits = NumTypeBits + 6 };
1905
1906 class ConstantArrayTypeBitfields {
1907 friend class ConstantArrayType;
1908
1909 LLVM_PREFERRED_TYPE(ArrayTypeBitfields)
1910 unsigned : NumArrayTypeBits;
1911
1912
1913 LLVM_PREFERRED_TYPE(bool)
1914 unsigned HasExternalSize : 1;
1915
1916 LLVM_PREFERRED_TYPE(unsigned)
1917 unsigned SizeWidth : 5;
1918 };
1919
1920 class BuiltinTypeBitfields {
1921 friend class BuiltinType;
1922
1923 LLVM_PREFERRED_TYPE(TypeBitfields)
1924 unsigned : NumTypeBits;
1925
1926
1927 static constexpr unsigned NumOfBuiltinTypeBits = 9;
1928 unsigned Kind : NumOfBuiltinTypeBits;
1929 };
1930
1931 public:
1932 static constexpr int FunctionTypeNumParamsWidth = 16;
1933 static constexpr int FunctionTypeNumParamsLimit = (1 << 16) - 1;
1934
1935 protected:
1936
1937
1938
1939 class FunctionTypeBitfields {
1940 friend class FunctionProtoType;
1941 friend class FunctionType;
1942
1943 LLVM_PREFERRED_TYPE(TypeBitfields)
1944 unsigned : NumTypeBits;
1945
1946
1947
1948 LLVM_PREFERRED_TYPE(CallingConv)
1949 unsigned ExtInfo : 13;
1950
1951
1952
1953
1954 LLVM_PREFERRED_TYPE(RefQualifierKind)
1955 unsigned RefQualifier : 2;
1956
1957
1958
1959
1960
1961
1962
1963 LLVM_PREFERRED_TYPE(Qualifiers)
1964 unsigned FastTypeQuals : Qualifiers::FastWidth;
1965
1966 LLVM_PREFERRED_TYPE(bool)
1967 unsigned HasExtQuals : 1;
1968
1969
1970
1971
1972
1973 unsigned NumParams : FunctionTypeNumParamsWidth;
1974
1975
1976 LLVM_PREFERRED_TYPE(ExceptionSpecificationType)
1977 unsigned ExceptionSpecType : 4;
1978
1979
1980 LLVM_PREFERRED_TYPE(bool)
1981 unsigned HasExtParameterInfos : 1;
1982
1983
1984 LLVM_PREFERRED_TYPE(bool)
1985 unsigned HasExtraBitfields : 1;
1986
1987
1988 LLVM_PREFERRED_TYPE(bool)
1989 unsigned Variadic : 1;
1990
1991
1992 LLVM_PREFERRED_TYPE(bool)
1993 unsigned HasTrailingReturn : 1;
1994 };
1995
1996 class ObjCObjectTypeBitfields {
1997 friend class ObjCObjectType;
1998
1999 LLVM_PREFERRED_TYPE(TypeBitfields)
2000 unsigned : NumTypeBits;
2001
2002
2003 unsigned NumTypeArgs : 7;
2004
2005
2006 unsigned NumProtocols : 6;
2007
2008
2009 LLVM_PREFERRED_TYPE(bool)
2010 unsigned IsKindOf : 1;
2011 };
2012
2013 class ReferenceTypeBitfields {
2014 friend class ReferenceType;
2015
2016 LLVM_PREFERRED_TYPE(TypeBitfields)
2017 unsigned : NumTypeBits;
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030 LLVM_PREFERRED_TYPE(bool)
2031 unsigned SpelledAsLValue : 1;
2032
2033
2034
2035 LLVM_PREFERRED_TYPE(bool)
2036 unsigned InnerRef : 1;
2037 };
2038
2039 class TypeWithKeywordBitfields {
2040 friend class TypeWithKeyword;
2041
2042 LLVM_PREFERRED_TYPE(TypeBitfields)
2043 unsigned : NumTypeBits;
2044
2045
2046 LLVM_PREFERRED_TYPE(ElaboratedTypeKeyword)
2047 unsigned Keyword : 8;
2048 };
2049
2050 enum { NumTypeWithKeywordBits = NumTypeBits + 8 };
2051
2052 class ElaboratedTypeBitfields {
2053 friend class ElaboratedType;
2054
2055 LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
2056 unsigned : NumTypeWithKeywordBits;
2057
2058
2059 LLVM_PREFERRED_TYPE(bool)
2060 unsigned HasOwnedTagDecl : 1;
2061 };
2062
2063 class VectorTypeBitfields {
2064 friend class VectorType;
2065 friend class DependentVectorType;
2066
2067 LLVM_PREFERRED_TYPE(TypeBitfields)
2068 unsigned : NumTypeBits;
2069
2070
2071
2072 LLVM_PREFERRED_TYPE(VectorKind)
2073 unsigned VecKind : 4;
2074
2075 uint32_t NumElements;
2076 };
2077
2078 class AttributedTypeBitfields {
2079 friend class AttributedType;
2080
2081 LLVM_PREFERRED_TYPE(TypeBitfields)
2082 unsigned : NumTypeBits;
2083
2084 LLVM_PREFERRED_TYPE(attr::Kind)
2085 unsigned AttrKind : 32 - NumTypeBits;
2086 };
2087
2088 class AutoTypeBitfields {
2089 friend class AutoType;
2090
2091 LLVM_PREFERRED_TYPE(TypeBitfields)
2092 unsigned : NumTypeBits;
2093
2094
2095
2096 LLVM_PREFERRED_TYPE(AutoTypeKeyword)
2097 unsigned Keyword : 2;
2098
2099
2100
2101
2102
2103
2104
2105
2106 unsigned NumArgs;
2107 };
2108
2109 class TypeOfBitfields {
2110 friend class TypeOfType;
2111 friend class TypeOfExprType;
2112
2113 LLVM_PREFERRED_TYPE(TypeBitfields)
2114 unsigned : NumTypeBits;
2115 LLVM_PREFERRED_TYPE(TypeOfKind)
2116 unsigned Kind : 1;
2117 };
2118
2119 class UsingBitfields {
2120 friend class UsingType;
2121
2122 LLVM_PREFERRED_TYPE(TypeBitfields)
2123 unsigned : NumTypeBits;
2124
2125
2126 LLVM_PREFERRED_TYPE(bool)
2127 unsigned hasTypeDifferentFromDecl : 1;
2128 };
2129
2130 class TypedefBitfields {
2131 friend class TypedefType;
2132
2133 LLVM_PREFERRED_TYPE(TypeBitfields)
2134 unsigned : NumTypeBits;
2135
2136
2137 LLVM_PREFERRED_TYPE(bool)
2138 unsigned hasTypeDifferentFromDecl : 1;
2139 };
2140
2141 class TemplateTypeParmTypeBitfields {
2142 friend class TemplateTypeParmType;
2143
2144 LLVM_PREFERRED_TYPE(TypeBitfields)
2145 unsigned : NumTypeBits;
2146
2147
2148 unsigned Depth : 15;
2149
2150
2151 LLVM_PREFERRED_TYPE(bool)
2152 unsigned ParameterPack : 1;
2153
2154
2155 unsigned Index : 16;
2156 };
2157
2158 class SubstTemplateTypeParmTypeBitfields {
2159 friend class SubstTemplateTypeParmType;
2160
2161 LLVM_PREFERRED_TYPE(TypeBitfields)
2162 unsigned : NumTypeBits;
2163
2164 LLVM_PREFERRED_TYPE(bool)
2165 unsigned HasNonCanonicalUnderlyingType : 1;
2166
2167 LLVM_PREFERRED_TYPE(SubstTemplateTypeParmTypeFlag)
2168 unsigned SubstitutionFlag : 1;
2169
2170
2171 unsigned Index : 15;
2172
2173
2174
2175
2176
2177
2178 unsigned PackIndex : 16;
2179 };
2180
2181 class SubstTemplateTypeParmPackTypeBitfields {
2182 friend class SubstTemplateTypeParmPackType;
2183
2184 LLVM_PREFERRED_TYPE(TypeBitfields)
2185 unsigned : NumTypeBits;
2186
2187
2188 unsigned Index : 16;
2189
2190
2191
2192
2193
2194 unsigned NumArgs : 16;
2195 };
2196
2197 class TemplateSpecializationTypeBitfields {
2198 friend class TemplateSpecializationType;
2199
2200 LLVM_PREFERRED_TYPE(TypeBitfields)
2201 unsigned : NumTypeBits;
2202
2203
2204 LLVM_PREFERRED_TYPE(bool)
2205 unsigned TypeAlias : 1;
2206
2207
2208
2209
2210
2211
2212
2213
2214 unsigned NumArgs;
2215 };
2216
2217 class DependentTemplateSpecializationTypeBitfields {
2218 friend class DependentTemplateSpecializationType;
2219
2220 LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
2221 unsigned : NumTypeWithKeywordBits;
2222
2223
2224
2225
2226
2227
2228
2229
2230 unsigned NumArgs;
2231 };
2232
2233 class PackExpansionTypeBitfields {
2234 friend class PackExpansionType;
2235
2236 LLVM_PREFERRED_TYPE(TypeBitfields)
2237 unsigned : NumTypeBits;
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250 unsigned NumExpansions;
2251 };
2252
2253 class CountAttributedTypeBitfields {
2254 friend class CountAttributedType;
2255
2256 LLVM_PREFERRED_TYPE(TypeBitfields)
2257 unsigned : NumTypeBits;
2258
2259 static constexpr unsigned NumCoupledDeclsBits = 4;
2260 unsigned NumCoupledDecls : NumCoupledDeclsBits;
2261 LLVM_PREFERRED_TYPE(bool)
2262 unsigned CountInBytes : 1;
2263 LLVM_PREFERRED_TYPE(bool)
2264 unsigned OrNull : 1;
2265 };
2266 static_assert(sizeof(CountAttributedTypeBitfields) <= sizeof(unsigned));
2267
2268 union {
2269 TypeBitfields TypeBits;
2270 ArrayTypeBitfields ArrayTypeBits;
2271 ConstantArrayTypeBitfields ConstantArrayTypeBits;
2272 AttributedTypeBitfields AttributedTypeBits;
2273 AutoTypeBitfields AutoTypeBits;
2274 TypeOfBitfields TypeOfBits;
2275 TypedefBitfields TypedefBits;
2276 UsingBitfields UsingBits;
2277 BuiltinTypeBitfields BuiltinTypeBits;
2278 FunctionTypeBitfields FunctionTypeBits;
2279 ObjCObjectTypeBitfields ObjCObjectTypeBits;
2280 ReferenceTypeBitfields ReferenceTypeBits;
2281 TypeWithKeywordBitfields TypeWithKeywordBits;
2282 ElaboratedTypeBitfields ElaboratedTypeBits;
2283 VectorTypeBitfields VectorTypeBits;
2284 TemplateTypeParmTypeBitfields TemplateTypeParmTypeBits;
2285 SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
2286 SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
2287 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
2288 DependentTemplateSpecializationTypeBitfields
2289 DependentTemplateSpecializationTypeBits;
2290 PackExpansionTypeBitfields PackExpansionTypeBits;
2291 CountAttributedTypeBitfields CountAttributedTypeBits;
2292 };
2293
2294 private:
2295 template <class T> friend class TypePropertyCache;
2296
2297
2298 void setFromAST(bool V = true) const {
2299 TypeBits.FromAST = V;
2300 }
2301
2302 protected:
2303 friend class ASTContext;
2304
2305 Type(TypeClass tc, QualType canon, TypeDependence Dependence)
2306 : ExtQualsTypeCommonBase(this,
2307 canon.isNull() ? QualType(this_(), 0) : canon) {
2308 static_assert(sizeof(*this) <=
2309 alignof(decltype(*this)) + sizeof(ExtQualsTypeCommonBase),
2310 "changing bitfields changed sizeof(Type)!");
2311 static_assert(alignof(decltype(*this)) % TypeAlignment == 0,
2312 "Insufficient alignment!");
2313 TypeBits.TC = tc;
2314 TypeBits.Dependence = static_cast<unsigned>(Dependence);
2315 TypeBits.CacheValid = false;
2316 TypeBits.CachedLocalOrUnnamed = false;
2317 TypeBits.CachedLinkage = llvm::to_underlying(Linkage::Invalid);
2318 TypeBits.FromAST = false;
2319 }
2320
2321
2322 Type *this_() { return this; }
2323
2324 void setDependence(TypeDependence D) {
2325 TypeBits.Dependence = static_cast<unsigned>(D);
2326 }
2327
2328 void addDependence(TypeDependence D) { setDependence(getDependence() | D); }
2329
2330 public:
2331 friend class ASTReader;
2332 friend class ASTWriter;
2333 template <class T> friend class serialization::AbstractTypeReader;
2334 template <class T> friend class serialization::AbstractTypeWriter;
2335
2336 Type(const Type &) = delete;
2337 Type(Type &&) = delete;
2338 Type &operator=(const Type &) = delete;
2339 Type &operator=(Type &&) = delete;
2340
2341 TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
2342
2343
2344 bool isFromAST() const { return TypeBits.FromAST; }
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361 bool containsUnexpandedParameterPack() const {
2362 return getDependence() & TypeDependence::UnexpandedPack;
2363 }
2364
2365
2366
2367 bool isCanonicalUnqualified() const {
2368 return CanonicalType == QualType(this, 0);
2369 }
2370
2371
2372
2373
2374 QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
2375
2376
2377
2378
2379
2380
2381
2382 bool isSizelessType() const;
2383 bool isSizelessBuiltinType() const;
2384
2385
2386 bool isSizelessVectorType() const;
2387
2388
2389 bool isSVESizelessBuiltinType() const;
2390
2391
2392 bool isRVVSizelessBuiltinType() const;
2393
2394
2395 bool isWebAssemblyExternrefType() const;
2396
2397
2398
2399
2400 bool isWebAssemblyTableType() const;
2401
2402
2403
2404
2405 bool isSveVLSBuiltinType() const;
2406
2407
2408
2409
2410 QualType getSveEltType(const ASTContext &Ctx) const;
2411
2412
2413
2414
2415 bool isRVVVLSBuiltinType() const;
2416
2417
2418
2419
2420 QualType getRVVEltType(const ASTContext &Ctx) const;
2421
2422
2423
2424 QualType getSizelessVectorEltType(const ASTContext &Ctx) const;
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437 bool isIncompleteType(NamedDecl **Def = nullptr) const;
2438
2439
2440
2441 bool isIncompleteOrObjectType() const {
2442 return !isFunctionType();
2443 }
2444
2445
2446 bool isObjectType() const {
2447
2448
2449
2450 return !isReferenceType() && !isFunctionType() && !isVoidType();
2451 }
2452
2453
2454
2455 bool isLiteralType(const ASTContext &Ctx) const;
2456
2457
2458 bool isStructuralType() const;
2459
2460
2461
2462 bool isStandardLayoutType() const;
2463
2464
2465
2466
2467
2468 bool isBuiltinType() const;
2469
2470
2471 bool isSpecificBuiltinType(unsigned K) const;
2472
2473
2474
2475
2476 bool isPlaceholderType() const;
2477 const BuiltinType *getAsPlaceholderType() const;
2478
2479
2480 bool isSpecificPlaceholderType(unsigned K) const;
2481
2482
2483
2484 bool isNonOverloadPlaceholderType() const;
2485
2486
2487
2488 bool isIntegerType() const;
2489 bool isEnumeralType() const;
2490
2491
2492 bool isScopedEnumeralType() const;
2493 bool isBooleanType() const;
2494 bool isCharType() const;
2495 bool isWideCharType() const;
2496 bool isChar8Type() const;
2497 bool isChar16Type() const;
2498 bool isChar32Type() const;
2499 bool isAnyCharacterType() const;
2500 bool isIntegralType(const ASTContext &Ctx) const;
2501
2502
2503 bool isIntegralOrEnumerationType() const;
2504
2505
2506 bool isIntegralOrUnscopedEnumerationType() const;
2507 bool isUnscopedEnumerationType() const;
2508
2509
2510 bool isRealFloatingType() const;
2511
2512
2513 bool isComplexType() const;
2514 bool isAnyComplexType() const;
2515 bool isFloatingType() const;
2516 bool isHalfType() const;
2517 bool isFloat16Type() const;
2518 bool isFloat32Type() const;
2519 bool isDoubleType() const;
2520 bool isBFloat16Type() const;
2521 bool isMFloat8Type() const;
2522 bool isFloat128Type() const;
2523 bool isIbm128Type() const;
2524 bool isRealType() const;
2525 bool isArithmeticType() const;
2526 bool isVoidType() const;
2527 bool isScalarType() const;
2528 bool isAggregateType() const;
2529 bool isFundamentalType() const;
2530 bool isCompoundType() const;
2531
2532
2533
2534 bool isFunctionType() const;
2535 bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
2536 bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
2537 bool isPointerType() const;
2538 bool isPointerOrReferenceType() const;
2539 bool isSignableType() const;
2540 bool isAnyPointerType() const;
2541 bool isCountAttributedType() const;
2542 bool isBlockPointerType() const;
2543 bool isVoidPointerType() const;
2544 bool isReferenceType() const;
2545 bool isLValueReferenceType() const;
2546 bool isRValueReferenceType() const;
2547 bool isObjectPointerType() const;
2548 bool isFunctionPointerType() const;
2549 bool isFunctionReferenceType() const;
2550 bool isMemberPointerType() const;
2551 bool isMemberFunctionPointerType() const;
2552 bool isMemberDataPointerType() const;
2553 bool isArrayType() const;
2554 bool isConstantArrayType() const;
2555 bool isIncompleteArrayType() const;
2556 bool isVariableArrayType() const;
2557 bool isArrayParameterType() const;
2558 bool isDependentSizedArrayType() const;
2559 bool isRecordType() const;
2560 bool isClassType() const;
2561 bool isStructureType() const;
2562 bool isStructureTypeWithFlexibleArrayMember() const;
2563 bool isObjCBoxableRecordType() const;
2564 bool isInterfaceType() const;
2565 bool isStructureOrClassType() const;
2566 bool isUnionType() const;
2567 bool isComplexIntegerType() const;
2568 bool isVectorType() const;
2569 bool isExtVectorType() const;
2570 bool isExtVectorBoolType() const;
2571 bool isSubscriptableVectorType() const;
2572 bool isMatrixType() const;
2573 bool isConstantMatrixType() const;
2574 bool isDependentAddressSpaceType() const;
2575 bool isObjCObjectPointerType() const;
2576 bool isObjCRetainableType() const;
2577 bool isObjCLifetimeType() const;
2578 bool isObjCIndirectLifetimeType() const;
2579 bool isObjCNSObjectType() const;
2580 bool isObjCIndependentClassType() const;
2581
2582
2583 bool isObjCObjectType() const;
2584 bool isObjCQualifiedInterfaceType() const;
2585 bool isObjCQualifiedIdType() const;
2586 bool isObjCQualifiedClassType() const;
2587 bool isObjCObjectOrInterfaceType() const;
2588 bool isObjCIdType() const;
2589 bool isDecltypeType() const;
2590
2591
2592
2593
2594
2595
2596 bool isObjCInertUnsafeUnretainedType() const {
2597 return hasAttr(attr::ObjCInertUnsafeUnretained);
2598 }
2599
2600
2601
2602
2603
2604
2605
2606
2607 bool isObjCIdOrObjectKindOfType(const ASTContext &ctx,
2608 const ObjCObjectType *&bound) const;
2609
2610 bool isObjCClassType() const;
2611
2612
2613
2614
2615
2616
2617
2618 bool isObjCClassOrClassKindOfType() const;
2619
2620 bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const;
2621 bool isObjCSelType() const;
2622 bool isObjCBuiltinType() const;
2623 bool isObjCARCBridgableType() const;
2624 bool isCARCBridgableType() const;
2625 bool isTemplateTypeParmType() const;
2626 bool isNullPtrType() const;
2627
2628 bool isNothrowT() const;
2629 bool isAlignValT() const;
2630 bool isStdByteType() const;
2631 bool isAtomicType() const;
2632 bool isUndeducedAutoType() const;
2633
2634 bool isTypedefNameType() const;
2635
2636 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2637 bool is##Id##Type() const;
2638 #include "clang/Basic/OpenCLImageTypes.def"
2639
2640 bool isImageType() const;
2641
2642 bool isSamplerT() const;
2643 bool isEventT() const;
2644 bool isClkEventT() const;
2645 bool isQueueT() const;
2646 bool isReserveIDT() const;
2647
2648 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2649 bool is##Id##Type() const;
2650 #include "clang/Basic/OpenCLExtensionTypes.def"
2651
2652 bool isOCLIntelSubgroupAVCType() const;
2653 bool isOCLExtOpaqueType() const;
2654
2655 bool isPipeType() const;
2656 bool isBitIntType() const;
2657 bool isOpenCLSpecificType() const;
2658
2659 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) bool is##Id##Type() const;
2660 #include "clang/Basic/HLSLIntangibleTypes.def"
2661 bool isHLSLSpecificType() const;
2662 bool isHLSLBuiltinIntangibleType() const;
2663 bool isHLSLAttributedResourceType() const;
2664 bool isHLSLIntangibleType()
2665 const;
2666
2667
2668
2669
2670 bool isObjCARCImplicitlyUnretainedType() const;
2671
2672
2673 bool isCUDADeviceBuiltinSurfaceType() const;
2674
2675 bool isCUDADeviceBuiltinTextureType() const;
2676
2677
2678 Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
2679
2680 enum ScalarTypeKind {
2681 STK_CPointer,
2682 STK_BlockPointer,
2683 STK_ObjCObjectPointer,
2684 STK_MemberPointer,
2685 STK_Bool,
2686 STK_Integral,
2687 STK_Floating,
2688 STK_IntegralComplex,
2689 STK_FloatingComplex,
2690 STK_FixedPoint
2691 };
2692
2693
2694 ScalarTypeKind getScalarTypeKind() const;
2695
2696 TypeDependence getDependence() const {
2697 return static_cast<TypeDependence>(TypeBits.Dependence);
2698 }
2699
2700
2701 bool containsErrors() const {
2702 return getDependence() & TypeDependence::Error;
2703 }
2704
2705
2706
2707 bool isDependentType() const {
2708 return getDependence() & TypeDependence::Dependent;
2709 }
2710
2711
2712
2713
2714
2715 bool isInstantiationDependentType() const {
2716 return getDependence() & TypeDependence::Instantiation;
2717 }
2718
2719
2720
2721
2722 bool isUndeducedType() const;
2723
2724
2725 bool isVariablyModifiedType() const {
2726 return getDependence() & TypeDependence::VariablyModified;
2727 }
2728
2729
2730
2731 bool hasSizedVLAType() const;
2732
2733
2734 bool hasUnnamedOrLocalType() const;
2735
2736 bool isOverloadableType() const;
2737
2738
2739 bool isElaboratedTypeSpecifier() const;
2740
2741 bool canDecayToPointerType() const;
2742
2743
2744
2745
2746 bool hasPointerRepresentation() const;
2747
2748
2749
2750 bool hasObjCPointerRepresentation() const;
2751
2752
2753
2754 bool hasIntegerRepresentation() const;
2755
2756
2757
2758 bool hasSignedIntegerRepresentation() const;
2759
2760
2761
2762 bool hasUnsignedIntegerRepresentation() const;
2763
2764
2765
2766 bool hasFloatingRepresentation() const;
2767
2768
2769
2770
2771 const RecordType *getAsStructureType() const;
2772
2773 const RecordType *getAsUnionType() const;
2774 const ComplexType *getAsComplexIntegerType() const;
2775 const ObjCObjectType *getAsObjCInterfaceType() const;
2776
2777
2778
2779 const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
2780 const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
2781 const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
2782 const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
2783
2784
2785
2786
2787 CXXRecordDecl *getAsCXXRecordDecl() const;
2788
2789
2790 RecordDecl *getAsRecordDecl() const;
2791
2792
2793
2794
2795 TagDecl *getAsTagDecl() const;
2796
2797
2798
2799
2800
2801
2802 const CXXRecordDecl *getPointeeCXXRecordDecl() const;
2803
2804
2805
2806
2807 DeducedType *getContainedDeducedType() const;
2808
2809
2810
2811
2812 AutoType *getContainedAutoType() const {
2813 return dyn_cast_or_null<AutoType>(getContainedDeducedType());
2814 }
2815
2816
2817
2818
2819 bool hasAutoForTrailingReturnType() const;
2820
2821
2822
2823
2824
2825
2826
2827 template <typename T> const T *getAs() const;
2828
2829
2830
2831
2832
2833
2834 template <typename T> const T *getAsAdjusted() const;
2835
2836
2837
2838 const ArrayType *getAsArrayTypeUnsafe() const;
2839
2840
2841
2842
2843
2844
2845
2846 template <typename T> const T *castAs() const;
2847
2848
2849
2850 const ArrayType *castAsArrayTypeUnsafe() const;
2851
2852
2853
2854 bool hasAttr(attr::Kind AK) const;
2855
2856
2857
2858
2859 const Type *getBaseElementTypeUnsafe() const;
2860
2861
2862
2863
2864 const Type *getArrayElementTypeNoTypeQual() const;
2865
2866
2867
2868
2869 const Type *getPointeeOrArrayElementType() const;
2870
2871
2872
2873 QualType getPointeeType() const;
2874
2875
2876
2877 const Type *getUnqualifiedDesugaredType() const;
2878
2879
2880
2881
2882 bool isSignedIntegerType() const;
2883
2884
2885
2886
2887 bool isUnsignedIntegerType() const;
2888
2889
2890
2891 bool isSignedIntegerOrEnumerationType() const;
2892
2893
2894
2895 bool isUnsignedIntegerOrEnumerationType() const;
2896
2897
2898
2899 bool isFixedPointType() const;
2900
2901
2902 bool isFixedPointOrIntegerType() const;
2903
2904
2905 bool isConvertibleToFixedPointType() const;
2906
2907
2908
2909 bool isSaturatedFixedPointType() const;
2910
2911
2912
2913 bool isUnsaturatedFixedPointType() const;
2914
2915
2916
2917 bool isSignedFixedPointType() const;
2918
2919
2920
2921 bool isUnsignedFixedPointType() const;
2922
2923
2924
2925
2926 bool isConstantSizeType() const;
2927
2928
2929
2930 bool isSpecifierType() const;
2931
2932
2933 Linkage getLinkage() const;
2934
2935
2936 Visibility getVisibility() const {
2937 return getLinkageAndVisibility().getVisibility();
2938 }
2939
2940
2941 bool isVisibilityExplicit() const {
2942 return getLinkageAndVisibility().isVisibilityExplicit();
2943 }
2944
2945
2946 LinkageInfo getLinkageAndVisibility() const;
2947
2948
2949
2950 bool isLinkageValid() const;
2951
2952
2953
2954
2955
2956
2957 std::optional<NullabilityKind> getNullability() const;
2958
2959
2960
2961
2962
2963
2964 bool canHaveNullability(bool ResultIfUnknown = true) const;
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981 std::optional<ArrayRef<QualType>>
2982 getObjCSubstitutions(const DeclContext *dc) const;
2983
2984
2985
2986 bool acceptsObjCTypeParams() const;
2987
2988 const char *getTypeClassName() const;
2989
2990 QualType getCanonicalTypeInternal() const {
2991 return CanonicalType;
2992 }
2993
2994 CanQualType getCanonicalTypeUnqualified() const;
2995 void dump() const;
2996 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
2997 };
2998
2999
3000
3001 template <> const TypedefType *Type::getAs() const;
3002 template <> const UsingType *Type::getAs() const;
3003
3004
3005
3006
3007 template <> const TemplateSpecializationType *Type::getAs() const;
3008
3009
3010
3011 template <> const AttributedType *Type::getAs() const;
3012
3013
3014
3015 template <> const BoundsAttributedType *Type::getAs() const;
3016
3017
3018
3019 template <> const CountAttributedType *Type::getAs() const;
3020
3021
3022
3023 #define TYPE(Class, Base)
3024 #define LEAF_TYPE(Class) \
3025 template <> inline const Class##Type *Type::getAs() const { \
3026 return dyn_cast<Class##Type>(CanonicalType); \
3027 } \
3028 template <> inline const Class##Type *Type::castAs() const { \
3029 return cast<Class##Type>(CanonicalType); \
3030 }
3031 #include "clang/AST/TypeNodes.inc"
3032
3033
3034
3035 class BuiltinType : public Type {
3036 public:
3037 enum Kind {
3038
3039 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id,
3040 #include "clang/Basic/OpenCLImageTypes.def"
3041
3042 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
3043 #include "clang/Basic/OpenCLExtensionTypes.def"
3044
3045 #define SVE_TYPE(Name, Id, SingletonId) Id,
3046 #include "clang/Basic/AArch64SVEACLETypes.def"
3047
3048 #define PPC_VECTOR_TYPE(Name, Id, Size) Id,
3049 #include "clang/Basic/PPCTypes.def"
3050
3051 #define RVV_TYPE(Name, Id, SingletonId) Id,
3052 #include "clang/Basic/RISCVVTypes.def"
3053
3054 #define WASM_TYPE(Name, Id, SingletonId) Id,
3055 #include "clang/Basic/WebAssemblyReferenceTypes.def"
3056
3057 #define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) Id,
3058 #include "clang/Basic/AMDGPUTypes.def"
3059
3060 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) Id,
3061 #include "clang/Basic/HLSLIntangibleTypes.def"
3062
3063 #define BUILTIN_TYPE(Id, SingletonId) Id,
3064 #define LAST_BUILTIN_TYPE(Id) LastKind = Id
3065 #include "clang/AST/BuiltinTypes.def"
3066 };
3067
3068 private:
3069 friend class ASTContext;
3070
3071 BuiltinType(Kind K)
3072 : Type(Builtin, QualType(),
3073 K == Dependent ? TypeDependence::DependentInstantiation
3074 : TypeDependence::None) {
3075 static_assert(Kind::LastKind <
3076 (1 << BuiltinTypeBitfields::NumOfBuiltinTypeBits) &&
3077 "Defined builtin type exceeds the allocated space for serial "
3078 "numbering");
3079 BuiltinTypeBits.Kind = K;
3080 }
3081
3082 public:
3083 Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
3084 StringRef getName(const PrintingPolicy &Policy) const;
3085
3086 const char *getNameAsCString(const PrintingPolicy &Policy) const {
3087
3088 StringRef str = getName(Policy);
3089 assert(!str.empty() && str.data()[str.size()] == '\0');
3090 return str.data();
3091 }
3092
3093 bool isSugared() const { return false; }
3094 QualType desugar() const { return QualType(this, 0); }
3095
3096 bool isInteger() const {
3097 return getKind() >= Bool && getKind() <= Int128;
3098 }
3099
3100 bool isSignedInteger() const {
3101 return getKind() >= Char_S && getKind() <= Int128;
3102 }
3103
3104 bool isUnsignedInteger() const {
3105 return getKind() >= Bool && getKind() <= UInt128;
3106 }
3107
3108 bool isFloatingPoint() const {
3109 return getKind() >= Half && getKind() <= Ibm128;
3110 }
3111
3112 bool isSVEBool() const { return getKind() == Kind::SveBool; }
3113
3114 bool isSVECount() const { return getKind() == Kind::SveCount; }
3115
3116
3117 static bool isPlaceholderTypeKind(Kind K) {
3118 return K >= Overload;
3119 }
3120
3121
3122
3123
3124 bool isPlaceholderType() const {
3125 return isPlaceholderTypeKind(getKind());
3126 }
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137 bool isNonOverloadPlaceholderType() const {
3138 return getKind() > Overload;
3139 }
3140
3141 static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
3142 };
3143
3144
3145
3146 class ComplexType : public Type, public llvm::FoldingSetNode {
3147 friend class ASTContext;
3148
3149 QualType ElementType;
3150
3151 ComplexType(QualType Element, QualType CanonicalPtr)
3152 : Type(Complex, CanonicalPtr, Element->getDependence()),
3153 ElementType(Element) {}
3154
3155 public:
3156 QualType getElementType() const { return ElementType; }
3157
3158 bool isSugared() const { return false; }
3159 QualType desugar() const { return QualType(this, 0); }
3160
3161 void Profile(llvm::FoldingSetNodeID &ID) {
3162 Profile(ID, getElementType());
3163 }
3164
3165 static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
3166 ID.AddPointer(Element.getAsOpaquePtr());
3167 }
3168
3169 static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
3170 };
3171
3172
3173 class ParenType : public Type, public llvm::FoldingSetNode {
3174 friend class ASTContext;
3175
3176 QualType Inner;
3177
3178 ParenType(QualType InnerType, QualType CanonType)
3179 : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {}
3180
3181 public:
3182 QualType getInnerType() const { return Inner; }
3183
3184 bool isSugared() const { return true; }
3185 QualType desugar() const { return getInnerType(); }
3186
3187 void Profile(llvm::FoldingSetNodeID &ID) {
3188 Profile(ID, getInnerType());
3189 }
3190
3191 static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
3192 Inner.Profile(ID);
3193 }
3194
3195 static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
3196 };
3197
3198
3199 class PointerType : public Type, public llvm::FoldingSetNode {
3200 friend class ASTContext;
3201
3202 QualType PointeeType;
3203
3204 PointerType(QualType Pointee, QualType CanonicalPtr)
3205 : Type(Pointer, CanonicalPtr, Pointee->getDependence()),
3206 PointeeType(Pointee) {}
3207
3208 public:
3209 QualType getPointeeType() const { return PointeeType; }
3210
3211 bool isSugared() const { return false; }
3212 QualType desugar() const { return QualType(this, 0); }
3213
3214 void Profile(llvm::FoldingSetNodeID &ID) {
3215 Profile(ID, getPointeeType());
3216 }
3217
3218 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
3219 ID.AddPointer(Pointee.getAsOpaquePtr());
3220 }
3221
3222 static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
3223 };
3224
3225
3226
3227 class TypeCoupledDeclRefInfo {
3228 public:
3229 using BaseTy = llvm::PointerIntPair<ValueDecl *, 1, unsigned>;
3230
3231 private:
3232 enum {
3233 DerefShift = 0,
3234 DerefMask = 1,
3235 };
3236 BaseTy Data;
3237
3238 public:
3239
3240
3241
3242 TypeCoupledDeclRefInfo(ValueDecl *D = nullptr, bool Deref = false);
3243
3244 bool isDeref() const;
3245 ValueDecl *getDecl() const;
3246 unsigned getInt() const;
3247 void *getOpaqueValue() const;
3248 bool operator==(const TypeCoupledDeclRefInfo &Other) const;
3249 void setFromOpaqueValue(void *V);
3250 };
3251
3252
3253
3254
3255
3256
3257
3258
3259 class BoundsAttributedType : public Type, public llvm::FoldingSetNode {
3260 QualType WrappedTy;
3261
3262 protected:
3263 ArrayRef<TypeCoupledDeclRefInfo> Decls;
3264
3265 BoundsAttributedType(TypeClass TC, QualType Wrapped, QualType Canon);
3266
3267 public:
3268 bool isSugared() const { return true; }
3269 QualType desugar() const { return WrappedTy; }
3270
3271 using decl_iterator = const TypeCoupledDeclRefInfo *;
3272 using decl_range = llvm::iterator_range<decl_iterator>;
3273
3274 decl_iterator dependent_decl_begin() const { return Decls.begin(); }
3275 decl_iterator dependent_decl_end() const { return Decls.end(); }
3276
3277 unsigned getNumCoupledDecls() const { return Decls.size(); }
3278
3279 decl_range dependent_decls() const {
3280 return decl_range(dependent_decl_begin(), dependent_decl_end());
3281 }
3282
3283 ArrayRef<TypeCoupledDeclRefInfo> getCoupledDecls() const {
3284 return {dependent_decl_begin(), dependent_decl_end()};
3285 }
3286
3287 bool referencesFieldDecls() const;
3288
3289 static bool classof(const Type *T) {
3290
3291
3292
3293 switch (T->getTypeClass()) {
3294 case CountAttributed:
3295 return true;
3296 default:
3297 return false;
3298 }
3299 }
3300 };
3301
3302
3303
3304 class CountAttributedType final
3305 : public BoundsAttributedType,
3306 public llvm::TrailingObjects<CountAttributedType,
3307 TypeCoupledDeclRefInfo> {
3308 friend class ASTContext;
3309
3310 Expr *CountExpr;
3311
3312
3313
3314
3315
3316
3317 CountAttributedType(QualType Wrapped, QualType Canon, Expr *CountExpr,
3318 bool CountInBytes, bool OrNull,
3319 ArrayRef<TypeCoupledDeclRefInfo> CoupledDecls);
3320
3321 unsigned numTrailingObjects(OverloadToken<TypeCoupledDeclRefInfo>) const {
3322 return CountAttributedTypeBits.NumCoupledDecls;
3323 }
3324
3325 public:
3326 enum DynamicCountPointerKind {
3327 CountedBy = 0,
3328 SizedBy,
3329 CountedByOrNull,
3330 SizedByOrNull,
3331 };
3332
3333 Expr *getCountExpr() const { return CountExpr; }
3334 bool isCountInBytes() const { return CountAttributedTypeBits.CountInBytes; }
3335 bool isOrNull() const { return CountAttributedTypeBits.OrNull; }
3336
3337 DynamicCountPointerKind getKind() const {
3338 if (isOrNull())
3339 return isCountInBytes() ? SizedByOrNull : CountedByOrNull;
3340 return isCountInBytes() ? SizedBy : CountedBy;
3341 }
3342
3343 void Profile(llvm::FoldingSetNodeID &ID) {
3344 Profile(ID, desugar(), CountExpr, isCountInBytes(), isOrNull());
3345 }
3346
3347 static void Profile(llvm::FoldingSetNodeID &ID, QualType WrappedTy,
3348 Expr *CountExpr, bool CountInBytes, bool Nullable);
3349
3350 static bool classof(const Type *T) {
3351 return T->getTypeClass() == CountAttributed;
3352 }
3353 };
3354
3355
3356
3357
3358 class AdjustedType : public Type, public llvm::FoldingSetNode {
3359 QualType OriginalTy;
3360 QualType AdjustedTy;
3361
3362 protected:
3363 friend class ASTContext;
3364
3365 AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
3366 QualType CanonicalPtr)
3367 : Type(TC, CanonicalPtr, OriginalTy->getDependence()),
3368 OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
3369
3370 public:
3371 QualType getOriginalType() const { return OriginalTy; }
3372 QualType getAdjustedType() const { return AdjustedTy; }
3373
3374 bool isSugared() const { return true; }
3375 QualType desugar() const { return AdjustedTy; }
3376
3377 void Profile(llvm::FoldingSetNodeID &ID) {
3378 Profile(ID, OriginalTy, AdjustedTy);
3379 }
3380
3381 static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
3382 ID.AddPointer(Orig.getAsOpaquePtr());
3383 ID.AddPointer(New.getAsOpaquePtr());
3384 }
3385
3386 static bool classof(const Type *T) {
3387 return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
3388 }
3389 };
3390
3391
3392 class DecayedType : public AdjustedType {
3393 friend class ASTContext;
3394
3395 inline
3396 DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical);
3397
3398 public:
3399 QualType getDecayedType() const { return getAdjustedType(); }
3400
3401 inline QualType getPointeeType() const;
3402
3403 static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
3404 };
3405
3406
3407
3408
3409 class BlockPointerType : public Type, public llvm::FoldingSetNode {
3410 friend class ASTContext;
3411
3412
3413 QualType PointeeType;
3414
3415 BlockPointerType(QualType Pointee, QualType CanonicalCls)
3416 : Type(BlockPointer, CanonicalCls, Pointee->getDependence()),
3417 PointeeType(Pointee) {}
3418
3419 public:
3420
3421 QualType getPointeeType() const { return PointeeType; }
3422
3423 bool isSugared() const { return false; }
3424 QualType desugar() const { return QualType(this, 0); }
3425
3426 void Profile(llvm::FoldingSetNodeID &ID) {
3427 Profile(ID, getPointeeType());
3428 }
3429
3430 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
3431 ID.AddPointer(Pointee.getAsOpaquePtr());
3432 }
3433
3434 static bool classof(const Type *T) {
3435 return T->getTypeClass() == BlockPointer;
3436 }
3437 };
3438
3439
3440 class ReferenceType : public Type, public llvm::FoldingSetNode {
3441 QualType PointeeType;
3442
3443 protected:
3444 ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
3445 bool SpelledAsLValue)
3446 : Type(tc, CanonicalRef, Referencee->getDependence()),
3447 PointeeType(Referencee) {
3448 ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
3449 ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
3450 }
3451
3452 public:
3453 bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
3454 bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
3455
3456 QualType getPointeeTypeAsWritten() const { return PointeeType; }
3457
3458 QualType getPointeeType() const {
3459
3460 const ReferenceType *T = this;
3461 while (T->isInnerRef())
3462 T = T->PointeeType->castAs<ReferenceType>();
3463 return T->PointeeType;
3464 }
3465
3466 void Profile(llvm::FoldingSetNodeID &ID) {
3467 Profile(ID, PointeeType, isSpelledAsLValue());
3468 }
3469
3470 static void Profile(llvm::FoldingSetNodeID &ID,
3471 QualType Referencee,
3472 bool SpelledAsLValue) {
3473 ID.AddPointer(Referencee.getAsOpaquePtr());
3474 ID.AddBoolean(SpelledAsLValue);
3475 }
3476
3477 static bool classof(const Type *T) {
3478 return T->getTypeClass() == LValueReference ||
3479 T->getTypeClass() == RValueReference;
3480 }
3481 };
3482
3483
3484 class LValueReferenceType : public ReferenceType {
3485 friend class ASTContext;
3486
3487 LValueReferenceType(QualType Referencee, QualType CanonicalRef,
3488 bool SpelledAsLValue)
3489 : ReferenceType(LValueReference, Referencee, CanonicalRef,
3490 SpelledAsLValue) {}
3491
3492 public:
3493 bool isSugared() const { return false; }
3494 QualType desugar() const { return QualType(this, 0); }
3495
3496 static bool classof(const Type *T) {
3497 return T->getTypeClass() == LValueReference;
3498 }
3499 };
3500
3501
3502 class RValueReferenceType : public ReferenceType {
3503 friend class ASTContext;
3504
3505 RValueReferenceType(QualType Referencee, QualType CanonicalRef)
3506 : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {}
3507
3508 public:
3509 bool isSugared() const { return false; }
3510 QualType desugar() const { return QualType(this, 0); }
3511
3512 static bool classof(const Type *T) {
3513 return T->getTypeClass() == RValueReference;
3514 }
3515 };
3516
3517
3518
3519
3520 class MemberPointerType : public Type, public llvm::FoldingSetNode {
3521 friend class ASTContext;
3522
3523 QualType PointeeType;
3524
3525
3526
3527 const Type *Class;
3528
3529 MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
3530 : Type(MemberPointer, CanonicalPtr,
3531 (Cls->getDependence() & ~TypeDependence::VariablyModified) |
3532 Pointee->getDependence()),
3533 PointeeType(Pointee), Class(Cls) {}
3534
3535 public:
3536 QualType getPointeeType() const { return PointeeType; }
3537
3538
3539
3540 bool isMemberFunctionPointer() const {
3541 return PointeeType->isFunctionProtoType();
3542 }
3543
3544
3545
3546 bool isMemberDataPointer() const {
3547 return !PointeeType->isFunctionProtoType();
3548 }
3549
3550 const Type *getClass() const { return Class; }
3551 CXXRecordDecl *getMostRecentCXXRecordDecl() const;
3552
3553 bool isSugared() const { return false; }
3554 QualType desugar() const { return QualType(this, 0); }
3555
3556 void Profile(llvm::FoldingSetNodeID &ID) {
3557 Profile(ID, getPointeeType(), getClass());
3558 }
3559
3560 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
3561 const Type *Class) {
3562 ID.AddPointer(Pointee.getAsOpaquePtr());
3563 ID.AddPointer(Class);
3564 }
3565
3566 static bool classof(const Type *T) {
3567 return T->getTypeClass() == MemberPointer;
3568 }
3569 };
3570
3571
3572
3573
3574
3575 enum class ArraySizeModifier { Normal, Static, Star };
3576
3577
3578 class ArrayType : public Type, public llvm::FoldingSetNode {
3579 private:
3580
3581 QualType ElementType;
3582
3583 protected:
3584 friend class ASTContext;
3585
3586 ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm,
3587 unsigned tq, const Expr *sz = nullptr);
3588
3589 public:
3590 QualType getElementType() const { return ElementType; }
3591
3592 ArraySizeModifier getSizeModifier() const {
3593 return ArraySizeModifier(ArrayTypeBits.SizeModifier);
3594 }
3595
3596 Qualifiers getIndexTypeQualifiers() const {
3597 return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
3598 }
3599
3600 unsigned getIndexTypeCVRQualifiers() const {
3601 return ArrayTypeBits.IndexTypeQuals;
3602 }
3603
3604 static bool classof(const Type *T) {
3605 return T->getTypeClass() == ConstantArray ||
3606 T->getTypeClass() == VariableArray ||
3607 T->getTypeClass() == IncompleteArray ||
3608 T->getTypeClass() == DependentSizedArray ||
3609 T->getTypeClass() == ArrayParameter;
3610 }
3611 };
3612
3613
3614
3615
3616 class ConstantArrayType : public ArrayType {
3617 friend class ASTContext;
3618
3619 struct ExternalSize {
3620 ExternalSize(const llvm::APInt &Sz, const Expr *SE)
3621 : Size(Sz), SizeExpr(SE) {}
3622 llvm::APInt Size;
3623 const Expr *SizeExpr;
3624 };
3625
3626 union {
3627 uint64_t Size;
3628 ExternalSize *SizePtr;
3629 };
3630
3631 ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz,
3632 ArraySizeModifier SM, unsigned TQ)
3633 : ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), Size(Sz) {
3634 ConstantArrayTypeBits.HasExternalSize = false;
3635 ConstantArrayTypeBits.SizeWidth = Width / 8;
3636
3637
3638 assert(Width < 0xFF && "Type width in bits must be less than 8 bits");
3639 }
3640
3641 ConstantArrayType(QualType Et, QualType Can, ExternalSize *SzPtr,
3642 ArraySizeModifier SM, unsigned TQ)
3643 : ArrayType(ConstantArray, Et, Can, SM, TQ, SzPtr->SizeExpr),
3644 SizePtr(SzPtr) {
3645 ConstantArrayTypeBits.HasExternalSize = true;
3646 ConstantArrayTypeBits.SizeWidth = 0;
3647
3648 assert((SzPtr->SizeExpr == nullptr || !Can.isNull()) &&
3649 "canonical constant array should not have size expression");
3650 }
3651
3652 static ConstantArrayType *Create(const ASTContext &Ctx, QualType ET,
3653 QualType Can, const llvm::APInt &Sz,
3654 const Expr *SzExpr, ArraySizeModifier SzMod,
3655 unsigned Qual);
3656
3657 protected:
3658 ConstantArrayType(TypeClass Tc, const ConstantArrayType *ATy, QualType Can)
3659 : ArrayType(Tc, ATy->getElementType(), Can, ATy->getSizeModifier(),
3660 ATy->getIndexTypeQualifiers().getAsOpaqueValue(), nullptr) {
3661 ConstantArrayTypeBits.HasExternalSize =
3662 ATy->ConstantArrayTypeBits.HasExternalSize;
3663 if (!ConstantArrayTypeBits.HasExternalSize) {
3664 ConstantArrayTypeBits.SizeWidth = ATy->ConstantArrayTypeBits.SizeWidth;
3665 Size = ATy->Size;
3666 } else
3667 SizePtr = ATy->SizePtr;
3668 }
3669
3670 public:
3671
3672 llvm::APInt getSize() const {
3673 return ConstantArrayTypeBits.HasExternalSize
3674 ? SizePtr->Size
3675 : llvm::APInt(ConstantArrayTypeBits.SizeWidth * 8, Size);
3676 }
3677
3678
3679 unsigned getSizeBitWidth() const {
3680 return ConstantArrayTypeBits.HasExternalSize
3681 ? SizePtr->Size.getBitWidth()
3682 : static_cast<unsigned>(ConstantArrayTypeBits.SizeWidth * 8);
3683 }
3684
3685
3686 bool isZeroSize() const {
3687 return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero()
3688 : 0 == Size;
3689 }
3690
3691
3692 uint64_t getZExtSize() const {
3693 return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getZExtValue()
3694 : Size;
3695 }
3696
3697
3698 int64_t getSExtSize() const {
3699 return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getSExtValue()
3700 : static_cast<int64_t>(Size);
3701 }
3702
3703
3704
3705 uint64_t getLimitedSize() const {
3706 return ConstantArrayTypeBits.HasExternalSize
3707 ? SizePtr->Size.getLimitedValue()
3708 : Size;
3709 }
3710
3711
3712 const Expr *getSizeExpr() const {
3713 return ConstantArrayTypeBits.HasExternalSize ? SizePtr->SizeExpr : nullptr;
3714 }
3715
3716 bool isSugared() const { return false; }
3717 QualType desugar() const { return QualType(this, 0); }
3718
3719
3720
3721 static unsigned getNumAddressingBits(const ASTContext &Context,
3722 QualType ElementType,
3723 const llvm::APInt &NumElements);
3724
3725 unsigned getNumAddressingBits(const ASTContext &Context) const;
3726
3727
3728
3729 static unsigned getMaxSizeBits(const ASTContext &Context);
3730
3731 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
3732 Profile(ID, Ctx, getElementType(), getZExtSize(), getSizeExpr(),
3733 getSizeModifier(), getIndexTypeCVRQualifiers());
3734 }
3735
3736 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx,
3737 QualType ET, uint64_t ArraySize, const Expr *SizeExpr,
3738 ArraySizeModifier SizeMod, unsigned TypeQuals);
3739
3740 static bool classof(const Type *T) {
3741 return T->getTypeClass() == ConstantArray ||
3742 T->getTypeClass() == ArrayParameter;
3743 }
3744 };
3745
3746
3747
3748 class ArrayParameterType : public ConstantArrayType {
3749 friend class ASTContext;
3750
3751 ArrayParameterType(const ConstantArrayType *ATy, QualType CanTy)
3752 : ConstantArrayType(ArrayParameter, ATy, CanTy) {}
3753
3754 public:
3755 static bool classof(const Type *T) {
3756 return T->getTypeClass() == ArrayParameter;
3757 }
3758
3759 QualType getConstantArrayType(const ASTContext &Ctx) const;
3760 };
3761
3762
3763
3764
3765 class IncompleteArrayType : public ArrayType {
3766 friend class ASTContext;
3767
3768 IncompleteArrayType(QualType et, QualType can,
3769 ArraySizeModifier sm, unsigned tq)
3770 : ArrayType(IncompleteArray, et, can, sm, tq) {}
3771
3772 public:
3773 friend class StmtIteratorBase;
3774
3775 bool isSugared() const { return false; }
3776 QualType desugar() const { return QualType(this, 0); }
3777
3778 static bool classof(const Type *T) {
3779 return T->getTypeClass() == IncompleteArray;
3780 }
3781
3782 void Profile(llvm::FoldingSetNodeID &ID) {
3783 Profile(ID, getElementType(), getSizeModifier(),
3784 getIndexTypeCVRQualifiers());
3785 }
3786
3787 static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
3788 ArraySizeModifier SizeMod, unsigned TypeQuals) {
3789 ID.AddPointer(ET.getAsOpaquePtr());
3790 ID.AddInteger(llvm::to_underlying(SizeMod));
3791 ID.AddInteger(TypeQuals);
3792 }
3793 };
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809 class VariableArrayType : public ArrayType {
3810 friend class ASTContext;
3811
3812
3813
3814 Stmt *SizeExpr;
3815
3816
3817 SourceRange Brackets;
3818
3819 VariableArrayType(QualType et, QualType can, Expr *e,
3820 ArraySizeModifier sm, unsigned tq,
3821 SourceRange brackets)
3822 : ArrayType(VariableArray, et, can, sm, tq, e),
3823 SizeExpr((Stmt*) e), Brackets(brackets) {}
3824
3825 public:
3826 friend class StmtIteratorBase;
3827
3828 Expr *getSizeExpr() const {
3829
3830
3831 return (Expr*) SizeExpr;
3832 }
3833
3834 SourceRange getBracketsRange() const { return Brackets; }
3835 SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
3836 SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
3837
3838 bool isSugared() const { return false; }
3839 QualType desugar() const { return QualType(this, 0); }
3840
3841 static bool classof(const Type *T) {
3842 return T->getTypeClass() == VariableArray;
3843 }
3844
3845 void Profile(llvm::FoldingSetNodeID &ID) {
3846 llvm_unreachable("Cannot unique VariableArrayTypes.");
3847 }
3848 };
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863 class DependentSizedArrayType : public ArrayType {
3864 friend class ASTContext;
3865
3866
3867
3868
3869
3870
3871 Stmt *SizeExpr;
3872
3873
3874 SourceRange Brackets;
3875
3876 DependentSizedArrayType(QualType et, QualType can, Expr *e,
3877 ArraySizeModifier sm, unsigned tq,
3878 SourceRange brackets);
3879
3880 public:
3881 friend class StmtIteratorBase;
3882
3883 Expr *getSizeExpr() const {
3884
3885
3886 return (Expr*) SizeExpr;
3887 }
3888
3889 SourceRange getBracketsRange() const { return Brackets; }
3890 SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
3891 SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
3892
3893 bool isSugared() const { return false; }
3894 QualType desugar() const { return QualType(this, 0); }
3895
3896 static bool classof(const Type *T) {
3897 return T->getTypeClass() == DependentSizedArray;
3898 }
3899
3900 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
3901 Profile(ID, Context, getElementType(),
3902 getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
3903 }
3904
3905 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3906 QualType ET, ArraySizeModifier SizeMod,
3907 unsigned TypeQuals, Expr *E);
3908 };
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921 class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode {
3922 friend class ASTContext;
3923
3924 Expr *AddrSpaceExpr;
3925 QualType PointeeType;
3926 SourceLocation loc;
3927
3928 DependentAddressSpaceType(QualType PointeeType, QualType can,
3929 Expr *AddrSpaceExpr, SourceLocation loc);
3930
3931 public:
3932 Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; }
3933 QualType getPointeeType() const { return PointeeType; }
3934 SourceLocation getAttributeLoc() const { return loc; }
3935
3936 bool isSugared() const { return false; }
3937 QualType desugar() const { return QualType(this, 0); }
3938
3939 static bool classof(const Type *T) {
3940 return T->getTypeClass() == DependentAddressSpace;
3941 }
3942
3943 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
3944 Profile(ID, Context, getPointeeType(), getAddrSpaceExpr());
3945 }
3946
3947 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3948 QualType PointeeType, Expr *AddrSpaceExpr);
3949 };
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961 class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
3962 friend class ASTContext;
3963
3964 Expr *SizeExpr;
3965
3966
3967 QualType ElementType;
3968
3969 SourceLocation loc;
3970
3971 DependentSizedExtVectorType(QualType ElementType, QualType can,
3972 Expr *SizeExpr, SourceLocation loc);
3973
3974 public:
3975 Expr *getSizeExpr() const { return SizeExpr; }
3976 QualType getElementType() const { return ElementType; }
3977 SourceLocation getAttributeLoc() const { return loc; }
3978
3979 bool isSugared() const { return false; }
3980 QualType desugar() const { return QualType(this, 0); }
3981
3982 static bool classof(const Type *T) {
3983 return T->getTypeClass() == DependentSizedExtVector;
3984 }
3985
3986 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
3987 Profile(ID, Context, getElementType(), getSizeExpr());
3988 }
3989
3990 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3991 QualType ElementType, Expr *SizeExpr);
3992 };
3993
3994 enum class VectorKind {
3995
3996 Generic,
3997
3998
3999 AltiVecVector,
4000
4001
4002 AltiVecPixel,
4003
4004
4005 AltiVecBool,
4006
4007
4008 Neon,
4009
4010
4011 NeonPoly,
4012
4013
4014 SveFixedLengthData,
4015
4016
4017 SveFixedLengthPredicate,
4018
4019
4020 RVVFixedLengthData,
4021
4022
4023 RVVFixedLengthMask,
4024
4025 RVVFixedLengthMask_1,
4026 RVVFixedLengthMask_2,
4027 RVVFixedLengthMask_4
4028 };
4029
4030
4031
4032
4033
4034
4035 class VectorType : public Type, public llvm::FoldingSetNode {
4036 protected:
4037 friend class ASTContext;
4038
4039
4040 QualType ElementType;
4041
4042 VectorType(QualType vecType, unsigned nElements, QualType canonType,
4043 VectorKind vecKind);
4044
4045 VectorType(TypeClass tc, QualType vecType, unsigned nElements,
4046 QualType canonType, VectorKind vecKind);
4047
4048 public:
4049 QualType getElementType() const { return ElementType; }
4050 unsigned getNumElements() const { return VectorTypeBits.NumElements; }
4051
4052 bool isSugared() const { return false; }
4053 QualType desugar() const { return QualType(this, 0); }
4054
4055 VectorKind getVectorKind() const {
4056 return VectorKind(VectorTypeBits.VecKind);
4057 }
4058
4059 void Profile(llvm::FoldingSetNodeID &ID) {
4060 Profile(ID, getElementType(), getNumElements(),
4061 getTypeClass(), getVectorKind());
4062 }
4063
4064 static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
4065 unsigned NumElements, TypeClass TypeClass,
4066 VectorKind VecKind) {
4067 ID.AddPointer(ElementType.getAsOpaquePtr());
4068 ID.AddInteger(NumElements);
4069 ID.AddInteger(TypeClass);
4070 ID.AddInteger(llvm::to_underlying(VecKind));
4071 }
4072
4073 static bool classof(const Type *T) {
4074 return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
4075 }
4076 };
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087 class DependentVectorType : public Type, public llvm::FoldingSetNode {
4088 friend class ASTContext;
4089
4090 QualType ElementType;
4091 Expr *SizeExpr;
4092 SourceLocation Loc;
4093
4094 DependentVectorType(QualType ElementType, QualType CanonType, Expr *SizeExpr,
4095 SourceLocation Loc, VectorKind vecKind);
4096
4097 public:
4098 Expr *getSizeExpr() const { return SizeExpr; }
4099 QualType getElementType() const { return ElementType; }
4100 SourceLocation getAttributeLoc() const { return Loc; }
4101 VectorKind getVectorKind() const {
4102 return VectorKind(VectorTypeBits.VecKind);
4103 }
4104
4105 bool isSugared() const { return false; }
4106 QualType desugar() const { return QualType(this, 0); }
4107
4108 static bool classof(const Type *T) {
4109 return T->getTypeClass() == DependentVector;
4110 }
4111
4112 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
4113 Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind());
4114 }
4115
4116 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
4117 QualType ElementType, const Expr *SizeExpr,
4118 VectorKind VecKind);
4119 };
4120
4121
4122
4123
4124
4125
4126
4127 class ExtVectorType : public VectorType {
4128 friend class ASTContext;
4129
4130 ExtVectorType(QualType vecType, unsigned nElements, QualType canonType)
4131 : VectorType(ExtVector, vecType, nElements, canonType,
4132 VectorKind::Generic) {}
4133
4134 public:
4135 static int getPointAccessorIdx(char c) {
4136 switch (c) {
4137 default: return -1;
4138 case 'x': case 'r': return 0;
4139 case 'y': case 'g': return 1;
4140 case 'z': case 'b': return 2;
4141 case 'w': case 'a': return 3;
4142 }
4143 }
4144
4145 static int getNumericAccessorIdx(char c) {
4146 switch (c) {
4147 default: return -1;
4148 case '0': return 0;
4149 case '1': return 1;
4150 case '2': return 2;
4151 case '3': return 3;
4152 case '4': return 4;
4153 case '5': return 5;
4154 case '6': return 6;
4155 case '7': return 7;
4156 case '8': return 8;
4157 case '9': return 9;
4158 case 'A':
4159 case 'a': return 10;
4160 case 'B':
4161 case 'b': return 11;
4162 case 'C':
4163 case 'c': return 12;
4164 case 'D':
4165 case 'd': return 13;
4166 case 'E':
4167 case 'e': return 14;
4168 case 'F':
4169 case 'f': return 15;
4170 }
4171 }
4172
4173 static int getAccessorIdx(char c, bool isNumericAccessor) {
4174 if (isNumericAccessor)
4175 return getNumericAccessorIdx(c);
4176 else
4177 return getPointAccessorIdx(c);
4178 }
4179
4180 bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const {
4181 if (int idx = getAccessorIdx(c, isNumericAccessor)+1)
4182 return unsigned(idx-1) < getNumElements();
4183 return false;
4184 }
4185
4186 bool isSugared() const { return false; }
4187 QualType desugar() const { return QualType(this, 0); }
4188
4189 static bool classof(const Type *T) {
4190 return T->getTypeClass() == ExtVector;
4191 }
4192 };
4193
4194
4195
4196
4197 class MatrixType : public Type, public llvm::FoldingSetNode {
4198 protected:
4199 friend class ASTContext;
4200
4201
4202 QualType ElementType;
4203
4204 MatrixType(QualType ElementTy, QualType CanonElementTy);
4205
4206 MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy,
4207 const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr);
4208
4209 public:
4210
4211 QualType getElementType() const { return ElementType; }
4212
4213
4214
4215
4216
4217
4218 static bool isValidElementType(QualType T) {
4219 return T->isDependentType() ||
4220 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
4221 }
4222
4223 bool isSugared() const { return false; }
4224 QualType desugar() const { return QualType(this, 0); }
4225
4226 static bool classof(const Type *T) {
4227 return T->getTypeClass() == ConstantMatrix ||
4228 T->getTypeClass() == DependentSizedMatrix;
4229 }
4230 };
4231
4232
4233 class ConstantMatrixType final : public MatrixType {
4234 protected:
4235 friend class ASTContext;
4236
4237
4238 unsigned NumRows;
4239 unsigned NumColumns;
4240
4241 static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1;
4242
4243 ConstantMatrixType(QualType MatrixElementType, unsigned NRows,
4244 unsigned NColumns, QualType CanonElementType);
4245
4246 ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows,
4247 unsigned NColumns, QualType CanonElementType);
4248
4249 public:
4250
4251 unsigned getNumRows() const { return NumRows; }
4252
4253
4254 unsigned getNumColumns() const { return NumColumns; }
4255
4256
4257 unsigned getNumElementsFlattened() const {
4258 return getNumRows() * getNumColumns();
4259 }
4260
4261
4262 static constexpr bool isDimensionValid(size_t NumElements) {
4263 return NumElements > 0 && NumElements <= MaxElementsPerDimension;
4264 }
4265
4266
4267 static constexpr unsigned getMaxElementsPerDimension() {
4268 return MaxElementsPerDimension;
4269 }
4270
4271 void Profile(llvm::FoldingSetNodeID &ID) {
4272 Profile(ID, getElementType(), getNumRows(), getNumColumns(),
4273 getTypeClass());
4274 }
4275
4276 static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
4277 unsigned NumRows, unsigned NumColumns,
4278 TypeClass TypeClass) {
4279 ID.AddPointer(ElementType.getAsOpaquePtr());
4280 ID.AddInteger(NumRows);
4281 ID.AddInteger(NumColumns);
4282 ID.AddInteger(TypeClass);
4283 }
4284
4285 static bool classof(const Type *T) {
4286 return T->getTypeClass() == ConstantMatrix;
4287 }
4288 };
4289
4290
4291
4292 class DependentSizedMatrixType final : public MatrixType {
4293 friend class ASTContext;
4294
4295 Expr *RowExpr;
4296 Expr *ColumnExpr;
4297
4298 SourceLocation loc;
4299
4300 DependentSizedMatrixType(QualType ElementType, QualType CanonicalType,
4301 Expr *RowExpr, Expr *ColumnExpr, SourceLocation loc);
4302
4303 public:
4304 Expr *getRowExpr() const { return RowExpr; }
4305 Expr *getColumnExpr() const { return ColumnExpr; }
4306 SourceLocation getAttributeLoc() const { return loc; }
4307
4308 static bool classof(const Type *T) {
4309 return T->getTypeClass() == DependentSizedMatrix;
4310 }
4311
4312 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
4313 Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr());
4314 }
4315
4316 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
4317 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr);
4318 };
4319
4320
4321
4322 class FunctionType : public Type {
4323
4324 QualType ResultType;
4325
4326 public:
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348 class ExtParameterInfo {
4349 enum {
4350 ABIMask = 0x0F,
4351 IsConsumed = 0x10,
4352 HasPassObjSize = 0x20,
4353 IsNoEscape = 0x40,
4354 };
4355 unsigned char Data = 0;
4356
4357 public:
4358 ExtParameterInfo() = default;
4359
4360
4361 ParameterABI getABI() const { return ParameterABI(Data & ABIMask); }
4362 ExtParameterInfo withABI(ParameterABI kind) const {
4363 ExtParameterInfo copy = *this;
4364 copy.Data = (copy.Data & ~ABIMask) | unsigned(kind);
4365 return copy;
4366 }
4367
4368
4369
4370 bool isConsumed() const { return (Data & IsConsumed); }
4371 ExtParameterInfo withIsConsumed(bool consumed) const {
4372 ExtParameterInfo copy = *this;
4373 if (consumed)
4374 copy.Data |= IsConsumed;
4375 else
4376 copy.Data &= ~IsConsumed;
4377 return copy;
4378 }
4379
4380 bool hasPassObjectSize() const { return Data & HasPassObjSize; }
4381 ExtParameterInfo withHasPassObjectSize() const {
4382 ExtParameterInfo Copy = *this;
4383 Copy.Data |= HasPassObjSize;
4384 return Copy;
4385 }
4386
4387 bool isNoEscape() const { return Data & IsNoEscape; }
4388 ExtParameterInfo withIsNoEscape(bool NoEscape) const {
4389 ExtParameterInfo Copy = *this;
4390 if (NoEscape)
4391 Copy.Data |= IsNoEscape;
4392 else
4393 Copy.Data &= ~IsNoEscape;
4394 return Copy;
4395 }
4396
4397 unsigned char getOpaqueValue() const { return Data; }
4398 static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
4399 ExtParameterInfo result;
4400 result.Data = data;
4401 return result;
4402 }
4403
4404 friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) {
4405 return lhs.Data == rhs.Data;
4406 }
4407
4408 friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) {
4409 return lhs.Data != rhs.Data;
4410 }
4411 };
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433 class ExtInfo {
4434 friend class FunctionType;
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444 enum { CallConvMask = 0x1F };
4445 enum { NoReturnMask = 0x20 };
4446 enum { ProducesResultMask = 0x40 };
4447 enum { NoCallerSavedRegsMask = 0x80 };
4448 enum {
4449 RegParmMask = 0x700,
4450 RegParmOffset = 8
4451 };
4452 enum { NoCfCheckMask = 0x800 };
4453 enum { CmseNSCallMask = 0x1000 };
4454 uint16_t Bits = CC_C;
4455
4456 ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
4457
4458 public:
4459
4460
4461 ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
4462 bool producesResult, bool noCallerSavedRegs, bool NoCfCheck,
4463 bool cmseNSCall) {
4464 assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
4465 Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) |
4466 (producesResult ? ProducesResultMask : 0) |
4467 (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
4468 (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) |
4469 (NoCfCheck ? NoCfCheckMask : 0) |
4470 (cmseNSCall ? CmseNSCallMask : 0);
4471 }
4472
4473
4474
4475 ExtInfo() = default;
4476
4477
4478
4479 ExtInfo(CallingConv CC) : Bits(CC) {}
4480
4481 bool getNoReturn() const { return Bits & NoReturnMask; }
4482 bool getProducesResult() const { return Bits & ProducesResultMask; }
4483 bool getCmseNSCall() const { return Bits & CmseNSCallMask; }
4484 bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; }
4485 bool getNoCfCheck() const { return Bits & NoCfCheckMask; }
4486 bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; }
4487
4488 unsigned getRegParm() const {
4489 unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset;
4490 if (RegParm > 0)
4491 --RegParm;
4492 return RegParm;
4493 }
4494
4495 CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
4496
4497 bool operator==(ExtInfo Other) const {
4498 return Bits == Other.Bits;
4499 }
4500 bool operator!=(ExtInfo Other) const {
4501 return Bits != Other.Bits;
4502 }
4503
4504
4505
4506
4507 ExtInfo withNoReturn(bool noReturn) const {
4508 if (noReturn)
4509 return ExtInfo(Bits | NoReturnMask);
4510 else
4511 return ExtInfo(Bits & ~NoReturnMask);
4512 }
4513
4514 ExtInfo withProducesResult(bool producesResult) const {
4515 if (producesResult)
4516 return ExtInfo(Bits | ProducesResultMask);
4517 else
4518 return ExtInfo(Bits & ~ProducesResultMask);
4519 }
4520
4521 ExtInfo withCmseNSCall(bool cmseNSCall) const {
4522 if (cmseNSCall)
4523 return ExtInfo(Bits | CmseNSCallMask);
4524 else
4525 return ExtInfo(Bits & ~CmseNSCallMask);
4526 }
4527
4528 ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const {
4529 if (noCallerSavedRegs)
4530 return ExtInfo(Bits | NoCallerSavedRegsMask);
4531 else
4532 return ExtInfo(Bits & ~NoCallerSavedRegsMask);
4533 }
4534
4535 ExtInfo withNoCfCheck(bool noCfCheck) const {
4536 if (noCfCheck)
4537 return ExtInfo(Bits | NoCfCheckMask);
4538 else
4539 return ExtInfo(Bits & ~NoCfCheckMask);
4540 }
4541
4542 ExtInfo withRegParm(unsigned RegParm) const {
4543 assert(RegParm < 7 && "Invalid regparm value");
4544 return ExtInfo((Bits & ~RegParmMask) |
4545 ((RegParm + 1) << RegParmOffset));
4546 }
4547
4548 ExtInfo withCallingConv(CallingConv cc) const {
4549 return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc);
4550 }
4551
4552 void Profile(llvm::FoldingSetNodeID &ID) const {
4553 ID.AddInteger(Bits);
4554 }
4555 };
4556
4557
4558
4559
4560 struct ExceptionType { QualType Type; };
4561
4562
4563
4564
4565 struct alignas(void *) FunctionTypeExtraBitfields {
4566
4567
4568
4569 unsigned NumExceptionType : 10;
4570
4571 LLVM_PREFERRED_TYPE(bool)
4572 unsigned HasArmTypeAttributes : 1;
4573
4574 LLVM_PREFERRED_TYPE(bool)
4575 unsigned EffectsHaveConditions : 1;
4576 unsigned NumFunctionEffects : 4;
4577
4578 FunctionTypeExtraBitfields()
4579 : NumExceptionType(0), HasArmTypeAttributes(false),
4580 EffectsHaveConditions(false), NumFunctionEffects(0) {}
4581 };
4582
4583
4584
4585
4586 enum AArch64SMETypeAttributes : unsigned {
4587 SME_NormalFunction = 0,
4588 SME_PStateSMEnabledMask = 1 << 0,
4589 SME_PStateSMCompatibleMask = 1 << 1,
4590
4591
4592 SME_ZAShift = 2,
4593 SME_ZAMask = 0b111 << SME_ZAShift,
4594 SME_ZT0Shift = 5,
4595 SME_ZT0Mask = 0b111 << SME_ZT0Shift,
4596
4597
4598 SME_AgnosticZAStateShift = 8,
4599 SME_AgnosticZAStateMask = 1 << SME_AgnosticZAStateShift,
4600
4601 SME_AttributeMask =
4602 0b1'111'111'11 // We can't support more than 9 bits because of
4603
4604
4605 };
4606
4607 enum ArmStateValue : unsigned {
4608 ARM_None = 0,
4609 ARM_Preserves = 1,
4610 ARM_In = 2,
4611 ARM_Out = 3,
4612 ARM_InOut = 4,
4613 };
4614
4615 static ArmStateValue getArmZAState(unsigned AttrBits) {
4616 return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
4617 }
4618
4619 static ArmStateValue getArmZT0State(unsigned AttrBits) {
4620 return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift);
4621 }
4622
4623
4624
4625
4626 struct alignas(void *) FunctionTypeArmAttributes {
4627
4628
4629 unsigned AArch64SMEAttributes : 9;
4630
4631 FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {}
4632 };
4633
4634 protected:
4635 FunctionType(TypeClass tc, QualType res, QualType Canonical,
4636 TypeDependence Dependence, ExtInfo Info)
4637 : Type(tc, Canonical, Dependence), ResultType(res) {
4638 FunctionTypeBits.ExtInfo = Info.Bits;
4639 }
4640
4641 Qualifiers getFastTypeQuals() const {
4642 if (isFunctionProtoType())
4643 return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
4644
4645 return Qualifiers();
4646 }
4647
4648 public:
4649 QualType getReturnType() const { return ResultType; }
4650
4651 bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
4652 unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
4653
4654
4655
4656
4657 bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
4658
4659 bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); }
4660 CallingConv getCallConv() const { return getExtInfo().getCC(); }
4661 ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
4662
4663 static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0,
4664 "Const, volatile and restrict are assumed to be a subset of "
4665 "the fast qualifiers.");
4666
4667 bool isConst() const { return getFastTypeQuals().hasConst(); }
4668 bool isVolatile() const { return getFastTypeQuals().hasVolatile(); }
4669 bool isRestrict() const { return getFastTypeQuals().hasRestrict(); }
4670
4671
4672
4673 QualType getCallResultType(const ASTContext &Context) const {
4674 return getReturnType().getNonLValueExprType(Context);
4675 }
4676
4677 static StringRef getNameForCallConv(CallingConv CC);
4678
4679 static bool classof(const Type *T) {
4680 return T->getTypeClass() == FunctionNoProto ||
4681 T->getTypeClass() == FunctionProto;
4682 }
4683 };
4684
4685
4686
4687 class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
4688 friend class ASTContext;
4689
4690 FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
4691 : FunctionType(FunctionNoProto, Result, Canonical,
4692 Result->getDependence() &
4693 ~(TypeDependence::DependentInstantiation |
4694 TypeDependence::UnexpandedPack),
4695 Info) {}
4696
4697 public:
4698
4699
4700 bool isSugared() const { return false; }
4701 QualType desugar() const { return QualType(this, 0); }
4702
4703 void Profile(llvm::FoldingSetNodeID &ID) {
4704 Profile(ID, getReturnType(), getExtInfo());
4705 }
4706
4707 static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
4708 ExtInfo Info) {
4709 Info.Profile(ID);
4710 ID.AddPointer(ResultType.getAsOpaquePtr());
4711 }
4712
4713 static bool classof(const Type *T) {
4714 return T->getTypeClass() == FunctionNoProto;
4715 }
4716 };
4717
4718
4719
4720
4721
4722 class FunctionEffect {
4723 public:
4724
4725 enum class Kind : uint8_t {
4726 NonBlocking,
4727 NonAllocating,
4728 Blocking,
4729 Allocating,
4730 Last = Allocating
4731 };
4732 constexpr static size_t KindCount = static_cast<size_t>(Kind::Last) + 1;
4733
4734
4735 using Flags = unsigned;
4736 enum FlagBit : Flags {
4737
4738
4739
4740 FE_InferrableOnCallees = 0x1,
4741
4742
4743 FE_ExcludeThrow = 0x2,
4744 FE_ExcludeCatch = 0x4,
4745 FE_ExcludeObjCMessageSend = 0x8,
4746 FE_ExcludeStaticLocalVars = 0x10,
4747 FE_ExcludeThreadLocalVars = 0x20
4748 };
4749
4750 private:
4751 Kind FKind;
4752
4753
4754
4755
4756
4757 public:
4758 explicit FunctionEffect(Kind K) : FKind(K) {}
4759
4760
4761 Kind kind() const { return FKind; }
4762
4763
4764 Kind oppositeKind() const;
4765
4766
4767 uint32_t toOpaqueInt32() const { return uint32_t(FKind); }
4768 static FunctionEffect fromOpaqueInt32(uint32_t Value) {
4769 return FunctionEffect(Kind(Value));
4770 }
4771
4772
4773 Flags flags() const {
4774 switch (kind()) {
4775 case Kind::NonBlocking:
4776 return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
4777 FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars |
4778 FE_ExcludeThreadLocalVars;
4779 case Kind::NonAllocating:
4780
4781 return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
4782 FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars;
4783 case Kind::Blocking:
4784 case Kind::Allocating:
4785 return 0;
4786 }
4787 llvm_unreachable("unknown effect kind");
4788 }
4789
4790
4791 StringRef name() const;
4792
4793 friend raw_ostream &operator<<(raw_ostream &OS,
4794 const FunctionEffect &Effect) {
4795 OS << Effect.name();
4796 return OS;
4797 }
4798
4799
4800
4801
4802
4803
4804
4805 std::optional<FunctionEffect>
4806 effectProhibitingInference(const Decl &Callee,
4807 FunctionEffectKindSet CalleeFX) const;
4808
4809
4810
4811
4812
4813 bool shouldDiagnoseFunctionCall(bool Direct,
4814 FunctionEffectKindSet CalleeFX) const;
4815
4816 friend bool operator==(FunctionEffect LHS, FunctionEffect RHS) {
4817 return LHS.FKind == RHS.FKind;
4818 }
4819 friend bool operator!=(FunctionEffect LHS, FunctionEffect RHS) {
4820 return !(LHS == RHS);
4821 }
4822 friend bool operator<(FunctionEffect LHS, FunctionEffect RHS) {
4823 return LHS.FKind < RHS.FKind;
4824 }
4825 };
4826
4827
4828
4829 class EffectConditionExpr {
4830 Expr *Cond = nullptr;
4831
4832 public:
4833 EffectConditionExpr() = default;
4834 EffectConditionExpr(Expr *E) : Cond(E) {}
4835
4836 Expr *getCondition() const { return Cond; }
4837
4838 bool operator==(const EffectConditionExpr &RHS) const {
4839 return Cond == RHS.Cond;
4840 }
4841 };
4842
4843
4844
4845
4846 struct FunctionEffectWithCondition {
4847 FunctionEffect Effect;
4848 EffectConditionExpr Cond;
4849
4850 FunctionEffectWithCondition(FunctionEffect E, const EffectConditionExpr &C)
4851 : Effect(E), Cond(C) {}
4852
4853
4854 std::string description() const;
4855
4856 friend raw_ostream &operator<<(raw_ostream &OS,
4857 const FunctionEffectWithCondition &CFE);
4858 };
4859
4860
4861
4862 template <typename Container> class FunctionEffectIterator {
4863 friend Container;
4864
4865 const Container *Outer = nullptr;
4866 size_t Idx = 0;
4867
4868 public:
4869 FunctionEffectIterator();
4870 FunctionEffectIterator(const Container &O, size_t I) : Outer(&O), Idx(I) {}
4871 bool operator==(const FunctionEffectIterator &Other) const {
4872 return Idx == Other.Idx;
4873 }
4874 bool operator!=(const FunctionEffectIterator &Other) const {
4875 return Idx != Other.Idx;
4876 }
4877
4878 FunctionEffectIterator operator++() {
4879 ++Idx;
4880 return *this;
4881 }
4882
4883 FunctionEffectWithCondition operator*() const {
4884 assert(Outer != nullptr && "invalid FunctionEffectIterator");
4885 bool HasConds = !Outer->Conditions.empty();
4886 return FunctionEffectWithCondition{Outer->Effects[Idx],
4887 HasConds ? Outer->Conditions[Idx]
4888 : EffectConditionExpr()};
4889 }
4890 };
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909 class FunctionEffectsRef {
4910
4911
4912
4913
4914 friend FunctionProtoType;
4915 friend FunctionEffectSet;
4916
4917 ArrayRef<FunctionEffect> Effects;
4918 ArrayRef<EffectConditionExpr> Conditions;
4919
4920
4921
4922
4923
4924 FunctionEffectsRef(ArrayRef<FunctionEffect> FX,
4925 ArrayRef<EffectConditionExpr> Conds)
4926 : Effects(FX), Conditions(Conds) {}
4927
4928 public:
4929
4930
4931 static FunctionEffectsRef get(QualType QT);
4932
4933
4934 static FunctionEffectsRef create(ArrayRef<FunctionEffect> FX,
4935 ArrayRef<EffectConditionExpr> Conds);
4936
4937 FunctionEffectsRef() = default;
4938
4939 bool empty() const { return Effects.empty(); }
4940 size_t size() const { return Effects.size(); }
4941
4942 ArrayRef<FunctionEffect> effects() const { return Effects; }
4943 ArrayRef<EffectConditionExpr> conditions() const { return Conditions; }
4944
4945 using iterator = FunctionEffectIterator<FunctionEffectsRef>;
4946 friend iterator;
4947 iterator begin() const { return iterator(*this, 0); }
4948 iterator end() const { return iterator(*this, size()); }
4949
4950 friend bool operator==(const FunctionEffectsRef &LHS,
4951 const FunctionEffectsRef &RHS) {
4952 return LHS.Effects == RHS.Effects && LHS.Conditions == RHS.Conditions;
4953 }
4954 friend bool operator!=(const FunctionEffectsRef &LHS,
4955 const FunctionEffectsRef &RHS) {
4956 return !(LHS == RHS);
4957 }
4958
4959 void dump(llvm::raw_ostream &OS) const;
4960 };
4961
4962
4963 class FunctionEffectKindSet {
4964
4965 constexpr static size_t EndBitPos = FunctionEffect::KindCount;
4966 using KindBitsT = std::bitset<EndBitPos>;
4967
4968 KindBitsT KindBits{};
4969
4970 explicit FunctionEffectKindSet(KindBitsT KB) : KindBits(KB) {}
4971
4972
4973
4974
4975 constexpr static size_t kindToPos(FunctionEffect::Kind K) {
4976 return static_cast<size_t>(K);
4977 }
4978
4979 constexpr static FunctionEffect::Kind posToKind(size_t Pos) {
4980 return static_cast<FunctionEffect::Kind>(Pos);
4981 }
4982
4983
4984 class iterator {
4985 const FunctionEffectKindSet *Outer = nullptr;
4986 size_t Idx = 0;
4987
4988
4989
4990 void advanceToNextSetBit() {
4991 while (Idx < EndBitPos && !Outer->KindBits.test(Idx))
4992 ++Idx;
4993 }
4994
4995 public:
4996 iterator();
4997 iterator(const FunctionEffectKindSet &O, size_t I) : Outer(&O), Idx(I) {
4998 advanceToNextSetBit();
4999 }
5000 bool operator==(const iterator &Other) const { return Idx == Other.Idx; }
5001 bool operator!=(const iterator &Other) const { return Idx != Other.Idx; }
5002
5003 iterator operator++() {
5004 ++Idx;
5005 advanceToNextSetBit();
5006 return *this;
5007 }
5008
5009 FunctionEffect operator*() const {
5010 assert(Idx < EndBitPos && "Dereference of end iterator");
5011 return FunctionEffect(posToKind(Idx));
5012 }
5013 };
5014
5015 public:
5016 FunctionEffectKindSet() = default;
5017 explicit FunctionEffectKindSet(FunctionEffectsRef FX) { insert(FX); }
5018
5019 iterator begin() const { return iterator(*this, 0); }
5020 iterator end() const { return iterator(*this, EndBitPos); }
5021
5022 void insert(FunctionEffect Effect) { KindBits.set(kindToPos(Effect.kind())); }
5023 void insert(FunctionEffectsRef FX) {
5024 for (FunctionEffect Item : FX.effects())
5025 insert(Item);
5026 }
5027 void insert(FunctionEffectKindSet Set) { KindBits |= Set.KindBits; }
5028
5029 bool empty() const { return KindBits.none(); }
5030 bool contains(const FunctionEffect::Kind EK) const {
5031 return KindBits.test(kindToPos(EK));
5032 }
5033 void dump(llvm::raw_ostream &OS) const;
5034
5035 static FunctionEffectKindSet difference(FunctionEffectKindSet LHS,
5036 FunctionEffectKindSet RHS) {
5037 return FunctionEffectKindSet(LHS.KindBits & ~RHS.KindBits);
5038 }
5039 };
5040
5041
5042
5043
5044
5045 class FunctionEffectSet {
5046 SmallVector<FunctionEffect> Effects;
5047 SmallVector<EffectConditionExpr> Conditions;
5048
5049 public:
5050 FunctionEffectSet() = default;
5051
5052 explicit FunctionEffectSet(const FunctionEffectsRef &FX)
5053 : Effects(FX.effects()), Conditions(FX.conditions()) {}
5054
5055 bool empty() const { return Effects.empty(); }
5056 size_t size() const { return Effects.size(); }
5057
5058 using iterator = FunctionEffectIterator<FunctionEffectSet>;
5059 friend iterator;
5060 iterator begin() const { return iterator(*this, 0); }
5061 iterator end() const { return iterator(*this, size()); }
5062
5063 operator FunctionEffectsRef() const { return {Effects, Conditions}; }
5064
5065 void dump(llvm::raw_ostream &OS) const;
5066
5067
5068
5069
5070
5071
5072
5073 struct Conflict {
5074 FunctionEffectWithCondition Kept;
5075 FunctionEffectWithCondition Rejected;
5076 };
5077 using Conflicts = SmallVector<Conflict>;
5078
5079
5080 bool insert(const FunctionEffectWithCondition &NewEC, Conflicts &Errs);
5081
5082
5083 bool insert(const FunctionEffectsRef &Set, Conflicts &Errs);
5084
5085
5086
5087 static FunctionEffectSet getUnion(FunctionEffectsRef LHS,
5088 FunctionEffectsRef RHS, Conflicts &Errs);
5089 static FunctionEffectSet getIntersection(FunctionEffectsRef LHS,
5090 FunctionEffectsRef RHS);
5091 };
5092
5093
5094
5095
5096
5097
5098
5099
5100 class FunctionProtoType final
5101 : public FunctionType,
5102 public llvm::FoldingSetNode,
5103 private llvm::TrailingObjects<
5104 FunctionProtoType, QualType, SourceLocation,
5105 FunctionType::FunctionTypeExtraBitfields,
5106 FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType,
5107 Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers,
5108 FunctionEffect, EffectConditionExpr> {
5109 friend class ASTContext;
5110 friend TrailingObjects;
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160 public:
5161
5162
5163
5164
5165 struct ExceptionSpecInfo {
5166
5167 ExceptionSpecificationType Type = EST_None;
5168
5169
5170 ArrayRef<QualType> Exceptions;
5171
5172
5173 Expr *NoexceptExpr = nullptr;
5174
5175
5176
5177 FunctionDecl *SourceDecl = nullptr;
5178
5179
5180
5181 FunctionDecl *SourceTemplate = nullptr;
5182
5183 ExceptionSpecInfo() = default;
5184
5185 ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
5186
5187 void instantiate();
5188 };
5189
5190
5191
5192
5193 struct ExtProtoInfo {
5194 FunctionType::ExtInfo ExtInfo;
5195 unsigned Variadic : 1;
5196 unsigned HasTrailingReturn : 1;
5197 unsigned AArch64SMEAttributes : 9;
5198 Qualifiers TypeQuals;
5199 RefQualifierKind RefQualifier = RQ_None;
5200 ExceptionSpecInfo ExceptionSpec;
5201 const ExtParameterInfo *ExtParameterInfos = nullptr;
5202 SourceLocation EllipsisLoc;
5203 FunctionEffectsRef FunctionEffects;
5204
5205 ExtProtoInfo()
5206 : Variadic(false), HasTrailingReturn(false),
5207 AArch64SMEAttributes(SME_NormalFunction) {}
5208
5209 ExtProtoInfo(CallingConv CC)
5210 : ExtInfo(CC), Variadic(false), HasTrailingReturn(false),
5211 AArch64SMEAttributes(SME_NormalFunction) {}
5212
5213 ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) {
5214 ExtProtoInfo Result(*this);
5215 Result.ExceptionSpec = ESI;
5216 return Result;
5217 }
5218
5219 bool requiresFunctionProtoTypeExtraBitfields() const {
5220 return ExceptionSpec.Type == EST_Dynamic ||
5221 requiresFunctionProtoTypeArmAttributes() ||
5222 !FunctionEffects.empty();
5223 }
5224
5225 bool requiresFunctionProtoTypeArmAttributes() const {
5226 return AArch64SMEAttributes != SME_NormalFunction;
5227 }
5228
5229 void setArmSMEAttribute(AArch64SMETypeAttributes Kind, bool Enable = true) {
5230 if (Enable)
5231 AArch64SMEAttributes |= Kind;
5232 else
5233 AArch64SMEAttributes &= ~Kind;
5234 }
5235 };
5236
5237 private:
5238 unsigned numTrailingObjects(OverloadToken<QualType>) const {
5239 return getNumParams();
5240 }
5241
5242 unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
5243 return isVariadic();
5244 }
5245
5246 unsigned numTrailingObjects(OverloadToken<FunctionTypeArmAttributes>) const {
5247 return hasArmTypeAttributes();
5248 }
5249
5250 unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
5251 return hasExtraBitfields();
5252 }
5253
5254 unsigned numTrailingObjects(OverloadToken<ExceptionType>) const {
5255 return getExceptionSpecSize().NumExceptionType;
5256 }
5257
5258 unsigned numTrailingObjects(OverloadToken<Expr *>) const {
5259 return getExceptionSpecSize().NumExprPtr;
5260 }
5261
5262 unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const {
5263 return getExceptionSpecSize().NumFunctionDeclPtr;
5264 }
5265
5266 unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
5267 return hasExtParameterInfos() ? getNumParams() : 0;
5268 }
5269
5270 unsigned numTrailingObjects(OverloadToken<Qualifiers>) const {
5271 return hasExtQualifiers() ? 1 : 0;
5272 }
5273
5274 unsigned numTrailingObjects(OverloadToken<FunctionEffect>) const {
5275 return getNumFunctionEffects();
5276 }
5277
5278 unsigned numTrailingObjects(OverloadToken<EffectConditionExpr>) const {
5279 return getNumFunctionEffectConditions();
5280 }
5281
5282
5283
5284 static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
5285 unsigned numArgs) {
5286 for (unsigned Idx = 0; Idx < numArgs; ++Idx)
5287 if (ArgArray[Idx]->containsUnexpandedParameterPack())
5288 return true;
5289
5290 return false;
5291 }
5292
5293 FunctionProtoType(QualType result, ArrayRef<QualType> params,
5294 QualType canonical, const ExtProtoInfo &epi);
5295
5296
5297
5298
5299 struct ExceptionSpecSizeHolder {
5300 unsigned NumExceptionType;
5301 unsigned NumExprPtr;
5302 unsigned NumFunctionDeclPtr;
5303 };
5304
5305
5306
5307 static ExceptionSpecSizeHolder
5308 getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) {
5309 switch (EST) {
5310 case EST_None:
5311 case EST_DynamicNone:
5312 case EST_MSAny:
5313 case EST_BasicNoexcept:
5314 case EST_Unparsed:
5315 case EST_NoThrow:
5316 return {0, 0, 0};
5317
5318 case EST_Dynamic:
5319 return {NumExceptions, 0, 0};
5320
5321 case EST_DependentNoexcept:
5322 case EST_NoexceptFalse:
5323 case EST_NoexceptTrue:
5324 return {0, 1, 0};
5325
5326 case EST_Uninstantiated:
5327 return {0, 0, 2};
5328
5329 case EST_Unevaluated:
5330 return {0, 0, 1};
5331 }
5332 llvm_unreachable("bad exception specification kind");
5333 }
5334
5335
5336
5337 ExceptionSpecSizeHolder getExceptionSpecSize() const {
5338 return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions());
5339 }
5340
5341
5342 bool hasExtraBitfields() const {
5343 assert((getExceptionSpecType() != EST_Dynamic ||
5344 FunctionTypeBits.HasExtraBitfields) &&
5345 "ExtraBitfields are required for given ExceptionSpecType");
5346 return FunctionTypeBits.HasExtraBitfields;
5347
5348 }
5349
5350 bool hasArmTypeAttributes() const {
5351 return FunctionTypeBits.HasExtraBitfields &&
5352 getTrailingObjects<FunctionTypeExtraBitfields>()
5353 ->HasArmTypeAttributes;
5354 }
5355
5356 bool hasExtQualifiers() const {
5357 return FunctionTypeBits.HasExtQuals;
5358 }
5359
5360 public:
5361 unsigned getNumParams() const { return FunctionTypeBits.NumParams; }
5362
5363 QualType getParamType(unsigned i) const {
5364 assert(i < getNumParams() && "invalid parameter index");
5365 return param_type_begin()[i];
5366 }
5367
5368 ArrayRef<QualType> getParamTypes() const {
5369 return llvm::ArrayRef(param_type_begin(), param_type_end());
5370 }
5371
5372 ExtProtoInfo getExtProtoInfo() const {
5373 ExtProtoInfo EPI;
5374 EPI.ExtInfo = getExtInfo();
5375 EPI.Variadic = isVariadic();
5376 EPI.EllipsisLoc = getEllipsisLoc();
5377 EPI.HasTrailingReturn = hasTrailingReturn();
5378 EPI.ExceptionSpec = getExceptionSpecInfo();
5379 EPI.TypeQuals = getMethodQuals();
5380 EPI.RefQualifier = getRefQualifier();
5381 EPI.ExtParameterInfos = getExtParameterInfosOrNull();
5382 EPI.AArch64SMEAttributes = getAArch64SMEAttributes();
5383 EPI.FunctionEffects = getFunctionEffects();
5384 return EPI;
5385 }
5386
5387
5388 ExceptionSpecificationType getExceptionSpecType() const {
5389 return static_cast<ExceptionSpecificationType>(
5390 FunctionTypeBits.ExceptionSpecType);
5391 }
5392
5393
5394 bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; }
5395
5396
5397 bool hasDynamicExceptionSpec() const {
5398 return isDynamicExceptionSpec(getExceptionSpecType());
5399 }
5400
5401
5402 bool hasNoexceptExceptionSpec() const {
5403 return isNoexceptExceptionSpec(getExceptionSpecType());
5404 }
5405
5406
5407 bool hasDependentExceptionSpec() const;
5408
5409
5410
5411 bool hasInstantiationDependentExceptionSpec() const;
5412
5413
5414 ExceptionSpecInfo getExceptionSpecInfo() const {
5415 ExceptionSpecInfo Result;
5416 Result.Type = getExceptionSpecType();
5417 if (Result.Type == EST_Dynamic) {
5418 Result.Exceptions = exceptions();
5419 } else if (isComputedNoexcept(Result.Type)) {
5420 Result.NoexceptExpr = getNoexceptExpr();
5421 } else if (Result.Type == EST_Uninstantiated) {
5422 Result.SourceDecl = getExceptionSpecDecl();
5423 Result.SourceTemplate = getExceptionSpecTemplate();
5424 } else if (Result.Type == EST_Unevaluated) {
5425 Result.SourceDecl = getExceptionSpecDecl();
5426 }
5427 return Result;
5428 }
5429
5430
5431 unsigned getNumExceptions() const {
5432 return getExceptionSpecType() == EST_Dynamic
5433 ? getTrailingObjects<FunctionTypeExtraBitfields>()
5434 ->NumExceptionType
5435 : 0;
5436 }
5437
5438
5439 QualType getExceptionType(unsigned i) const {
5440 assert(i < getNumExceptions() && "Invalid exception number!");
5441 return exception_begin()[i];
5442 }
5443
5444
5445
5446 Expr *getNoexceptExpr() const {
5447 if (!isComputedNoexcept(getExceptionSpecType()))
5448 return nullptr;
5449 return *getTrailingObjects<Expr *>();
5450 }
5451
5452
5453
5454
5455
5456 FunctionDecl *getExceptionSpecDecl() const {
5457 if (getExceptionSpecType() != EST_Uninstantiated &&
5458 getExceptionSpecType() != EST_Unevaluated)
5459 return nullptr;
5460 return getTrailingObjects<FunctionDecl *>()[0];
5461 }
5462
5463
5464
5465
5466
5467 FunctionDecl *getExceptionSpecTemplate() const {
5468 if (getExceptionSpecType() != EST_Uninstantiated)
5469 return nullptr;
5470 return getTrailingObjects<FunctionDecl *>()[1];
5471 }
5472
5473
5474
5475 CanThrowResult canThrow() const;
5476
5477
5478
5479
5480 bool isNothrow(bool ResultIfDependent = false) const {
5481 return ResultIfDependent ? canThrow() != CT_Can : canThrow() == CT_Cannot;
5482 }
5483
5484
5485 bool isVariadic() const { return FunctionTypeBits.Variadic; }
5486
5487 SourceLocation getEllipsisLoc() const {
5488 return isVariadic() ? *getTrailingObjects<SourceLocation>()
5489 : SourceLocation();
5490 }
5491
5492
5493
5494
5495
5496
5497
5498 bool isTemplateVariadic() const;
5499
5500
5501 bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; }
5502
5503 Qualifiers getMethodQuals() const {
5504 if (hasExtQualifiers())
5505 return *getTrailingObjects<Qualifiers>();
5506 else
5507 return getFastTypeQuals();
5508 }
5509
5510
5511 RefQualifierKind getRefQualifier() const {
5512 return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
5513 }
5514
5515 using param_type_iterator = const QualType *;
5516
5517 ArrayRef<QualType> param_types() const {
5518 return llvm::ArrayRef(param_type_begin(), param_type_end());
5519 }
5520
5521 param_type_iterator param_type_begin() const {
5522 return getTrailingObjects<QualType>();
5523 }
5524
5525 param_type_iterator param_type_end() const {
5526 return param_type_begin() + getNumParams();
5527 }
5528
5529 using exception_iterator = const QualType *;
5530
5531 ArrayRef<QualType> exceptions() const {
5532 return llvm::ArrayRef(exception_begin(), exception_end());
5533 }
5534
5535 exception_iterator exception_begin() const {
5536 return reinterpret_cast<exception_iterator>(
5537 getTrailingObjects<ExceptionType>());
5538 }
5539
5540 exception_iterator exception_end() const {
5541 return exception_begin() + getNumExceptions();
5542 }
5543
5544
5545
5546 bool hasExtParameterInfos() const {
5547 return FunctionTypeBits.HasExtParameterInfos;
5548 }
5549
5550 ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
5551 assert(hasExtParameterInfos());
5552 return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(),
5553 getNumParams());
5554 }
5555
5556
5557
5558
5559 const ExtParameterInfo *getExtParameterInfosOrNull() const {
5560 if (!hasExtParameterInfos())
5561 return nullptr;
5562 return getTrailingObjects<ExtParameterInfo>();
5563 }
5564
5565
5566
5567 unsigned getAArch64SMEAttributes() const {
5568 if (!hasArmTypeAttributes())
5569 return SME_NormalFunction;
5570 return getTrailingObjects<FunctionTypeArmAttributes>()
5571 ->AArch64SMEAttributes;
5572 }
5573
5574 ExtParameterInfo getExtParameterInfo(unsigned I) const {
5575 assert(I < getNumParams() && "parameter index out of range");
5576 if (hasExtParameterInfos())
5577 return getTrailingObjects<ExtParameterInfo>()[I];
5578 return ExtParameterInfo();
5579 }
5580
5581 ParameterABI getParameterABI(unsigned I) const {
5582 assert(I < getNumParams() && "parameter index out of range");
5583 if (hasExtParameterInfos())
5584 return getTrailingObjects<ExtParameterInfo>()[I].getABI();
5585 return ParameterABI::Ordinary;
5586 }
5587
5588 bool isParamConsumed(unsigned I) const {
5589 assert(I < getNumParams() && "parameter index out of range");
5590 if (hasExtParameterInfos())
5591 return getTrailingObjects<ExtParameterInfo>()[I].isConsumed();
5592 return false;
5593 }
5594
5595 unsigned getNumFunctionEffects() const {
5596 return hasExtraBitfields()
5597 ? getTrailingObjects<FunctionTypeExtraBitfields>()
5598 ->NumFunctionEffects
5599 : 0;
5600 }
5601
5602
5603 ArrayRef<FunctionEffect> getFunctionEffectsWithoutConditions() const {
5604 if (hasExtraBitfields()) {
5605 const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>();
5606 if (Bitfields->NumFunctionEffects > 0)
5607 return {getTrailingObjects<FunctionEffect>(),
5608 Bitfields->NumFunctionEffects};
5609 }
5610 return {};
5611 }
5612
5613 unsigned getNumFunctionEffectConditions() const {
5614 if (hasExtraBitfields()) {
5615 const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>();
5616 if (Bitfields->EffectsHaveConditions)
5617 return Bitfields->NumFunctionEffects;
5618 }
5619 return 0;
5620 }
5621
5622
5623 ArrayRef<EffectConditionExpr> getFunctionEffectConditions() const {
5624 if (hasExtraBitfields()) {
5625 const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>();
5626 if (Bitfields->EffectsHaveConditions)
5627 return {getTrailingObjects<EffectConditionExpr>(),
5628 Bitfields->NumFunctionEffects};
5629 }
5630 return {};
5631 }
5632
5633
5634 FunctionEffectsRef getFunctionEffects() const {
5635 if (hasExtraBitfields()) {
5636 const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>();
5637 if (Bitfields->NumFunctionEffects > 0) {
5638 const size_t NumConds = Bitfields->EffectsHaveConditions
5639 ? Bitfields->NumFunctionEffects
5640 : 0;
5641 return FunctionEffectsRef(
5642 {getTrailingObjects<FunctionEffect>(),
5643 Bitfields->NumFunctionEffects},
5644 {NumConds ? getTrailingObjects<EffectConditionExpr>() : nullptr,
5645 NumConds});
5646 }
5647 }
5648 return {};
5649 }
5650
5651 bool isSugared() const { return false; }
5652 QualType desugar() const { return QualType(this, 0); }
5653
5654 void printExceptionSpecification(raw_ostream &OS,
5655 const PrintingPolicy &Policy) const;
5656
5657 static bool classof(const Type *T) {
5658 return T->getTypeClass() == FunctionProto;
5659 }
5660
5661 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
5662 static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
5663 param_type_iterator ArgTys, unsigned NumArgs,
5664 const ExtProtoInfo &EPI, const ASTContext &Context,
5665 bool Canonical);
5666 };
5667
5668
5669
5670
5671
5672
5673 class UnresolvedUsingType : public Type {
5674 friend class ASTContext;
5675
5676 UnresolvedUsingTypenameDecl *Decl;
5677
5678 UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
5679 : Type(UnresolvedUsing, QualType(),
5680 TypeDependence::DependentInstantiation),
5681 Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {}
5682
5683 public:
5684 UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
5685
5686 bool isSugared() const { return false; }
5687 QualType desugar() const { return QualType(this, 0); }
5688
5689 static bool classof(const Type *T) {
5690 return T->getTypeClass() == UnresolvedUsing;
5691 }
5692
5693 void Profile(llvm::FoldingSetNodeID &ID) {
5694 return Profile(ID, Decl);
5695 }
5696
5697 static void Profile(llvm::FoldingSetNodeID &ID,
5698 UnresolvedUsingTypenameDecl *D) {
5699 ID.AddPointer(D);
5700 }
5701 };
5702
5703 class UsingType final : public Type,
5704 public llvm::FoldingSetNode,
5705 private llvm::TrailingObjects<UsingType, QualType> {
5706 UsingShadowDecl *Found;
5707 friend class ASTContext;
5708 friend TrailingObjects;
5709
5710 UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon);
5711
5712 public:
5713 UsingShadowDecl *getFoundDecl() const { return Found; }
5714 QualType getUnderlyingType() const;
5715
5716 bool isSugared() const { return true; }
5717
5718
5719 QualType desugar() const { return getUnderlyingType(); }
5720
5721
5722 bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; }
5723
5724 void Profile(llvm::FoldingSetNodeID &ID) {
5725 Profile(ID, Found, getUnderlyingType());
5726 }
5727 static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found,
5728 QualType Underlying) {
5729 ID.AddPointer(Found);
5730 Underlying.Profile(ID);
5731 }
5732 static bool classof(const Type *T) { return T->getTypeClass() == Using; }
5733 };
5734
5735 class TypedefType final : public Type,
5736 public llvm::FoldingSetNode,
5737 private llvm::TrailingObjects<TypedefType, QualType> {
5738 TypedefNameDecl *Decl;
5739 friend class ASTContext;
5740 friend TrailingObjects;
5741
5742 TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying,
5743 QualType can);
5744
5745 public:
5746 TypedefNameDecl *getDecl() const { return Decl; }
5747
5748 bool isSugared() const { return true; }
5749
5750
5751 QualType desugar() const;
5752
5753
5754 bool typeMatchesDecl() const { return !TypedefBits.hasTypeDifferentFromDecl; }
5755
5756 void Profile(llvm::FoldingSetNodeID &ID) {
5757 Profile(ID, Decl, typeMatchesDecl() ? QualType() : desugar());
5758 }
5759 static void Profile(llvm::FoldingSetNodeID &ID, const TypedefNameDecl *Decl,
5760 QualType Underlying) {
5761 ID.AddPointer(Decl);
5762 if (!Underlying.isNull())
5763 Underlying.Profile(ID);
5764 }
5765
5766 static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
5767 };
5768
5769
5770
5771 class MacroQualifiedType : public Type {
5772 friend class ASTContext;
5773
5774 QualType UnderlyingTy;
5775 const IdentifierInfo *MacroII;
5776
5777 MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy,
5778 const IdentifierInfo *MacroII)
5779 : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()),
5780 UnderlyingTy(UnderlyingTy), MacroII(MacroII) {
5781 assert(isa<AttributedType>(UnderlyingTy) &&
5782 "Expected a macro qualified type to only wrap attributed types.");
5783 }
5784
5785 public:
5786 const IdentifierInfo *getMacroIdentifier() const { return MacroII; }
5787 QualType getUnderlyingType() const { return UnderlyingTy; }
5788
5789
5790
5791 QualType getModifiedType() const;
5792
5793 bool isSugared() const { return true; }
5794 QualType desugar() const;
5795
5796 static bool classof(const Type *T) {
5797 return T->getTypeClass() == MacroQualified;
5798 }
5799 };
5800
5801
5802
5803 class TypeOfExprType : public Type {
5804 Expr *TOExpr;
5805 const ASTContext &Context;
5806
5807 protected:
5808 friend class ASTContext;
5809
5810 TypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind,
5811 QualType Can = QualType());
5812
5813 public:
5814 Expr *getUnderlyingExpr() const { return TOExpr; }
5815
5816
5817 TypeOfKind getKind() const {
5818 return static_cast<TypeOfKind>(TypeOfBits.Kind);
5819 }
5820
5821
5822 QualType desugar() const;
5823
5824
5825 bool isSugared() const;
5826
5827 static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
5828 };
5829
5830
5831
5832
5833
5834
5835
5836 class DependentTypeOfExprType : public TypeOfExprType,
5837 public llvm::FoldingSetNode {
5838 public:
5839 DependentTypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind)
5840 : TypeOfExprType(Context, E, Kind) {}
5841
5842 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
5843 Profile(ID, Context, getUnderlyingExpr(),
5844 getKind() == TypeOfKind::Unqualified);
5845 }
5846
5847 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
5848 Expr *E, bool IsUnqual);
5849 };
5850
5851
5852
5853 class TypeOfType : public Type {
5854 friend class ASTContext;
5855
5856 QualType TOType;
5857 const ASTContext &Context;
5858
5859 TypeOfType(const ASTContext &Context, QualType T, QualType Can,
5860 TypeOfKind Kind);
5861
5862 public:
5863 QualType getUnmodifiedType() const { return TOType; }
5864
5865
5866 QualType desugar() const;
5867
5868
5869 bool isSugared() const { return true; }
5870
5871
5872 TypeOfKind getKind() const {
5873 return static_cast<TypeOfKind>(TypeOfBits.Kind);
5874 }
5875
5876 static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
5877 };
5878
5879
5880 class DecltypeType : public Type {
5881 Expr *E;
5882 QualType UnderlyingType;
5883
5884 protected:
5885 friend class ASTContext;
5886
5887 DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
5888
5889 public:
5890 Expr *getUnderlyingExpr() const { return E; }
5891 QualType getUnderlyingType() const { return UnderlyingType; }
5892
5893
5894 QualType desugar() const;
5895
5896
5897 bool isSugared() const;
5898
5899 static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
5900 };
5901
5902
5903
5904
5905
5906
5907
5908 class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
5909 public:
5910 DependentDecltypeType(Expr *E, QualType UnderlyingTpe);
5911
5912 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
5913 Profile(ID, Context, getUnderlyingExpr());
5914 }
5915
5916 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
5917 Expr *E);
5918 };
5919
5920 class PackIndexingType final
5921 : public Type,
5922 public llvm::FoldingSetNode,
5923 private llvm::TrailingObjects<PackIndexingType, QualType> {
5924 friend TrailingObjects;
5925
5926 const ASTContext &Context;
5927 QualType Pattern;
5928 Expr *IndexExpr;
5929
5930 unsigned Size : 31;
5931
5932 LLVM_PREFERRED_TYPE(bool)
5933 unsigned FullySubstituted : 1;
5934
5935 protected:
5936 friend class ASTContext;
5937 PackIndexingType(const ASTContext &Context, QualType Canonical,
5938 QualType Pattern, Expr *IndexExpr, bool FullySubstituted,
5939 ArrayRef<QualType> Expansions = {});
5940
5941 public:
5942 Expr *getIndexExpr() const { return IndexExpr; }
5943 QualType getPattern() const { return Pattern; }
5944
5945 bool isSugared() const { return hasSelectedType(); }
5946
5947 QualType desugar() const {
5948 if (hasSelectedType())
5949 return getSelectedType();
5950 return QualType(this, 0);
5951 }
5952
5953 QualType getSelectedType() const {
5954 assert(hasSelectedType() && "Type is dependant");
5955 return *(getExpansionsPtr() + *getSelectedIndex());
5956 }
5957
5958 std::optional<unsigned> getSelectedIndex() const;
5959
5960 bool hasSelectedType() const { return getSelectedIndex() != std::nullopt; }
5961
5962 bool isFullySubstituted() const { return FullySubstituted; }
5963
5964 bool expandsToEmptyPack() const { return isFullySubstituted() && Size == 0; }
5965
5966 ArrayRef<QualType> getExpansions() const {
5967 return {getExpansionsPtr(), Size};
5968 }
5969
5970 static bool classof(const Type *T) {
5971 return T->getTypeClass() == PackIndexing;
5972 }
5973
5974 void Profile(llvm::FoldingSetNodeID &ID) {
5975 if (hasSelectedType())
5976 getSelectedType().Profile(ID);
5977 else
5978 Profile(ID, Context, getPattern(), getIndexExpr(), isFullySubstituted());
5979 }
5980 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
5981 QualType Pattern, Expr *E, bool FullySubstituted);
5982
5983 private:
5984 const QualType *getExpansionsPtr() const {
5985 return getTrailingObjects<QualType>();
5986 }
5987
5988 static TypeDependence computeDependence(QualType Pattern, Expr *IndexExpr,
5989 ArrayRef<QualType> Expansions = {});
5990
5991 unsigned numTrailingObjects(OverloadToken<QualType>) const { return Size; }
5992 };
5993
5994
5995 class UnaryTransformType : public Type {
5996 public:
5997 enum UTTKind {
5998 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum,
5999 #include "clang/Basic/TransformTypeTraits.def"
6000 };
6001
6002 private:
6003
6004 QualType BaseType;
6005
6006
6007 QualType UnderlyingType;
6008
6009 UTTKind UKind;
6010
6011 protected:
6012 friend class ASTContext;
6013
6014 UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
6015 QualType CanonicalTy);
6016
6017 public:
6018 bool isSugared() const { return !isDependentType(); }
6019 QualType desugar() const { return UnderlyingType; }
6020
6021 QualType getUnderlyingType() const { return UnderlyingType; }
6022 QualType getBaseType() const { return BaseType; }
6023
6024 UTTKind getUTTKind() const { return UKind; }
6025
6026 static bool classof(const Type *T) {
6027 return T->getTypeClass() == UnaryTransform;
6028 }
6029 };
6030
6031
6032
6033
6034
6035
6036
6037 class DependentUnaryTransformType : public UnaryTransformType,
6038 public llvm::FoldingSetNode {
6039 public:
6040 DependentUnaryTransformType(const ASTContext &C, QualType BaseType,
6041 UTTKind UKind);
6042
6043 void Profile(llvm::FoldingSetNodeID &ID) {
6044 Profile(ID, getBaseType(), getUTTKind());
6045 }
6046
6047 static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType,
6048 UTTKind UKind) {
6049 ID.AddPointer(BaseType.getAsOpaquePtr());
6050 ID.AddInteger((unsigned)UKind);
6051 }
6052 };
6053
6054 class TagType : public Type {
6055 friend class ASTReader;
6056 template <class T> friend class serialization::AbstractTypeReader;
6057
6058
6059
6060 TagDecl *decl;
6061
6062 protected:
6063 TagType(TypeClass TC, const TagDecl *D, QualType can);
6064
6065 public:
6066 TagDecl *getDecl() const;
6067
6068
6069 bool isBeingDefined() const;
6070
6071 static bool classof(const Type *T) {
6072 return T->getTypeClass() == Enum || T->getTypeClass() == Record;
6073 }
6074 };
6075
6076
6077
6078 class RecordType : public TagType {
6079 protected:
6080 friend class ASTContext;
6081
6082 explicit RecordType(const RecordDecl *D)
6083 : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {}
6084 explicit RecordType(TypeClass TC, RecordDecl *D)
6085 : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {}
6086
6087 public:
6088 RecordDecl *getDecl() const {
6089 return reinterpret_cast<RecordDecl*>(TagType::getDecl());
6090 }
6091
6092
6093
6094 bool hasConstFields() const;
6095
6096 bool isSugared() const { return false; }
6097 QualType desugar() const { return QualType(this, 0); }
6098
6099 static bool classof(const Type *T) { return T->getTypeClass() == Record; }
6100 };
6101
6102
6103
6104 class EnumType : public TagType {
6105 friend class ASTContext;
6106
6107 explicit EnumType(const EnumDecl *D)
6108 : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {}
6109
6110 public:
6111 EnumDecl *getDecl() const {
6112 return reinterpret_cast<EnumDecl*>(TagType::getDecl());
6113 }
6114
6115 bool isSugared() const { return false; }
6116 QualType desugar() const { return QualType(this, 0); }
6117
6118 static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
6119 };
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133 class AttributedType : public Type, public llvm::FoldingSetNode {
6134 public:
6135 using Kind = attr::Kind;
6136
6137 private:
6138 friend class ASTContext;
6139
6140 const Attr *Attribute;
6141
6142 QualType ModifiedType;
6143 QualType EquivalentType;
6144
6145 AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
6146 QualType equivalent)
6147 : AttributedType(canon, attrKind, nullptr, modified, equivalent) {}
6148
6149 AttributedType(QualType canon, const Attr *attr, QualType modified,
6150 QualType equivalent);
6151
6152 private:
6153 AttributedType(QualType canon, attr::Kind attrKind, const Attr *attr,
6154 QualType modified, QualType equivalent);
6155
6156 public:
6157 Kind getAttrKind() const {
6158 return static_cast<Kind>(AttributedTypeBits.AttrKind);
6159 }
6160
6161 const Attr *getAttr() const { return Attribute; }
6162
6163 QualType getModifiedType() const { return ModifiedType; }
6164 QualType getEquivalentType() const { return EquivalentType; }
6165
6166 bool isSugared() const { return true; }
6167 QualType desugar() const { return getEquivalentType(); }
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184 bool isQualifier() const;
6185
6186 bool isMSTypeSpec() const;
6187
6188 bool isWebAssemblyFuncrefSpec() const;
6189
6190 bool isCallingConv() const;
6191
6192 std::optional<NullabilityKind> getImmediateNullability() const;
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203 static std::optional<NullabilityKind> stripOuterNullability(QualType &T);
6204
6205 void Profile(llvm::FoldingSetNodeID &ID) {
6206 Profile(ID, getAttrKind(), ModifiedType, EquivalentType, Attribute);
6207 }
6208
6209 static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
6210 QualType modified, QualType equivalent,
6211 const Attr *attr) {
6212 ID.AddInteger(attrKind);
6213 ID.AddPointer(modified.getAsOpaquePtr());
6214 ID.AddPointer(equivalent.getAsOpaquePtr());
6215 ID.AddPointer(attr);
6216 }
6217
6218 static bool classof(const Type *T) {
6219 return T->getTypeClass() == Attributed;
6220 }
6221 };
6222
6223 class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
6224 private:
6225 friend class ASTContext;
6226
6227 QualType WrappedType;
6228 const BTFTypeTagAttr *BTFAttr;
6229
6230 BTFTagAttributedType(QualType Canon, QualType Wrapped,
6231 const BTFTypeTagAttr *BTFAttr)
6232 : Type(BTFTagAttributed, Canon, Wrapped->getDependence()),
6233 WrappedType(Wrapped), BTFAttr(BTFAttr) {}
6234
6235 public:
6236 QualType getWrappedType() const { return WrappedType; }
6237 const BTFTypeTagAttr *getAttr() const { return BTFAttr; }
6238
6239 bool isSugared() const { return true; }
6240 QualType desugar() const { return getWrappedType(); }
6241
6242 void Profile(llvm::FoldingSetNodeID &ID) {
6243 Profile(ID, WrappedType, BTFAttr);
6244 }
6245
6246 static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped,
6247 const BTFTypeTagAttr *BTFAttr) {
6248 ID.AddPointer(Wrapped.getAsOpaquePtr());
6249 ID.AddPointer(BTFAttr);
6250 }
6251
6252 static bool classof(const Type *T) {
6253 return T->getTypeClass() == BTFTagAttributed;
6254 }
6255 };
6256
6257 class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
6258 public:
6259 struct Attributes {
6260
6261 llvm::dxil::ResourceClass ResourceClass;
6262
6263 LLVM_PREFERRED_TYPE(bool)
6264 uint8_t IsROV : 1;
6265
6266 LLVM_PREFERRED_TYPE(bool)
6267 uint8_t RawBuffer : 1;
6268
6269 Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV,
6270 bool RawBuffer)
6271 : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {}
6272
6273 Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {}
6274
6275 friend bool operator==(const Attributes &LHS, const Attributes &RHS) {
6276 return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer) ==
6277 std::tie(RHS.ResourceClass, RHS.IsROV, RHS.RawBuffer);
6278 }
6279 friend bool operator!=(const Attributes &LHS, const Attributes &RHS) {
6280 return !(LHS == RHS);
6281 }
6282 };
6283
6284 private:
6285 friend class ASTContext;
6286
6287 QualType WrappedType;
6288 QualType ContainedType;
6289 const Attributes Attrs;
6290
6291 HLSLAttributedResourceType(QualType Wrapped, QualType Contained,
6292 const Attributes &Attrs)
6293 : Type(HLSLAttributedResource, QualType(),
6294 Contained.isNull() ? TypeDependence::None
6295 : Contained->getDependence()),
6296 WrappedType(Wrapped), ContainedType(Contained), Attrs(Attrs) {}
6297
6298 public:
6299 QualType getWrappedType() const { return WrappedType; }
6300 QualType getContainedType() const { return ContainedType; }
6301 bool hasContainedType() const { return !ContainedType.isNull(); }
6302 const Attributes &getAttrs() const { return Attrs; }
6303
6304 bool isSugared() const { return false; }
6305 QualType desugar() const { return QualType(this, 0); }
6306
6307 void Profile(llvm::FoldingSetNodeID &ID) {
6308 Profile(ID, WrappedType, ContainedType, Attrs);
6309 }
6310
6311 static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped,
6312 QualType Contained, const Attributes &Attrs) {
6313 ID.AddPointer(Wrapped.getAsOpaquePtr());
6314 ID.AddPointer(Contained.getAsOpaquePtr());
6315 ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass));
6316 ID.AddBoolean(Attrs.IsROV);
6317 ID.AddBoolean(Attrs.RawBuffer);
6318 }
6319
6320 static bool classof(const Type *T) {
6321 return T->getTypeClass() == HLSLAttributedResource;
6322 }
6323
6324
6325 static const HLSLAttributedResourceType *
6326 findHandleTypeOnResource(const Type *RT);
6327 };
6328
6329 class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
6330 friend class ASTContext;
6331
6332
6333 TemplateTypeParmDecl *TTPDecl;
6334
6335 TemplateTypeParmType(unsigned D, unsigned I, bool PP,
6336 TemplateTypeParmDecl *TTPDecl, QualType Canon)
6337 : Type(TemplateTypeParm, Canon,
6338 TypeDependence::DependentInstantiation |
6339 (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)),
6340 TTPDecl(TTPDecl) {
6341 assert(!TTPDecl == Canon.isNull());
6342 TemplateTypeParmTypeBits.Depth = D;
6343 TemplateTypeParmTypeBits.Index = I;
6344 TemplateTypeParmTypeBits.ParameterPack = PP;
6345 }
6346
6347 public:
6348 unsigned getDepth() const { return TemplateTypeParmTypeBits.Depth; }
6349 unsigned getIndex() const { return TemplateTypeParmTypeBits.Index; }
6350 bool isParameterPack() const {
6351 return TemplateTypeParmTypeBits.ParameterPack;
6352 }
6353
6354 TemplateTypeParmDecl *getDecl() const { return TTPDecl; }
6355
6356 IdentifierInfo *getIdentifier() const;
6357
6358 bool isSugared() const { return false; }
6359 QualType desugar() const { return QualType(this, 0); }
6360
6361 void Profile(llvm::FoldingSetNodeID &ID) {
6362 Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
6363 }
6364
6365 static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
6366 unsigned Index, bool ParameterPack,
6367 TemplateTypeParmDecl *TTPDecl) {
6368 ID.AddInteger(Depth);
6369 ID.AddInteger(Index);
6370 ID.AddBoolean(ParameterPack);
6371 ID.AddPointer(TTPDecl);
6372 }
6373
6374 static bool classof(const Type *T) {
6375 return T->getTypeClass() == TemplateTypeParm;
6376 }
6377 };
6378
6379
6380
6381
6382
6383
6384
6385
6386 class SubstTemplateTypeParmType final
6387 : public Type,
6388 public llvm::FoldingSetNode,
6389 private llvm::TrailingObjects<SubstTemplateTypeParmType, QualType> {
6390 friend class ASTContext;
6391 friend class llvm::TrailingObjects<SubstTemplateTypeParmType, QualType>;
6392
6393 Decl *AssociatedDecl;
6394
6395 SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
6396 unsigned Index, std::optional<unsigned> PackIndex,
6397 SubstTemplateTypeParmTypeFlag Flag);
6398
6399 public:
6400
6401
6402 QualType getReplacementType() const {
6403 return SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType
6404 ? *getTrailingObjects<QualType>()
6405 : getCanonicalTypeInternal();
6406 }
6407
6408
6409
6410
6411 Decl *getAssociatedDecl() const { return AssociatedDecl; }
6412
6413
6414 const TemplateTypeParmDecl *getReplacedParameter() const;
6415
6416
6417
6418 unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; }
6419
6420 std::optional<unsigned> getPackIndex() const {
6421 if (SubstTemplateTypeParmTypeBits.PackIndex == 0)
6422 return std::nullopt;
6423 return SubstTemplateTypeParmTypeBits.PackIndex - 1;
6424 }
6425
6426 SubstTemplateTypeParmTypeFlag getSubstitutionFlag() const {
6427 return static_cast<SubstTemplateTypeParmTypeFlag>(
6428 SubstTemplateTypeParmTypeBits.SubstitutionFlag);
6429 }
6430
6431 bool isSugared() const { return true; }
6432 QualType desugar() const { return getReplacementType(); }
6433
6434 void Profile(llvm::FoldingSetNodeID &ID) {
6435 Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(),
6436 getPackIndex(), getSubstitutionFlag());
6437 }
6438
6439 static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
6440 const Decl *AssociatedDecl, unsigned Index,
6441 std::optional<unsigned> PackIndex,
6442 SubstTemplateTypeParmTypeFlag Flag) {
6443 Replacement.Profile(ID);
6444 ID.AddPointer(AssociatedDecl);
6445 ID.AddInteger(Index);
6446 ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
6447 ID.AddInteger(llvm::to_underlying(Flag));
6448 assert((Flag != SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace ||
6449 PackIndex) &&
6450 "ExpandPacksInPlace needs a valid PackIndex");
6451 }
6452
6453 static bool classof(const Type *T) {
6454 return T->getTypeClass() == SubstTemplateTypeParm;
6455 }
6456 };
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470 class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
6471 friend class ASTContext;
6472
6473
6474
6475 const TemplateArgument *Arguments;
6476
6477 llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
6478
6479 SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl,
6480 unsigned Index, bool Final,
6481 const TemplateArgument &ArgPack);
6482
6483 public:
6484 IdentifierInfo *getIdentifier() const;
6485
6486
6487
6488
6489 Decl *getAssociatedDecl() const;
6490
6491
6492 const TemplateTypeParmDecl *getReplacedParameter() const;
6493
6494
6495
6496 unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
6497
6498
6499 bool getFinal() const;
6500
6501 unsigned getNumArgs() const {
6502 return SubstTemplateTypeParmPackTypeBits.NumArgs;
6503 }
6504
6505 bool isSugared() const { return false; }
6506 QualType desugar() const { return QualType(this, 0); }
6507
6508 TemplateArgument getArgumentPack() const;
6509
6510 void Profile(llvm::FoldingSetNodeID &ID);
6511 static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl,
6512 unsigned Index, bool Final,
6513 const TemplateArgument &ArgPack);
6514
6515 static bool classof(const Type *T) {
6516 return T->getTypeClass() == SubstTemplateTypeParmPack;
6517 }
6518 };
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528 class DeducedType : public Type {
6529 QualType DeducedAsType;
6530
6531 protected:
6532 DeducedType(TypeClass TC, QualType DeducedAsType,
6533 TypeDependence ExtraDependence, QualType Canon)
6534 : Type(TC, Canon,
6535 ExtraDependence | (DeducedAsType.isNull()
6536 ? TypeDependence::None
6537 : DeducedAsType->getDependence() &
6538 ~TypeDependence::VariablyModified)),
6539 DeducedAsType(DeducedAsType) {}
6540
6541 public:
6542 bool isSugared() const { return !DeducedAsType.isNull(); }
6543 QualType desugar() const {
6544 return isSugared() ? DeducedAsType : QualType(this, 0);
6545 }
6546
6547
6548
6549 QualType getDeducedType() const { return DeducedAsType; }
6550 bool isDeduced() const {
6551 return !DeducedAsType.isNull() || isDependentType();
6552 }
6553
6554 static bool classof(const Type *T) {
6555 return T->getTypeClass() == Auto ||
6556 T->getTypeClass() == DeducedTemplateSpecialization;
6557 }
6558 };
6559
6560
6561
6562 class AutoType : public DeducedType {
6563 friend class ASTContext;
6564
6565 ConceptDecl *TypeConstraintConcept;
6566
6567 AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
6568 TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD,
6569 ArrayRef<TemplateArgument> TypeConstraintArgs);
6570
6571 public:
6572 ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
6573 return {reinterpret_cast<const TemplateArgument *>(this + 1),
6574 AutoTypeBits.NumArgs};
6575 }
6576
6577 ConceptDecl *getTypeConstraintConcept() const {
6578 return TypeConstraintConcept;
6579 }
6580
6581 bool isConstrained() const {
6582 return TypeConstraintConcept != nullptr;
6583 }
6584
6585 bool isDecltypeAuto() const {
6586 return getKeyword() == AutoTypeKeyword::DecltypeAuto;
6587 }
6588
6589 bool isGNUAutoType() const {
6590 return getKeyword() == AutoTypeKeyword::GNUAutoType;
6591 }
6592
6593 AutoTypeKeyword getKeyword() const {
6594 return (AutoTypeKeyword)AutoTypeBits.Keyword;
6595 }
6596
6597 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
6598 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
6599 QualType Deduced, AutoTypeKeyword Keyword,
6600 bool IsDependent, ConceptDecl *CD,
6601 ArrayRef<TemplateArgument> Arguments);
6602
6603 static bool classof(const Type *T) {
6604 return T->getTypeClass() == Auto;
6605 }
6606 };
6607
6608
6609 class DeducedTemplateSpecializationType : public DeducedType,
6610 public llvm::FoldingSetNode {
6611 friend class ASTContext;
6612
6613
6614 TemplateName Template;
6615
6616 DeducedTemplateSpecializationType(TemplateName Template,
6617 QualType DeducedAsType,
6618 bool IsDeducedAsDependent, QualType Canon)
6619 : DeducedType(DeducedTemplateSpecialization, DeducedAsType,
6620 toTypeDependence(Template.getDependence()) |
6621 (IsDeducedAsDependent
6622 ? TypeDependence::DependentInstantiation
6623 : TypeDependence::None),
6624 Canon),
6625 Template(Template) {}
6626
6627 public:
6628
6629 TemplateName getTemplateName() const { return Template;}
6630
6631 void Profile(llvm::FoldingSetNodeID &ID) const {
6632 Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
6633 }
6634
6635 static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
6636 QualType Deduced, bool IsDependent) {
6637 Template.Profile(ID);
6638 Deduced.Profile(ID);
6639 ID.AddBoolean(IsDependent || Template.isDependent());
6640 }
6641
6642 static bool classof(const Type *T) {
6643 return T->getTypeClass() == DeducedTemplateSpecialization;
6644 }
6645 };
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667 class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
6668 friend class ASTContext;
6669
6670
6671
6672
6673
6674
6675
6676
6677 TemplateName Template;
6678
6679 TemplateSpecializationType(TemplateName T,
6680 ArrayRef<TemplateArgument> Args,
6681 QualType Canon,
6682 QualType Aliased);
6683
6684 public:
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696 static bool
6697 anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
6698 ArrayRef<TemplateArgument> Converted);
6699 static bool
6700 anyDependentTemplateArguments(const TemplateArgumentListInfo &,
6701 ArrayRef<TemplateArgument> Converted);
6702 static bool anyInstantiationDependentTemplateArguments(
6703 ArrayRef<TemplateArgumentLoc> Args);
6704
6705
6706
6707 bool isCurrentInstantiation() const {
6708 return isa<InjectedClassNameType>(getCanonicalTypeInternal());
6709 }
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726 bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; }
6727
6728
6729
6730 QualType getAliasedType() const;
6731
6732
6733 TemplateName getTemplateName() const { return Template; }
6734
6735 ArrayRef<TemplateArgument> template_arguments() const {
6736 return {reinterpret_cast<const TemplateArgument *>(this + 1),
6737 TemplateSpecializationTypeBits.NumArgs};
6738 }
6739
6740 bool isSugared() const {
6741 return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
6742 }
6743
6744 QualType desugar() const {
6745 return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal();
6746 }
6747
6748 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
6749 static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
6750 ArrayRef<TemplateArgument> Args,
6751 const ASTContext &Context);
6752
6753 static bool classof(const Type *T) {
6754 return T->getTypeClass() == TemplateSpecialization;
6755 }
6756 };
6757
6758
6759
6760 void printTemplateArgumentList(raw_ostream &OS,
6761 ArrayRef<TemplateArgument> Args,
6762 const PrintingPolicy &Policy,
6763 const TemplateParameterList *TPL = nullptr);
6764
6765 void printTemplateArgumentList(raw_ostream &OS,
6766 ArrayRef<TemplateArgumentLoc> Args,
6767 const PrintingPolicy &Policy,
6768 const TemplateParameterList *TPL = nullptr);
6769
6770 void printTemplateArgumentList(raw_ostream &OS,
6771 const TemplateArgumentListInfo &Args,
6772 const PrintingPolicy &Policy,
6773 const TemplateParameterList *TPL = nullptr);
6774
6775
6776
6777 bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
6778 const NamedDecl *Param,
6779 ArrayRef<TemplateArgument> Args,
6780 unsigned Depth);
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799 class InjectedClassNameType : public Type {
6800 friend class ASTContext;
6801 friend class ASTNodeImporter;
6802 friend class ASTReader;
6803
6804
6805 template <class T> friend class serialization::AbstractTypeReader;
6806
6807 CXXRecordDecl *Decl;
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818 QualType InjectedType;
6819
6820 InjectedClassNameType(CXXRecordDecl *D, QualType TST)
6821 : Type(InjectedClassName, QualType(),
6822 TypeDependence::DependentInstantiation),
6823 Decl(D), InjectedType(TST) {
6824 assert(isa<TemplateSpecializationType>(TST));
6825 assert(!TST.hasQualifiers());
6826 assert(TST->isDependentType());
6827 }
6828
6829 public:
6830 QualType getInjectedSpecializationType() const { return InjectedType; }
6831
6832 const TemplateSpecializationType *getInjectedTST() const {
6833 return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
6834 }
6835
6836 TemplateName getTemplateName() const {
6837 return getInjectedTST()->getTemplateName();
6838 }
6839
6840 CXXRecordDecl *getDecl() const;
6841
6842 bool isSugared() const { return false; }
6843 QualType desugar() const { return QualType(this, 0); }
6844
6845 static bool classof(const Type *T) {
6846 return T->getTypeClass() == InjectedClassName;
6847 }
6848 };
6849
6850
6851
6852 enum class ElaboratedTypeKeyword {
6853
6854 Struct,
6855
6856
6857 Interface,
6858
6859
6860 Union,
6861
6862
6863 Class,
6864
6865
6866 Enum,
6867
6868
6869
6870 Typename,
6871
6872
6873 None
6874 };
6875
6876
6877 enum class TagTypeKind {
6878
6879 Struct,
6880
6881
6882 Interface,
6883
6884
6885 Union,
6886
6887
6888 Class,
6889
6890
6891 Enum
6892 };
6893
6894
6895
6896
6897
6898 class TypeWithKeyword : public Type {
6899 protected:
6900 TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
6901 QualType Canonical, TypeDependence Dependence)
6902 : Type(tc, Canonical, Dependence) {
6903 TypeWithKeywordBits.Keyword = llvm::to_underlying(Keyword);
6904 }
6905
6906 public:
6907 ElaboratedTypeKeyword getKeyword() const {
6908 return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
6909 }
6910
6911
6912 static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
6913
6914
6915
6916 static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
6917
6918
6919 static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
6920
6921
6922
6923
6924 static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
6925
6926 static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
6927
6928 static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
6929
6930 static StringRef getTagTypeKindName(TagTypeKind Kind) {
6931 return getKeywordName(getKeywordForTagTypeKind(Kind));
6932 }
6933
6934 class CannotCastToThisType {};
6935 static CannotCastToThisType classof(const Type *);
6936 };
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946 class ElaboratedType final
6947 : public TypeWithKeyword,
6948 public llvm::FoldingSetNode,
6949 private llvm::TrailingObjects<ElaboratedType, TagDecl *> {
6950 friend class ASTContext;
6951 friend TrailingObjects;
6952
6953
6954 NestedNameSpecifier *NNS;
6955
6956
6957 QualType NamedType;
6958
6959
6960
6961
6962
6963 ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
6964 QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
6965 : TypeWithKeyword(Keyword, Elaborated, CanonType,
6966
6967
6968
6969
6970 NamedType->getDependence() |
6971 (NNS ? toSyntacticDependence(
6972 toTypeDependence(NNS->getDependence()))
6973 : TypeDependence::None)),
6974 NNS(NNS), NamedType(NamedType) {
6975 ElaboratedTypeBits.HasOwnedTagDecl = false;
6976 if (OwnedTagDecl) {
6977 ElaboratedTypeBits.HasOwnedTagDecl = true;
6978 *getTrailingObjects<TagDecl *>() = OwnedTagDecl;
6979 }
6980 }
6981
6982 public:
6983
6984 NestedNameSpecifier *getQualifier() const { return NNS; }
6985
6986
6987 QualType getNamedType() const { return NamedType; }
6988
6989
6990 QualType desugar() const { return getNamedType(); }
6991
6992
6993 bool isSugared() const { return true; }
6994
6995
6996
6997 TagDecl *getOwnedTagDecl() const {
6998 return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects<TagDecl *>()
6999 : nullptr;
7000 }
7001
7002 void Profile(llvm::FoldingSetNodeID &ID) {
7003 Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl());
7004 }
7005
7006 static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
7007 NestedNameSpecifier *NNS, QualType NamedType,
7008 TagDecl *OwnedTagDecl) {
7009 ID.AddInteger(llvm::to_underlying(Keyword));
7010 ID.AddPointer(NNS);
7011 NamedType.Profile(ID);
7012 ID.AddPointer(OwnedTagDecl);
7013 }
7014
7015 static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
7016 };
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030 class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
7031 friend class ASTContext;
7032
7033
7034 NestedNameSpecifier *NNS;
7035
7036
7037 const IdentifierInfo *Name;
7038
7039 DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
7040 const IdentifierInfo *Name, QualType CanonType)
7041 : TypeWithKeyword(Keyword, DependentName, CanonType,
7042 TypeDependence::DependentInstantiation |
7043 toTypeDependence(NNS->getDependence())),
7044 NNS(NNS), Name(Name) {
7045 assert(NNS);
7046 assert(Name);
7047 }
7048
7049 public:
7050
7051 NestedNameSpecifier *getQualifier() const { return NNS; }
7052
7053
7054
7055 const IdentifierInfo *getIdentifier() const {
7056 return Name;
7057 }
7058
7059 bool isSugared() const { return false; }
7060 QualType desugar() const { return QualType(this, 0); }
7061
7062 void Profile(llvm::FoldingSetNodeID &ID) {
7063 Profile(ID, getKeyword(), NNS, Name);
7064 }
7065
7066 static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
7067 NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
7068 ID.AddInteger(llvm::to_underlying(Keyword));
7069 ID.AddPointer(NNS);
7070 ID.AddPointer(Name);
7071 }
7072
7073 static bool classof(const Type *T) {
7074 return T->getTypeClass() == DependentName;
7075 }
7076 };
7077
7078
7079
7080
7081 class DependentTemplateSpecializationType : public TypeWithKeyword,
7082 public llvm::FoldingSetNode {
7083 friend class ASTContext;
7084
7085
7086 NestedNameSpecifier *NNS;
7087
7088
7089 const IdentifierInfo *Name;
7090
7091 DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
7092 NestedNameSpecifier *NNS,
7093 const IdentifierInfo *Name,
7094 ArrayRef<TemplateArgument> Args,
7095 QualType Canon);
7096
7097 public:
7098 NestedNameSpecifier *getQualifier() const { return NNS; }
7099 const IdentifierInfo *getIdentifier() const { return Name; }
7100
7101 ArrayRef<TemplateArgument> template_arguments() const {
7102 return {reinterpret_cast<const TemplateArgument *>(this + 1),
7103 DependentTemplateSpecializationTypeBits.NumArgs};
7104 }
7105
7106 bool isSugared() const { return false; }
7107 QualType desugar() const { return QualType(this, 0); }
7108
7109 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
7110 Profile(ID, Context, getKeyword(), NNS, Name, template_arguments());
7111 }
7112
7113 static void Profile(llvm::FoldingSetNodeID &ID,
7114 const ASTContext &Context,
7115 ElaboratedTypeKeyword Keyword,
7116 NestedNameSpecifier *Qualifier,
7117 const IdentifierInfo *Name,
7118 ArrayRef<TemplateArgument> Args);
7119
7120 static bool classof(const Type *T) {
7121 return T->getTypeClass() == DependentTemplateSpecialization;
7122 }
7123 };
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147 class PackExpansionType : public Type, public llvm::FoldingSetNode {
7148 friend class ASTContext;
7149
7150
7151 QualType Pattern;
7152
7153 PackExpansionType(QualType Pattern, QualType Canon,
7154 std::optional<unsigned> NumExpansions)
7155 : Type(PackExpansion, Canon,
7156 (Pattern->getDependence() | TypeDependence::Dependent |
7157 TypeDependence::Instantiation) &
7158 ~TypeDependence::UnexpandedPack),
7159 Pattern(Pattern) {
7160 PackExpansionTypeBits.NumExpansions =
7161 NumExpansions ? *NumExpansions + 1 : 0;
7162 }
7163
7164 public:
7165
7166
7167
7168 QualType getPattern() const { return Pattern; }
7169
7170
7171
7172 std::optional<unsigned> getNumExpansions() const {
7173 if (PackExpansionTypeBits.NumExpansions)
7174 return PackExpansionTypeBits.NumExpansions - 1;
7175 return std::nullopt;
7176 }
7177
7178 bool isSugared() const { return false; }
7179 QualType desugar() const { return QualType(this, 0); }
7180
7181 void Profile(llvm::FoldingSetNodeID &ID) {
7182 Profile(ID, getPattern(), getNumExpansions());
7183 }
7184
7185 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
7186 std::optional<unsigned> NumExpansions) {
7187 ID.AddPointer(Pattern.getAsOpaquePtr());
7188 ID.AddBoolean(NumExpansions.has_value());
7189 if (NumExpansions)
7190 ID.AddInteger(*NumExpansions);
7191 }
7192
7193 static bool classof(const Type *T) {
7194 return T->getTypeClass() == PackExpansion;
7195 }
7196 };
7197
7198
7199
7200 template <class T>
7201 class ObjCProtocolQualifiers {
7202 protected:
7203 ObjCProtocolQualifiers() = default;
7204
7205 ObjCProtocolDecl * const *getProtocolStorage() const {
7206 return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage();
7207 }
7208
7209 ObjCProtocolDecl **getProtocolStorage() {
7210 return static_cast<T*>(this)->getProtocolStorageImpl();
7211 }
7212
7213 void setNumProtocols(unsigned N) {
7214 static_cast<T*>(this)->setNumProtocolsImpl(N);
7215 }
7216
7217 void initialize(ArrayRef<ObjCProtocolDecl *> protocols) {
7218 setNumProtocols(protocols.size());
7219 assert(getNumProtocols() == protocols.size() &&
7220 "bitfield overflow in protocol count");
7221 if (!protocols.empty())
7222 memcpy(getProtocolStorage(), protocols.data(),
7223 protocols.size() * sizeof(ObjCProtocolDecl*));
7224 }
7225
7226 public:
7227 using qual_iterator = ObjCProtocolDecl * const *;
7228 using qual_range = llvm::iterator_range<qual_iterator>;
7229
7230 qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
7231 qual_iterator qual_begin() const { return getProtocolStorage(); }
7232 qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
7233
7234 bool qual_empty() const { return getNumProtocols() == 0; }
7235
7236
7237
7238 unsigned getNumProtocols() const {
7239 return static_cast<const T*>(this)->getNumProtocolsImpl();
7240 }
7241
7242
7243 ObjCProtocolDecl *getProtocol(unsigned I) const {
7244 assert(I < getNumProtocols() && "Out-of-range protocol access");
7245 return qual_begin()[I];
7246 }
7247
7248
7249 ArrayRef<ObjCProtocolDecl *> getProtocols() const {
7250 return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
7251 }
7252 };
7253
7254
7255
7256 class ObjCTypeParamType : public Type,
7257 public ObjCProtocolQualifiers<ObjCTypeParamType>,
7258 public llvm::FoldingSetNode {
7259 friend class ASTContext;
7260 friend class ObjCProtocolQualifiers<ObjCTypeParamType>;
7261
7262
7263 unsigned NumProtocols : 6;
7264
7265 ObjCTypeParamDecl *OTPDecl;
7266
7267
7268
7269
7270 ObjCProtocolDecl **getProtocolStorageImpl();
7271
7272
7273
7274 unsigned getNumProtocolsImpl() const {
7275 return NumProtocols;
7276 }
7277
7278 void setNumProtocolsImpl(unsigned N) {
7279 NumProtocols = N;
7280 }
7281
7282 ObjCTypeParamType(const ObjCTypeParamDecl *D,
7283 QualType can,
7284 ArrayRef<ObjCProtocolDecl *> protocols);
7285
7286 public:
7287 bool isSugared() const { return true; }
7288 QualType desugar() const { return getCanonicalTypeInternal(); }
7289
7290 static bool classof(const Type *T) {
7291 return T->getTypeClass() == ObjCTypeParam;
7292 }
7293
7294 void Profile(llvm::FoldingSetNodeID &ID);
7295 static void Profile(llvm::FoldingSetNodeID &ID,
7296 const ObjCTypeParamDecl *OTPDecl,
7297 QualType CanonicalType,
7298 ArrayRef<ObjCProtocolDecl *> protocols);
7299
7300 ObjCTypeParamDecl *getDecl() const { return OTPDecl; }
7301 };
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331 class ObjCObjectType : public Type,
7332 public ObjCProtocolQualifiers<ObjCObjectType> {
7333 friend class ObjCProtocolQualifiers<ObjCObjectType>;
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348 QualType BaseType;
7349
7350
7351 mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
7352 CachedSuperClassType;
7353
7354 QualType *getTypeArgStorage();
7355 const QualType *getTypeArgStorage() const {
7356 return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
7357 }
7358
7359 ObjCProtocolDecl **getProtocolStorageImpl();
7360
7361
7362 unsigned getNumProtocolsImpl() const {
7363 return ObjCObjectTypeBits.NumProtocols;
7364 }
7365 void setNumProtocolsImpl(unsigned N) {
7366 ObjCObjectTypeBits.NumProtocols = N;
7367 }
7368
7369 protected:
7370 enum Nonce_ObjCInterface { Nonce_ObjCInterface };
7371
7372 ObjCObjectType(QualType Canonical, QualType Base,
7373 ArrayRef<QualType> typeArgs,
7374 ArrayRef<ObjCProtocolDecl *> protocols,
7375 bool isKindOf);
7376
7377 ObjCObjectType(enum Nonce_ObjCInterface)
7378 : Type(ObjCInterface, QualType(), TypeDependence::None),
7379 BaseType(QualType(this_(), 0)) {
7380 ObjCObjectTypeBits.NumProtocols = 0;
7381 ObjCObjectTypeBits.NumTypeArgs = 0;
7382 ObjCObjectTypeBits.IsKindOf = 0;
7383 }
7384
7385 void computeSuperClassTypeSlow() const;
7386
7387 public:
7388
7389
7390
7391
7392
7393
7394 QualType getBaseType() const { return BaseType; }
7395
7396 bool isObjCId() const {
7397 return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
7398 }
7399
7400 bool isObjCClass() const {
7401 return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
7402 }
7403
7404 bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
7405 bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
7406 bool isObjCUnqualifiedIdOrClass() const {
7407 if (!qual_empty()) return false;
7408 if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
7409 return T->getKind() == BuiltinType::ObjCId ||
7410 T->getKind() == BuiltinType::ObjCClass;
7411 return false;
7412 }
7413 bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
7414 bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
7415
7416
7417
7418 ObjCInterfaceDecl *getInterface() const;
7419
7420
7421
7422 bool isSpecialized() const;
7423
7424
7425 bool isSpecializedAsWritten() const {
7426 return ObjCObjectTypeBits.NumTypeArgs > 0;
7427 }
7428
7429
7430
7431 bool isUnspecialized() const { return !isSpecialized(); }
7432
7433
7434
7435 bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
7436
7437
7438 ArrayRef<QualType> getTypeArgs() const;
7439
7440
7441
7442 ArrayRef<QualType> getTypeArgsAsWritten() const {
7443 return llvm::ArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs);
7444 }
7445
7446
7447 bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
7448
7449
7450 bool isKindOfType() const;
7451
7452
7453
7454
7455
7456
7457
7458 QualType getSuperClassType() const {
7459 if (!CachedSuperClassType.getInt())
7460 computeSuperClassTypeSlow();
7461
7462 assert(CachedSuperClassType.getInt() && "Superclass not set?");
7463 return QualType(CachedSuperClassType.getPointer(), 0);
7464 }
7465
7466
7467
7468 QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const;
7469
7470 bool isSugared() const { return false; }
7471 QualType desugar() const { return QualType(this, 0); }
7472
7473 static bool classof(const Type *T) {
7474 return T->getTypeClass() == ObjCObject ||
7475 T->getTypeClass() == ObjCInterface;
7476 }
7477 };
7478
7479
7480
7481
7482
7483 class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
7484 friend class ASTContext;
7485
7486
7487
7488
7489 ObjCObjectTypeImpl(QualType Canonical, QualType Base,
7490 ArrayRef<QualType> typeArgs,
7491 ArrayRef<ObjCProtocolDecl *> protocols,
7492 bool isKindOf)
7493 : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
7494
7495 public:
7496 void Profile(llvm::FoldingSetNodeID &ID);
7497 static void Profile(llvm::FoldingSetNodeID &ID,
7498 QualType Base,
7499 ArrayRef<QualType> typeArgs,
7500 ArrayRef<ObjCProtocolDecl *> protocols,
7501 bool isKindOf);
7502 };
7503
7504 inline QualType *ObjCObjectType::getTypeArgStorage() {
7505 return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
7506 }
7507
7508 inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() {
7509 return reinterpret_cast<ObjCProtocolDecl**>(
7510 getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
7511 }
7512
7513 inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
7514 return reinterpret_cast<ObjCProtocolDecl**>(
7515 static_cast<ObjCTypeParamType*>(this)+1);
7516 }
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530 class ObjCInterfaceType : public ObjCObjectType {
7531 friend class ASTContext;
7532 friend class ASTReader;
7533 template <class T> friend class serialization::AbstractTypeReader;
7534
7535 ObjCInterfaceDecl *Decl;
7536
7537 ObjCInterfaceType(const ObjCInterfaceDecl *D)
7538 : ObjCObjectType(Nonce_ObjCInterface),
7539 Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
7540
7541 public:
7542
7543 ObjCInterfaceDecl *getDecl() const;
7544
7545 bool isSugared() const { return false; }
7546 QualType desugar() const { return QualType(this, 0); }
7547
7548 static bool classof(const Type *T) {
7549 return T->getTypeClass() == ObjCInterface;
7550 }
7551
7552
7553
7554
7555
7556 enum {
7557 qual_iterator,
7558 qual_begin,
7559 qual_end,
7560 getNumProtocols,
7561 getProtocol
7562 };
7563 };
7564
7565 inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
7566 QualType baseType = getBaseType();
7567 while (const auto *ObjT = baseType->getAs<ObjCObjectType>()) {
7568 if (const auto *T = dyn_cast<ObjCInterfaceType>(ObjT))
7569 return T->getDecl();
7570
7571 baseType = ObjT->getBaseType();
7572 }
7573
7574 return nullptr;
7575 }
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586 class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
7587 friend class ASTContext;
7588
7589 QualType PointeeType;
7590
7591 ObjCObjectPointerType(QualType Canonical, QualType Pointee)
7592 : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()),
7593 PointeeType(Pointee) {}
7594
7595 public:
7596
7597
7598 QualType getPointeeType() const { return PointeeType; }
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623 const ObjCObjectType *getObjectType() const {
7624 return PointeeType->castAs<ObjCObjectType>();
7625 }
7626
7627
7628
7629
7630
7631
7632 const ObjCInterfaceType *getInterfaceType() const;
7633
7634
7635
7636
7637
7638 ObjCInterfaceDecl *getInterfaceDecl() const {
7639 return getObjectType()->getInterface();
7640 }
7641
7642
7643
7644 bool isObjCIdType() const {
7645 return getObjectType()->isObjCUnqualifiedId();
7646 }
7647
7648
7649
7650 bool isObjCClassType() const {
7651 return getObjectType()->isObjCUnqualifiedClass();
7652 }
7653
7654
7655 bool isObjCIdOrClassType() const {
7656 return getObjectType()->isObjCUnqualifiedIdOrClass();
7657 }
7658
7659
7660
7661 bool isObjCQualifiedIdType() const {
7662 return getObjectType()->isObjCQualifiedId();
7663 }
7664
7665
7666
7667 bool isObjCQualifiedClassType() const {
7668 return getObjectType()->isObjCQualifiedClass();
7669 }
7670
7671
7672 bool isKindOfType() const { return getObjectType()->isKindOfType(); }
7673
7674
7675 bool isSpecialized() const { return getObjectType()->isSpecialized(); }
7676
7677
7678 bool isSpecializedAsWritten() const {
7679 return getObjectType()->isSpecializedAsWritten();
7680 }
7681
7682
7683 bool isUnspecialized() const { return getObjectType()->isUnspecialized(); }
7684
7685
7686
7687 bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
7688
7689
7690 ArrayRef<QualType> getTypeArgs() const {
7691 return getObjectType()->getTypeArgs();
7692 }
7693
7694
7695 ArrayRef<QualType> getTypeArgsAsWritten() const {
7696 return getObjectType()->getTypeArgsAsWritten();
7697 }
7698
7699
7700
7701
7702 using qual_iterator = ObjCObjectType::qual_iterator;
7703 using qual_range = llvm::iterator_range<qual_iterator>;
7704
7705 qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
7706
7707 qual_iterator qual_begin() const {
7708 return getObjectType()->qual_begin();
7709 }
7710
7711 qual_iterator qual_end() const {
7712 return getObjectType()->qual_end();
7713 }
7714
7715 bool qual_empty() const { return getObjectType()->qual_empty(); }
7716
7717
7718 unsigned getNumProtocols() const {
7719 return getObjectType()->getNumProtocols();
7720 }
7721
7722
7723 ObjCProtocolDecl *getProtocol(unsigned I) const {
7724 return getObjectType()->getProtocol(I);
7725 }
7726
7727 bool isSugared() const { return false; }
7728 QualType desugar() const { return QualType(this, 0); }
7729
7730
7731
7732
7733
7734
7735
7736 QualType getSuperClassType() const;
7737
7738
7739
7740 const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals(
7741 const ASTContext &ctx) const;
7742
7743 void Profile(llvm::FoldingSetNodeID &ID) {
7744 Profile(ID, getPointeeType());
7745 }
7746
7747 static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
7748 ID.AddPointer(T.getAsOpaquePtr());
7749 }
7750
7751 static bool classof(const Type *T) {
7752 return T->getTypeClass() == ObjCObjectPointer;
7753 }
7754 };
7755
7756 class AtomicType : public Type, public llvm::FoldingSetNode {
7757 friend class ASTContext;
7758
7759 QualType ValueType;
7760
7761 AtomicType(QualType ValTy, QualType Canonical)
7762 : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {}
7763
7764 public:
7765
7766
7767 QualType getValueType() const { return ValueType; }
7768
7769 bool isSugared() const { return false; }
7770 QualType desugar() const { return QualType(this, 0); }
7771
7772 void Profile(llvm::FoldingSetNodeID &ID) {
7773 Profile(ID, getValueType());
7774 }
7775
7776 static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
7777 ID.AddPointer(T.getAsOpaquePtr());
7778 }
7779
7780 static bool classof(const Type *T) {
7781 return T->getTypeClass() == Atomic;
7782 }
7783 };
7784
7785
7786 class PipeType : public Type, public llvm::FoldingSetNode {
7787 friend class ASTContext;
7788
7789 QualType ElementType;
7790 bool isRead;
7791
7792 PipeType(QualType elemType, QualType CanonicalPtr, bool isRead)
7793 : Type(Pipe, CanonicalPtr, elemType->getDependence()),
7794 ElementType(elemType), isRead(isRead) {}
7795
7796 public:
7797 QualType getElementType() const { return ElementType; }
7798
7799 bool isSugared() const { return false; }
7800
7801 QualType desugar() const { return QualType(this, 0); }
7802
7803 void Profile(llvm::FoldingSetNodeID &ID) {
7804 Profile(ID, getElementType(), isReadOnly());
7805 }
7806
7807 static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) {
7808 ID.AddPointer(T.getAsOpaquePtr());
7809 ID.AddBoolean(isRead);
7810 }
7811
7812 static bool classof(const Type *T) {
7813 return T->getTypeClass() == Pipe;
7814 }
7815
7816 bool isReadOnly() const { return isRead; }
7817 };
7818
7819
7820 class BitIntType final : public Type, public llvm::FoldingSetNode {
7821 friend class ASTContext;
7822 LLVM_PREFERRED_TYPE(bool)
7823 unsigned IsUnsigned : 1;
7824 unsigned NumBits : 24;
7825
7826 protected:
7827 BitIntType(bool isUnsigned, unsigned NumBits);
7828
7829 public:
7830 bool isUnsigned() const { return IsUnsigned; }
7831 bool isSigned() const { return !IsUnsigned; }
7832 unsigned getNumBits() const { return NumBits; }
7833
7834 bool isSugared() const { return false; }
7835 QualType desugar() const { return QualType(this, 0); }
7836
7837 void Profile(llvm::FoldingSetNodeID &ID) const {
7838 Profile(ID, isUnsigned(), getNumBits());
7839 }
7840
7841 static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned,
7842 unsigned NumBits) {
7843 ID.AddBoolean(IsUnsigned);
7844 ID.AddInteger(NumBits);
7845 }
7846
7847 static bool classof(const Type *T) { return T->getTypeClass() == BitInt; }
7848 };
7849
7850 class DependentBitIntType final : public Type, public llvm::FoldingSetNode {
7851 friend class ASTContext;
7852 llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
7853
7854 protected:
7855 DependentBitIntType(bool IsUnsigned, Expr *NumBits);
7856
7857 public:
7858 bool isUnsigned() const;
7859 bool isSigned() const { return !isUnsigned(); }
7860 Expr *getNumBitsExpr() const;
7861
7862 bool isSugared() const { return false; }
7863 QualType desugar() const { return QualType(this, 0); }
7864
7865 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
7866 Profile(ID, Context, isUnsigned(), getNumBitsExpr());
7867 }
7868 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
7869 bool IsUnsigned, Expr *NumBitsExpr);
7870
7871 static bool classof(const Type *T) {
7872 return T->getTypeClass() == DependentBitInt;
7873 }
7874 };
7875
7876
7877 class QualifierCollector : public Qualifiers {
7878 public:
7879 QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {}
7880
7881
7882
7883
7884 const Type *strip(QualType type) {
7885 addFastQualifiers(type.getLocalFastQualifiers());
7886 if (!type.hasLocalNonFastQualifiers())
7887 return type.getTypePtrUnsafe();
7888
7889 const ExtQuals *extQuals = type.getExtQualsUnsafe();
7890 addConsistentQualifiers(extQuals->getQualifiers());
7891 return extQuals->getBaseType();
7892 }
7893
7894
7895 QualType apply(const ASTContext &Context, QualType QT) const;
7896
7897
7898 QualType apply(const ASTContext &Context, const Type* T) const;
7899 };
7900
7901
7902
7903
7904
7905
7906
7907
7908 class alignas(8) TypeSourceInfo {
7909
7910
7911 friend class ASTContext;
7912
7913 QualType Ty;
7914
7915 TypeSourceInfo(QualType ty, size_t DataSize);
7916
7917 public:
7918
7919 QualType getType() const { return Ty; }
7920
7921
7922 TypeLoc getTypeLoc() const;
7923
7924
7925 void overrideType(QualType T) { Ty = T; }
7926 };
7927
7928
7929
7930 inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
7931 SplitQualType desugar =
7932 Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
7933 desugar.Quals.addConsistentQualifiers(Quals);
7934 return desugar;
7935 }
7936
7937 inline const Type *QualType::getTypePtr() const {
7938 return getCommonPtr()->BaseType;
7939 }
7940
7941 inline const Type *QualType::getTypePtrOrNull() const {
7942 return (isNull() ? nullptr : getCommonPtr()->BaseType);
7943 }
7944
7945 inline bool QualType::isReferenceable() const {
7946
7947
7948
7949 const Type &Self = **this;
7950 if (Self.isObjectType() || Self.isReferenceType())
7951 return true;
7952 if (const auto *F = Self.getAs<FunctionProtoType>())
7953 return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None;
7954
7955 return false;
7956 }
7957
7958 inline SplitQualType QualType::split() const {
7959 if (!hasLocalNonFastQualifiers())
7960 return SplitQualType(getTypePtrUnsafe(),
7961 Qualifiers::fromFastMask(getLocalFastQualifiers()));
7962
7963 const ExtQuals *eq = getExtQualsUnsafe();
7964 Qualifiers qs = eq->getQualifiers();
7965 qs.addFastQualifiers(getLocalFastQualifiers());
7966 return SplitQualType(eq->getBaseType(), qs);
7967 }
7968
7969 inline Qualifiers QualType::getLocalQualifiers() const {
7970 Qualifiers Quals;
7971 if (hasLocalNonFastQualifiers())
7972 Quals = getExtQualsUnsafe()->getQualifiers();
7973 Quals.addFastQualifiers(getLocalFastQualifiers());
7974 return Quals;
7975 }
7976
7977 inline Qualifiers QualType::getQualifiers() const {
7978 Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers();
7979 quals.addFastQualifiers(getLocalFastQualifiers());
7980 return quals;
7981 }
7982
7983 inline unsigned QualType::getCVRQualifiers() const {
7984 unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers();
7985 cvr |= getLocalCVRQualifiers();
7986 return cvr;
7987 }
7988
7989 inline QualType QualType::getCanonicalType() const {
7990 QualType canon = getCommonPtr()->CanonicalType;
7991 return canon.withFastQualifiers(getLocalFastQualifiers());
7992 }
7993
7994 inline bool QualType::isCanonical() const {
7995 return getTypePtr()->isCanonicalUnqualified();
7996 }
7997
7998 inline bool QualType::isCanonicalAsParam() const {
7999 if (!isCanonical()) return false;
8000 if (hasLocalQualifiers()) return false;
8001
8002 const Type *T = getTypePtr();
8003 if (T->isVariablyModifiedType() && T->hasSizedVLAType())
8004 return false;
8005
8006 return !isa<FunctionType>(T) &&
8007 (!isa<ArrayType>(T) || isa<ArrayParameterType>(T));
8008 }
8009
8010 inline bool QualType::isConstQualified() const {
8011 return isLocalConstQualified() ||
8012 getCommonPtr()->CanonicalType.isLocalConstQualified();
8013 }
8014
8015 inline bool QualType::isRestrictQualified() const {
8016 return isLocalRestrictQualified() ||
8017 getCommonPtr()->CanonicalType.isLocalRestrictQualified();
8018 }
8019
8020
8021 inline bool QualType::isVolatileQualified() const {
8022 return isLocalVolatileQualified() ||
8023 getCommonPtr()->CanonicalType.isLocalVolatileQualified();
8024 }
8025
8026 inline bool QualType::hasQualifiers() const {
8027 return hasLocalQualifiers() ||
8028 getCommonPtr()->CanonicalType.hasLocalQualifiers();
8029 }
8030
8031 inline QualType QualType::getUnqualifiedType() const {
8032 if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
8033 return QualType(getTypePtr(), 0);
8034
8035 return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
8036 }
8037
8038 inline SplitQualType QualType::getSplitUnqualifiedType() const {
8039 if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
8040 return split();
8041
8042 return getSplitUnqualifiedTypeImpl(*this);
8043 }
8044
8045 inline void QualType::removeLocalConst() {
8046 removeLocalFastQualifiers(Qualifiers::Const);
8047 }
8048
8049 inline void QualType::removeLocalRestrict() {
8050 removeLocalFastQualifiers(Qualifiers::Restrict);
8051 }
8052
8053 inline void QualType::removeLocalVolatile() {
8054 removeLocalFastQualifiers(Qualifiers::Volatile);
8055 }
8056
8057
8058 inline bool QualType::hasAddressSpace() const {
8059 return getQualifiers().hasAddressSpace();
8060 }
8061
8062
8063 inline LangAS QualType::getAddressSpace() const {
8064 return getQualifiers().getAddressSpace();
8065 }
8066
8067
8068 inline Qualifiers::GC QualType::getObjCGCAttr() const {
8069 return getQualifiers().getObjCGCAttr();
8070 }
8071
8072 inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const {
8073 if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl())
8074 return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD);
8075 return false;
8076 }
8077
8078 inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const {
8079 if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl())
8080 return hasNonTrivialToPrimitiveDestructCUnion(RD);
8081 return false;
8082 }
8083
8084 inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const {
8085 if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl())
8086 return hasNonTrivialToPrimitiveCopyCUnion(RD);
8087 return false;
8088 }
8089
8090 inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
8091 if (const auto *PT = t.getAs<PointerType>()) {
8092 if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>())
8093 return FT->getExtInfo();
8094 } else if (const auto *FT = t.getAs<FunctionType>())
8095 return FT->getExtInfo();
8096
8097 return FunctionType::ExtInfo();
8098 }
8099
8100 inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
8101 return getFunctionExtInfo(*t);
8102 }
8103
8104
8105
8106
8107
8108
8109 inline bool QualType::isMoreQualifiedThan(QualType other,
8110 const ASTContext &Ctx) const {
8111 Qualifiers MyQuals = getQualifiers();
8112 Qualifiers OtherQuals = other.getQualifiers();
8113 return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals, Ctx));
8114 }
8115
8116
8117
8118
8119
8120 inline bool QualType::isAtLeastAsQualifiedAs(QualType other,
8121 const ASTContext &Ctx) const {
8122 Qualifiers OtherQuals = other.getQualifiers();
8123
8124
8125 if (getUnqualifiedType()->isVoidType())
8126 OtherQuals.removeUnaligned();
8127
8128 return getQualifiers().compatiblyIncludes(OtherQuals, Ctx);
8129 }
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140 inline QualType QualType::getNonReferenceType() const {
8141 if (const auto *RefType = (*this)->getAs<ReferenceType>())
8142 return RefType->getPointeeType();
8143 else
8144 return *this;
8145 }
8146
8147 inline bool QualType::isCForbiddenLValueType() const {
8148 return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
8149 getTypePtr()->isFunctionType());
8150 }
8151
8152
8153
8154
8155 inline bool Type::isFundamentalType() const {
8156 return isVoidType() ||
8157 isNullPtrType() ||
8158
8159
8160 (isArithmeticType() && !isEnumeralType());
8161 }
8162
8163
8164
8165
8166 inline bool Type::isCompoundType() const {
8167
8168
8169
8170 return isArrayType() ||
8171
8172 isFunctionType() ||
8173
8174 isPointerType() ||
8175
8176 isReferenceType() ||
8177
8178 isRecordType() ||
8179
8180
8181 isUnionType() ||
8182
8183 isEnumeralType() ||
8184
8185 isMemberPointerType();
8186 }
8187
8188 inline bool Type::isFunctionType() const {
8189 return isa<FunctionType>(CanonicalType);
8190 }
8191
8192 inline bool Type::isPointerType() const {
8193 return isa<PointerType>(CanonicalType);
8194 }
8195
8196 inline bool Type::isPointerOrReferenceType() const {
8197 return isPointerType() || isReferenceType();
8198 }
8199
8200 inline bool Type::isAnyPointerType() const {
8201 return isPointerType() || isObjCObjectPointerType();
8202 }
8203
8204 inline bool Type::isSignableType() const { return isPointerType(); }
8205
8206 inline bool Type::isBlockPointerType() const {
8207 return isa<BlockPointerType>(CanonicalType);
8208 }
8209
8210 inline bool Type::isReferenceType() const {
8211 return isa<ReferenceType>(CanonicalType);
8212 }
8213
8214 inline bool Type::isLValueReferenceType() const {
8215 return isa<LValueReferenceType>(CanonicalType);
8216 }
8217
8218 inline bool Type::isRValueReferenceType() const {
8219 return isa<RValueReferenceType>(CanonicalType);
8220 }
8221
8222 inline bool Type::isObjectPointerType() const {
8223
8224
8225
8226 if (const auto *T = getAs<PointerType>())
8227 return !T->getPointeeType()->isFunctionType();
8228 else
8229 return false;
8230 }
8231
8232 inline bool Type::isFunctionPointerType() const {
8233 if (const auto *T = getAs<PointerType>())
8234 return T->getPointeeType()->isFunctionType();
8235 else
8236 return false;
8237 }
8238
8239 inline bool Type::isFunctionReferenceType() const {
8240 if (const auto *T = getAs<ReferenceType>())
8241 return T->getPointeeType()->isFunctionType();
8242 else
8243 return false;
8244 }
8245
8246 inline bool Type::isMemberPointerType() const {
8247 return isa<MemberPointerType>(CanonicalType);
8248 }
8249
8250 inline bool Type::isMemberFunctionPointerType() const {
8251 if (const auto *T = getAs<MemberPointerType>())
8252 return T->isMemberFunctionPointer();
8253 else
8254 return false;
8255 }
8256
8257 inline bool Type::isMemberDataPointerType() const {
8258 if (const auto *T = getAs<MemberPointerType>())
8259 return T->isMemberDataPointer();
8260 else
8261 return false;
8262 }
8263
8264 inline bool Type::isArrayType() const {
8265 return isa<ArrayType>(CanonicalType);
8266 }
8267
8268 inline bool Type::isConstantArrayType() const {
8269 return isa<ConstantArrayType>(CanonicalType);
8270 }
8271
8272 inline bool Type::isIncompleteArrayType() const {
8273 return isa<IncompleteArrayType>(CanonicalType);
8274 }
8275
8276 inline bool Type::isVariableArrayType() const {
8277 return isa<VariableArrayType>(CanonicalType);
8278 }
8279
8280 inline bool Type::isArrayParameterType() const {
8281 return isa<ArrayParameterType>(CanonicalType);
8282 }
8283
8284 inline bool Type::isDependentSizedArrayType() const {
8285 return isa<DependentSizedArrayType>(CanonicalType);
8286 }
8287
8288 inline bool Type::isBuiltinType() const {
8289 return isa<BuiltinType>(CanonicalType);
8290 }
8291
8292 inline bool Type::isRecordType() const {
8293 return isa<RecordType>(CanonicalType);
8294 }
8295
8296 inline bool Type::isEnumeralType() const {
8297 return isa<EnumType>(CanonicalType);
8298 }
8299
8300 inline bool Type::isAnyComplexType() const {
8301 return isa<ComplexType>(CanonicalType);
8302 }
8303
8304 inline bool Type::isVectorType() const {
8305 return isa<VectorType>(CanonicalType);
8306 }
8307
8308 inline bool Type::isExtVectorType() const {
8309 return isa<ExtVectorType>(CanonicalType);
8310 }
8311
8312 inline bool Type::isExtVectorBoolType() const {
8313 if (!isExtVectorType())
8314 return false;
8315 return cast<ExtVectorType>(CanonicalType)->getElementType()->isBooleanType();
8316 }
8317
8318 inline bool Type::isSubscriptableVectorType() const {
8319 return isVectorType() || isSveVLSBuiltinType();
8320 }
8321
8322 inline bool Type::isMatrixType() const {
8323 return isa<MatrixType>(CanonicalType);
8324 }
8325
8326 inline bool Type::isConstantMatrixType() const {
8327 return isa<ConstantMatrixType>(CanonicalType);
8328 }
8329
8330 inline bool Type::isDependentAddressSpaceType() const {
8331 return isa<DependentAddressSpaceType>(CanonicalType);
8332 }
8333
8334 inline bool Type::isObjCObjectPointerType() const {
8335 return isa<ObjCObjectPointerType>(CanonicalType);
8336 }
8337
8338 inline bool Type::isObjCObjectType() const {
8339 return isa<ObjCObjectType>(CanonicalType);
8340 }
8341
8342 inline bool Type::isObjCObjectOrInterfaceType() const {
8343 return isa<ObjCInterfaceType>(CanonicalType) ||
8344 isa<ObjCObjectType>(CanonicalType);
8345 }
8346
8347 inline bool Type::isAtomicType() const {
8348 return isa<AtomicType>(CanonicalType);
8349 }
8350
8351 inline bool Type::isUndeducedAutoType() const {
8352 return isa<AutoType>(CanonicalType);
8353 }
8354
8355 inline bool Type::isObjCQualifiedIdType() const {
8356 if (const auto *OPT = getAs<ObjCObjectPointerType>())
8357 return OPT->isObjCQualifiedIdType();
8358 return false;
8359 }
8360
8361 inline bool Type::isObjCQualifiedClassType() const {
8362 if (const auto *OPT = getAs<ObjCObjectPointerType>())
8363 return OPT->isObjCQualifiedClassType();
8364 return false;
8365 }
8366
8367 inline bool Type::isObjCIdType() const {
8368 if (const auto *OPT = getAs<ObjCObjectPointerType>())
8369 return OPT->isObjCIdType();
8370 return false;
8371 }
8372
8373 inline bool Type::isObjCClassType() const {
8374 if (const auto *OPT = getAs<ObjCObjectPointerType>())
8375 return OPT->isObjCClassType();
8376 return false;
8377 }
8378
8379 inline bool Type::isObjCSelType() const {
8380 if (const auto *OPT = getAs<PointerType>())
8381 return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
8382 return false;
8383 }
8384
8385 inline bool Type::isObjCBuiltinType() const {
8386 return isObjCIdType() || isObjCClassType() || isObjCSelType();
8387 }
8388
8389 inline bool Type::isDecltypeType() const {
8390 return isa<DecltypeType>(this);
8391 }
8392
8393 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
8394 inline bool Type::is##Id##Type() const { \
8395 return isSpecificBuiltinType(BuiltinType::Id); \
8396 }
8397 #include "clang/Basic/OpenCLImageTypes.def"
8398
8399 inline bool Type::isSamplerT() const {
8400 return isSpecificBuiltinType(BuiltinType::OCLSampler);
8401 }
8402
8403 inline bool Type::isEventT() const {
8404 return isSpecificBuiltinType(BuiltinType::OCLEvent);
8405 }
8406
8407 inline bool Type::isClkEventT() const {
8408 return isSpecificBuiltinType(BuiltinType::OCLClkEvent);
8409 }
8410
8411 inline bool Type::isQueueT() const {
8412 return isSpecificBuiltinType(BuiltinType::OCLQueue);
8413 }
8414
8415 inline bool Type::isReserveIDT() const {
8416 return isSpecificBuiltinType(BuiltinType::OCLReserveID);
8417 }
8418
8419 inline bool Type::isImageType() const {
8420 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() ||
8421 return
8422 #include "clang/Basic/OpenCLImageTypes.def"
8423 false;
8424 }
8425
8426 inline bool Type::isPipeType() const {
8427 return isa<PipeType>(CanonicalType);
8428 }
8429
8430 inline bool Type::isBitIntType() const {
8431 return isa<BitIntType>(CanonicalType);
8432 }
8433
8434 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
8435 inline bool Type::is##Id##Type() const { \
8436 return isSpecificBuiltinType(BuiltinType::Id); \
8437 }
8438 #include "clang/Basic/OpenCLExtensionTypes.def"
8439
8440 inline bool Type::isOCLIntelSubgroupAVCType() const {
8441 #define INTEL_SUBGROUP_AVC_TYPE(ExtType, Id) \
8442 isOCLIntelSubgroupAVC##Id##Type() ||
8443 return
8444 #include "clang/Basic/OpenCLExtensionTypes.def"
8445 false;
8446 }
8447
8448 inline bool Type::isOCLExtOpaqueType() const {
8449 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) is##Id##Type() ||
8450 return
8451 #include "clang/Basic/OpenCLExtensionTypes.def"
8452 false;
8453 }
8454
8455 inline bool Type::isOpenCLSpecificType() const {
8456 return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
8457 isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType();
8458 }
8459
8460 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
8461 inline bool Type::is##Id##Type() const { \
8462 return isSpecificBuiltinType(BuiltinType::Id); \
8463 }
8464 #include "clang/Basic/HLSLIntangibleTypes.def"
8465
8466 inline bool Type::isHLSLBuiltinIntangibleType() const {
8467 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) is##Id##Type() ||
8468 return
8469 #include "clang/Basic/HLSLIntangibleTypes.def"
8470 false;
8471 }
8472
8473 inline bool Type::isHLSLSpecificType() const {
8474 return isHLSLBuiltinIntangibleType() || isHLSLAttributedResourceType();
8475 }
8476
8477 inline bool Type::isHLSLAttributedResourceType() const {
8478 return isa<HLSLAttributedResourceType>(this);
8479 }
8480
8481 inline bool Type::isTemplateTypeParmType() const {
8482 return isa<TemplateTypeParmType>(CanonicalType);
8483 }
8484
8485 inline bool Type::isSpecificBuiltinType(unsigned K) const {
8486 if (const BuiltinType *BT = getAs<BuiltinType>()) {
8487 return BT->getKind() == static_cast<BuiltinType::Kind>(K);
8488 }
8489 return false;
8490 }
8491
8492 inline bool Type::isPlaceholderType() const {
8493 if (const auto *BT = dyn_cast<BuiltinType>(this))
8494 return BT->isPlaceholderType();
8495 return false;
8496 }
8497
8498 inline const BuiltinType *Type::getAsPlaceholderType() const {
8499 if (const auto *BT = dyn_cast<BuiltinType>(this))
8500 if (BT->isPlaceholderType())
8501 return BT;
8502 return nullptr;
8503 }
8504
8505 inline bool Type::isSpecificPlaceholderType(unsigned K) const {
8506 assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
8507 return isSpecificBuiltinType(K);
8508 }
8509
8510 inline bool Type::isNonOverloadPlaceholderType() const {
8511 if (const auto *BT = dyn_cast<BuiltinType>(this))
8512 return BT->isNonOverloadPlaceholderType();
8513 return false;
8514 }
8515
8516 inline bool Type::isVoidType() const {
8517 return isSpecificBuiltinType(BuiltinType::Void);
8518 }
8519
8520 inline bool Type::isHalfType() const {
8521
8522 return isSpecificBuiltinType(BuiltinType::Half);
8523 }
8524
8525 inline bool Type::isFloat16Type() const {
8526 return isSpecificBuiltinType(BuiltinType::Float16);
8527 }
8528
8529 inline bool Type::isFloat32Type() const {
8530 return isSpecificBuiltinType(BuiltinType::Float);
8531 }
8532
8533 inline bool Type::isDoubleType() const {
8534 return isSpecificBuiltinType(BuiltinType::Double);
8535 }
8536
8537 inline bool Type::isBFloat16Type() const {
8538 return isSpecificBuiltinType(BuiltinType::BFloat16);
8539 }
8540
8541 inline bool Type::isMFloat8Type() const {
8542 return isSpecificBuiltinType(BuiltinType::MFloat8);
8543 }
8544
8545 inline bool Type::isFloat128Type() const {
8546 return isSpecificBuiltinType(BuiltinType::Float128);
8547 }
8548
8549 inline bool Type::isIbm128Type() const {
8550 return isSpecificBuiltinType(BuiltinType::Ibm128);
8551 }
8552
8553 inline bool Type::isNullPtrType() const {
8554 return isSpecificBuiltinType(BuiltinType::NullPtr);
8555 }
8556
8557 bool IsEnumDeclComplete(EnumDecl *);
8558 bool IsEnumDeclScoped(EnumDecl *);
8559
8560 inline bool Type::isIntegerType() const {
8561 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
8562 return BT->getKind() >= BuiltinType::Bool &&
8563 BT->getKind() <= BuiltinType::Int128;
8564 if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
8565
8566
8567 return IsEnumDeclComplete(ET->getDecl()) &&
8568 !IsEnumDeclScoped(ET->getDecl());
8569 }
8570 return isBitIntType();
8571 }
8572
8573 inline bool Type::isFixedPointType() const {
8574 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
8575 return BT->getKind() >= BuiltinType::ShortAccum &&
8576 BT->getKind() <= BuiltinType::SatULongFract;
8577 }
8578 return false;
8579 }
8580
8581 inline bool Type::isFixedPointOrIntegerType() const {
8582 return isFixedPointType() || isIntegerType();
8583 }
8584
8585 inline bool Type::isConvertibleToFixedPointType() const {
8586 return isRealFloatingType() || isFixedPointOrIntegerType();
8587 }
8588
8589 inline bool Type::isSaturatedFixedPointType() const {
8590 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
8591 return BT->getKind() >= BuiltinType::SatShortAccum &&
8592 BT->getKind() <= BuiltinType::SatULongFract;
8593 }
8594 return false;
8595 }
8596
8597 inline bool Type::isUnsaturatedFixedPointType() const {
8598 return isFixedPointType() && !isSaturatedFixedPointType();
8599 }
8600
8601 inline bool Type::isSignedFixedPointType() const {
8602 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
8603 return ((BT->getKind() >= BuiltinType::ShortAccum &&
8604 BT->getKind() <= BuiltinType::LongAccum) ||
8605 (BT->getKind() >= BuiltinType::ShortFract &&
8606 BT->getKind() <= BuiltinType::LongFract) ||
8607 (BT->getKind() >= BuiltinType::SatShortAccum &&
8608 BT->getKind() <= BuiltinType::SatLongAccum) ||
8609 (BT->getKind() >= BuiltinType::SatShortFract &&
8610 BT->getKind() <= BuiltinType::SatLongFract));
8611 }
8612 return false;
8613 }
8614
8615 inline bool Type::isUnsignedFixedPointType() const {
8616 return isFixedPointType() && !isSignedFixedPointType();
8617 }
8618
8619 inline bool Type::isScalarType() const {
8620 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
8621 return BT->getKind() > BuiltinType::Void &&
8622 BT->getKind() <= BuiltinType::NullPtr;
8623 if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
8624
8625
8626 return IsEnumDeclComplete(ET->getDecl());
8627 return isa<PointerType>(CanonicalType) ||
8628 isa<BlockPointerType>(CanonicalType) ||
8629 isa<MemberPointerType>(CanonicalType) ||
8630 isa<ComplexType>(CanonicalType) ||
8631 isa<ObjCObjectPointerType>(CanonicalType) ||
8632 isBitIntType();
8633 }
8634
8635 inline bool Type::isIntegralOrEnumerationType() const {
8636 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
8637 return BT->getKind() >= BuiltinType::Bool &&
8638 BT->getKind() <= BuiltinType::Int128;
8639
8640
8641
8642 if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
8643 return IsEnumDeclComplete(ET->getDecl());
8644
8645 return isBitIntType();
8646 }
8647
8648 inline bool Type::isBooleanType() const {
8649 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
8650 return BT->getKind() == BuiltinType::Bool;
8651 return false;
8652 }
8653
8654 inline bool Type::isUndeducedType() const {
8655 auto *DT = getContainedDeducedType();
8656 return DT && !DT->isDeduced();
8657 }
8658
8659
8660
8661 inline bool Type::isOverloadableType() const {
8662 if (!isDependentType())
8663 return isRecordType() || isEnumeralType();
8664 return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
8665 !isMemberPointerType();
8666 }
8667
8668
8669 inline bool Type::isTypedefNameType() const {
8670 if (getAs<TypedefType>())
8671 return true;
8672 if (auto *TST = getAs<TemplateSpecializationType>())
8673 return TST->isTypeAlias();
8674 return false;
8675 }
8676
8677
8678 inline bool Type::canDecayToPointerType() const {
8679 return isFunctionType() || (isArrayType() && !isArrayParameterType());
8680 }
8681
8682 inline bool Type::hasPointerRepresentation() const {
8683 return (isPointerType() || isReferenceType() || isBlockPointerType() ||
8684 isObjCObjectPointerType() || isNullPtrType());
8685 }
8686
8687 inline bool Type::hasObjCPointerRepresentation() const {
8688 return isObjCObjectPointerType();
8689 }
8690
8691 inline const Type *Type::getBaseElementTypeUnsafe() const {
8692 const Type *type = this;
8693 while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe())
8694 type = arrayType->getElementType().getTypePtr();
8695 return type;
8696 }
8697
8698 inline const Type *Type::getPointeeOrArrayElementType() const {
8699 const Type *type = this;
8700 if (type->isAnyPointerType())
8701 return type->getPointeeType().getTypePtr();
8702 else if (type->isArrayType())
8703 return type->getBaseElementTypeUnsafe();
8704 return type;
8705 }
8706
8707
8708 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
8709 LangAS AS) {
8710 PD.AddTaggedVal(llvm::to_underlying(AS),
8711 DiagnosticsEngine::ArgumentKind::ak_addrspace);
8712 return PD;
8713 }
8714
8715
8716
8717 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
8718 Qualifiers Q) {
8719 PD.AddTaggedVal(Q.getAsOpaqueValue(),
8720 DiagnosticsEngine::ArgumentKind::ak_qual);
8721 return PD;
8722 }
8723
8724
8725
8726 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
8727 QualType T) {
8728 PD.AddTaggedVal(reinterpret_cast<uint64_t>(T.getAsOpaquePtr()),
8729 DiagnosticsEngine::ak_qualtype);
8730 return PD;
8731 }
8732
8733
8734
8735 template <typename T>
8736 using TypeIsArrayType =
8737 std::integral_constant<bool, std::is_same<T, ArrayType>::value ||
8738 std::is_base_of<ArrayType, T>::value>;
8739
8740
8741 template <typename T> const T *Type::getAs() const {
8742 static_assert(!TypeIsArrayType<T>::value,
8743 "ArrayType cannot be used with getAs!");
8744
8745
8746 if (const auto *Ty = dyn_cast<T>(this))
8747 return Ty;
8748
8749
8750 if (!isa<T>(CanonicalType))
8751 return nullptr;
8752
8753
8754
8755 return cast<T>(getUnqualifiedDesugaredType());
8756 }
8757
8758 template <typename T> const T *Type::getAsAdjusted() const {
8759 static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
8760
8761
8762 if (const auto *Ty = dyn_cast<T>(this))
8763 return Ty;
8764
8765
8766 if (!isa<T>(CanonicalType))
8767 return nullptr;
8768
8769
8770
8771 const Type *Ty = this;
8772 while (Ty) {
8773 if (const auto *A = dyn_cast<AttributedType>(Ty))
8774 Ty = A->getModifiedType().getTypePtr();
8775 else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty))
8776 Ty = A->getWrappedType().getTypePtr();
8777 else if (const auto *A = dyn_cast<HLSLAttributedResourceType>(Ty))
8778 Ty = A->getWrappedType().getTypePtr();
8779 else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
8780 Ty = E->desugar().getTypePtr();
8781 else if (const auto *P = dyn_cast<ParenType>(Ty))
8782 Ty = P->desugar().getTypePtr();
8783 else if (const auto *A = dyn_cast<AdjustedType>(Ty))
8784 Ty = A->desugar().getTypePtr();
8785 else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty))
8786 Ty = M->desugar().getTypePtr();
8787 else
8788 break;
8789 }
8790
8791
8792
8793 return dyn_cast<T>(Ty);
8794 }
8795
8796 inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
8797
8798 if (const auto *arr = dyn_cast<ArrayType>(this))
8799 return arr;
8800
8801
8802 if (!isa<ArrayType>(CanonicalType))
8803 return nullptr;
8804
8805
8806
8807 return cast<ArrayType>(getUnqualifiedDesugaredType());
8808 }
8809
8810 template <typename T> const T *Type::castAs() const {
8811 static_assert(!TypeIsArrayType<T>::value,
8812 "ArrayType cannot be used with castAs!");
8813
8814 if (const auto *ty = dyn_cast<T>(this)) return ty;
8815 assert(isa<T>(CanonicalType));
8816 return cast<T>(getUnqualifiedDesugaredType());
8817 }
8818
8819 inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
8820 assert(isa<ArrayType>(CanonicalType));
8821 if (const auto *arr = dyn_cast<ArrayType>(this)) return arr;
8822 return cast<ArrayType>(getUnqualifiedDesugaredType());
8823 }
8824
8825 DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr,
8826 QualType CanonicalPtr)
8827 : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
8828 #ifndef NDEBUG
8829 QualType Adjusted = getAdjustedType();
8830 (void)AttributedType::stripOuterNullability(Adjusted);
8831 assert(isa<PointerType>(Adjusted));
8832 #endif
8833 }
8834
8835 QualType DecayedType::getPointeeType() const {
8836 QualType Decayed = getDecayedType();
8837 (void)AttributedType::stripOuterNullability(Decayed);
8838 return cast<PointerType>(Decayed)->getPointeeType();
8839 }
8840
8841
8842
8843
8844
8845 void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
8846 unsigned Scale);
8847
8848 inline FunctionEffectsRef FunctionEffectsRef::get(QualType QT) {
8849 const Type *TypePtr = QT.getTypePtr();
8850 while (true) {
8851 if (QualType Pointee = TypePtr->getPointeeType(); !Pointee.isNull())
8852 TypePtr = Pointee.getTypePtr();
8853 else if (TypePtr->isArrayType())
8854 TypePtr = TypePtr->getBaseElementTypeUnsafe();
8855 else
8856 break;
8857 }
8858 if (const auto *FPT = TypePtr->getAs<FunctionProtoType>())
8859 return FPT->getFunctionEffects();
8860 return {};
8861 }
8862
8863 }
8864
8865 #endif