File indexing completed on 2026-05-10 08:36:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_CANONICALTYPE_H
0015 #define LLVM_CLANG_AST_CANONICALTYPE_H
0016
0017 #include "clang/AST/Type.h"
0018 #include "clang/Basic/Diagnostic.h"
0019 #include "clang/Basic/SourceLocation.h"
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/FoldingSet.h"
0022 #include "llvm/ADT/iterator.h"
0023 #include "llvm/Support/Casting.h"
0024 #include "llvm/Support/PointerLikeTypeTraits.h"
0025 #include <cassert>
0026 #include <iterator>
0027 #include <type_traits>
0028
0029 namespace clang {
0030
0031 template<typename T> class CanProxy;
0032 template<typename T> struct CanProxyAdaptor;
0033 class ASTContext;
0034 class CXXRecordDecl;
0035 class EnumDecl;
0036 class Expr;
0037 class IdentifierInfo;
0038 class ObjCInterfaceDecl;
0039 class RecordDecl;
0040 class TagDecl;
0041 class TemplateTypeParmDecl;
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template<typename T = Type>
0066 class CanQual {
0067
0068 QualType Stored;
0069
0070 public:
0071
0072 CanQual() = default;
0073
0074
0075
0076 template <typename U>
0077 CanQual(const CanQual<U> &Other,
0078 std::enable_if_t<std::is_base_of<T, U>::value, int> = 0);
0079
0080
0081
0082
0083
0084 const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
0085
0086
0087
0088 const T *getTypePtrOrNull() const {
0089 return cast_or_null<T>(Stored.getTypePtrOrNull());
0090 }
0091
0092
0093 operator QualType() const { return Stored; }
0094
0095
0096 explicit operator bool() const { return !isNull(); }
0097
0098 bool isNull() const {
0099 return Stored.isNull();
0100 }
0101
0102 SplitQualType split() const { return Stored.split(); }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 template<typename U> CanProxy<U> getAs() const;
0122
0123 template<typename U> CanProxy<U> castAs() const;
0124
0125
0126
0127 CanProxy<T> operator->() const;
0128
0129
0130 Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
0131
0132
0133 unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
0134
0135
0136 bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
0137
0138 bool isConstQualified() const {
0139 return Stored.isLocalConstQualified();
0140 }
0141
0142 bool isVolatileQualified() const {
0143 return Stored.isLocalVolatileQualified();
0144 }
0145
0146 bool isRestrictQualified() const {
0147 return Stored.isLocalRestrictQualified();
0148 }
0149
0150
0151
0152
0153 bool isCanonicalAsParam() const {
0154 return Stored.isCanonicalAsParam();
0155 }
0156
0157
0158 CanQual<T> getUnqualifiedType() const;
0159
0160
0161
0162 QualType withConst() const {
0163 return Stored.withConst();
0164 }
0165
0166
0167
0168 bool isMoreQualifiedThan(CanQual<T> Other, const ASTContext &Ctx) const {
0169 return Stored.isMoreQualifiedThan(Other.Stored, Ctx);
0170 }
0171
0172
0173
0174 bool isAtLeastAsQualifiedAs(CanQual<T> Other, const ASTContext &Ctx) const {
0175 return Stored.isAtLeastAsQualifiedAs(Other.Stored, Ctx);
0176 }
0177
0178
0179
0180 CanQual<Type> getNonReferenceType() const;
0181
0182
0183 void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
0184
0185
0186 static CanQual<T> getFromOpaquePtr(void *Ptr);
0187
0188
0189
0190
0191
0192
0193 static CanQual<T> CreateUnsafe(QualType Other);
0194
0195 void dump() const { Stored.dump(); }
0196
0197 void Profile(llvm::FoldingSetNodeID &ID) const {
0198 ID.AddPointer(getAsOpaquePtr());
0199 }
0200 };
0201
0202 template<typename T, typename U>
0203 inline bool operator==(CanQual<T> x, CanQual<U> y) {
0204 return x.getAsOpaquePtr() == y.getAsOpaquePtr();
0205 }
0206
0207 template<typename T, typename U>
0208 inline bool operator!=(CanQual<T> x, CanQual<U> y) {
0209 return x.getAsOpaquePtr() != y.getAsOpaquePtr();
0210 }
0211
0212
0213 using CanQualType = CanQual<Type>;
0214
0215 inline CanQualType Type::getCanonicalTypeUnqualified() const {
0216 return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
0217 }
0218
0219 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
0220 CanQualType T) {
0221 DB << static_cast<QualType>(T);
0222 return DB;
0223 }
0224
0225
0226
0227
0228
0229 #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \
0230 CanQualType Accessor() const { \
0231 return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
0232 }
0233
0234 #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
0235 Type Accessor() const { return this->getTypePtr()->Accessor(); }
0236
0237
0238
0239 template<typename T>
0240 class CanProxyBase {
0241 protected:
0242 CanQual<T> Stored;
0243
0244 public:
0245
0246 const T *getTypePtr() const { return Stored.getTypePtr(); }
0247
0248
0249
0250
0251
0252
0253
0254
0255 operator const T*() const { return this->Stored.getTypePtrOrNull(); }
0256
0257
0258
0259 template<typename U> CanProxy<U> getAs() const {
0260 return this->Stored.template getAs<U>();
0261 }
0262
0263 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
0264
0265
0266 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
0267 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
0268 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType)
0269 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType)
0270 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
0271 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
0272 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
0273 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
0274 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
0275 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
0276 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
0277 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
0278 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
0279 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
0280 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
0281 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
0282 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
0283 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
0284 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
0285 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
0286 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
0287 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
0288 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
0289 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
0290 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
0291 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
0292 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
0293 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
0294 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
0295 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
0296 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
0297 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
0298 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
0299 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
0300 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
0301 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
0302 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
0303 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantArrayType)
0304 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
0305 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
0306 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
0307 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
0308 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
0309 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
0310 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
0311 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
0312 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
0313 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
0314 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
0315 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
0316 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
0317
0318
0319
0320
0321
0322
0323
0324 const CanProxyAdaptor<T> *operator->() const {
0325 return static_cast<const CanProxyAdaptor<T> *>(this);
0326 }
0327 };
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 template<typename T>
0340 struct CanProxyAdaptor : CanProxyBase<T> {};
0341
0342
0343
0344
0345
0346
0347
0348
0349 template<typename T>
0350 class CanProxy : public CanProxyAdaptor<T> {
0351 public:
0352
0353 CanProxy() = default;
0354
0355
0356 CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
0357
0358
0359 operator CanQual<T>() const { return this->Stored; }
0360 };
0361
0362 }
0363
0364 namespace llvm {
0365
0366
0367
0368
0369 template<typename T>
0370 struct simplify_type< ::clang::CanQual<T>> {
0371 using SimpleType = const T *;
0372
0373 static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
0374 return Val.getTypePtr();
0375 }
0376 };
0377
0378
0379 template<typename T>
0380 struct PointerLikeTypeTraits<clang::CanQual<T>> {
0381 static void *getAsVoidPointer(clang::CanQual<T> P) {
0382 return P.getAsOpaquePtr();
0383 }
0384
0385 static clang::CanQual<T> getFromVoidPointer(void *P) {
0386 return clang::CanQual<T>::getFromOpaquePtr(P);
0387 }
0388
0389
0390 static constexpr int NumLowBitsAvailable = 0;
0391 };
0392
0393 }
0394
0395 namespace clang {
0396
0397
0398
0399
0400
0401
0402
0403 template <typename InputIterator>
0404 struct CanTypeIterator
0405 : llvm::iterator_adaptor_base<
0406 CanTypeIterator<InputIterator>, InputIterator,
0407 typename std::iterator_traits<InputIterator>::iterator_category,
0408 CanQualType,
0409 typename std::iterator_traits<InputIterator>::difference_type,
0410 CanProxy<Type>, CanQualType> {
0411 CanTypeIterator() = default;
0412 explicit CanTypeIterator(InputIterator Iter)
0413 : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
0414
0415 CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
0416 CanProxy<Type> operator->() const;
0417 };
0418
0419 template<>
0420 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
0421 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
0422 };
0423
0424 template<>
0425 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
0426 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0427 };
0428
0429 template<>
0430 struct CanProxyAdaptor<BlockPointerType>
0431 : public CanProxyBase<BlockPointerType> {
0432 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0433 };
0434
0435 template<>
0436 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
0437 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0438 };
0439
0440 template<>
0441 struct CanProxyAdaptor<LValueReferenceType>
0442 : public CanProxyBase<LValueReferenceType> {
0443 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0444 };
0445
0446 template<>
0447 struct CanProxyAdaptor<RValueReferenceType>
0448 : public CanProxyBase<RValueReferenceType> {
0449 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0450 };
0451
0452 template<>
0453 struct CanProxyAdaptor<MemberPointerType>
0454 : public CanProxyBase<MemberPointerType> {
0455 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0456 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
0457 };
0458
0459
0460
0461 template<> struct CanProxyAdaptor<ArrayType>;
0462 template<> struct CanProxyAdaptor<ConstantArrayType>;
0463 template<> struct CanProxyAdaptor<IncompleteArrayType>;
0464 template<> struct CanProxyAdaptor<VariableArrayType>;
0465 template<> struct CanProxyAdaptor<DependentSizedArrayType>;
0466
0467 template<>
0468 struct CanProxyAdaptor<DependentSizedExtVectorType>
0469 : public CanProxyBase<DependentSizedExtVectorType> {
0470 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
0471 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
0472 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
0473 };
0474
0475 template<>
0476 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
0477 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
0478 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
0479 };
0480
0481 template<>
0482 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
0483 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
0484 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
0485 };
0486
0487 template<>
0488 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
0489 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
0490 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
0491 };
0492
0493 template<>
0494 struct CanProxyAdaptor<FunctionNoProtoType>
0495 : public CanProxyBase<FunctionNoProtoType> {
0496 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
0497 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
0498 };
0499
0500 template<>
0501 struct CanProxyAdaptor<FunctionProtoType>
0502 : public CanProxyBase<FunctionProtoType> {
0503 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
0504 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
0505 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
0506 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
0507 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
0508 ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
0509
0510 CanQualType getParamType(unsigned i) const {
0511 return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
0512 }
0513
0514 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
0515 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals)
0516
0517 using param_type_iterator =
0518 CanTypeIterator<FunctionProtoType::param_type_iterator>;
0519
0520 param_type_iterator param_type_begin() const {
0521 return param_type_iterator(this->getTypePtr()->param_type_begin());
0522 }
0523
0524 param_type_iterator param_type_end() const {
0525 return param_type_iterator(this->getTypePtr()->param_type_end());
0526 }
0527
0528
0529 };
0530
0531 template<>
0532 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
0533 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnmodifiedType)
0534 };
0535
0536 template<>
0537 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
0538 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
0539 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
0540 };
0541
0542 template <>
0543 struct CanProxyAdaptor<UnaryTransformType>
0544 : public CanProxyBase<UnaryTransformType> {
0545 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
0546 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
0547 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
0548 };
0549
0550 template<>
0551 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
0552 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
0553 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
0554 };
0555
0556 template<>
0557 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
0558 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
0559 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
0560 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
0561 };
0562
0563 template<>
0564 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
0565 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
0566 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
0567 };
0568
0569 template<>
0570 struct CanProxyAdaptor<TemplateTypeParmType>
0571 : public CanProxyBase<TemplateTypeParmType> {
0572 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
0573 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
0574 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
0575 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
0576 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
0577 };
0578
0579 template<>
0580 struct CanProxyAdaptor<ObjCObjectType>
0581 : public CanProxyBase<ObjCObjectType> {
0582 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
0583 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
0584 getInterface)
0585 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
0586 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
0587 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
0588 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
0589
0590 using qual_iterator = ObjCObjectPointerType::qual_iterator;
0591
0592 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
0593 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
0594 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
0595 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
0596 };
0597
0598 template<>
0599 struct CanProxyAdaptor<ObjCObjectPointerType>
0600 : public CanProxyBase<ObjCObjectPointerType> {
0601 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
0602 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
0603 getInterfaceType)
0604 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
0605 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
0606 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
0607 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
0608
0609 using qual_iterator = ObjCObjectPointerType::qual_iterator;
0610
0611 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
0612 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
0613 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
0614 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
0615 };
0616
0617
0618
0619
0620 template<typename T>
0621 inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
0622 return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
0623 }
0624
0625 template<typename T>
0626 inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
0627 if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
0628 return RefType->getPointeeType();
0629 else
0630 return *this;
0631 }
0632
0633 template<typename T>
0634 CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
0635 CanQual<T> Result;
0636 Result.Stored = QualType::getFromOpaquePtr(Ptr);
0637 assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
0638 Result.Stored.isCanonical()) && "Type is not canonical!");
0639 return Result;
0640 }
0641
0642 template<typename T>
0643 CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
0644 assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
0645 assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
0646 "Dynamic type does not meet the static type's requires");
0647 CanQual<T> Result;
0648 Result.Stored = Other;
0649 return Result;
0650 }
0651
0652 template<typename T>
0653 template<typename U>
0654 CanProxy<U> CanQual<T>::getAs() const {
0655 static_assert(!TypeIsArrayType<T>::value,
0656 "ArrayType cannot be used with getAs!");
0657
0658 if (Stored.isNull())
0659 return CanProxy<U>();
0660
0661 if (isa<U>(Stored.getTypePtr()))
0662 return CanQual<U>::CreateUnsafe(Stored);
0663
0664 return CanProxy<U>();
0665 }
0666
0667 template<typename T>
0668 template<typename U>
0669 CanProxy<U> CanQual<T>::castAs() const {
0670 static_assert(!TypeIsArrayType<U>::value,
0671 "ArrayType cannot be used with castAs!");
0672
0673 assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
0674 return CanQual<U>::CreateUnsafe(Stored);
0675 }
0676
0677 template<typename T>
0678 CanProxy<T> CanQual<T>::operator->() const {
0679 return CanProxy<T>(*this);
0680 }
0681
0682 template <typename InputIterator>
0683 CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
0684 return CanProxy<Type>(*this);
0685 }
0686
0687 }
0688
0689 #endif