1 //===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the CanQual class template, which provides access to 10 // canonical types. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_CANONICALTYPE_H 15 #define LLVM_CLANG_AST_CANONICALTYPE_H 16 17 #include "clang/AST/Type.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/SourceLocation.h" 20 #include "llvm/ADT/ArrayRef.h" 21 #include "llvm/ADT/FoldingSet.h" 22 #include "llvm/ADT/iterator.h" 23 #include "llvm/Support/Casting.h" 24 #include "llvm/Support/PointerLikeTypeTraits.h" 25 #include <cassert> 26 #include <iterator> 27 #include <type_traits> 28 29 namespace clang { 30 31 template<typename T> class CanProxy; 32 template<typename T> struct CanProxyAdaptor; 33 class CXXRecordDecl; 34 class EnumDecl; 35 class Expr; 36 class IdentifierInfo; 37 class ObjCInterfaceDecl; 38 class RecordDecl; 39 class TagDecl; 40 class TemplateTypeParmDecl; 41 42 //----------------------------------------------------------------------------// 43 // Canonical, qualified type template 44 //----------------------------------------------------------------------------// 45 46 /// Represents a canonical, potentially-qualified type. 47 /// 48 /// The CanQual template is a lightweight smart pointer that provides access 49 /// to the canonical representation of a type, where all typedefs and other 50 /// syntactic sugar has been eliminated. A CanQualType may also have various 51 /// qualifiers (const, volatile, restrict) attached to it. 52 /// 53 /// The template type parameter @p T is one of the Type classes (PointerType, 54 /// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that 55 /// type (or some subclass of that type). The typedef @c CanQualType is just 56 /// a shorthand for @c CanQual<Type>. 57 /// 58 /// An instance of @c CanQual<T> can be implicitly converted to a 59 /// @c CanQual<U> when T is derived from U, which essentially provides an 60 /// implicit upcast. For example, @c CanQual<LValueReferenceType> can be 61 /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can 62 /// be implicitly converted to a QualType, but the reverse operation requires 63 /// a call to ASTContext::getCanonicalType(). 64 template<typename T = Type> 65 class CanQual { 66 /// The actual, canonical type. 67 QualType Stored; 68 69 public: 70 /// Constructs a NULL canonical type. 71 CanQual() = default; 72 73 /// Converting constructor that permits implicit upcasting of 74 /// canonical type pointers. 75 template <typename U> 76 CanQual(const CanQual<U> &Other, 77 typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0); 78 79 /// Retrieve the underlying type pointer, which refers to a 80 /// canonical type. 81 /// 82 /// The underlying pointer must not be nullptr. 83 const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); } 84 85 /// Retrieve the underlying type pointer, which refers to a 86 /// canonical type, or nullptr. 87 const T *getTypePtrOrNull() const { 88 return cast_or_null<T>(Stored.getTypePtrOrNull()); 89 } 90 91 /// Implicit conversion to a qualified type. 92 operator QualType() const { return Stored; } 93 94 /// Implicit conversion to bool. 95 explicit operator bool() const { return !isNull(); } 96 97 bool isNull() const { 98 return Stored.isNull(); 99 } 100 101 SplitQualType split() const { return Stored.split(); } 102 103 /// Retrieve a canonical type pointer with a different static type, 104 /// upcasting or downcasting as needed. 105 /// 106 /// The getAs() function is typically used to try to downcast to a 107 /// more specific (canonical) type in the type system. For example: 108 /// 109 /// @code 110 /// void f(CanQual<Type> T) { 111 /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { 112 /// // look at Ptr's pointee type 113 /// } 114 /// } 115 /// @endcode 116 /// 117 /// \returns A proxy pointer to the same type, but with the specified 118 /// static type (@p U). If the dynamic type is not the specified static type 119 /// or a derived class thereof, a NULL canonical type. 120 template<typename U> CanProxy<U> getAs() const; 121 122 template<typename U> CanProxy<U> castAs() const; 123 124 /// Overloaded arrow operator that produces a canonical type 125 /// proxy. 126 CanProxy<T> operator->() const; 127 128 /// Retrieve all qualifiers. 129 Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); } 130 131 /// Retrieve the const/volatile/restrict qualifiers. 132 unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); } 133 134 /// Determines whether this type has any qualifiers 135 bool hasQualifiers() const { return Stored.hasLocalQualifiers(); } 136 137 bool isConstQualified() const { 138 return Stored.isLocalConstQualified(); 139 } 140 141 bool isVolatileQualified() const { 142 return Stored.isLocalVolatileQualified(); 143 } 144 145 bool isRestrictQualified() const { 146 return Stored.isLocalRestrictQualified(); 147 } 148 149 /// Determines if this canonical type is furthermore 150 /// canonical as a parameter. The parameter-canonicalization 151 /// process decays arrays to pointers and drops top-level qualifiers. 152 bool isCanonicalAsParam() const { 153 return Stored.isCanonicalAsParam(); 154 } 155 156 /// Retrieve the unqualified form of this type. 157 CanQual<T> getUnqualifiedType() const; 158 159 /// Retrieves a version of this type with const applied. 160 /// Note that this does not always yield a canonical type. 161 QualType withConst() const { 162 return Stored.withConst(); 163 } 164 165 /// Determines whether this canonical type is more qualified than 166 /// the @p Other canonical type. 167 bool isMoreQualifiedThan(CanQual<T> Other) const { 168 return Stored.isMoreQualifiedThan(Other.Stored); 169 } 170 171 /// Determines whether this canonical type is at least as qualified as 172 /// the @p Other canonical type. 173 bool isAtLeastAsQualifiedAs(CanQual<T> Other) const { 174 return Stored.isAtLeastAsQualifiedAs(Other.Stored); 175 } 176 177 /// If the canonical type is a reference type, returns the type that 178 /// it refers to; otherwise, returns the type itself. 179 CanQual<Type> getNonReferenceType() const; 180 181 /// Retrieve the internal representation of this canonical type. 182 void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); } 183 184 /// Construct a canonical type from its internal representation. 185 static CanQual<T> getFromOpaquePtr(void *Ptr); 186 187 /// Builds a canonical type from a QualType. 188 /// 189 /// This routine is inherently unsafe, because it requires the user to 190 /// ensure that the given type is a canonical type with the correct 191 // (dynamic) type. 192 static CanQual<T> CreateUnsafe(QualType Other); 193 194 void dump() const { Stored.dump(); } 195 196 void Profile(llvm::FoldingSetNodeID &ID) const { 197 ID.AddPointer(getAsOpaquePtr()); 198 } 199 }; 200 201 template<typename T, typename U> 202 inline bool operator==(CanQual<T> x, CanQual<U> y) { 203 return x.getAsOpaquePtr() == y.getAsOpaquePtr(); 204 } 205 206 template<typename T, typename U> 207 inline bool operator!=(CanQual<T> x, CanQual<U> y) { 208 return x.getAsOpaquePtr() != y.getAsOpaquePtr(); 209 } 210 211 /// Represents a canonical, potentially-qualified type. 212 using CanQualType = CanQual<Type>; 213 214 inline CanQualType Type::getCanonicalTypeUnqualified() const { 215 return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); 216 } 217 218 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 219 CanQualType T) { 220 DB << static_cast<QualType>(T); 221 return DB; 222 } 223 224 //----------------------------------------------------------------------------// 225 // Internal proxy classes used by canonical types 226 //----------------------------------------------------------------------------// 227 228 #define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \ 229 CanQualType Accessor() const { \ 230 return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \ 231 } 232 233 #define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \ 234 Type Accessor() const { return this->getTypePtr()->Accessor(); } 235 236 /// Base class of all canonical proxy types, which is responsible for 237 /// storing the underlying canonical type and providing basic conversions. 238 template<typename T> 239 class CanProxyBase { 240 protected: 241 CanQual<T> Stored; 242 243 public: 244 /// Retrieve the pointer to the underlying Type 245 const T *getTypePtr() const { return Stored.getTypePtr(); } 246 247 /// Implicit conversion to the underlying pointer. 248 /// 249 /// Also provides the ability to use canonical type proxies in a Boolean 250 // context,e.g., 251 /// @code 252 /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... } 253 /// @endcode 254 operator const T*() const { return this->Stored.getTypePtrOrNull(); } 255 256 /// Try to convert the given canonical type to a specific structural 257 /// type. 258 template<typename U> CanProxy<U> getAs() const { 259 return this->Stored.template getAs<U>(); 260 } 261 262 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass) 263 264 // Type predicates 265 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) 266 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) 267 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) 268 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) 269 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) 270 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType) 271 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType) 272 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType) 273 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType) 274 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType) 275 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType) 276 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType) 277 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType) 278 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType) 279 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType) 280 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType) 281 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType) 282 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType) 283 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType) 284 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType) 285 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType) 286 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType) 287 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType) 288 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType) 289 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType) 290 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType) 291 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType) 292 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType) 293 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType) 294 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) 295 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) 296 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType) 297 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType) 298 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType) 299 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType) 300 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation) 301 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation) 302 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation) 303 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation) 304 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation) 305 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation) 306 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType) 307 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType) 308 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType) 309 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType) 310 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType) 311 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType) 312 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType) 313 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl) 314 315 /// Retrieve the proxy-adaptor type. 316 /// 317 /// This arrow operator is used when CanProxyAdaptor has been specialized 318 /// for the given type T. In that case, we reference members of the 319 /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden 320 /// by the arrow operator in the primary CanProxyAdaptor template. 321 const CanProxyAdaptor<T> *operator->() const { 322 return static_cast<const CanProxyAdaptor<T> *>(this); 323 } 324 }; 325 326 /// Replaceable canonical proxy adaptor class that provides the link 327 /// between a canonical type and the accessors of the type. 328 /// 329 /// The CanProxyAdaptor is a replaceable class template that is instantiated 330 /// as part of each canonical proxy type. The primary template merely provides 331 /// redirection to the underlying type (T), e.g., @c PointerType. One can 332 /// provide specializations of this class template for each underlying type 333 /// that provide accessors returning canonical types (@c CanQualType) rather 334 /// than the more typical @c QualType, to propagate the notion of "canonical" 335 /// through the system. 336 template<typename T> 337 struct CanProxyAdaptor : CanProxyBase<T> {}; 338 339 /// Canonical proxy type returned when retrieving the members of a 340 /// canonical type or as the result of the @c CanQual<T>::getAs member 341 /// function. 342 /// 343 /// The CanProxy type mainly exists as a proxy through which operator-> will 344 /// look to either map down to a raw T* (e.g., PointerType*) or to a proxy 345 /// type that provides canonical-type access to the fields of the type. 346 template<typename T> 347 class CanProxy : public CanProxyAdaptor<T> { 348 public: 349 /// Build a NULL proxy. 350 CanProxy() = default; 351 352 /// Build a proxy to the given canonical type. 353 CanProxy(CanQual<T> Stored) { this->Stored = Stored; } 354 355 /// Implicit conversion to the stored canonical type. 356 operator CanQual<T>() const { return this->Stored; } 357 }; 358 359 } // namespace clang 360 361 namespace llvm { 362 363 /// Implement simplify_type for CanQual<T>, so that we can dyn_cast from 364 /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. 365 /// to return smart pointer (proxies?). 366 template<typename T> 367 struct simplify_type< ::clang::CanQual<T>> { 368 using SimpleType = const T *; 369 370 static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) { 371 return Val.getTypePtr(); 372 } 373 }; 374 375 // Teach SmallPtrSet that CanQual<T> is "basically a pointer". 376 template<typename T> 377 struct PointerLikeTypeTraits<clang::CanQual<T>> { 378 static void *getAsVoidPointer(clang::CanQual<T> P) { 379 return P.getAsOpaquePtr(); 380 } 381 382 static clang::CanQual<T> getFromVoidPointer(void *P) { 383 return clang::CanQual<T>::getFromOpaquePtr(P); 384 } 385 386 // qualifier information is encoded in the low bits. 387 enum { NumLowBitsAvailable = 0 }; 388 }; 389 390 } // namespace llvm 391 392 namespace clang { 393 394 //----------------------------------------------------------------------------// 395 // Canonical proxy adaptors for canonical type nodes. 396 //----------------------------------------------------------------------------// 397 398 /// Iterator adaptor that turns an iterator over canonical QualTypes 399 /// into an iterator over CanQualTypes. 400 template <typename InputIterator> 401 struct CanTypeIterator 402 : llvm::iterator_adaptor_base< 403 CanTypeIterator<InputIterator>, InputIterator, 404 typename std::iterator_traits<InputIterator>::iterator_category, 405 CanQualType, 406 typename std::iterator_traits<InputIterator>::difference_type, 407 CanProxy<Type>, CanQualType> { 408 CanTypeIterator() = default; 409 explicit CanTypeIterator(InputIterator Iter) 410 : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {} 411 412 CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); } 413 CanProxy<Type> operator->() const; 414 }; 415 416 template<> 417 struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> { 418 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 419 }; 420 421 template<> 422 struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> { 423 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 424 }; 425 426 template<> 427 struct CanProxyAdaptor<BlockPointerType> 428 : public CanProxyBase<BlockPointerType> { 429 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 430 }; 431 432 template<> 433 struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> { 434 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 435 }; 436 437 template<> 438 struct CanProxyAdaptor<LValueReferenceType> 439 : public CanProxyBase<LValueReferenceType> { 440 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 441 }; 442 443 template<> 444 struct CanProxyAdaptor<RValueReferenceType> 445 : public CanProxyBase<RValueReferenceType> { 446 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 447 }; 448 449 template<> 450 struct CanProxyAdaptor<MemberPointerType> 451 : public CanProxyBase<MemberPointerType> { 452 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 453 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass) 454 }; 455 456 // CanProxyAdaptors for arrays are intentionally unimplemented because 457 // they are not safe. 458 template<> struct CanProxyAdaptor<ArrayType>; 459 template<> struct CanProxyAdaptor<ConstantArrayType>; 460 template<> struct CanProxyAdaptor<IncompleteArrayType>; 461 template<> struct CanProxyAdaptor<VariableArrayType>; 462 template<> struct CanProxyAdaptor<DependentSizedArrayType>; 463 464 template<> 465 struct CanProxyAdaptor<DependentSizedExtVectorType> 466 : public CanProxyBase<DependentSizedExtVectorType> { 467 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 468 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr) 469 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc) 470 }; 471 472 template<> 473 struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> { 474 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 475 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) 476 }; 477 478 template<> 479 struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> { 480 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) 481 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements) 482 }; 483 484 template<> 485 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> { 486 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType) 487 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) 488 }; 489 490 template<> 491 struct CanProxyAdaptor<FunctionNoProtoType> 492 : public CanProxyBase<FunctionNoProtoType> { 493 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType) 494 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) 495 }; 496 497 template<> 498 struct CanProxyAdaptor<FunctionProtoType> 499 : public CanProxyBase<FunctionProtoType> { 500 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType) 501 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) 502 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams) 503 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos) 504 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR( 505 ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos) 506 507 CanQualType getParamType(unsigned i) const { 508 return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i)); 509 } 510 511 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) 512 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals) 513 514 using param_type_iterator = 515 CanTypeIterator<FunctionProtoType::param_type_iterator>; 516 517 param_type_iterator param_type_begin() const { 518 return param_type_iterator(this->getTypePtr()->param_type_begin()); 519 } 520 521 param_type_iterator param_type_end() const { 522 return param_type_iterator(this->getTypePtr()->param_type_end()); 523 } 524 525 // Note: canonical function types never have exception specifications 526 }; 527 528 template<> 529 struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> { 530 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 531 }; 532 533 template<> 534 struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> { 535 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr) 536 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 537 }; 538 539 template <> 540 struct CanProxyAdaptor<UnaryTransformType> 541 : public CanProxyBase<UnaryTransformType> { 542 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) 543 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) 544 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind) 545 }; 546 547 template<> 548 struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> { 549 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl) 550 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 551 }; 552 553 template<> 554 struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> { 555 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl) 556 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 557 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields) 558 }; 559 560 template<> 561 struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> { 562 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl) 563 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) 564 }; 565 566 template<> 567 struct CanProxyAdaptor<TemplateTypeParmType> 568 : public CanProxyBase<TemplateTypeParmType> { 569 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth) 570 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex) 571 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack) 572 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl) 573 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier) 574 }; 575 576 template<> 577 struct CanProxyAdaptor<ObjCObjectType> 578 : public CanProxyBase<ObjCObjectType> { 579 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) 580 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *, 581 getInterface) 582 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId) 583 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass) 584 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) 585 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) 586 587 using qual_iterator = ObjCObjectPointerType::qual_iterator; 588 589 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) 590 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) 591 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) 592 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) 593 }; 594 595 template<> 596 struct CanProxyAdaptor<ObjCObjectPointerType> 597 : public CanProxyBase<ObjCObjectPointerType> { 598 LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) 599 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *, 600 getInterfaceType) 601 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType) 602 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType) 603 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType) 604 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) 605 606 using qual_iterator = ObjCObjectPointerType::qual_iterator; 607 608 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) 609 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) 610 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) 611 LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) 612 }; 613 614 //----------------------------------------------------------------------------// 615 // Method and function definitions 616 //----------------------------------------------------------------------------// 617 template<typename T> 618 inline CanQual<T> CanQual<T>::getUnqualifiedType() const { 619 return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType()); 620 } 621 622 template<typename T> 623 inline CanQual<Type> CanQual<T>::getNonReferenceType() const { 624 if (CanQual<ReferenceType> RefType = getAs<ReferenceType>()) 625 return RefType->getPointeeType(); 626 else 627 return *this; 628 } 629 630 template<typename T> 631 CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) { 632 CanQual<T> Result; 633 Result.Stored = QualType::getFromOpaquePtr(Ptr); 634 assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 || 635 Result.Stored.isCanonical()) && "Type is not canonical!"); 636 return Result; 637 } 638 639 template<typename T> 640 CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) { 641 assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!"); 642 assert((Other.isNull() || isa<T>(Other.getTypePtr())) && 643 "Dynamic type does not meet the static type's requires"); 644 CanQual<T> Result; 645 Result.Stored = Other; 646 return Result; 647 } 648 649 template<typename T> 650 template<typename U> 651 CanProxy<U> CanQual<T>::getAs() const { 652 static_assert(!TypeIsArrayType<T>::value, 653 "ArrayType cannot be used with getAs!"); 654 655 if (Stored.isNull()) 656 return CanProxy<U>(); 657 658 if (isa<U>(Stored.getTypePtr())) 659 return CanQual<U>::CreateUnsafe(Stored); 660 661 return CanProxy<U>(); 662 } 663 664 template<typename T> 665 template<typename U> 666 CanProxy<U> CanQual<T>::castAs() const { 667 static_assert(!TypeIsArrayType<U>::value, 668 "ArrayType cannot be used with castAs!"); 669 670 assert(!Stored.isNull() && isa<U>(Stored.getTypePtr())); 671 return CanQual<U>::CreateUnsafe(Stored); 672 } 673 674 template<typename T> 675 CanProxy<T> CanQual<T>::operator->() const { 676 return CanProxy<T>(*this); 677 } 678 679 template <typename InputIterator> 680 CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const { 681 return CanProxy<Type>(*this); 682 } 683 684 } // namespace clang 685 686 #endif // LLVM_CLANG_AST_CANONICALTYPE_H 687