Type.h revision 251662
1193326Sed//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the Type interface and subclasses. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_TYPE_H 15193326Sed#define LLVM_CLANG_AST_TYPE_H 16193326Sed 17249423Sdim#include "clang/AST/NestedNameSpecifier.h" 18249423Sdim#include "clang/AST/TemplateName.h" 19193326Sed#include "clang/Basic/Diagnostic.h" 20221345Sdim#include "clang/Basic/ExceptionSpecificationType.h" 21193326Sed#include "clang/Basic/IdentifierTable.h" 22249423Sdim#include "clang/Basic/LLVM.h" 23203955Srdivacky#include "clang/Basic/Linkage.h" 24206084Srdivacky#include "clang/Basic/PartialDiagnostic.h" 25249423Sdim#include "clang/Basic/Specifiers.h" 26218893Sdim#include "clang/Basic/Visibility.h" 27193326Sed#include "llvm/ADT/APSInt.h" 28193326Sed#include "llvm/ADT/FoldingSet.h" 29218893Sdim#include "llvm/ADT/Optional.h" 30193326Sed#include "llvm/ADT/PointerIntPair.h" 31193326Sed#include "llvm/ADT/PointerUnion.h" 32239462Sdim#include "llvm/ADT/Twine.h" 33249423Sdim#include "llvm/Support/ErrorHandling.h" 34249423Sdim#include "llvm/Support/type_traits.h" 35193326Sed 36198092Srdivackynamespace clang { 37198092Srdivacky enum { 38218893Sdim TypeAlignmentInBits = 4, 39198092Srdivacky TypeAlignment = 1 << TypeAlignmentInBits 40198092Srdivacky }; 41200583Srdivacky class Type; 42200583Srdivacky class ExtQuals; 43200583Srdivacky class QualType; 44198092Srdivacky} 45193326Sed 46193326Sednamespace llvm { 47193326Sed template <typename T> 48193326Sed class PointerLikeTypeTraits; 49193326Sed template<> 50193326Sed class PointerLikeTypeTraits< ::clang::Type*> { 51193326Sed public: 52193326Sed static inline void *getAsVoidPointer(::clang::Type *P) { return P; } 53193326Sed static inline ::clang::Type *getFromVoidPointer(void *P) { 54193326Sed return static_cast< ::clang::Type*>(P); 55193326Sed } 56198092Srdivacky enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; 57193326Sed }; 58198092Srdivacky template<> 59198092Srdivacky class PointerLikeTypeTraits< ::clang::ExtQuals*> { 60198092Srdivacky public: 61198092Srdivacky static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } 62198092Srdivacky static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { 63198092Srdivacky return static_cast< ::clang::ExtQuals*>(P); 64198092Srdivacky } 65198092Srdivacky enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; 66198092Srdivacky }; 67200583Srdivacky 68200583Srdivacky template <> 69200583Srdivacky struct isPodLike<clang::QualType> { static const bool value = true; }; 70193326Sed} 71193326Sed 72193326Sednamespace clang { 73193326Sed class ASTContext; 74221345Sdim class TypedefNameDecl; 75193326Sed class TemplateDecl; 76193326Sed class TemplateTypeParmDecl; 77193326Sed class NonTypeTemplateParmDecl; 78193326Sed class TemplateTemplateParmDecl; 79193326Sed class TagDecl; 80193326Sed class RecordDecl; 81193326Sed class CXXRecordDecl; 82193326Sed class EnumDecl; 83193326Sed class FieldDecl; 84234982Sdim class FunctionDecl; 85193326Sed class ObjCInterfaceDecl; 86193326Sed class ObjCProtocolDecl; 87193326Sed class ObjCMethodDecl; 88200583Srdivacky class UnresolvedUsingTypenameDecl; 89193326Sed class Expr; 90193326Sed class Stmt; 91193326Sed class SourceLocation; 92193326Sed class StmtIteratorBase; 93193326Sed class TemplateArgument; 94198893Srdivacky class TemplateArgumentLoc; 95199990Srdivacky class TemplateArgumentListInfo; 96208600Srdivacky class ElaboratedType; 97218893Sdim class ExtQuals; 98218893Sdim class ExtQualsTypeCommonBase; 99198092Srdivacky struct PrintingPolicy; 100193326Sed 101234353Sdim template <typename> class CanQual; 102204643Srdivacky typedef CanQual<Type> CanQualType; 103204643Srdivacky 104193326Sed // Provide forward declarations for all of the *Type classes 105193326Sed#define TYPE(Class, Base) class Class##Type; 106193326Sed#include "clang/AST/TypeNodes.def" 107193326Sed 108198092Srdivacky/// Qualifiers - The collection of all-type qualifiers we support. 109198092Srdivacky/// Clang supports five independent qualifiers: 110198092Srdivacky/// * C99: const, volatile, and restrict 111198092Srdivacky/// * Embedded C (TR18037): address spaces 112198092Srdivacky/// * Objective C: the GC attributes (none, weak, or strong) 113198092Srdivackyclass Qualifiers { 114193326Sedpublic: 115198092Srdivacky enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. 116193326Sed Const = 0x1, 117193326Sed Restrict = 0x2, 118193326Sed Volatile = 0x4, 119198092Srdivacky CVRMask = Const | Volatile | Restrict 120193326Sed }; 121198092Srdivacky 122198092Srdivacky enum GC { 123193326Sed GCNone = 0, 124193326Sed Weak, 125193326Sed Strong 126193326Sed }; 127198092Srdivacky 128224145Sdim enum ObjCLifetime { 129224145Sdim /// There is no lifetime qualification on this type. 130224145Sdim OCL_None, 131224145Sdim 132224145Sdim /// This object can be modified without requiring retains or 133224145Sdim /// releases. 134224145Sdim OCL_ExplicitNone, 135224145Sdim 136224145Sdim /// Assigning into this object requires the old value to be 137224145Sdim /// released and the new value to be retained. The timing of the 138224145Sdim /// release of the old value is inexact: it may be moved to 139224145Sdim /// immediately after the last known point where the value is 140224145Sdim /// live. 141224145Sdim OCL_Strong, 142224145Sdim 143224145Sdim /// Reading or writing from this object requires a barrier call. 144224145Sdim OCL_Weak, 145224145Sdim 146224145Sdim /// Assigning into this object requires a lifetime extension. 147224145Sdim OCL_Autoreleasing 148224145Sdim }; 149224145Sdim 150198092Srdivacky enum { 151198092Srdivacky /// The maximum supported address space number. 152198092Srdivacky /// 24 bits should be enough for anyone. 153198092Srdivacky MaxAddressSpace = 0xffffffu, 154198092Srdivacky 155198092Srdivacky /// The width of the "fast" qualifier mask. 156218893Sdim FastWidth = 3, 157198092Srdivacky 158198092Srdivacky /// The fast qualifier mask. 159198092Srdivacky FastMask = (1 << FastWidth) - 1 160198092Srdivacky }; 161198092Srdivacky 162198092Srdivacky Qualifiers() : Mask(0) {} 163198092Srdivacky 164243830Sdim /// \brief Returns the common set of qualifiers while removing them from 165243830Sdim /// the given sets. 166243830Sdim static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { 167243830Sdim // If both are only CVR-qualified, bit operations are sufficient. 168243830Sdim if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { 169243830Sdim Qualifiers Q; 170243830Sdim Q.Mask = L.Mask & R.Mask; 171243830Sdim L.Mask &= ~Q.Mask; 172243830Sdim R.Mask &= ~Q.Mask; 173243830Sdim return Q; 174243830Sdim } 175243830Sdim 176243830Sdim Qualifiers Q; 177243830Sdim unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); 178243830Sdim Q.addCVRQualifiers(CommonCRV); 179243830Sdim L.removeCVRQualifiers(CommonCRV); 180243830Sdim R.removeCVRQualifiers(CommonCRV); 181243830Sdim 182243830Sdim if (L.getObjCGCAttr() == R.getObjCGCAttr()) { 183243830Sdim Q.setObjCGCAttr(L.getObjCGCAttr()); 184243830Sdim L.removeObjCGCAttr(); 185243830Sdim R.removeObjCGCAttr(); 186243830Sdim } 187243830Sdim 188243830Sdim if (L.getObjCLifetime() == R.getObjCLifetime()) { 189243830Sdim Q.setObjCLifetime(L.getObjCLifetime()); 190243830Sdim L.removeObjCLifetime(); 191243830Sdim R.removeObjCLifetime(); 192243830Sdim } 193243830Sdim 194243830Sdim if (L.getAddressSpace() == R.getAddressSpace()) { 195243830Sdim Q.setAddressSpace(L.getAddressSpace()); 196243830Sdim L.removeAddressSpace(); 197243830Sdim R.removeAddressSpace(); 198243830Sdim } 199243830Sdim return Q; 200243830Sdim } 201243830Sdim 202198092Srdivacky static Qualifiers fromFastMask(unsigned Mask) { 203198092Srdivacky Qualifiers Qs; 204198092Srdivacky Qs.addFastQualifiers(Mask); 205198092Srdivacky return Qs; 206198092Srdivacky } 207198092Srdivacky 208198092Srdivacky static Qualifiers fromCVRMask(unsigned CVR) { 209198092Srdivacky Qualifiers Qs; 210198092Srdivacky Qs.addCVRQualifiers(CVR); 211198092Srdivacky return Qs; 212198092Srdivacky } 213198092Srdivacky 214198092Srdivacky // Deserialize qualifiers from an opaque representation. 215198092Srdivacky static Qualifiers fromOpaqueValue(unsigned opaque) { 216198092Srdivacky Qualifiers Qs; 217198092Srdivacky Qs.Mask = opaque; 218198092Srdivacky return Qs; 219198092Srdivacky } 220198092Srdivacky 221198092Srdivacky // Serialize these qualifiers into an opaque representation. 222198092Srdivacky unsigned getAsOpaqueValue() const { 223198092Srdivacky return Mask; 224198092Srdivacky } 225198092Srdivacky 226198092Srdivacky bool hasConst() const { return Mask & Const; } 227198092Srdivacky void setConst(bool flag) { 228198092Srdivacky Mask = (Mask & ~Const) | (flag ? Const : 0); 229198092Srdivacky } 230198092Srdivacky void removeConst() { Mask &= ~Const; } 231198092Srdivacky void addConst() { Mask |= Const; } 232198092Srdivacky 233198092Srdivacky bool hasVolatile() const { return Mask & Volatile; } 234198092Srdivacky void setVolatile(bool flag) { 235198092Srdivacky Mask = (Mask & ~Volatile) | (flag ? Volatile : 0); 236198092Srdivacky } 237198092Srdivacky void removeVolatile() { Mask &= ~Volatile; } 238198092Srdivacky void addVolatile() { Mask |= Volatile; } 239198092Srdivacky 240198092Srdivacky bool hasRestrict() const { return Mask & Restrict; } 241198092Srdivacky void setRestrict(bool flag) { 242198092Srdivacky Mask = (Mask & ~Restrict) | (flag ? Restrict : 0); 243198092Srdivacky } 244198092Srdivacky void removeRestrict() { Mask &= ~Restrict; } 245198092Srdivacky void addRestrict() { Mask |= Restrict; } 246198092Srdivacky 247198092Srdivacky bool hasCVRQualifiers() const { return getCVRQualifiers(); } 248198092Srdivacky unsigned getCVRQualifiers() const { return Mask & CVRMask; } 249198092Srdivacky void setCVRQualifiers(unsigned mask) { 250198092Srdivacky assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); 251198092Srdivacky Mask = (Mask & ~CVRMask) | mask; 252198092Srdivacky } 253198092Srdivacky void removeCVRQualifiers(unsigned mask) { 254198092Srdivacky assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); 255198092Srdivacky Mask &= ~mask; 256198092Srdivacky } 257198092Srdivacky void removeCVRQualifiers() { 258198092Srdivacky removeCVRQualifiers(CVRMask); 259198092Srdivacky } 260198092Srdivacky void addCVRQualifiers(unsigned mask) { 261198092Srdivacky assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); 262198092Srdivacky Mask |= mask; 263198092Srdivacky } 264198092Srdivacky 265198092Srdivacky bool hasObjCGCAttr() const { return Mask & GCAttrMask; } 266198092Srdivacky GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } 267198092Srdivacky void setObjCGCAttr(GC type) { 268198092Srdivacky Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); 269198092Srdivacky } 270198092Srdivacky void removeObjCGCAttr() { setObjCGCAttr(GCNone); } 271198092Srdivacky void addObjCGCAttr(GC type) { 272198092Srdivacky assert(type); 273198092Srdivacky setObjCGCAttr(type); 274198092Srdivacky } 275221345Sdim Qualifiers withoutObjCGCAttr() const { 276221345Sdim Qualifiers qs = *this; 277221345Sdim qs.removeObjCGCAttr(); 278221345Sdim return qs; 279221345Sdim } 280234353Sdim Qualifiers withoutObjCLifetime() const { 281224145Sdim Qualifiers qs = *this; 282224145Sdim qs.removeObjCLifetime(); 283224145Sdim return qs; 284224145Sdim } 285198092Srdivacky 286224145Sdim bool hasObjCLifetime() const { return Mask & LifetimeMask; } 287224145Sdim ObjCLifetime getObjCLifetime() const { 288224145Sdim return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); 289224145Sdim } 290224145Sdim void setObjCLifetime(ObjCLifetime type) { 291224145Sdim Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); 292224145Sdim } 293224145Sdim void removeObjCLifetime() { setObjCLifetime(OCL_None); } 294224145Sdim void addObjCLifetime(ObjCLifetime type) { 295224145Sdim assert(type); 296234353Sdim assert(!hasObjCLifetime()); 297234353Sdim Mask |= (type << LifetimeShift); 298224145Sdim } 299224145Sdim 300224145Sdim /// True if the lifetime is neither None or ExplicitNone. 301224145Sdim bool hasNonTrivialObjCLifetime() const { 302224145Sdim ObjCLifetime lifetime = getObjCLifetime(); 303224145Sdim return (lifetime > OCL_ExplicitNone); 304224145Sdim } 305224145Sdim 306224145Sdim /// True if the lifetime is either strong or weak. 307224145Sdim bool hasStrongOrWeakObjCLifetime() const { 308224145Sdim ObjCLifetime lifetime = getObjCLifetime(); 309224145Sdim return (lifetime == OCL_Strong || lifetime == OCL_Weak); 310224145Sdim } 311234353Sdim 312198092Srdivacky bool hasAddressSpace() const { return Mask & AddressSpaceMask; } 313198092Srdivacky unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; } 314198092Srdivacky void setAddressSpace(unsigned space) { 315198092Srdivacky assert(space <= MaxAddressSpace); 316198092Srdivacky Mask = (Mask & ~AddressSpaceMask) 317198092Srdivacky | (((uint32_t) space) << AddressSpaceShift); 318198092Srdivacky } 319198092Srdivacky void removeAddressSpace() { setAddressSpace(0); } 320198092Srdivacky void addAddressSpace(unsigned space) { 321198092Srdivacky assert(space); 322198092Srdivacky setAddressSpace(space); 323198092Srdivacky } 324198092Srdivacky 325198092Srdivacky // Fast qualifiers are those that can be allocated directly 326198092Srdivacky // on a QualType object. 327198092Srdivacky bool hasFastQualifiers() const { return getFastQualifiers(); } 328198092Srdivacky unsigned getFastQualifiers() const { return Mask & FastMask; } 329198092Srdivacky void setFastQualifiers(unsigned mask) { 330198092Srdivacky assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); 331198092Srdivacky Mask = (Mask & ~FastMask) | mask; 332198092Srdivacky } 333198092Srdivacky void removeFastQualifiers(unsigned mask) { 334198092Srdivacky assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); 335198092Srdivacky Mask &= ~mask; 336198092Srdivacky } 337198092Srdivacky void removeFastQualifiers() { 338198092Srdivacky removeFastQualifiers(FastMask); 339198092Srdivacky } 340198092Srdivacky void addFastQualifiers(unsigned mask) { 341198092Srdivacky assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); 342198092Srdivacky Mask |= mask; 343198092Srdivacky } 344198092Srdivacky 345198092Srdivacky /// hasNonFastQualifiers - Return true if the set contains any 346198092Srdivacky /// qualifiers which require an ExtQuals node to be allocated. 347198092Srdivacky bool hasNonFastQualifiers() const { return Mask & ~FastMask; } 348198092Srdivacky Qualifiers getNonFastQualifiers() const { 349198092Srdivacky Qualifiers Quals = *this; 350198092Srdivacky Quals.setFastQualifiers(0); 351198092Srdivacky return Quals; 352198092Srdivacky } 353198092Srdivacky 354198092Srdivacky /// hasQualifiers - Return true if the set contains any qualifiers. 355198092Srdivacky bool hasQualifiers() const { return Mask; } 356198092Srdivacky bool empty() const { return !Mask; } 357198092Srdivacky 358198092Srdivacky /// \brief Add the qualifiers from the given set to this set. 359198092Srdivacky void addQualifiers(Qualifiers Q) { 360198092Srdivacky // If the other set doesn't have any non-boolean qualifiers, just 361198092Srdivacky // bit-or it in. 362198092Srdivacky if (!(Q.Mask & ~CVRMask)) 363198092Srdivacky Mask |= Q.Mask; 364198092Srdivacky else { 365198092Srdivacky Mask |= (Q.Mask & CVRMask); 366198092Srdivacky if (Q.hasAddressSpace()) 367198092Srdivacky addAddressSpace(Q.getAddressSpace()); 368198092Srdivacky if (Q.hasObjCGCAttr()) 369198092Srdivacky addObjCGCAttr(Q.getObjCGCAttr()); 370224145Sdim if (Q.hasObjCLifetime()) 371224145Sdim addObjCLifetime(Q.getObjCLifetime()); 372198092Srdivacky } 373198092Srdivacky } 374198092Srdivacky 375243830Sdim /// \brief Remove the qualifiers from the given set from this set. 376243830Sdim void removeQualifiers(Qualifiers Q) { 377243830Sdim // If the other set doesn't have any non-boolean qualifiers, just 378243830Sdim // bit-and the inverse in. 379243830Sdim if (!(Q.Mask & ~CVRMask)) 380243830Sdim Mask &= ~Q.Mask; 381243830Sdim else { 382243830Sdim Mask &= ~(Q.Mask & CVRMask); 383243830Sdim if (getObjCGCAttr() == Q.getObjCGCAttr()) 384243830Sdim removeObjCGCAttr(); 385243830Sdim if (getObjCLifetime() == Q.getObjCLifetime()) 386243830Sdim removeObjCLifetime(); 387243830Sdim if (getAddressSpace() == Q.getAddressSpace()) 388243830Sdim removeAddressSpace(); 389243830Sdim } 390243830Sdim } 391243830Sdim 392218893Sdim /// \brief Add the qualifiers from the given set to this set, given that 393218893Sdim /// they don't conflict. 394218893Sdim void addConsistentQualifiers(Qualifiers qs) { 395218893Sdim assert(getAddressSpace() == qs.getAddressSpace() || 396218893Sdim !hasAddressSpace() || !qs.hasAddressSpace()); 397218893Sdim assert(getObjCGCAttr() == qs.getObjCGCAttr() || 398218893Sdim !hasObjCGCAttr() || !qs.hasObjCGCAttr()); 399224145Sdim assert(getObjCLifetime() == qs.getObjCLifetime() || 400224145Sdim !hasObjCLifetime() || !qs.hasObjCLifetime()); 401218893Sdim Mask |= qs.Mask; 402218893Sdim } 403218893Sdim 404218893Sdim /// \brief Determines if these qualifiers compatibly include another set. 405218893Sdim /// Generally this answers the question of whether an object with the other 406218893Sdim /// qualifiers can be safely used as an object with these qualifiers. 407218893Sdim bool compatiblyIncludes(Qualifiers other) const { 408234353Sdim return 409223017Sdim // Address spaces must match exactly. 410223017Sdim getAddressSpace() == other.getAddressSpace() && 411223017Sdim // ObjC GC qualifiers can match, be added, or be removed, but can't be 412223017Sdim // changed. 413223017Sdim (getObjCGCAttr() == other.getObjCGCAttr() || 414223017Sdim !hasObjCGCAttr() || !other.hasObjCGCAttr()) && 415224145Sdim // ObjC lifetime qualifiers must match exactly. 416224145Sdim getObjCLifetime() == other.getObjCLifetime() && 417223017Sdim // CVR qualifiers may subset. 418223017Sdim (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); 419218893Sdim } 420218893Sdim 421224145Sdim /// \brief Determines if these qualifiers compatibly include another set of 422224145Sdim /// qualifiers from the narrow perspective of Objective-C ARC lifetime. 423224145Sdim /// 424224145Sdim /// One set of Objective-C lifetime qualifiers compatibly includes the other 425234353Sdim /// if the lifetime qualifiers match, or if both are non-__weak and the 426224145Sdim /// including set also contains the 'const' qualifier. 427224145Sdim bool compatiblyIncludesObjCLifetime(Qualifiers other) const { 428224145Sdim if (getObjCLifetime() == other.getObjCLifetime()) 429224145Sdim return true; 430234353Sdim 431224145Sdim if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) 432224145Sdim return false; 433234353Sdim 434224145Sdim return hasConst(); 435224145Sdim } 436234353Sdim 437221345Sdim /// \brief Determine whether this set of qualifiers is a strict superset of 438221345Sdim /// another set of qualifiers, not considering qualifier compatibility. 439221345Sdim bool isStrictSupersetOf(Qualifiers Other) const; 440234353Sdim 441198092Srdivacky bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } 442198092Srdivacky bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } 443198092Srdivacky 444198092Srdivacky operator bool() const { return hasQualifiers(); } 445198092Srdivacky 446198092Srdivacky Qualifiers &operator+=(Qualifiers R) { 447198092Srdivacky addQualifiers(R); 448198092Srdivacky return *this; 449198092Srdivacky } 450198092Srdivacky 451198092Srdivacky // Union two qualifier sets. If an enumerated qualifier appears 452198092Srdivacky // in both sets, use the one from the right. 453198092Srdivacky friend Qualifiers operator+(Qualifiers L, Qualifiers R) { 454198092Srdivacky L += R; 455198092Srdivacky return L; 456198092Srdivacky } 457234353Sdim 458212904Sdim Qualifiers &operator-=(Qualifiers R) { 459243830Sdim removeQualifiers(R); 460212904Sdim return *this; 461212904Sdim } 462198092Srdivacky 463212904Sdim /// \brief Compute the difference between two qualifier sets. 464212904Sdim friend Qualifiers operator-(Qualifiers L, Qualifiers R) { 465212904Sdim L -= R; 466212904Sdim return L; 467212904Sdim } 468234353Sdim 469198092Srdivacky std::string getAsString() const; 470239462Sdim std::string getAsString(const PrintingPolicy &Policy) const; 471198092Srdivacky 472239462Sdim bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; 473239462Sdim void print(raw_ostream &OS, const PrintingPolicy &Policy, 474239462Sdim bool appendSpaceIfNonEmpty = false) const; 475239462Sdim 476198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) const { 477198092Srdivacky ID.AddInteger(Mask); 478198092Srdivacky } 479198092Srdivacky 480198092Srdivackyprivate: 481198092Srdivacky 482224145Sdim // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31| 483224145Sdim // |C R V|GCAttr|Lifetime|AddressSpace| 484198092Srdivacky uint32_t Mask; 485198092Srdivacky 486198092Srdivacky static const uint32_t GCAttrMask = 0x18; 487198092Srdivacky static const uint32_t GCAttrShift = 3; 488224145Sdim static const uint32_t LifetimeMask = 0xE0; 489224145Sdim static const uint32_t LifetimeShift = 5; 490224145Sdim static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask); 491224145Sdim static const uint32_t AddressSpaceShift = 8; 492198092Srdivacky}; 493198092Srdivacky 494234353Sdim/// A std::pair-like structure for storing a qualified type split 495234353Sdim/// into its local qualifiers and its locally-unqualified type. 496234353Sdimstruct SplitQualType { 497234353Sdim /// The locally-unqualified type. 498234353Sdim const Type *Ty; 499202879Srdivacky 500234353Sdim /// The local qualifiers. 501234353Sdim Qualifiers Quals; 502234353Sdim 503234353Sdim SplitQualType() : Ty(0), Quals() {} 504234353Sdim SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} 505234353Sdim 506234353Sdim SplitQualType getSingleStepDesugaredType() const; // end of this file 507234353Sdim 508234353Sdim // Make llvm::tie work. 509234353Sdim operator std::pair<const Type *,Qualifiers>() const { 510234353Sdim return std::pair<const Type *,Qualifiers>(Ty, Quals); 511234353Sdim } 512234353Sdim 513234353Sdim friend bool operator==(SplitQualType a, SplitQualType b) { 514234353Sdim return a.Ty == b.Ty && a.Quals == b.Quals; 515234353Sdim } 516234353Sdim friend bool operator!=(SplitQualType a, SplitQualType b) { 517234353Sdim return a.Ty != b.Ty || a.Quals != b.Quals; 518234353Sdim } 519234353Sdim}; 520234353Sdim 521198092Srdivacky/// QualType - For efficiency, we don't store CV-qualified types as nodes on 522198092Srdivacky/// their own: instead each reference to a type stores the qualifiers. This 523198092Srdivacky/// greatly reduces the number of nodes we need to allocate for types (for 524198092Srdivacky/// example we only need one for 'int', 'const int', 'volatile int', 525198092Srdivacky/// 'const volatile int', etc). 526198092Srdivacky/// 527198092Srdivacky/// As an added efficiency bonus, instead of making this a pair, we 528198092Srdivacky/// just store the two bits we care about in the low bits of the 529198092Srdivacky/// pointer. To handle the packing/unpacking, we make QualType be a 530198092Srdivacky/// simple wrapper class that acts like a smart pointer. A third bit 531198092Srdivacky/// indicates whether there are extended qualifiers present, in which 532198092Srdivacky/// case the pointer points to a special structure. 533198092Srdivackyclass QualType { 534198092Srdivacky // Thankfully, these are efficiently composable. 535198092Srdivacky llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>, 536198092Srdivacky Qualifiers::FastWidth> Value; 537198092Srdivacky 538198092Srdivacky const ExtQuals *getExtQualsUnsafe() const { 539198092Srdivacky return Value.getPointer().get<const ExtQuals*>(); 540198092Srdivacky } 541198092Srdivacky 542198092Srdivacky const Type *getTypePtrUnsafe() const { 543198092Srdivacky return Value.getPointer().get<const Type*>(); 544198092Srdivacky } 545198092Srdivacky 546218893Sdim const ExtQualsTypeCommonBase *getCommonPtr() const { 547218893Sdim assert(!isNull() && "Cannot retrieve a NULL type pointer"); 548218893Sdim uintptr_t CommonPtrVal 549218893Sdim = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); 550218893Sdim CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); 551218893Sdim return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); 552218893Sdim } 553218893Sdim 554198092Srdivacky friend class QualifierCollector; 555198092Srdivackypublic: 556193326Sed QualType() {} 557198092Srdivacky 558193326Sed QualType(const Type *Ptr, unsigned Quals) 559198092Srdivacky : Value(Ptr, Quals) {} 560198092Srdivacky QualType(const ExtQuals *Ptr, unsigned Quals) 561198092Srdivacky : Value(Ptr, Quals) {} 562193326Sed 563199482Srdivacky unsigned getLocalFastQualifiers() const { return Value.getInt(); } 564199482Srdivacky void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } 565198092Srdivacky 566198092Srdivacky /// Retrieves a pointer to the underlying (unqualified) type. 567218893Sdim /// 568218893Sdim /// This function requires that the type not be NULL. If the type might be 569218893Sdim /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). 570218893Sdim const Type *getTypePtr() const; 571234353Sdim 572218893Sdim const Type *getTypePtrOrNull() const; 573198092Srdivacky 574226633Sdim /// Retrieves a pointer to the name of the base type. 575226633Sdim const IdentifierInfo *getBaseTypeIdentifier() const; 576226633Sdim 577218893Sdim /// Divides a QualType into its unqualified type and a set of local 578218893Sdim /// qualifiers. 579218893Sdim SplitQualType split() const; 580218893Sdim 581193326Sed void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 582218893Sdim static QualType getFromOpaquePtr(const void *Ptr) { 583193326Sed QualType T; 584218893Sdim T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); 585193326Sed return T; 586193326Sed } 587198092Srdivacky 588218893Sdim const Type &operator*() const { 589193326Sed return *getTypePtr(); 590193326Sed } 591193326Sed 592218893Sdim const Type *operator->() const { 593193326Sed return getTypePtr(); 594193326Sed } 595198092Srdivacky 596198398Srdivacky bool isCanonical() const; 597198398Srdivacky bool isCanonicalAsParam() const; 598198398Srdivacky 599193326Sed /// isNull - Return true if this QualType doesn't point to a type yet. 600193326Sed bool isNull() const { 601198092Srdivacky return Value.getPointer().isNull(); 602193326Sed } 603193326Sed 604234353Sdim /// \brief Determine whether this particular QualType instance has the 605199482Srdivacky /// "const" qualifier set, without looking through typedefs that may have 606199482Srdivacky /// added "const" at a different level. 607199482Srdivacky bool isLocalConstQualified() const { 608199482Srdivacky return (getLocalFastQualifiers() & Qualifiers::Const); 609193326Sed } 610234353Sdim 611199482Srdivacky /// \brief Determine whether this type is const-qualified. 612199482Srdivacky bool isConstQualified() const; 613234353Sdim 614234353Sdim /// \brief Determine whether this particular QualType instance has the 615199482Srdivacky /// "restrict" qualifier set, without looking through typedefs that may have 616199482Srdivacky /// added "restrict" at a different level. 617199482Srdivacky bool isLocalRestrictQualified() const { 618199482Srdivacky return (getLocalFastQualifiers() & Qualifiers::Restrict); 619198092Srdivacky } 620234353Sdim 621199482Srdivacky /// \brief Determine whether this type is restrict-qualified. 622199482Srdivacky bool isRestrictQualified() const; 623234353Sdim 624234353Sdim /// \brief Determine whether this particular QualType instance has the 625199482Srdivacky /// "volatile" qualifier set, without looking through typedefs that may have 626199482Srdivacky /// added "volatile" at a different level. 627199482Srdivacky bool isLocalVolatileQualified() const { 628218893Sdim return (getLocalFastQualifiers() & Qualifiers::Volatile); 629193326Sed } 630198092Srdivacky 631199482Srdivacky /// \brief Determine whether this type is volatile-qualified. 632199482Srdivacky bool isVolatileQualified() const; 633234353Sdim 634199482Srdivacky /// \brief Determine whether this particular QualType instance has any 635234353Sdim /// qualifiers, without looking through any typedefs that might add 636199482Srdivacky /// qualifiers at a different level. 637199482Srdivacky bool hasLocalQualifiers() const { 638199482Srdivacky return getLocalFastQualifiers() || hasLocalNonFastQualifiers(); 639193326Sed } 640193326Sed 641199482Srdivacky /// \brief Determine whether this type has any qualifiers. 642199482Srdivacky bool hasQualifiers() const; 643234353Sdim 644199482Srdivacky /// \brief Determine whether this particular QualType instance has any 645199482Srdivacky /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType 646199482Srdivacky /// instance. 647199482Srdivacky bool hasLocalNonFastQualifiers() const { 648199482Srdivacky return Value.getPointer().is<const ExtQuals*>(); 649198092Srdivacky } 650193326Sed 651199482Srdivacky /// \brief Retrieve the set of qualifiers local to this particular QualType 652199482Srdivacky /// instance, not including any qualifiers acquired through typedefs or 653199482Srdivacky /// other sugar. 654218893Sdim Qualifiers getLocalQualifiers() const; 655193326Sed 656199482Srdivacky /// \brief Retrieve the set of qualifiers applied to this type. 657199482Srdivacky Qualifiers getQualifiers() const; 658234353Sdim 659234353Sdim /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 660199482Srdivacky /// local to this particular QualType instance, not including any qualifiers 661199482Srdivacky /// acquired through typedefs or other sugar. 662199482Srdivacky unsigned getLocalCVRQualifiers() const { 663218893Sdim return getLocalFastQualifiers(); 664193326Sed } 665198092Srdivacky 666234353Sdim /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 667199482Srdivacky /// applied to this type. 668199482Srdivacky unsigned getCVRQualifiers() const; 669201361Srdivacky 670198092Srdivacky bool isConstant(ASTContext& Ctx) const { 671198092Srdivacky return QualType::isConstant(*this, Ctx); 672193326Sed } 673193326Sed 674224145Sdim /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). 675224145Sdim bool isPODType(ASTContext &Context) const; 676224145Sdim 677239462Sdim /// isCXX98PODType() - Return true if this is a POD type according to the 678239462Sdim /// rules of the C++98 standard, regardless of the current compilation's 679239462Sdim /// language. 680239462Sdim bool isCXX98PODType(ASTContext &Context) const; 681239462Sdim 682224145Sdim /// isCXX11PODType() - Return true if this is a POD type according to the 683224145Sdim /// more relaxed rules of the C++11 standard, regardless of the current 684224145Sdim /// compilation's language. 685224145Sdim /// (C++0x [basic.types]p9) 686224145Sdim bool isCXX11PODType(ASTContext &Context) const; 687234353Sdim 688224145Sdim /// isTrivialType - Return true if this is a trivial type 689224145Sdim /// (C++0x [basic.types]p9) 690234353Sdim bool isTrivialType(ASTContext &Context) const; 691224145Sdim 692224145Sdim /// isTriviallyCopyableType - Return true if this is a trivially 693224145Sdim /// copyable type (C++0x [basic.types]p9) 694224145Sdim bool isTriviallyCopyableType(ASTContext &Context) const; 695224145Sdim 696198092Srdivacky // Don't promise in the API that anything besides 'const' can be 697198092Srdivacky // easily added. 698198092Srdivacky 699234353Sdim /// addConst - add the specified type qualifier to this QualType. 700198092Srdivacky void addConst() { 701198092Srdivacky addFastQualifiers(Qualifiers::Const); 702198092Srdivacky } 703198092Srdivacky QualType withConst() const { 704198092Srdivacky return withFastQualifiers(Qualifiers::Const); 705198092Srdivacky } 706198092Srdivacky 707234353Sdim /// addVolatile - add the specified type qualifier to this QualType. 708223017Sdim void addVolatile() { 709223017Sdim addFastQualifiers(Qualifiers::Volatile); 710223017Sdim } 711223017Sdim QualType withVolatile() const { 712223017Sdim return withFastQualifiers(Qualifiers::Volatile); 713223017Sdim } 714234353Sdim 715234353Sdim /// Add the restrict qualifier to this QualType. 716234353Sdim void addRestrict() { 717234353Sdim addFastQualifiers(Qualifiers::Restrict); 718234353Sdim } 719234353Sdim QualType withRestrict() const { 720234353Sdim return withFastQualifiers(Qualifiers::Restrict); 721234353Sdim } 722223017Sdim 723224145Sdim QualType withCVRQualifiers(unsigned CVR) const { 724224145Sdim return withFastQualifiers(CVR); 725224145Sdim } 726224145Sdim 727198092Srdivacky void addFastQualifiers(unsigned TQs) { 728198092Srdivacky assert(!(TQs & ~Qualifiers::FastMask) 729198092Srdivacky && "non-fast qualifier bits set in mask!"); 730198092Srdivacky Value.setInt(Value.getInt() | TQs); 731198092Srdivacky } 732198092Srdivacky 733218893Sdim void removeLocalConst(); 734218893Sdim void removeLocalVolatile(); 735218893Sdim void removeLocalRestrict(); 736218893Sdim void removeLocalCVRQualifiers(unsigned Mask); 737198092Srdivacky 738218893Sdim void removeLocalFastQualifiers() { Value.setInt(0); } 739218893Sdim void removeLocalFastQualifiers(unsigned Mask) { 740198092Srdivacky assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers"); 741198092Srdivacky Value.setInt(Value.getInt() & ~Mask); 742198092Srdivacky } 743198092Srdivacky 744198092Srdivacky // Creates a type with the given qualifiers in addition to any 745198092Srdivacky // qualifiers already on this type. 746198092Srdivacky QualType withFastQualifiers(unsigned TQs) const { 747198092Srdivacky QualType T = *this; 748198092Srdivacky T.addFastQualifiers(TQs); 749198092Srdivacky return T; 750198092Srdivacky } 751198092Srdivacky 752198092Srdivacky // Creates a type with exactly the given fast qualifiers, removing 753198092Srdivacky // any existing fast qualifiers. 754218893Sdim QualType withExactLocalFastQualifiers(unsigned TQs) const { 755218893Sdim return withoutLocalFastQualifiers().withFastQualifiers(TQs); 756198092Srdivacky } 757198092Srdivacky 758198092Srdivacky // Removes fast qualifiers, but leaves any extended qualifiers in place. 759218893Sdim QualType withoutLocalFastQualifiers() const { 760198092Srdivacky QualType T = *this; 761218893Sdim T.removeLocalFastQualifiers(); 762198092Srdivacky return T; 763198092Srdivacky } 764198092Srdivacky 765218893Sdim QualType getCanonicalType() const; 766218893Sdim 767199482Srdivacky /// \brief Return this type with all of the instance-specific qualifiers 768199482Srdivacky /// removed, but without removing any qualifiers that may have been applied 769199482Srdivacky /// through typedefs. 770199482Srdivacky QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } 771198092Srdivacky 772218893Sdim /// \brief Retrieve the unqualified variant of the given type, 773218893Sdim /// removing as little sugar as possible. 774218893Sdim /// 775218893Sdim /// This routine looks through various kinds of sugar to find the 776218893Sdim /// least-desugared type that is unqualified. For example, given: 777218893Sdim /// 778218893Sdim /// \code 779218893Sdim /// typedef int Integer; 780218893Sdim /// typedef const Integer CInteger; 781218893Sdim /// typedef CInteger DifferenceType; 782218893Sdim /// \endcode 783218893Sdim /// 784218893Sdim /// Executing \c getUnqualifiedType() on the type \c DifferenceType will 785218893Sdim /// desugar until we hit the type \c Integer, which has no qualifiers on it. 786218893Sdim /// 787249423Sdim /// The resulting type might still be qualified if it's sugar for an array 788249423Sdim /// type. To strip qualifiers even from within a sugared array type, use 789218893Sdim /// ASTContext::getUnqualifiedArrayType. 790218893Sdim inline QualType getUnqualifiedType() const; 791218893Sdim 792218893Sdim /// getSplitUnqualifiedType - Retrieve the unqualified variant of the 793218893Sdim /// given type, removing as little sugar as possible. 794218893Sdim /// 795218893Sdim /// Like getUnqualifiedType(), but also returns the set of 796218893Sdim /// qualifiers that were built up. 797218893Sdim /// 798249423Sdim /// The resulting type might still be qualified if it's sugar for an array 799249423Sdim /// type. To strip qualifiers even from within a sugared array type, use 800218893Sdim /// ASTContext::getUnqualifiedArrayType. 801218893Sdim inline SplitQualType getSplitUnqualifiedType() const; 802234353Sdim 803221345Sdim /// \brief Determine whether this type is more qualified than the other 804221345Sdim /// given type, requiring exact equality for non-CVR qualifiers. 805193326Sed bool isMoreQualifiedThan(QualType Other) const; 806221345Sdim 807221345Sdim /// \brief Determine whether this type is at least as qualified as the other 808221345Sdim /// given type, requiring exact equality for non-CVR qualifiers. 809193326Sed bool isAtLeastAsQualifiedAs(QualType Other) const; 810234353Sdim 811193326Sed QualType getNonReferenceType() const; 812198092Srdivacky 813210299Sed /// \brief Determine the type of a (typically non-lvalue) expression with the 814210299Sed /// specified result type. 815234353Sdim /// 816210299Sed /// This routine should be used for expressions for which the return type is 817210299Sed /// explicitly specified (e.g., in a cast or call) and isn't necessarily 818234353Sdim /// an lvalue. It removes a top-level reference (since there are no 819210299Sed /// expressions of reference type) and deletes top-level cvr-qualifiers 820210299Sed /// from non-class types (in C++) or all types (in C). 821210299Sed QualType getNonLValueExprType(ASTContext &Context) const; 822234353Sdim 823193326Sed /// getDesugaredType - Return the specified type with any "sugar" removed from 824193326Sed /// the type. This takes off typedefs, typeof's etc. If the outer level of 825193326Sed /// the type is already concrete, it returns it unmodified. This is similar 826193326Sed /// to getting the canonical type, but it doesn't remove *all* typedefs. For 827193326Sed /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is 828193326Sed /// concrete. 829198092Srdivacky /// 830198092Srdivacky /// Qualifiers are left in place. 831218893Sdim QualType getDesugaredType(const ASTContext &Context) const { 832218893Sdim return getDesugaredType(*this, Context); 833198092Srdivacky } 834193326Sed 835218893Sdim SplitQualType getSplitDesugaredType() const { 836218893Sdim return getSplitDesugaredType(*this); 837218893Sdim } 838218893Sdim 839224145Sdim /// \brief Return the specified type with one level of "sugar" removed from 840234353Sdim /// the type. 841224145Sdim /// 842224145Sdim /// This routine takes off the first typedef, typeof, etc. If the outer level 843224145Sdim /// of the type is already concrete, it returns it unmodified. 844234353Sdim QualType getSingleStepDesugaredType(const ASTContext &Context) const { 845234353Sdim return getSingleStepDesugaredTypeImpl(*this, Context); 846234353Sdim } 847234353Sdim 848218893Sdim /// IgnoreParens - Returns the specified type after dropping any 849218893Sdim /// outer-level parentheses. 850218893Sdim QualType IgnoreParens() const { 851218893Sdim if (isa<ParenType>(*this)) 852218893Sdim return QualType::IgnoreParens(*this); 853218893Sdim return *this; 854218893Sdim } 855218893Sdim 856193326Sed /// operator==/!= - Indicate whether the specified types and qualifiers are 857193326Sed /// identical. 858198092Srdivacky friend bool operator==(const QualType &LHS, const QualType &RHS) { 859198092Srdivacky return LHS.Value == RHS.Value; 860193326Sed } 861198092Srdivacky friend bool operator!=(const QualType &LHS, const QualType &RHS) { 862198092Srdivacky return LHS.Value != RHS.Value; 863193326Sed } 864218893Sdim std::string getAsString() const { 865218893Sdim return getAsString(split()); 866218893Sdim } 867218893Sdim static std::string getAsString(SplitQualType split) { 868234353Sdim return getAsString(split.Ty, split.Quals); 869218893Sdim } 870218893Sdim static std::string getAsString(const Type *ty, Qualifiers qs); 871193326Sed 872239462Sdim std::string getAsString(const PrintingPolicy &Policy) const; 873239462Sdim 874239462Sdim void print(raw_ostream &OS, const PrintingPolicy &Policy, 875239462Sdim const Twine &PlaceHolder = Twine()) const { 876239462Sdim print(split(), OS, Policy, PlaceHolder); 877193326Sed } 878239462Sdim static void print(SplitQualType split, raw_ostream &OS, 879239462Sdim const PrintingPolicy &policy, const Twine &PlaceHolder) { 880239462Sdim return print(split.Ty, split.Quals, OS, policy, PlaceHolder); 881239462Sdim } 882239462Sdim static void print(const Type *ty, Qualifiers qs, 883239462Sdim raw_ostream &OS, const PrintingPolicy &policy, 884239462Sdim const Twine &PlaceHolder); 885239462Sdim 886195341Sed void getAsStringInternal(std::string &Str, 887218893Sdim const PrintingPolicy &Policy) const { 888218893Sdim return getAsStringInternal(split(), Str, Policy); 889218893Sdim } 890218893Sdim static void getAsStringInternal(SplitQualType split, std::string &out, 891218893Sdim const PrintingPolicy &policy) { 892234353Sdim return getAsStringInternal(split.Ty, split.Quals, out, policy); 893218893Sdim } 894218893Sdim static void getAsStringInternal(const Type *ty, Qualifiers qs, 895218893Sdim std::string &out, 896218893Sdim const PrintingPolicy &policy); 897198092Srdivacky 898239462Sdim class StreamedQualTypeHelper { 899239462Sdim const QualType &T; 900239462Sdim const PrintingPolicy &Policy; 901239462Sdim const Twine &PlaceHolder; 902239462Sdim public: 903239462Sdim StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, 904239462Sdim const Twine &PlaceHolder) 905239462Sdim : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { } 906239462Sdim 907239462Sdim friend raw_ostream &operator<<(raw_ostream &OS, 908239462Sdim const StreamedQualTypeHelper &SQT) { 909239462Sdim SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder); 910239462Sdim return OS; 911239462Sdim } 912239462Sdim }; 913239462Sdim 914239462Sdim StreamedQualTypeHelper stream(const PrintingPolicy &Policy, 915239462Sdim const Twine &PlaceHolder = Twine()) const { 916239462Sdim return StreamedQualTypeHelper(*this, Policy, PlaceHolder); 917239462Sdim } 918239462Sdim 919193326Sed void dump(const char *s) const; 920193326Sed void dump() const; 921198092Srdivacky 922193326Sed void Profile(llvm::FoldingSetNodeID &ID) const { 923193326Sed ID.AddPointer(getAsOpaquePtr()); 924193326Sed } 925193326Sed 926193326Sed /// getAddressSpace - Return the address space of this type. 927193326Sed inline unsigned getAddressSpace() const; 928198092Srdivacky 929224145Sdim /// getObjCGCAttr - Returns gc attribute of this type. 930198092Srdivacky inline Qualifiers::GC getObjCGCAttr() const; 931193326Sed 932193326Sed /// isObjCGCWeak true when Type is objc's weak. 933193326Sed bool isObjCGCWeak() const { 934198092Srdivacky return getObjCGCAttr() == Qualifiers::Weak; 935193326Sed } 936193326Sed 937193326Sed /// isObjCGCStrong true when Type is objc's strong. 938193326Sed bool isObjCGCStrong() const { 939198092Srdivacky return getObjCGCAttr() == Qualifiers::Strong; 940193326Sed } 941198092Srdivacky 942224145Sdim /// getObjCLifetime - Returns lifetime attribute of this type. 943224145Sdim Qualifiers::ObjCLifetime getObjCLifetime() const { 944224145Sdim return getQualifiers().getObjCLifetime(); 945224145Sdim } 946224145Sdim 947224145Sdim bool hasNonTrivialObjCLifetime() const { 948224145Sdim return getQualifiers().hasNonTrivialObjCLifetime(); 949224145Sdim } 950224145Sdim 951224145Sdim bool hasStrongOrWeakObjCLifetime() const { 952224145Sdim return getQualifiers().hasStrongOrWeakObjCLifetime(); 953224145Sdim } 954224145Sdim 955218893Sdim enum DestructionKind { 956218893Sdim DK_none, 957224145Sdim DK_cxx_destructor, 958224145Sdim DK_objc_strong_lifetime, 959224145Sdim DK_objc_weak_lifetime 960218893Sdim }; 961218893Sdim 962218893Sdim /// isDestructedType - nonzero if objects of this type require 963218893Sdim /// non-trivial work to clean up after. Non-zero because it's 964218893Sdim /// conceivable that qualifiers (objc_gc(weak)?) could make 965218893Sdim /// something require destruction. 966218893Sdim DestructionKind isDestructedType() const { 967218893Sdim return isDestructedTypeImpl(*this); 968218893Sdim } 969218893Sdim 970234353Sdim /// \brief Determine whether expressions of the given type are forbidden 971224145Sdim /// from being lvalues in C. 972224145Sdim /// 973224145Sdim /// The expression types that are forbidden to be lvalues are: 974224145Sdim /// - 'void', but not qualified void 975224145Sdim /// - function types 976224145Sdim /// 977224145Sdim /// The exact rule here is C99 6.3.2.1: 978224145Sdim /// An lvalue is an expression with an object type or an incomplete 979224145Sdim /// type other than void. 980224145Sdim bool isCForbiddenLValueType() const; 981224145Sdim 982198092Srdivackyprivate: 983198092Srdivacky // These methods are implemented in a separate translation unit; 984198092Srdivacky // "static"-ize them to avoid creating temporary QualTypes in the 985198092Srdivacky // caller. 986198092Srdivacky static bool isConstant(QualType T, ASTContext& Ctx); 987218893Sdim static QualType getDesugaredType(QualType T, const ASTContext &Context); 988218893Sdim static SplitQualType getSplitDesugaredType(QualType T); 989218893Sdim static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); 990234353Sdim static QualType getSingleStepDesugaredTypeImpl(QualType type, 991234353Sdim const ASTContext &C); 992218893Sdim static QualType IgnoreParens(QualType T); 993218893Sdim static DestructionKind isDestructedTypeImpl(QualType type); 994193326Sed}; 995193326Sed 996193326Sed} // end clang. 997193326Sed 998193326Sednamespace llvm { 999193326Sed/// Implement simplify_type for QualType, so that we can dyn_cast from QualType 1000193326Sed/// to a specific Type class. 1001249423Sdimtemplate<> struct simplify_type< ::clang::QualType> { 1002218893Sdim typedef const ::clang::Type *SimpleType; 1003249423Sdim static SimpleType getSimplifiedValue(::clang::QualType Val) { 1004193326Sed return Val.getTypePtr(); 1005193326Sed } 1006193326Sed}; 1007198092Srdivacky 1008193326Sed// Teach SmallPtrSet that QualType is "basically a pointer". 1009193326Sedtemplate<> 1010193326Sedclass PointerLikeTypeTraits<clang::QualType> { 1011193326Sedpublic: 1012193326Sed static inline void *getAsVoidPointer(clang::QualType P) { 1013193326Sed return P.getAsOpaquePtr(); 1014193326Sed } 1015193326Sed static inline clang::QualType getFromVoidPointer(void *P) { 1016193326Sed return clang::QualType::getFromOpaquePtr(P); 1017193326Sed } 1018198092Srdivacky // Various qualifiers go in low bits. 1019193326Sed enum { NumLowBitsAvailable = 0 }; 1020193326Sed}; 1021198092Srdivacky 1022193326Sed} // end namespace llvm 1023193326Sed 1024193326Sednamespace clang { 1025193326Sed 1026234353Sdim/// \brief Base class that is common to both the \c ExtQuals and \c Type 1027218893Sdim/// classes, which allows \c QualType to access the common fields between the 1028218893Sdim/// two. 1029218893Sdim/// 1030218893Sdimclass ExtQualsTypeCommonBase { 1031218893Sdim ExtQualsTypeCommonBase(const Type *baseType, QualType canon) 1032218893Sdim : BaseType(baseType), CanonicalType(canon) {} 1033218893Sdim 1034218893Sdim /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or 1035218893Sdim /// a self-referential pointer (for \c Type). 1036218893Sdim /// 1037234353Sdim /// This pointer allows an efficient mapping from a QualType to its 1038218893Sdim /// underlying type pointer. 1039218893Sdim const Type *const BaseType; 1040218893Sdim 1041218893Sdim /// \brief The canonical type of this type. A QualType. 1042218893Sdim QualType CanonicalType; 1043218893Sdim 1044218893Sdim friend class QualType; 1045218893Sdim friend class Type; 1046218893Sdim friend class ExtQuals; 1047218893Sdim}; 1048234353Sdim 1049218893Sdim/// ExtQuals - We can encode up to four bits in the low bits of a 1050218893Sdim/// type pointer, but there are many more type qualifiers that we want 1051218893Sdim/// to be able to apply to an arbitrary type. Therefore we have this 1052218893Sdim/// struct, intended to be heap-allocated and used by QualType to 1053218893Sdim/// store qualifiers. 1054218893Sdim/// 1055234353Sdim/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers 1056218893Sdim/// in three low bits on the QualType pointer; a fourth bit records whether 1057218893Sdim/// the pointer is an ExtQuals node. The extended qualifiers (address spaces, 1058218893Sdim/// Objective-C GC attributes) are much more rare. 1059218893Sdimclass ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { 1060218893Sdim // NOTE: changing the fast qualifiers should be straightforward as 1061218893Sdim // long as you don't make 'const' non-fast. 1062218893Sdim // 1. Qualifiers: 1063218893Sdim // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). 1064218893Sdim // Fast qualifiers must occupy the low-order bits. 1065218893Sdim // b) Update Qualifiers::FastWidth and FastMask. 1066218893Sdim // 2. QualType: 1067218893Sdim // a) Update is{Volatile,Restrict}Qualified(), defined inline. 1068218893Sdim // b) Update remove{Volatile,Restrict}, defined near the end of 1069218893Sdim // this header. 1070218893Sdim // 3. ASTContext: 1071218893Sdim // a) Update get{Volatile,Restrict}Type. 1072218893Sdim 1073218893Sdim /// Quals - the immutable set of qualifiers applied by this 1074218893Sdim /// node; always contains extended qualifiers. 1075218893Sdim Qualifiers Quals; 1076218893Sdim 1077218893Sdim ExtQuals *this_() { return this; } 1078218893Sdim 1079218893Sdimpublic: 1080234353Sdim ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) 1081218893Sdim : ExtQualsTypeCommonBase(baseType, 1082218893Sdim canon.isNull() ? QualType(this_(), 0) : canon), 1083218893Sdim Quals(quals) 1084218893Sdim { 1085218893Sdim assert(Quals.hasNonFastQualifiers() 1086218893Sdim && "ExtQuals created with no fast qualifiers"); 1087218893Sdim assert(!Quals.hasFastQualifiers() 1088218893Sdim && "ExtQuals created with fast qualifiers"); 1089218893Sdim } 1090218893Sdim 1091218893Sdim Qualifiers getQualifiers() const { return Quals; } 1092218893Sdim 1093218893Sdim bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } 1094218893Sdim Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } 1095218893Sdim 1096224145Sdim bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } 1097224145Sdim Qualifiers::ObjCLifetime getObjCLifetime() const { 1098224145Sdim return Quals.getObjCLifetime(); 1099224145Sdim } 1100224145Sdim 1101218893Sdim bool hasAddressSpace() const { return Quals.hasAddressSpace(); } 1102218893Sdim unsigned getAddressSpace() const { return Quals.getAddressSpace(); } 1103218893Sdim 1104218893Sdim const Type *getBaseType() const { return BaseType; } 1105218893Sdim 1106218893Sdimpublic: 1107218893Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 1108218893Sdim Profile(ID, getBaseType(), Quals); 1109218893Sdim } 1110218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, 1111218893Sdim const Type *BaseType, 1112218893Sdim Qualifiers Quals) { 1113218893Sdim assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!"); 1114218893Sdim ID.AddPointer(BaseType); 1115218893Sdim Quals.Profile(ID); 1116218893Sdim } 1117218893Sdim}; 1118218893Sdim 1119234353Sdim/// \brief The kind of C++0x ref-qualifier associated with a function type, 1120234353Sdim/// which determines whether a member function's "this" object can be an 1121218893Sdim/// lvalue, rvalue, or neither. 1122218893Sdimenum RefQualifierKind { 1123218893Sdim /// \brief No ref-qualifier was provided. 1124218893Sdim RQ_None = 0, 1125218893Sdim /// \brief An lvalue ref-qualifier was provided (\c &). 1126218893Sdim RQ_LValue, 1127218893Sdim /// \brief An rvalue ref-qualifier was provided (\c &&). 1128218893Sdim RQ_RValue 1129218893Sdim}; 1130234353Sdim 1131193326Sed/// Type - This is the base class of the type hierarchy. A central concept 1132193326Sed/// with types is that each type always has a canonical type. A canonical type 1133193326Sed/// is the type with any typedef names stripped out of it or the types it 1134193326Sed/// references. For example, consider: 1135193326Sed/// 1136193326Sed/// typedef int foo; 1137193326Sed/// typedef foo* bar; 1138193326Sed/// 'int *' 'foo *' 'bar' 1139193326Sed/// 1140193326Sed/// There will be a Type object created for 'int'. Since int is canonical, its 1141193326Sed/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a 1142193326Sed/// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next 1143193326Sed/// there is a PointerType that represents 'int*', which, like 'int', is 1144193326Sed/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical 1145193326Sed/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type 1146193326Sed/// is also 'int*'. 1147193326Sed/// 1148193326Sed/// Non-canonical types are useful for emitting diagnostics, without losing 1149193326Sed/// information about typedefs being used. Canonical types are useful for type 1150193326Sed/// comparisons (they allow by-pointer equality tests) and useful for reasoning 1151193326Sed/// about whether something has a particular form (e.g. is a function type), 1152193326Sed/// because they implicitly, recursively, strip all typedefs out of a type. 1153193326Sed/// 1154193326Sed/// Types, once created, are immutable. 1155193326Sed/// 1156218893Sdimclass Type : public ExtQualsTypeCommonBase { 1157193326Sedpublic: 1158193326Sed enum TypeClass { 1159193326Sed#define TYPE(Class, Base) Class, 1160203955Srdivacky#define LAST_TYPE(Class) TypeLast = Class, 1161193326Sed#define ABSTRACT_TYPE(Class, Base) 1162193326Sed#include "clang/AST/TypeNodes.def" 1163193326Sed TagFirst = Record, TagLast = Enum 1164193326Sed }; 1165198092Srdivacky 1166193326Sedprivate: 1167243830Sdim Type(const Type &) LLVM_DELETED_FUNCTION; 1168243830Sdim void operator=(const Type &) LLVM_DELETED_FUNCTION; 1169208600Srdivacky 1170218893Sdim /// Bitfields required by the Type class. 1171218893Sdim class TypeBitfields { 1172218893Sdim friend class Type; 1173218893Sdim template <class T> friend class TypePropertyCache; 1174193326Sed 1175218893Sdim /// TypeClass bitfield - Enum that specifies what subclass this belongs to. 1176218893Sdim unsigned TC : 8; 1177203955Srdivacky 1178218893Sdim /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]). 1179218893Sdim unsigned Dependent : 1; 1180234353Sdim 1181234353Sdim /// \brief Whether this type somehow involves a template parameter, even 1182224145Sdim /// if the resolution of the type does not depend on a template parameter. 1183224145Sdim unsigned InstantiationDependent : 1; 1184234353Sdim 1185218893Sdim /// \brief Whether this type is a variably-modified type (C99 6.7.5). 1186218893Sdim unsigned VariablyModified : 1; 1187218893Sdim 1188218893Sdim /// \brief Whether this type contains an unexpanded parameter pack 1189218893Sdim /// (for C++0x variadic templates). 1190218893Sdim unsigned ContainsUnexpandedParameterPack : 1; 1191234353Sdim 1192249423Sdim /// \brief True if the cache (i.e. the bitfields here starting with 1193249423Sdim /// 'Cache') is valid. 1194249423Sdim mutable unsigned CacheValid : 1; 1195234353Sdim 1196218893Sdim /// \brief Linkage of this type. 1197218893Sdim mutable unsigned CachedLinkage : 2; 1198210299Sed 1199234353Sdim /// \brief Whether this type involves and local or unnamed types. 1200218893Sdim mutable unsigned CachedLocalOrUnnamed : 1; 1201234353Sdim 1202218893Sdim /// \brief FromAST - Whether this type comes from an AST file. 1203218893Sdim mutable unsigned FromAST : 1; 1204210299Sed 1205218893Sdim bool isCacheValid() const { 1206249423Sdim return CacheValid; 1207218893Sdim } 1208218893Sdim Linkage getLinkage() const { 1209218893Sdim assert(isCacheValid() && "getting linkage from invalid cache"); 1210218893Sdim return static_cast<Linkage>(CachedLinkage); 1211218893Sdim } 1212218893Sdim bool hasLocalOrUnnamedType() const { 1213218893Sdim assert(isCacheValid() && "getting linkage from invalid cache"); 1214218893Sdim return CachedLocalOrUnnamed; 1215218893Sdim } 1216218893Sdim }; 1217234353Sdim enum { NumTypeBits = 19 }; 1218218893Sdim 1219218893Sdimprotected: 1220218893Sdim // These classes allow subclasses to somewhat cleanly pack bitfields 1221218893Sdim // into Type. 1222218893Sdim 1223218893Sdim class ArrayTypeBitfields { 1224218893Sdim friend class ArrayType; 1225218893Sdim 1226218893Sdim unsigned : NumTypeBits; 1227218893Sdim 1228218893Sdim /// IndexTypeQuals - CVR qualifiers from declarations like 1229218893Sdim /// 'int X[static restrict 4]'. For function parameters only. 1230218893Sdim unsigned IndexTypeQuals : 3; 1231218893Sdim 1232218893Sdim /// SizeModifier - storage class qualifiers from declarations like 1233218893Sdim /// 'int X[static restrict 4]'. For function parameters only. 1234218893Sdim /// Actually an ArrayType::ArraySizeModifier. 1235218893Sdim unsigned SizeModifier : 3; 1236218893Sdim }; 1237218893Sdim 1238218893Sdim class BuiltinTypeBitfields { 1239218893Sdim friend class BuiltinType; 1240218893Sdim 1241218893Sdim unsigned : NumTypeBits; 1242218893Sdim 1243218893Sdim /// The kind (BuiltinType::Kind) of builtin type this is. 1244218893Sdim unsigned Kind : 8; 1245218893Sdim }; 1246218893Sdim 1247218893Sdim class FunctionTypeBitfields { 1248218893Sdim friend class FunctionType; 1249218893Sdim 1250218893Sdim unsigned : NumTypeBits; 1251218893Sdim 1252218893Sdim /// Extra information which affects how the function is called, like 1253218893Sdim /// regparm and the calling convention. 1254243830Sdim unsigned ExtInfo : 9; 1255218893Sdim 1256218893Sdim /// TypeQuals - Used only by FunctionProtoType, put here to pack with the 1257218893Sdim /// other bitfields. 1258218893Sdim /// The qualifiers are part of FunctionProtoType because... 1259218893Sdim /// 1260218893Sdim /// C++ 8.3.5p4: The return type, the parameter type list and the 1261218893Sdim /// cv-qualifier-seq, [...], are part of the function type. 1262218893Sdim unsigned TypeQuals : 3; 1263218893Sdim }; 1264218893Sdim 1265218893Sdim class ObjCObjectTypeBitfields { 1266218893Sdim friend class ObjCObjectType; 1267218893Sdim 1268218893Sdim unsigned : NumTypeBits; 1269218893Sdim 1270218893Sdim /// NumProtocols - The number of protocols stored directly on this 1271218893Sdim /// object type. 1272218893Sdim unsigned NumProtocols : 32 - NumTypeBits; 1273218893Sdim }; 1274218893Sdim 1275218893Sdim class ReferenceTypeBitfields { 1276218893Sdim friend class ReferenceType; 1277218893Sdim 1278218893Sdim unsigned : NumTypeBits; 1279218893Sdim 1280218893Sdim /// True if the type was originally spelled with an lvalue sigil. 1281218893Sdim /// This is never true of rvalue references but can also be false 1282218893Sdim /// on lvalue references because of C++0x [dcl.typedef]p9, 1283218893Sdim /// as follows: 1284218893Sdim /// 1285218893Sdim /// typedef int &ref; // lvalue, spelled lvalue 1286218893Sdim /// typedef int &&rvref; // rvalue 1287218893Sdim /// ref &a; // lvalue, inner ref, spelled lvalue 1288218893Sdim /// ref &&a; // lvalue, inner ref 1289218893Sdim /// rvref &a; // lvalue, inner ref, spelled lvalue 1290218893Sdim /// rvref &&a; // rvalue, inner ref 1291218893Sdim unsigned SpelledAsLValue : 1; 1292218893Sdim 1293218893Sdim /// True if the inner type is a reference type. This only happens 1294218893Sdim /// in non-canonical forms. 1295218893Sdim unsigned InnerRef : 1; 1296218893Sdim }; 1297218893Sdim 1298218893Sdim class TypeWithKeywordBitfields { 1299218893Sdim friend class TypeWithKeyword; 1300218893Sdim 1301218893Sdim unsigned : NumTypeBits; 1302218893Sdim 1303218893Sdim /// An ElaboratedTypeKeyword. 8 bits for efficient access. 1304218893Sdim unsigned Keyword : 8; 1305218893Sdim }; 1306218893Sdim 1307218893Sdim class VectorTypeBitfields { 1308218893Sdim friend class VectorType; 1309218893Sdim 1310218893Sdim unsigned : NumTypeBits; 1311218893Sdim 1312218893Sdim /// VecKind - The kind of vector, either a generic vector type or some 1313218893Sdim /// target-specific vector type such as for AltiVec or Neon. 1314218893Sdim unsigned VecKind : 3; 1315218893Sdim 1316218893Sdim /// NumElements - The number of elements in the vector. 1317218893Sdim unsigned NumElements : 29 - NumTypeBits; 1318218893Sdim }; 1319218893Sdim 1320218893Sdim class AttributedTypeBitfields { 1321218893Sdim friend class AttributedType; 1322218893Sdim 1323218893Sdim unsigned : NumTypeBits; 1324218893Sdim 1325218893Sdim /// AttrKind - an AttributedType::Kind 1326218893Sdim unsigned AttrKind : 32 - NumTypeBits; 1327218893Sdim }; 1328218893Sdim 1329251662Sdim class AutoTypeBitfields { 1330251662Sdim friend class AutoType; 1331251662Sdim 1332251662Sdim unsigned : NumTypeBits; 1333251662Sdim 1334251662Sdim /// Was this placeholder type spelled as 'decltype(auto)'? 1335251662Sdim unsigned IsDecltypeAuto : 1; 1336251662Sdim }; 1337251662Sdim 1338218893Sdim union { 1339218893Sdim TypeBitfields TypeBits; 1340218893Sdim ArrayTypeBitfields ArrayTypeBits; 1341218893Sdim AttributedTypeBitfields AttributedTypeBits; 1342251662Sdim AutoTypeBitfields AutoTypeBits; 1343218893Sdim BuiltinTypeBitfields BuiltinTypeBits; 1344218893Sdim FunctionTypeBitfields FunctionTypeBits; 1345218893Sdim ObjCObjectTypeBitfields ObjCObjectTypeBits; 1346218893Sdim ReferenceTypeBitfields ReferenceTypeBits; 1347218893Sdim TypeWithKeywordBitfields TypeWithKeywordBits; 1348218893Sdim VectorTypeBitfields VectorTypeBits; 1349218893Sdim }; 1350218893Sdim 1351218893Sdimprivate: 1352212904Sdim /// \brief Set whether this type comes from an AST file. 1353234353Sdim void setFromAST(bool V = true) const { 1354218893Sdim TypeBits.FromAST = V; 1355210299Sed } 1356210299Sed 1357218893Sdim template <class T> friend class TypePropertyCache; 1358218893Sdim 1359208600Srdivackyprotected: 1360193326Sed // silence VC++ warning C4355: 'this' : used in base member initializer list 1361193326Sed Type *this_() { return this; } 1362234353Sdim Type(TypeClass tc, QualType canon, bool Dependent, 1363224145Sdim bool InstantiationDependent, bool VariablyModified, 1364218893Sdim bool ContainsUnexpandedParameterPack) 1365218893Sdim : ExtQualsTypeCommonBase(this, 1366218893Sdim canon.isNull() ? QualType(this_(), 0) : canon) { 1367218893Sdim TypeBits.TC = tc; 1368218893Sdim TypeBits.Dependent = Dependent; 1369224145Sdim TypeBits.InstantiationDependent = Dependent || InstantiationDependent; 1370218893Sdim TypeBits.VariablyModified = VariablyModified; 1371218893Sdim TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; 1372249423Sdim TypeBits.CacheValid = false; 1373218893Sdim TypeBits.CachedLocalOrUnnamed = false; 1374218893Sdim TypeBits.CachedLinkage = NoLinkage; 1375218893Sdim TypeBits.FromAST = false; 1376218893Sdim } 1377193326Sed friend class ASTContext; 1378198092Srdivacky 1379234353Sdim void setDependent(bool D = true) { 1380234353Sdim TypeBits.Dependent = D; 1381224145Sdim if (D) 1382224145Sdim TypeBits.InstantiationDependent = true; 1383224145Sdim } 1384234353Sdim void setInstantiationDependent(bool D = true) { 1385224145Sdim TypeBits.InstantiationDependent = D; } 1386234353Sdim void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; 1387224145Sdim } 1388218893Sdim void setContainsUnexpandedParameterPack(bool PP = true) { 1389218893Sdim TypeBits.ContainsUnexpandedParameterPack = PP; 1390218893Sdim } 1391218893Sdim 1392193326Sedpublic: 1393218893Sdim TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } 1394198092Srdivacky 1395212904Sdim /// \brief Whether this type comes from an AST file. 1396218893Sdim bool isFromAST() const { return TypeBits.FromAST; } 1397210299Sed 1398218893Sdim /// \brief Whether this type is or contains an unexpanded parameter 1399218893Sdim /// pack, used to support C++0x variadic templates. 1400218893Sdim /// 1401218893Sdim /// A type that contains a parameter pack shall be expanded by the 1402218893Sdim /// ellipsis operator at some point. For example, the typedef in the 1403218893Sdim /// following example contains an unexpanded parameter pack 'T': 1404218893Sdim /// 1405218893Sdim /// \code 1406218893Sdim /// template<typename ...T> 1407218893Sdim /// struct X { 1408218893Sdim /// typedef T* pointer_types; // ill-formed; T is a parameter pack. 1409218893Sdim /// }; 1410218893Sdim /// \endcode 1411218893Sdim /// 1412234353Sdim /// Note that this routine does not specify which 1413234353Sdim bool containsUnexpandedParameterPack() const { 1414218893Sdim return TypeBits.ContainsUnexpandedParameterPack; 1415218893Sdim } 1416218893Sdim 1417218893Sdim /// Determines if this type would be canonical if it had no further 1418218893Sdim /// qualification. 1419198398Srdivacky bool isCanonicalUnqualified() const { 1420218893Sdim return CanonicalType == QualType(this, 0); 1421198398Srdivacky } 1422193326Sed 1423234353Sdim /// Pull a single level of sugar off of this locally-unqualified type. 1424234353Sdim /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() 1425234353Sdim /// or QualType::getSingleStepDesugaredType(const ASTContext&). 1426234353Sdim QualType getLocallyUnqualifiedSingleStepDesugaredType() const; 1427234353Sdim 1428198092Srdivacky /// Types are partitioned into 3 broad categories (C99 6.2.5p1): 1429193326Sed /// object types, function types, and incomplete types. 1430198092Srdivacky 1431193326Sed /// isIncompleteType - Return true if this is an incomplete type. 1432193326Sed /// A type that can describe objects, but which lacks information needed to 1433193326Sed /// determine its size (e.g. void, or a fwd declared struct). Clients of this 1434198092Srdivacky /// routine will need to determine if the size is actually required. 1435234353Sdim /// 1436234353Sdim /// \brief Def If non-NULL, and the type refers to some kind of declaration 1437234353Sdim /// that can be completed (such as a C struct, C++ class, or Objective-C 1438234353Sdim /// class), will be set to the declaration. 1439234353Sdim bool isIncompleteType(NamedDecl **Def = 0) const; 1440193326Sed 1441193326Sed /// isIncompleteOrObjectType - Return true if this is an incomplete or object 1442193326Sed /// type, in other words, not a function type. 1443193326Sed bool isIncompleteOrObjectType() const { 1444193326Sed return !isFunctionType(); 1445193326Sed } 1446234353Sdim 1447218893Sdim /// \brief Determine whether this type is an object type. 1448218893Sdim bool isObjectType() const { 1449218893Sdim // C++ [basic.types]p8: 1450234353Sdim // An object type is a (possibly cv-qualified) type that is not a 1451218893Sdim // function type, not a reference type, and not a void type. 1452218893Sdim return !isReferenceType() && !isFunctionType() && !isVoidType(); 1453218893Sdim } 1454193326Sed 1455200583Srdivacky /// isLiteralType - Return true if this is a literal type 1456251662Sdim /// (C++11 [basic.types]p10) 1457251662Sdim bool isLiteralType(ASTContext &Ctx) const; 1458200583Srdivacky 1459221345Sdim /// \brief Test if this type is a standard-layout type. 1460221345Sdim /// (C++0x [basic.type]p9) 1461221345Sdim bool isStandardLayoutType() const; 1462221345Sdim 1463193326Sed /// Helper methods to distinguish type categories. All type predicates 1464193326Sed /// operate on the canonical type, ignoring typedefs and qualifiers. 1465193326Sed 1466210299Sed /// isBuiltinType - returns true if the type is a builtin type. 1467210299Sed bool isBuiltinType() const; 1468210299Sed 1469193326Sed /// isSpecificBuiltinType - Test for a particular builtin type. 1470193326Sed bool isSpecificBuiltinType(unsigned K) const; 1471198092Srdivacky 1472218893Sdim /// isPlaceholderType - Test for a type which does not represent an 1473218893Sdim /// actual type-system type but is instead used as a placeholder for 1474218893Sdim /// various convenient purposes within Clang. All such types are 1475218893Sdim /// BuiltinTypes. 1476218893Sdim bool isPlaceholderType() const; 1477226633Sdim const BuiltinType *getAsPlaceholderType() const; 1478218893Sdim 1479221345Sdim /// isSpecificPlaceholderType - Test for a specific placeholder type. 1480221345Sdim bool isSpecificPlaceholderType(unsigned K) const; 1481221345Sdim 1482234353Sdim /// isNonOverloadPlaceholderType - Test for a placeholder type 1483234353Sdim /// other than Overload; see BuiltinType::isNonOverloadPlaceholderType. 1484234353Sdim bool isNonOverloadPlaceholderType() const; 1485234353Sdim 1486193326Sed /// isIntegerType() does *not* include complex integers (a GCC extension). 1487193326Sed /// isComplexIntegerType() can be used to test for complex integers. 1488193326Sed bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) 1489193326Sed bool isEnumeralType() const; 1490193326Sed bool isBooleanType() const; 1491193326Sed bool isCharType() const; 1492193326Sed bool isWideCharType() const; 1493226633Sdim bool isChar16Type() const; 1494226633Sdim bool isChar32Type() const; 1495200583Srdivacky bool isAnyCharacterType() const; 1496210299Sed bool isIntegralType(ASTContext &Ctx) const; 1497234353Sdim 1498210299Sed /// \brief Determine whether this type is an integral or enumeration type. 1499210299Sed bool isIntegralOrEnumerationType() const; 1500218893Sdim /// \brief Determine whether this type is an integral or unscoped enumeration 1501218893Sdim /// type. 1502218893Sdim bool isIntegralOrUnscopedEnumerationType() const; 1503234353Sdim 1504193326Sed /// Floating point categories. 1505193326Sed bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) 1506193326Sed /// isComplexType() does *not* include complex integers (a GCC extension). 1507193326Sed /// isComplexIntegerType() can be used to test for complex integers. 1508193326Sed bool isComplexType() const; // C99 6.2.5p11 (complex) 1509193326Sed bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. 1510193326Sed bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) 1511226633Sdim bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) 1512193326Sed bool isRealType() const; // C99 6.2.5p17 (real floating + integer) 1513193326Sed bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) 1514193326Sed bool isVoidType() const; // C99 6.2.5p19 1515193326Sed bool isDerivedType() const; // C99 6.2.5p20 1516193326Sed bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) 1517193326Sed bool isAggregateType() const; 1518221345Sdim bool isFundamentalType() const; 1519221345Sdim bool isCompoundType() const; 1520198092Srdivacky 1521193326Sed // Type Predicates: Check to see if this type is structurally the specified 1522193326Sed // type, ignoring typedefs and qualifiers. 1523193326Sed bool isFunctionType() const; 1524198092Srdivacky bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } 1525198092Srdivacky bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } 1526193326Sed bool isPointerType() const; 1527198092Srdivacky bool isAnyPointerType() const; // Any C pointer or ObjC object pointer 1528193326Sed bool isBlockPointerType() const; 1529195341Sed bool isVoidPointerType() const; 1530193326Sed bool isReferenceType() const; 1531193326Sed bool isLValueReferenceType() const; 1532193326Sed bool isRValueReferenceType() const; 1533193326Sed bool isFunctionPointerType() const; 1534193326Sed bool isMemberPointerType() const; 1535193326Sed bool isMemberFunctionPointerType() const; 1536212904Sdim bool isMemberDataPointerType() const; 1537193326Sed bool isArrayType() const; 1538193326Sed bool isConstantArrayType() const; 1539193326Sed bool isIncompleteArrayType() const; 1540193326Sed bool isVariableArrayType() const; 1541193326Sed bool isDependentSizedArrayType() const; 1542193326Sed bool isRecordType() const; 1543198092Srdivacky bool isClassType() const; 1544198092Srdivacky bool isStructureType() const; 1545243830Sdim bool isInterfaceType() const; 1546207619Srdivacky bool isStructureOrClassType() const; 1547193326Sed bool isUnionType() const; 1548193326Sed bool isComplexIntegerType() const; // GCC _Complex integer type. 1549193326Sed bool isVectorType() const; // GCC vector type. 1550193326Sed bool isExtVectorType() const; // Extended vector type. 1551224145Sdim bool isObjCObjectPointerType() const; // pointer to ObjC object 1552224145Sdim bool isObjCRetainableType() const; // ObjC object or block pointer 1553224145Sdim bool isObjCLifetimeType() const; // (array of)* retainable type 1554224145Sdim bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type 1555224145Sdim bool isObjCNSObjectType() const; // __attribute__((NSObject)) 1556198092Srdivacky // FIXME: change this to 'raw' interface type, so we can used 'interface' type 1557198092Srdivacky // for the common case. 1558208600Srdivacky bool isObjCObjectType() const; // NSString or typeof(*(id)0) 1559193326Sed bool isObjCQualifiedInterfaceType() const; // NSString<foo> 1560193326Sed bool isObjCQualifiedIdType() const; // id<foo> 1561198092Srdivacky bool isObjCQualifiedClassType() const; // Class<foo> 1562212904Sdim bool isObjCObjectOrInterfaceType() const; 1563198092Srdivacky bool isObjCIdType() const; // id 1564198092Srdivacky bool isObjCClassType() const; // Class 1565199990Srdivacky bool isObjCSelType() const; // Class 1566198092Srdivacky bool isObjCBuiltinType() const; // 'id' or 'Class' 1567224145Sdim bool isObjCARCBridgableType() const; 1568224145Sdim bool isCARCBridgableType() const; 1569193326Sed bool isTemplateTypeParmType() const; // C++ template type parameter 1570193326Sed bool isNullPtrType() const; // C++0x nullptr_t 1571234353Sdim bool isAtomicType() const; // C11 _Atomic() 1572193326Sed 1573249423Sdim bool isImage1dT() const; // OpenCL image1d_t 1574249423Sdim bool isImage1dArrayT() const; // OpenCL image1d_array_t 1575249423Sdim bool isImage1dBufferT() const; // OpenCL image1d_buffer_t 1576249423Sdim bool isImage2dT() const; // OpenCL image2d_t 1577249423Sdim bool isImage2dArrayT() const; // OpenCL image2d_array_t 1578249423Sdim bool isImage3dT() const; // OpenCL image3d_t 1579249423Sdim 1580249423Sdim bool isImageType() const; // Any OpenCL image type 1581249423Sdim 1582249423Sdim bool isSamplerT() const; // OpenCL sampler_t 1583249423Sdim bool isEventT() const; // OpenCL event_t 1584249423Sdim 1585249423Sdim bool isOpenCLSpecificType() const; // Any OpenCL specific type 1586249423Sdim 1587224145Sdim /// Determines if this type, which must satisfy 1588224145Sdim /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather 1589224145Sdim /// than implicitly __strong. 1590224145Sdim bool isObjCARCImplicitlyUnretainedType() const; 1591224145Sdim 1592224145Sdim /// Return the implicit lifetime for this type, which must not be dependent. 1593224145Sdim Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; 1594224145Sdim 1595218893Sdim enum ScalarTypeKind { 1596226633Sdim STK_CPointer, 1597226633Sdim STK_BlockPointer, 1598226633Sdim STK_ObjCObjectPointer, 1599218893Sdim STK_MemberPointer, 1600218893Sdim STK_Bool, 1601218893Sdim STK_Integral, 1602218893Sdim STK_Floating, 1603218893Sdim STK_IntegralComplex, 1604218893Sdim STK_FloatingComplex 1605218893Sdim }; 1606218893Sdim /// getScalarTypeKind - Given that this is a scalar type, classify it. 1607218893Sdim ScalarTypeKind getScalarTypeKind() const; 1608218893Sdim 1609193326Sed /// isDependentType - Whether this type is a dependent type, meaning 1610198092Srdivacky /// that its definition somehow depends on a template parameter 1611193326Sed /// (C++ [temp.dep.type]). 1612218893Sdim bool isDependentType() const { return TypeBits.Dependent; } 1613234353Sdim 1614224145Sdim /// \brief Determine whether this type is an instantiation-dependent type, 1615224145Sdim /// meaning that the type involves a template parameter (even if the 1616224145Sdim /// definition does not actually depend on the type substituted for that 1617224145Sdim /// template parameter). 1618234353Sdim bool isInstantiationDependentType() const { 1619234353Sdim return TypeBits.InstantiationDependent; 1620224145Sdim } 1621234353Sdim 1622251662Sdim /// \brief Determine whether this type is an undeduced type, meaning that 1623251662Sdim /// it somehow involves a C++11 'auto' type which has not yet been deduced. 1624251662Sdim bool isUndeducedType() const; 1625251662Sdim 1626218893Sdim /// \brief Whether this type is a variably-modified type (C99 6.7.5). 1627218893Sdim bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } 1628218893Sdim 1629218893Sdim /// \brief Whether this type involves a variable-length array type 1630218893Sdim /// with a definite size. 1631218893Sdim bool hasSizedVLAType() const; 1632234353Sdim 1633218893Sdim /// \brief Whether this type is or contains a local or unnamed type. 1634218893Sdim bool hasUnnamedOrLocalType() const; 1635234353Sdim 1636193326Sed bool isOverloadableType() const; 1637193326Sed 1638206084Srdivacky /// \brief Determine wither this type is a C++ elaborated-type-specifier. 1639206084Srdivacky bool isElaboratedTypeSpecifier() const; 1640224145Sdim 1641224145Sdim bool canDecayToPointerType() const; 1642234353Sdim 1643193326Sed /// hasPointerRepresentation - Whether this type is represented 1644193326Sed /// natively as a pointer; this includes pointers, references, block 1645193326Sed /// pointers, and Objective-C interface, qualified id, and qualified 1646193326Sed /// interface types, as well as nullptr_t. 1647193326Sed bool hasPointerRepresentation() const; 1648193326Sed 1649193326Sed /// hasObjCPointerRepresentation - Whether this type can represent 1650193326Sed /// an objective pointer type for the purpose of GC'ability 1651198092Srdivacky bool hasObjCPointerRepresentation() const; 1652193326Sed 1653212904Sdim /// \brief Determine whether this type has an integer representation 1654212904Sdim /// of some sort, e.g., it is an integer type or a vector. 1655212904Sdim bool hasIntegerRepresentation() const; 1656212904Sdim 1657212904Sdim /// \brief Determine whether this type has an signed integer representation 1658212904Sdim /// of some sort, e.g., it is an signed integer type or a vector. 1659212904Sdim bool hasSignedIntegerRepresentation() const; 1660212904Sdim 1661212904Sdim /// \brief Determine whether this type has an unsigned integer representation 1662212904Sdim /// of some sort, e.g., it is an unsigned integer type or a vector. 1663212904Sdim bool hasUnsignedIntegerRepresentation() const; 1664212904Sdim 1665210299Sed /// \brief Determine whether this type has a floating-point representation 1666210299Sed /// of some sort, e.g., it is a floating-point type or a vector thereof. 1667210299Sed bool hasFloatingRepresentation() const; 1668212904Sdim 1669193326Sed // Type Checking Functions: Check to see if this type is structurally the 1670193326Sed // specified type, ignoring typedefs and qualifiers, and return a pointer to 1671193326Sed // the best type we can. 1672193326Sed const RecordType *getAsStructureType() const; 1673193326Sed /// NOTE: getAs*ArrayType are methods on ASTContext. 1674193326Sed const RecordType *getAsUnionType() const; 1675193326Sed const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. 1676198092Srdivacky // The following is a convenience method that returns an ObjCObjectPointerType 1677198092Srdivacky // for object declared using an interface. 1678198092Srdivacky const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; 1679194613Sed const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; 1680221345Sdim const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; 1681208600Srdivacky const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; 1682193326Sed 1683207619Srdivacky /// \brief Retrieves the CXXRecordDecl that this type refers to, either 1684234353Sdim /// because the type is a RecordType or because it is the injected-class-name 1685207619Srdivacky /// type of a class template or class template partial specialization. 1686207619Srdivacky CXXRecordDecl *getAsCXXRecordDecl() const; 1687218893Sdim 1688243830Sdim /// If this is a pointer or reference to a RecordType, return the 1689243830Sdim /// CXXRecordDecl that that type refers to. 1690243830Sdim /// 1691243830Sdim /// If this is not a pointer or reference, or the type being pointed to does 1692243830Sdim /// not refer to a CXXRecordDecl, returns NULL. 1693243830Sdim const CXXRecordDecl *getPointeeCXXRecordDecl() const; 1694243830Sdim 1695218893Sdim /// \brief Get the AutoType whose type will be deduced for a variable with 1696218893Sdim /// an initializer of this type. This looks through declarators like pointer 1697218893Sdim /// types, but not through decltype or typedefs. 1698218893Sdim AutoType *getContainedAutoType() const; 1699234353Sdim 1700218893Sdim /// Member-template getAs<specific type>'. Look through sugar for 1701239462Sdim /// an instance of \<specific type>. This scheme will eventually 1702218893Sdim /// replace the specific getAsXXXX methods above. 1703218893Sdim /// 1704218893Sdim /// There are some specializations of this member template listed 1705218893Sdim /// immediately following this class. 1706198092Srdivacky template <typename T> const T *getAs() const; 1707198092Srdivacky 1708218893Sdim /// A variant of getAs<> for array types which silently discards 1709218893Sdim /// qualifiers from the outermost type. 1710218893Sdim const ArrayType *getAsArrayTypeUnsafe() const; 1711218893Sdim 1712218893Sdim /// Member-template castAs<specific type>. Look through sugar for 1713239462Sdim /// the underlying instance of \<specific type>. 1714218893Sdim /// 1715218893Sdim /// This method has the same relationship to getAs<T> as cast<T> has 1716218893Sdim /// to dyn_cast<T>; which is to say, the underlying type *must* 1717218893Sdim /// have the intended type, and this method will never return null. 1718218893Sdim template <typename T> const T *castAs() const; 1719218893Sdim 1720218893Sdim /// A variant of castAs<> for array type which silently discards 1721218893Sdim /// qualifiers from the outermost type. 1722218893Sdim const ArrayType *castAsArrayTypeUnsafe() const; 1723218893Sdim 1724218893Sdim /// getBaseElementTypeUnsafe - Get the base element type of this 1725218893Sdim /// type, potentially discarding type qualifiers. This method 1726218893Sdim /// should never be used when type qualifiers are meaningful. 1727218893Sdim const Type *getBaseElementTypeUnsafe() const; 1728218893Sdim 1729193326Sed /// getArrayElementTypeNoTypeQual - If this is an array type, return the 1730193326Sed /// element type of the array, potentially with type qualifiers missing. 1731193326Sed /// This method should never be used when type qualifiers are meaningful. 1732193326Sed const Type *getArrayElementTypeNoTypeQual() const; 1733198092Srdivacky 1734198092Srdivacky /// getPointeeType - If this is a pointer, ObjC object pointer, or block 1735198092Srdivacky /// pointer, this returns the respective pointee. 1736198092Srdivacky QualType getPointeeType() const; 1737198092Srdivacky 1738198092Srdivacky /// getUnqualifiedDesugaredType() - Return the specified type with 1739198092Srdivacky /// any "sugar" removed from the type, removing any typedefs, 1740198092Srdivacky /// typeofs, etc., as well as any qualifiers. 1741198092Srdivacky const Type *getUnqualifiedDesugaredType() const; 1742198092Srdivacky 1743193326Sed /// More type predicates useful for type checking/promotion 1744193326Sed bool isPromotableIntegerType() const; // C99 6.3.1.1p2 1745193326Sed 1746193326Sed /// isSignedIntegerType - Return true if this is an integer type that is 1747193326Sed /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], 1748223017Sdim /// or an enum decl which has a signed representation. 1749193326Sed bool isSignedIntegerType() const; 1750193326Sed 1751193326Sed /// isUnsignedIntegerType - Return true if this is an integer type that is 1752234353Sdim /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], 1753223017Sdim /// or an enum decl which has an unsigned representation. 1754193326Sed bool isUnsignedIntegerType() const; 1755193326Sed 1756234353Sdim /// Determines whether this is an integer type that is signed or an 1757223017Sdim /// enumeration types whose underlying type is a signed integer type. 1758223017Sdim bool isSignedIntegerOrEnumerationType() const; 1759234353Sdim 1760234353Sdim /// Determines whether this is an integer type that is unsigned or an 1761223017Sdim /// enumeration types whose underlying type is a unsigned integer type. 1762223017Sdim bool isUnsignedIntegerOrEnumerationType() const; 1763223017Sdim 1764193326Sed /// isConstantSizeType - Return true if this is not a variable sized type, 1765193326Sed /// according to the rules of C99 6.7.5p3. It is not legal to call this on 1766193326Sed /// incomplete types. 1767193326Sed bool isConstantSizeType() const; 1768193326Sed 1769193326Sed /// isSpecifierType - Returns true if this type can be represented by some 1770193326Sed /// set of type specifiers. 1771193326Sed bool isSpecifierType() const; 1772193326Sed 1773208600Srdivacky /// \brief Determine the linkage of this type. 1774208600Srdivacky Linkage getLinkage() const; 1775218893Sdim 1776218893Sdim /// \brief Determine the visibility of this type. 1777249423Sdim Visibility getVisibility() const { 1778249423Sdim return getLinkageAndVisibility().getVisibility(); 1779249423Sdim } 1780218893Sdim 1781234353Sdim /// \brief Return true if the visibility was explicitly set is the code. 1782249423Sdim bool isVisibilityExplicit() const { 1783249423Sdim return getLinkageAndVisibility().isVisibilityExplicit(); 1784249423Sdim } 1785234353Sdim 1786218893Sdim /// \brief Determine the linkage and visibility of this type. 1787249423Sdim LinkageInfo getLinkageAndVisibility() const; 1788234353Sdim 1789249423Sdim /// \brief True if the computed linkage is valid. Used for consistency 1790249423Sdim /// checking. Should always return true. 1791249423Sdim bool isLinkageValid() const; 1792234353Sdim 1793198092Srdivacky const char *getTypeClassName() const; 1794198092Srdivacky 1795204643Srdivacky QualType getCanonicalTypeInternal() const { 1796204643Srdivacky return CanonicalType; 1797204643Srdivacky } 1798204643Srdivacky CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h 1799234353Sdim LLVM_ATTRIBUTE_USED void dump() const; 1800224145Sdim 1801212904Sdim friend class ASTReader; 1802212904Sdim friend class ASTWriter; 1803193326Sed}; 1804193326Sed 1805239462Sdim/// \brief This will check for a TypedefType by removing any existing sugar 1806239462Sdim/// until it reaches a TypedefType or a non-sugared type. 1807239462Sdimtemplate <> const TypedefType *Type::getAs() const; 1808193326Sed 1809243830Sdim/// \brief This will check for a TemplateSpecializationType by removing any 1810243830Sdim/// existing sugar until it reaches a TemplateSpecializationType or a 1811243830Sdim/// non-sugared type. 1812243830Sdimtemplate <> const TemplateSpecializationType *Type::getAs() const; 1813243830Sdim 1814198092Srdivacky// We can do canonical leaf types faster, because we don't have to 1815198092Srdivacky// worry about preserving child type decoration. 1816198092Srdivacky#define TYPE(Class, Base) 1817198092Srdivacky#define LEAF_TYPE(Class) \ 1818198092Srdivackytemplate <> inline const Class##Type *Type::getAs() const { \ 1819198092Srdivacky return dyn_cast<Class##Type>(CanonicalType); \ 1820218893Sdim} \ 1821218893Sdimtemplate <> inline const Class##Type *Type::castAs() const { \ 1822218893Sdim return cast<Class##Type>(CanonicalType); \ 1823198092Srdivacky} 1824198092Srdivacky#include "clang/AST/TypeNodes.def" 1825193326Sed 1826193326Sed 1827193326Sed/// BuiltinType - This class is used for builtin types like 'int'. Builtin 1828193326Sed/// types are always canonical and have a literal name field. 1829193326Sedclass BuiltinType : public Type { 1830193326Sedpublic: 1831193326Sed enum Kind { 1832234353Sdim#define BUILTIN_TYPE(Id, SingletonId) Id, 1833234353Sdim#define LAST_BUILTIN_TYPE(Id) LastKind = Id 1834234353Sdim#include "clang/AST/BuiltinTypes.def" 1835193326Sed }; 1836218893Sdim 1837193326Sedpublic: 1838198092Srdivacky BuiltinType(Kind K) 1839218893Sdim : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), 1840224145Sdim /*InstantiationDependent=*/(K == Dependent), 1841218893Sdim /*VariablyModified=*/false, 1842218893Sdim /*Unexpanded paramter pack=*/false) { 1843218893Sdim BuiltinTypeBits.Kind = K; 1844218893Sdim } 1845198092Srdivacky 1846218893Sdim Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } 1847239462Sdim StringRef getName(const PrintingPolicy &Policy) const; 1848239462Sdim const char *getNameAsCString(const PrintingPolicy &Policy) const { 1849239462Sdim // The StringRef is null-terminated. 1850239462Sdim StringRef str = getName(Policy); 1851239462Sdim assert(!str.empty() && str.data()[str.size()] == '\0'); 1852239462Sdim return str.data(); 1853239462Sdim } 1854198092Srdivacky 1855198092Srdivacky bool isSugared() const { return false; } 1856198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1857198092Srdivacky 1858199482Srdivacky bool isInteger() const { 1859218893Sdim return getKind() >= Bool && getKind() <= Int128; 1860199482Srdivacky } 1861198092Srdivacky 1862199482Srdivacky bool isSignedInteger() const { 1863218893Sdim return getKind() >= Char_S && getKind() <= Int128; 1864199482Srdivacky } 1865199482Srdivacky 1866199482Srdivacky bool isUnsignedInteger() const { 1867218893Sdim return getKind() >= Bool && getKind() <= UInt128; 1868199482Srdivacky } 1869199482Srdivacky 1870199482Srdivacky bool isFloatingPoint() const { 1871226633Sdim return getKind() >= Half && getKind() <= LongDouble; 1872199482Srdivacky } 1873199482Srdivacky 1874234353Sdim /// Determines whether the given kind corresponds to a placeholder type. 1875234353Sdim static bool isPlaceholderTypeKind(Kind K) { 1876234353Sdim return K >= Overload; 1877234353Sdim } 1878234353Sdim 1879221345Sdim /// Determines whether this type is a placeholder type, i.e. a type 1880221345Sdim /// which cannot appear in arbitrary positions in a fully-formed 1881221345Sdim /// expression. 1882218893Sdim bool isPlaceholderType() const { 1883234353Sdim return isPlaceholderTypeKind(getKind()); 1884218893Sdim } 1885218893Sdim 1886234353Sdim /// Determines whether this type is a placeholder type other than 1887234353Sdim /// Overload. Most placeholder types require only syntactic 1888234353Sdim /// information about their context in order to be resolved (e.g. 1889234353Sdim /// whether it is a call expression), which means they can (and 1890234353Sdim /// should) be resolved in an earlier "phase" of analysis. 1891234353Sdim /// Overload expressions sometimes pick up further information 1892234353Sdim /// from their context, like whether the context expects a 1893234353Sdim /// specific function-pointer type, and so frequently need 1894234353Sdim /// special treatment. 1895234353Sdim bool isNonOverloadPlaceholderType() const { 1896234353Sdim return getKind() > Overload; 1897234353Sdim } 1898234353Sdim 1899193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } 1900193326Sed}; 1901193326Sed 1902193326Sed/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex 1903193326Sed/// types (_Complex float etc) as well as the GCC integer complex extensions. 1904193326Sed/// 1905193326Sedclass ComplexType : public Type, public llvm::FoldingSetNode { 1906193326Sed QualType ElementType; 1907193326Sed ComplexType(QualType Element, QualType CanonicalPtr) : 1908218893Sdim Type(Complex, CanonicalPtr, Element->isDependentType(), 1909224145Sdim Element->isInstantiationDependentType(), 1910218893Sdim Element->isVariablyModifiedType(), 1911218893Sdim Element->containsUnexpandedParameterPack()), 1912193326Sed ElementType(Element) { 1913193326Sed } 1914193326Sed friend class ASTContext; // ASTContext creates these. 1915208600Srdivacky 1916193326Sedpublic: 1917193326Sed QualType getElementType() const { return ElementType; } 1918198092Srdivacky 1919198092Srdivacky bool isSugared() const { return false; } 1920198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1921198092Srdivacky 1922193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 1923193326Sed Profile(ID, getElementType()); 1924193326Sed } 1925193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { 1926193326Sed ID.AddPointer(Element.getAsOpaquePtr()); 1927193326Sed } 1928198092Srdivacky 1929193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Complex; } 1930193326Sed}; 1931193326Sed 1932218893Sdim/// ParenType - Sugar for parentheses used when specifying types. 1933218893Sdim/// 1934218893Sdimclass ParenType : public Type, public llvm::FoldingSetNode { 1935218893Sdim QualType Inner; 1936218893Sdim 1937218893Sdim ParenType(QualType InnerType, QualType CanonType) : 1938218893Sdim Type(Paren, CanonType, InnerType->isDependentType(), 1939224145Sdim InnerType->isInstantiationDependentType(), 1940218893Sdim InnerType->isVariablyModifiedType(), 1941218893Sdim InnerType->containsUnexpandedParameterPack()), 1942218893Sdim Inner(InnerType) { 1943218893Sdim } 1944218893Sdim friend class ASTContext; // ASTContext creates these. 1945218893Sdim 1946218893Sdimpublic: 1947218893Sdim 1948218893Sdim QualType getInnerType() const { return Inner; } 1949218893Sdim 1950218893Sdim bool isSugared() const { return true; } 1951218893Sdim QualType desugar() const { return getInnerType(); } 1952218893Sdim 1953218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 1954218893Sdim Profile(ID, getInnerType()); 1955218893Sdim } 1956218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { 1957218893Sdim Inner.Profile(ID); 1958218893Sdim } 1959218893Sdim 1960218893Sdim static bool classof(const Type *T) { return T->getTypeClass() == Paren; } 1961218893Sdim}; 1962218893Sdim 1963193326Sed/// PointerType - C99 6.7.5.1 - Pointer Declarators. 1964193326Sed/// 1965193326Sedclass PointerType : public Type, public llvm::FoldingSetNode { 1966193326Sed QualType PointeeType; 1967193326Sed 1968193326Sed PointerType(QualType Pointee, QualType CanonicalPtr) : 1969218893Sdim Type(Pointer, CanonicalPtr, Pointee->isDependentType(), 1970224145Sdim Pointee->isInstantiationDependentType(), 1971218893Sdim Pointee->isVariablyModifiedType(), 1972234353Sdim Pointee->containsUnexpandedParameterPack()), 1973218893Sdim PointeeType(Pointee) { 1974193326Sed } 1975193326Sed friend class ASTContext; // ASTContext creates these. 1976208600Srdivacky 1977193326Sedpublic: 1978198092Srdivacky 1979193326Sed QualType getPointeeType() const { return PointeeType; } 1980193326Sed 1981198092Srdivacky bool isSugared() const { return false; } 1982198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1983198092Srdivacky 1984193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 1985193326Sed Profile(ID, getPointeeType()); 1986193326Sed } 1987193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 1988193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 1989193326Sed } 1990198092Srdivacky 1991193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } 1992193326Sed}; 1993193326Sed 1994193326Sed/// BlockPointerType - pointer to a block type. 1995193326Sed/// This type is to represent types syntactically represented as 1996193326Sed/// "void (^)(int)", etc. Pointee is required to always be a function type. 1997193326Sed/// 1998193326Sedclass BlockPointerType : public Type, public llvm::FoldingSetNode { 1999193326Sed QualType PointeeType; // Block is some kind of pointer type 2000193326Sed BlockPointerType(QualType Pointee, QualType CanonicalCls) : 2001218893Sdim Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), 2002224145Sdim Pointee->isInstantiationDependentType(), 2003218893Sdim Pointee->isVariablyModifiedType(), 2004218893Sdim Pointee->containsUnexpandedParameterPack()), 2005193326Sed PointeeType(Pointee) { 2006193326Sed } 2007193326Sed friend class ASTContext; // ASTContext creates these. 2008234353Sdim 2009193326Sedpublic: 2010198092Srdivacky 2011193326Sed // Get the pointee type. Pointee is required to always be a function type. 2012193326Sed QualType getPointeeType() const { return PointeeType; } 2013193326Sed 2014198092Srdivacky bool isSugared() const { return false; } 2015198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2016198092Srdivacky 2017193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2018193326Sed Profile(ID, getPointeeType()); 2019193326Sed } 2020193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 2021193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 2022193326Sed } 2023198092Srdivacky 2024198092Srdivacky static bool classof(const Type *T) { 2025198092Srdivacky return T->getTypeClass() == BlockPointer; 2026193326Sed } 2027193326Sed}; 2028193326Sed 2029193326Sed/// ReferenceType - Base for LValueReferenceType and RValueReferenceType 2030193326Sed/// 2031193326Sedclass ReferenceType : public Type, public llvm::FoldingSetNode { 2032193326Sed QualType PointeeType; 2033193326Sed 2034193326Sedprotected: 2035198398Srdivacky ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, 2036198398Srdivacky bool SpelledAsLValue) : 2037218893Sdim Type(tc, CanonicalRef, Referencee->isDependentType(), 2038224145Sdim Referencee->isInstantiationDependentType(), 2039218893Sdim Referencee->isVariablyModifiedType(), 2040234353Sdim Referencee->containsUnexpandedParameterPack()), 2041234353Sdim PointeeType(Referencee) 2042218893Sdim { 2043218893Sdim ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; 2044218893Sdim ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); 2045193326Sed } 2046234353Sdim 2047193326Sedpublic: 2048218893Sdim bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } 2049218893Sdim bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } 2050234353Sdim 2051198398Srdivacky QualType getPointeeTypeAsWritten() const { return PointeeType; } 2052198398Srdivacky QualType getPointeeType() const { 2053198398Srdivacky // FIXME: this might strip inner qualifiers; okay? 2054198398Srdivacky const ReferenceType *T = this; 2055218893Sdim while (T->isInnerRef()) 2056218893Sdim T = T->PointeeType->castAs<ReferenceType>(); 2057198398Srdivacky return T->PointeeType; 2058198398Srdivacky } 2059198398Srdivacky 2060193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2061218893Sdim Profile(ID, PointeeType, isSpelledAsLValue()); 2062193326Sed } 2063198398Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 2064198398Srdivacky QualType Referencee, 2065198398Srdivacky bool SpelledAsLValue) { 2066193326Sed ID.AddPointer(Referencee.getAsOpaquePtr()); 2067198398Srdivacky ID.AddBoolean(SpelledAsLValue); 2068193326Sed } 2069193326Sed 2070193326Sed static bool classof(const Type *T) { 2071193326Sed return T->getTypeClass() == LValueReference || 2072193326Sed T->getTypeClass() == RValueReference; 2073193326Sed } 2074193326Sed}; 2075193326Sed 2076193326Sed/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference 2077193326Sed/// 2078193326Sedclass LValueReferenceType : public ReferenceType { 2079198398Srdivacky LValueReferenceType(QualType Referencee, QualType CanonicalRef, 2080198398Srdivacky bool SpelledAsLValue) : 2081198398Srdivacky ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue) 2082198398Srdivacky {} 2083193326Sed friend class ASTContext; // ASTContext creates these 2084193326Sedpublic: 2085198092Srdivacky bool isSugared() const { return false; } 2086198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2087198092Srdivacky 2088193326Sed static bool classof(const Type *T) { 2089193326Sed return T->getTypeClass() == LValueReference; 2090193326Sed } 2091193326Sed}; 2092193326Sed 2093193326Sed/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference 2094193326Sed/// 2095193326Sedclass RValueReferenceType : public ReferenceType { 2096193326Sed RValueReferenceType(QualType Referencee, QualType CanonicalRef) : 2097198398Srdivacky ReferenceType(RValueReference, Referencee, CanonicalRef, false) { 2098193326Sed } 2099193326Sed friend class ASTContext; // ASTContext creates these 2100193326Sedpublic: 2101198092Srdivacky bool isSugared() const { return false; } 2102198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2103198092Srdivacky 2104193326Sed static bool classof(const Type *T) { 2105193326Sed return T->getTypeClass() == RValueReference; 2106193326Sed } 2107193326Sed}; 2108193326Sed 2109193326Sed/// MemberPointerType - C++ 8.3.3 - Pointers to members 2110193326Sed/// 2111193326Sedclass MemberPointerType : public Type, public llvm::FoldingSetNode { 2112193326Sed QualType PointeeType; 2113193326Sed /// The class of which the pointee is a member. Must ultimately be a 2114193326Sed /// RecordType, but could be a typedef or a template parameter too. 2115193326Sed const Type *Class; 2116193326Sed 2117193326Sed MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : 2118193326Sed Type(MemberPointer, CanonicalPtr, 2119218893Sdim Cls->isDependentType() || Pointee->isDependentType(), 2120234353Sdim (Cls->isInstantiationDependentType() || 2121224145Sdim Pointee->isInstantiationDependentType()), 2122218893Sdim Pointee->isVariablyModifiedType(), 2123234353Sdim (Cls->containsUnexpandedParameterPack() || 2124218893Sdim Pointee->containsUnexpandedParameterPack())), 2125193326Sed PointeeType(Pointee), Class(Cls) { 2126193326Sed } 2127193326Sed friend class ASTContext; // ASTContext creates these. 2128234353Sdim 2129193326Sedpublic: 2130193326Sed QualType getPointeeType() const { return PointeeType; } 2131193326Sed 2132212904Sdim /// Returns true if the member type (i.e. the pointee type) is a 2133212904Sdim /// function type rather than a data-member type. 2134212904Sdim bool isMemberFunctionPointer() const { 2135212904Sdim return PointeeType->isFunctionProtoType(); 2136212904Sdim } 2137212904Sdim 2138212904Sdim /// Returns true if the member type (i.e. the pointee type) is a 2139212904Sdim /// data type rather than a function type. 2140212904Sdim bool isMemberDataPointer() const { 2141212904Sdim return !PointeeType->isFunctionProtoType(); 2142212904Sdim } 2143212904Sdim 2144193326Sed const Type *getClass() const { return Class; } 2145193326Sed 2146198092Srdivacky bool isSugared() const { return false; } 2147198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2148198092Srdivacky 2149193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2150193326Sed Profile(ID, getPointeeType(), getClass()); 2151193326Sed } 2152193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, 2153193326Sed const Type *Class) { 2154193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 2155193326Sed ID.AddPointer(Class); 2156193326Sed } 2157193326Sed 2158193326Sed static bool classof(const Type *T) { 2159193326Sed return T->getTypeClass() == MemberPointer; 2160193326Sed } 2161193326Sed}; 2162193326Sed 2163193326Sed/// ArrayType - C99 6.7.5.2 - Array Declarators. 2164193326Sed/// 2165193326Sedclass ArrayType : public Type, public llvm::FoldingSetNode { 2166193326Sedpublic: 2167193326Sed /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4]) 2168193326Sed /// an array with a static size (e.g. int X[static 4]), or an array 2169193326Sed /// with a star size (e.g. int X[*]). 2170193326Sed /// 'static' is only allowed on function parameters. 2171193326Sed enum ArraySizeModifier { 2172193326Sed Normal, Static, Star 2173193326Sed }; 2174193326Sedprivate: 2175193326Sed /// ElementType - The element type of the array. 2176193326Sed QualType ElementType; 2177198092Srdivacky 2178193326Sedprotected: 2179193326Sed // C++ [temp.dep.type]p1: 2180193326Sed // A type is dependent if it is... 2181193326Sed // - an array type constructed from any dependent type or whose 2182193326Sed // size is specified by a constant expression that is 2183193326Sed // value-dependent, 2184193326Sed ArrayType(TypeClass tc, QualType et, QualType can, 2185218893Sdim ArraySizeModifier sm, unsigned tq, 2186218893Sdim bool ContainsUnexpandedParameterPack) 2187218893Sdim : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, 2188224145Sdim et->isInstantiationDependentType() || tc == DependentSizedArray, 2189218893Sdim (tc == VariableArray || et->isVariablyModifiedType()), 2190218893Sdim ContainsUnexpandedParameterPack), 2191218893Sdim ElementType(et) { 2192218893Sdim ArrayTypeBits.IndexTypeQuals = tq; 2193218893Sdim ArrayTypeBits.SizeModifier = sm; 2194218893Sdim } 2195193326Sed 2196193326Sed friend class ASTContext; // ASTContext creates these. 2197208600Srdivacky 2198193326Sedpublic: 2199193326Sed QualType getElementType() const { return ElementType; } 2200193326Sed ArraySizeModifier getSizeModifier() const { 2201218893Sdim return ArraySizeModifier(ArrayTypeBits.SizeModifier); 2202193326Sed } 2203198092Srdivacky Qualifiers getIndexTypeQualifiers() const { 2204218893Sdim return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); 2205198092Srdivacky } 2206218893Sdim unsigned getIndexTypeCVRQualifiers() const { 2207218893Sdim return ArrayTypeBits.IndexTypeQuals; 2208218893Sdim } 2209198092Srdivacky 2210193326Sed static bool classof(const Type *T) { 2211193326Sed return T->getTypeClass() == ConstantArray || 2212193326Sed T->getTypeClass() == VariableArray || 2213193326Sed T->getTypeClass() == IncompleteArray || 2214193326Sed T->getTypeClass() == DependentSizedArray; 2215193326Sed } 2216193326Sed}; 2217193326Sed 2218198092Srdivacky/// ConstantArrayType - This class represents the canonical version of 2219198092Srdivacky/// C arrays with a specified constant size. For example, the canonical 2220198092Srdivacky/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element 2221198092Srdivacky/// type is 'int' and the size is 404. 2222193326Sedclass ConstantArrayType : public ArrayType { 2223193326Sed llvm::APInt Size; // Allows us to unique the type. 2224198092Srdivacky 2225193326Sed ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, 2226193326Sed ArraySizeModifier sm, unsigned tq) 2227218893Sdim : ArrayType(ConstantArray, et, can, sm, tq, 2228218893Sdim et->containsUnexpandedParameterPack()), 2229198092Srdivacky Size(size) {} 2230198092Srdivackyprotected: 2231198092Srdivacky ConstantArrayType(TypeClass tc, QualType et, QualType can, 2232198092Srdivacky const llvm::APInt &size, ArraySizeModifier sm, unsigned tq) 2233234353Sdim : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()), 2234218893Sdim Size(size) {} 2235193326Sed friend class ASTContext; // ASTContext creates these. 2236193326Sedpublic: 2237193326Sed const llvm::APInt &getSize() const { return Size; } 2238198092Srdivacky bool isSugared() const { return false; } 2239198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2240198092Srdivacky 2241234353Sdim 2242212904Sdim /// \brief Determine the number of bits required to address a member of 2243212904Sdim // an array with the given element type and number of elements. 2244212904Sdim static unsigned getNumAddressingBits(ASTContext &Context, 2245212904Sdim QualType ElementType, 2246212904Sdim const llvm::APInt &NumElements); 2247234353Sdim 2248212904Sdim /// \brief Determine the maximum number of active bits that an array's size 2249212904Sdim /// can require, which limits the maximum size of the array. 2250212904Sdim static unsigned getMaxSizeBits(ASTContext &Context); 2251234353Sdim 2252193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2253198092Srdivacky Profile(ID, getElementType(), getSize(), 2254198092Srdivacky getSizeModifier(), getIndexTypeCVRQualifiers()); 2255193326Sed } 2256193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, 2257193326Sed const llvm::APInt &ArraySize, ArraySizeModifier SizeMod, 2258193326Sed unsigned TypeQuals) { 2259193326Sed ID.AddPointer(ET.getAsOpaquePtr()); 2260193326Sed ID.AddInteger(ArraySize.getZExtValue()); 2261193326Sed ID.AddInteger(SizeMod); 2262193326Sed ID.AddInteger(TypeQuals); 2263193326Sed } 2264198092Srdivacky static bool classof(const Type *T) { 2265198398Srdivacky return T->getTypeClass() == ConstantArray; 2266193326Sed } 2267193326Sed}; 2268193326Sed 2269193326Sed/// IncompleteArrayType - This class represents C arrays with an unspecified 2270193326Sed/// size. For example 'int A[]' has an IncompleteArrayType where the element 2271193326Sed/// type is 'int' and the size is unspecified. 2272193326Sedclass IncompleteArrayType : public ArrayType { 2273198092Srdivacky 2274193326Sed IncompleteArrayType(QualType et, QualType can, 2275198092Srdivacky ArraySizeModifier sm, unsigned tq) 2276234353Sdim : ArrayType(IncompleteArray, et, can, sm, tq, 2277218893Sdim et->containsUnexpandedParameterPack()) {} 2278193326Sed friend class ASTContext; // ASTContext creates these. 2279193326Sedpublic: 2280198092Srdivacky bool isSugared() const { return false; } 2281198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2282193326Sed 2283198092Srdivacky static bool classof(const Type *T) { 2284198092Srdivacky return T->getTypeClass() == IncompleteArray; 2285193326Sed } 2286198092Srdivacky 2287193326Sed friend class StmtIteratorBase; 2288198092Srdivacky 2289193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2290198092Srdivacky Profile(ID, getElementType(), getSizeModifier(), 2291198092Srdivacky getIndexTypeCVRQualifiers()); 2292193326Sed } 2293198092Srdivacky 2294193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, 2295193326Sed ArraySizeModifier SizeMod, unsigned TypeQuals) { 2296193326Sed ID.AddPointer(ET.getAsOpaquePtr()); 2297193326Sed ID.AddInteger(SizeMod); 2298193326Sed ID.AddInteger(TypeQuals); 2299193326Sed } 2300193326Sed}; 2301193326Sed 2302193326Sed/// VariableArrayType - This class represents C arrays with a specified size 2303193326Sed/// which is not an integer-constant-expression. For example, 'int s[x+foo()]'. 2304193326Sed/// Since the size expression is an arbitrary expression, we store it as such. 2305193326Sed/// 2306193326Sed/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and 2307193326Sed/// should not be: two lexically equivalent variable array types could mean 2308193326Sed/// different things, for example, these variables do not have the same type 2309193326Sed/// dynamically: 2310193326Sed/// 2311193326Sed/// void foo(int x) { 2312193326Sed/// int Y[x]; 2313193326Sed/// ++x; 2314193326Sed/// int Z[x]; 2315193326Sed/// } 2316193326Sed/// 2317193326Sedclass VariableArrayType : public ArrayType { 2318198092Srdivacky /// SizeExpr - An assignment expression. VLA's are only permitted within 2319198092Srdivacky /// a function block. 2320193326Sed Stmt *SizeExpr; 2321198092Srdivacky /// Brackets - The left and right array brackets. 2322198092Srdivacky SourceRange Brackets; 2323198092Srdivacky 2324193326Sed VariableArrayType(QualType et, QualType can, Expr *e, 2325198092Srdivacky ArraySizeModifier sm, unsigned tq, 2326198092Srdivacky SourceRange brackets) 2327234353Sdim : ArrayType(VariableArray, et, can, sm, tq, 2328218893Sdim et->containsUnexpandedParameterPack()), 2329198092Srdivacky SizeExpr((Stmt*) e), Brackets(brackets) {} 2330193326Sed friend class ASTContext; // ASTContext creates these. 2331193326Sed 2332193326Sedpublic: 2333198092Srdivacky Expr *getSizeExpr() const { 2334193326Sed // We use C-style casts instead of cast<> here because we do not wish 2335193326Sed // to have a dependency of Type.h on Stmt.h/Expr.h. 2336193326Sed return (Expr*) SizeExpr; 2337193326Sed } 2338198092Srdivacky SourceRange getBracketsRange() const { return Brackets; } 2339198092Srdivacky SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } 2340198092Srdivacky SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } 2341198092Srdivacky 2342198092Srdivacky bool isSugared() const { return false; } 2343198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2344198092Srdivacky 2345198092Srdivacky static bool classof(const Type *T) { 2346198092Srdivacky return T->getTypeClass() == VariableArray; 2347193326Sed } 2348198092Srdivacky 2349193326Sed friend class StmtIteratorBase; 2350198092Srdivacky 2351193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2352226633Sdim llvm_unreachable("Cannot unique VariableArrayTypes."); 2353193326Sed } 2354193326Sed}; 2355193326Sed 2356193326Sed/// DependentSizedArrayType - This type represents an array type in 2357193326Sed/// C++ whose size is a value-dependent expression. For example: 2358199990Srdivacky/// 2359199990Srdivacky/// \code 2360198092Srdivacky/// template<typename T, int Size> 2361193326Sed/// class array { 2362193326Sed/// T data[Size]; 2363193326Sed/// }; 2364199990Srdivacky/// \endcode 2365199990Srdivacky/// 2366193326Sed/// For these types, we won't actually know what the array bound is 2367193326Sed/// until template instantiation occurs, at which point this will 2368193326Sed/// become either a ConstantArrayType or a VariableArrayType. 2369193326Sedclass DependentSizedArrayType : public ArrayType { 2370218893Sdim const ASTContext &Context; 2371198092Srdivacky 2372199990Srdivacky /// \brief An assignment expression that will instantiate to the 2373193326Sed /// size of the array. 2374199990Srdivacky /// 2375199990Srdivacky /// The expression itself might be NULL, in which case the array 2376199990Srdivacky /// type will have its size deduced from an initializer. 2377193326Sed Stmt *SizeExpr; 2378199990Srdivacky 2379198092Srdivacky /// Brackets - The left and right array brackets. 2380198092Srdivacky SourceRange Brackets; 2381198092Srdivacky 2382218893Sdim DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, 2383198092Srdivacky Expr *e, ArraySizeModifier sm, unsigned tq, 2384218893Sdim SourceRange brackets); 2385218893Sdim 2386193326Sed friend class ASTContext; // ASTContext creates these. 2387193326Sed 2388193326Sedpublic: 2389198092Srdivacky Expr *getSizeExpr() const { 2390193326Sed // We use C-style casts instead of cast<> here because we do not wish 2391193326Sed // to have a dependency of Type.h on Stmt.h/Expr.h. 2392193326Sed return (Expr*) SizeExpr; 2393193326Sed } 2394198092Srdivacky SourceRange getBracketsRange() const { return Brackets; } 2395198092Srdivacky SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } 2396198092Srdivacky SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } 2397198092Srdivacky 2398198092Srdivacky bool isSugared() const { return false; } 2399198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2400198092Srdivacky 2401198092Srdivacky static bool classof(const Type *T) { 2402198092Srdivacky return T->getTypeClass() == DependentSizedArray; 2403193326Sed } 2404198092Srdivacky 2405193326Sed friend class StmtIteratorBase; 2406198092Srdivacky 2407198092Srdivacky 2408193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2409198092Srdivacky Profile(ID, Context, getElementType(), 2410198092Srdivacky getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); 2411193326Sed } 2412198092Srdivacky 2413218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 2414198092Srdivacky QualType ET, ArraySizeModifier SizeMod, 2415198092Srdivacky unsigned TypeQuals, Expr *E); 2416193326Sed}; 2417193326Sed 2418194613Sed/// DependentSizedExtVectorType - This type represent an extended vector type 2419194613Sed/// where either the type or size is dependent. For example: 2420194613Sed/// @code 2421194613Sed/// template<typename T, int Size> 2422194613Sed/// class vector { 2423194613Sed/// typedef T __attribute__((ext_vector_type(Size))) type; 2424194613Sed/// } 2425194613Sed/// @endcode 2426198092Srdivackyclass DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { 2427218893Sdim const ASTContext &Context; 2428194613Sed Expr *SizeExpr; 2429194613Sed /// ElementType - The element type of the array. 2430194613Sed QualType ElementType; 2431194613Sed SourceLocation loc; 2432198092Srdivacky 2433218893Sdim DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, 2434218893Sdim QualType can, Expr *SizeExpr, SourceLocation loc); 2435218893Sdim 2436194613Sed friend class ASTContext; 2437194613Sed 2438194613Sedpublic: 2439198092Srdivacky Expr *getSizeExpr() const { return SizeExpr; } 2440194613Sed QualType getElementType() const { return ElementType; } 2441194613Sed SourceLocation getAttributeLoc() const { return loc; } 2442194613Sed 2443198092Srdivacky bool isSugared() const { return false; } 2444198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2445198092Srdivacky 2446198092Srdivacky static bool classof(const Type *T) { 2447198092Srdivacky return T->getTypeClass() == DependentSizedExtVector; 2448194613Sed } 2449198092Srdivacky 2450198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 2451198092Srdivacky Profile(ID, Context, getElementType(), getSizeExpr()); 2452198092Srdivacky } 2453198092Srdivacky 2454218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 2455198092Srdivacky QualType ElementType, Expr *SizeExpr); 2456194613Sed}; 2457194613Sed 2458198092Srdivacky 2459193326Sed/// VectorType - GCC generic vector type. This type is created using 2460198092Srdivacky/// __attribute__((vector_size(n)), where "n" specifies the vector size in 2461203955Srdivacky/// bytes; or from an Altivec __vector or vector declaration. 2462203955Srdivacky/// Since the constructor takes the number of vector elements, the 2463193326Sed/// client is responsible for converting the size into the number of elements. 2464193326Sedclass VectorType : public Type, public llvm::FoldingSetNode { 2465210299Sedpublic: 2466218893Sdim enum VectorKind { 2467218893Sdim GenericVector, // not a target-specific vector type 2468218893Sdim AltiVecVector, // is AltiVec vector 2469218893Sdim AltiVecPixel, // is AltiVec 'vector Pixel' 2470218893Sdim AltiVecBool, // is AltiVec 'vector bool ...' 2471218893Sdim NeonVector, // is ARM Neon vector 2472218893Sdim NeonPolyVector // is ARM Neon polynomial vector 2473210299Sed }; 2474193326Sedprotected: 2475193326Sed /// ElementType - The element type of the vector. 2476193326Sed QualType ElementType; 2477198092Srdivacky 2478203955Srdivacky VectorType(QualType vecType, unsigned nElements, QualType canonType, 2479218893Sdim VectorKind vecKind); 2480234353Sdim 2481198092Srdivacky VectorType(TypeClass tc, QualType vecType, unsigned nElements, 2482218893Sdim QualType canonType, VectorKind vecKind); 2483218893Sdim 2484193326Sed friend class ASTContext; // ASTContext creates these. 2485234353Sdim 2486193326Sedpublic: 2487198092Srdivacky 2488193326Sed QualType getElementType() const { return ElementType; } 2489218893Sdim unsigned getNumElements() const { return VectorTypeBits.NumElements; } 2490193326Sed 2491198092Srdivacky bool isSugared() const { return false; } 2492198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2493198092Srdivacky 2494218893Sdim VectorKind getVectorKind() const { 2495218893Sdim return VectorKind(VectorTypeBits.VecKind); 2496218893Sdim } 2497210299Sed 2498193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2499218893Sdim Profile(ID, getElementType(), getNumElements(), 2500218893Sdim getTypeClass(), getVectorKind()); 2501193326Sed } 2502198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, 2503203955Srdivacky unsigned NumElements, TypeClass TypeClass, 2504218893Sdim VectorKind VecKind) { 2505193326Sed ID.AddPointer(ElementType.getAsOpaquePtr()); 2506193326Sed ID.AddInteger(NumElements); 2507193326Sed ID.AddInteger(TypeClass); 2508218893Sdim ID.AddInteger(VecKind); 2509193326Sed } 2510203955Srdivacky 2511198092Srdivacky static bool classof(const Type *T) { 2512198092Srdivacky return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; 2513193326Sed } 2514193326Sed}; 2515193326Sed 2516193326Sed/// ExtVectorType - Extended vector type. This type is created using 2517193326Sed/// __attribute__((ext_vector_type(n)), where "n" is the number of elements. 2518193326Sed/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This 2519193326Sed/// class enables syntactic extensions, like Vector Components for accessing 2520193326Sed/// points, colors, and textures (modeled after OpenGL Shading Language). 2521193326Sedclass ExtVectorType : public VectorType { 2522193326Sed ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) : 2523218893Sdim VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} 2524193326Sed friend class ASTContext; // ASTContext creates these. 2525193326Sedpublic: 2526193326Sed static int getPointAccessorIdx(char c) { 2527193326Sed switch (c) { 2528193326Sed default: return -1; 2529193326Sed case 'x': return 0; 2530193326Sed case 'y': return 1; 2531193326Sed case 'z': return 2; 2532193326Sed case 'w': return 3; 2533193326Sed } 2534193326Sed } 2535193326Sed static int getNumericAccessorIdx(char c) { 2536193326Sed switch (c) { 2537193326Sed default: return -1; 2538193326Sed case '0': return 0; 2539193326Sed case '1': return 1; 2540193326Sed case '2': return 2; 2541193326Sed case '3': return 3; 2542193326Sed case '4': return 4; 2543193326Sed case '5': return 5; 2544193326Sed case '6': return 6; 2545193326Sed case '7': return 7; 2546193326Sed case '8': return 8; 2547193326Sed case '9': return 9; 2548195099Sed case 'A': 2549193326Sed case 'a': return 10; 2550195099Sed case 'B': 2551193326Sed case 'b': return 11; 2552195099Sed case 'C': 2553193326Sed case 'c': return 12; 2554195099Sed case 'D': 2555193326Sed case 'd': return 13; 2556195099Sed case 'E': 2557193326Sed case 'e': return 14; 2558195099Sed case 'F': 2559193326Sed case 'f': return 15; 2560193326Sed } 2561193326Sed } 2562198092Srdivacky 2563193326Sed static int getAccessorIdx(char c) { 2564193326Sed if (int idx = getPointAccessorIdx(c)+1) return idx-1; 2565193326Sed return getNumericAccessorIdx(c); 2566193326Sed } 2567198092Srdivacky 2568193326Sed bool isAccessorWithinNumElements(char c) const { 2569193326Sed if (int idx = getAccessorIdx(c)+1) 2570218893Sdim return unsigned(idx-1) < getNumElements(); 2571193326Sed return false; 2572193326Sed } 2573198092Srdivacky bool isSugared() const { return false; } 2574198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2575198092Srdivacky 2576198092Srdivacky static bool classof(const Type *T) { 2577198092Srdivacky return T->getTypeClass() == ExtVector; 2578193326Sed } 2579193326Sed}; 2580193326Sed 2581193326Sed/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base 2582193326Sed/// class of FunctionNoProtoType and FunctionProtoType. 2583193326Sed/// 2584193326Sedclass FunctionType : public Type { 2585193326Sed // The type returned by the function. 2586193326Sed QualType ResultType; 2587206084Srdivacky 2588206084Srdivacky public: 2589218893Sdim /// ExtInfo - A class which abstracts out some details necessary for 2590218893Sdim /// making a call. 2591218893Sdim /// 2592218893Sdim /// It is not actually used directly for storing this information in 2593218893Sdim /// a FunctionType, although FunctionType does currently use the 2594218893Sdim /// same bit-pattern. 2595218893Sdim /// 2596218893Sdim // If you add a field (say Foo), other than the obvious places (both, 2597218893Sdim // constructors, compile failures), what you need to update is 2598218893Sdim // * Operator== 2599206084Srdivacky // * getFoo 2600206084Srdivacky // * withFoo 2601206084Srdivacky // * functionType. Add Foo, getFoo. 2602206084Srdivacky // * ASTContext::getFooType 2603206084Srdivacky // * ASTContext::mergeFunctionTypes 2604206084Srdivacky // * FunctionNoProtoType::Profile 2605206084Srdivacky // * FunctionProtoType::Profile 2606206084Srdivacky // * TypePrinter::PrintFunctionProto 2607212904Sdim // * AST read and write 2608206084Srdivacky // * Codegen 2609218893Sdim class ExtInfo { 2610243830Sdim // Feel free to rearrange or add bits, but if you go over 9, 2611218893Sdim // you'll need to adjust both the Bits field below and 2612218893Sdim // Type::FunctionTypeBitfields. 2613206084Srdivacky 2614224145Sdim // | CC |noreturn|produces|regparm| 2615243830Sdim // |0 .. 3| 4 | 5 | 6 .. 8| 2616224145Sdim // 2617224145Sdim // regparm is either 0 (no regparm attribute) or the regparm value+1. 2618243830Sdim enum { CallConvMask = 0xF }; 2619243830Sdim enum { NoReturnMask = 0x10 }; 2620243830Sdim enum { ProducesResultMask = 0x20 }; 2621224145Sdim enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask), 2622243830Sdim RegParmOffset = 6 }; // Assumed to be the last field 2623218893Sdim 2624224145Sdim uint16_t Bits; 2625218893Sdim 2626224145Sdim ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} 2627218893Sdim 2628218893Sdim friend class FunctionType; 2629218893Sdim 2630206084Srdivacky public: 2631206084Srdivacky // Constructor with no defaults. Use this when you know that you 2632212904Sdim // have all the elements (when reading an AST file for example). 2633224145Sdim ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, 2634224145Sdim bool producesResult) { 2635224145Sdim assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); 2636218893Sdim Bits = ((unsigned) cc) | 2637218893Sdim (noReturn ? NoReturnMask : 0) | 2638224145Sdim (producesResult ? ProducesResultMask : 0) | 2639224145Sdim (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0); 2640218893Sdim } 2641206084Srdivacky 2642206084Srdivacky // Constructor with all defaults. Use when for example creating a 2643206084Srdivacky // function know to use defaults. 2644218893Sdim ExtInfo() : Bits(0) {} 2645206084Srdivacky 2646218893Sdim bool getNoReturn() const { return Bits & NoReturnMask; } 2647224145Sdim bool getProducesResult() const { return Bits & ProducesResultMask; } 2648224145Sdim bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } 2649234353Sdim unsigned getRegParm() const { 2650224145Sdim unsigned RegParm = Bits >> RegParmOffset; 2651224145Sdim if (RegParm > 0) 2652224145Sdim --RegParm; 2653224145Sdim return RegParm; 2654224145Sdim } 2655218893Sdim CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } 2656206084Srdivacky 2657218893Sdim bool operator==(ExtInfo Other) const { 2658218893Sdim return Bits == Other.Bits; 2659206084Srdivacky } 2660218893Sdim bool operator!=(ExtInfo Other) const { 2661218893Sdim return Bits != Other.Bits; 2662206084Srdivacky } 2663206084Srdivacky 2664206084Srdivacky // Note that we don't have setters. That is by design, use 2665206084Srdivacky // the following with methods instead of mutating these objects. 2666206084Srdivacky 2667206084Srdivacky ExtInfo withNoReturn(bool noReturn) const { 2668218893Sdim if (noReturn) 2669218893Sdim return ExtInfo(Bits | NoReturnMask); 2670218893Sdim else 2671218893Sdim return ExtInfo(Bits & ~NoReturnMask); 2672206084Srdivacky } 2673206084Srdivacky 2674224145Sdim ExtInfo withProducesResult(bool producesResult) const { 2675224145Sdim if (producesResult) 2676224145Sdim return ExtInfo(Bits | ProducesResultMask); 2677224145Sdim else 2678224145Sdim return ExtInfo(Bits & ~ProducesResultMask); 2679224145Sdim } 2680224145Sdim 2681206084Srdivacky ExtInfo withRegParm(unsigned RegParm) const { 2682224145Sdim assert(RegParm < 7 && "Invalid regparm value"); 2683224145Sdim return ExtInfo((Bits & ~RegParmMask) | 2684224145Sdim ((RegParm + 1) << RegParmOffset)); 2685206084Srdivacky } 2686206084Srdivacky 2687206084Srdivacky ExtInfo withCallingConv(CallingConv cc) const { 2688218893Sdim return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); 2689206084Srdivacky } 2690206084Srdivacky 2691218893Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 2692218893Sdim ID.AddInteger(Bits); 2693218893Sdim } 2694206084Srdivacky }; 2695206084Srdivacky 2696193326Sedprotected: 2697234353Sdim FunctionType(TypeClass tc, QualType res, 2698249423Sdim unsigned typeQuals, QualType Canonical, bool Dependent, 2699224145Sdim bool InstantiationDependent, 2700234353Sdim bool VariablyModified, bool ContainsUnexpandedParameterPack, 2701218893Sdim ExtInfo Info) 2702234353Sdim : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, 2703234353Sdim ContainsUnexpandedParameterPack), 2704218893Sdim ResultType(res) { 2705218893Sdim FunctionTypeBits.ExtInfo = Info.Bits; 2706218893Sdim FunctionTypeBits.TypeQuals = typeQuals; 2707218893Sdim } 2708218893Sdim unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; } 2709234353Sdim 2710193326Sedpublic: 2711198092Srdivacky 2712193326Sed QualType getResultType() const { return ResultType; } 2713221345Sdim 2714221345Sdim bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } 2715218893Sdim unsigned getRegParmType() const { return getExtInfo().getRegParm(); } 2716249423Sdim /// \brief Determine whether this function type includes the GNU noreturn 2717249423Sdim /// attribute. The C++11 [[noreturn]] attribute does not affect the function 2718249423Sdim /// type. 2719218893Sdim bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } 2720218893Sdim CallingConv getCallConv() const { return getExtInfo().getCC(); } 2721218893Sdim ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } 2722239462Sdim bool isConst() const { return getTypeQuals() & Qualifiers::Const; } 2723239462Sdim bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; } 2724239462Sdim bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; } 2725193326Sed 2726210299Sed /// \brief Determine the type of an expression that calls a function of 2727210299Sed /// this type. 2728234353Sdim QualType getCallResultType(ASTContext &Context) const { 2729210299Sed return getResultType().getNonLValueExprType(Context); 2730210299Sed } 2731210299Sed 2732226633Sdim static StringRef getNameForCallConv(CallingConv CC); 2733203955Srdivacky 2734193326Sed static bool classof(const Type *T) { 2735193326Sed return T->getTypeClass() == FunctionNoProto || 2736193326Sed T->getTypeClass() == FunctionProto; 2737193326Sed } 2738193326Sed}; 2739193326Sed 2740193326Sed/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has 2741193326Sed/// no information available about its arguments. 2742193326Sedclass FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { 2743218893Sdim FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) 2744249423Sdim : FunctionType(FunctionNoProto, Result, 0, Canonical, 2745224145Sdim /*Dependent=*/false, /*InstantiationDependent=*/false, 2746234353Sdim Result->isVariablyModifiedType(), 2747218893Sdim /*ContainsUnexpandedParameterPack=*/false, Info) {} 2748218893Sdim 2749193326Sed friend class ASTContext; // ASTContext creates these. 2750234353Sdim 2751193326Sedpublic: 2752193326Sed // No additional state past what FunctionType provides. 2753193326Sed 2754198092Srdivacky bool isSugared() const { return false; } 2755198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2756198092Srdivacky 2757193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2758206084Srdivacky Profile(ID, getResultType(), getExtInfo()); 2759193326Sed } 2760198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, 2761218893Sdim ExtInfo Info) { 2762218893Sdim Info.Profile(ID); 2763193326Sed ID.AddPointer(ResultType.getAsOpaquePtr()); 2764193326Sed } 2765198092Srdivacky 2766193326Sed static bool classof(const Type *T) { 2767193326Sed return T->getTypeClass() == FunctionNoProto; 2768193326Sed } 2769193326Sed}; 2770193326Sed 2771193326Sed/// FunctionProtoType - Represents a prototype with argument type info, e.g. 2772193326Sed/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no 2773193326Sed/// arguments, not as having a single void argument. Such a type can have an 2774193326Sed/// exception specification, but this specification is not part of the canonical 2775193326Sed/// type. 2776193326Sedclass FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { 2777218893Sdimpublic: 2778218893Sdim /// ExtProtoInfo - Extra information about a function prototype. 2779218893Sdim struct ExtProtoInfo { 2780218893Sdim ExtProtoInfo() : 2781234353Sdim Variadic(false), HasTrailingReturn(false), TypeQuals(0), 2782234353Sdim ExceptionSpecType(EST_None), RefQualifier(RQ_None), 2783234982Sdim NumExceptions(0), Exceptions(0), NoexceptExpr(0), 2784234982Sdim ExceptionSpecDecl(0), ExceptionSpecTemplate(0), 2785234982Sdim ConsumedArguments(0) {} 2786218893Sdim 2787218893Sdim FunctionType::ExtInfo ExtInfo; 2788234353Sdim bool Variadic : 1; 2789234353Sdim bool HasTrailingReturn : 1; 2790234353Sdim unsigned char TypeQuals; 2791221345Sdim ExceptionSpecificationType ExceptionSpecType; 2792218893Sdim RefQualifierKind RefQualifier; 2793218893Sdim unsigned NumExceptions; 2794218893Sdim const QualType *Exceptions; 2795221345Sdim Expr *NoexceptExpr; 2796234982Sdim FunctionDecl *ExceptionSpecDecl; 2797234982Sdim FunctionDecl *ExceptionSpecTemplate; 2798224145Sdim const bool *ConsumedArguments; 2799218893Sdim }; 2800218893Sdim 2801218893Sdimprivate: 2802218893Sdim /// \brief Determine whether there are any argument types that 2803218893Sdim /// contain an unexpanded parameter pack. 2804234353Sdim static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, 2805218893Sdim unsigned numArgs) { 2806193326Sed for (unsigned Idx = 0; Idx < numArgs; ++Idx) 2807218893Sdim if (ArgArray[Idx]->containsUnexpandedParameterPack()) 2808218893Sdim return true; 2809193326Sed 2810193326Sed return false; 2811193326Sed } 2812193326Sed 2813249423Sdim FunctionProtoType(QualType result, ArrayRef<QualType> args, 2814218893Sdim QualType canonical, const ExtProtoInfo &epi); 2815193326Sed 2816193326Sed /// NumArgs - The number of arguments this function has, not counting '...'. 2817249423Sdim unsigned NumArgs : 15; 2818193326Sed 2819193326Sed /// NumExceptions - The number of types in the exception spec, if any. 2820221345Sdim unsigned NumExceptions : 9; 2821193326Sed 2822221345Sdim /// ExceptionSpecType - The type of exception specification this function has. 2823221345Sdim unsigned ExceptionSpecType : 3; 2824193326Sed 2825224145Sdim /// HasAnyConsumedArgs - Whether this function has any consumed arguments. 2826224145Sdim unsigned HasAnyConsumedArgs : 1; 2827224145Sdim 2828234353Sdim /// Variadic - Whether the function is variadic. 2829234353Sdim unsigned Variadic : 1; 2830234353Sdim 2831234353Sdim /// HasTrailingReturn - Whether this function has a trailing return type. 2832234353Sdim unsigned HasTrailingReturn : 1; 2833234353Sdim 2834249423Sdim /// \brief The ref-qualifier associated with a \c FunctionProtoType. 2835249423Sdim /// 2836249423Sdim /// This is a value of type \c RefQualifierKind. 2837249423Sdim unsigned RefQualifier : 2; 2838249423Sdim 2839234353Sdim // ArgInfo - There is an variable size array after the class in memory that 2840234353Sdim // holds the argument types. 2841234353Sdim 2842234353Sdim // Exceptions - There is another variable size array after ArgInfo that 2843234353Sdim // holds the exception types. 2844234353Sdim 2845234353Sdim // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing 2846234353Sdim // to the expression in the noexcept() specifier. 2847234353Sdim 2848234982Sdim // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may 2849234982Sdim // be a pair of FunctionDecl* pointing to the function which should be used to 2850234982Sdim // instantiate this function type's exception specification, and the function 2851234982Sdim // from which it should be instantiated. 2852234982Sdim 2853234353Sdim // ConsumedArgs - A variable size array, following Exceptions 2854234353Sdim // and of length NumArgs, holding flags indicating which arguments 2855234353Sdim // are consumed. This only appears if HasAnyConsumedArgs is true. 2856234353Sdim 2857193326Sed friend class ASTContext; // ASTContext creates these. 2858193326Sed 2859224145Sdim const bool *getConsumedArgsBuffer() const { 2860224145Sdim assert(hasAnyConsumedArgs()); 2861224145Sdim 2862224145Sdim // Find the end of the exceptions. 2863224145Sdim Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end()); 2864224145Sdim if (getExceptionSpecType() != EST_ComputedNoexcept) 2865224145Sdim eh_end += NumExceptions; 2866224145Sdim else 2867224145Sdim eh_end += 1; // NoexceptExpr 2868224145Sdim 2869224145Sdim return reinterpret_cast<const bool*>(eh_end); 2870224145Sdim } 2871224145Sdim 2872193326Sedpublic: 2873193326Sed unsigned getNumArgs() const { return NumArgs; } 2874193326Sed QualType getArgType(unsigned i) const { 2875193326Sed assert(i < NumArgs && "Invalid argument number!"); 2876193326Sed return arg_type_begin()[i]; 2877193326Sed } 2878249423Sdim ArrayRef<QualType> getArgTypes() const { 2879249423Sdim return ArrayRef<QualType>(arg_type_begin(), arg_type_end()); 2880249423Sdim } 2881193326Sed 2882218893Sdim ExtProtoInfo getExtProtoInfo() const { 2883218893Sdim ExtProtoInfo EPI; 2884218893Sdim EPI.ExtInfo = getExtInfo(); 2885218893Sdim EPI.Variadic = isVariadic(); 2886234353Sdim EPI.HasTrailingReturn = hasTrailingReturn(); 2887221345Sdim EPI.ExceptionSpecType = getExceptionSpecType(); 2888218893Sdim EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals()); 2889218893Sdim EPI.RefQualifier = getRefQualifier(); 2890221345Sdim if (EPI.ExceptionSpecType == EST_Dynamic) { 2891221345Sdim EPI.NumExceptions = NumExceptions; 2892221345Sdim EPI.Exceptions = exception_begin(); 2893221345Sdim } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 2894221345Sdim EPI.NoexceptExpr = getNoexceptExpr(); 2895234982Sdim } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { 2896234982Sdim EPI.ExceptionSpecDecl = getExceptionSpecDecl(); 2897234982Sdim EPI.ExceptionSpecTemplate = getExceptionSpecTemplate(); 2898239462Sdim } else if (EPI.ExceptionSpecType == EST_Unevaluated) { 2899239462Sdim EPI.ExceptionSpecDecl = getExceptionSpecDecl(); 2900221345Sdim } 2901224145Sdim if (hasAnyConsumedArgs()) 2902224145Sdim EPI.ConsumedArguments = getConsumedArgsBuffer(); 2903218893Sdim return EPI; 2904218893Sdim } 2905218893Sdim 2906221345Sdim /// \brief Get the kind of exception specification on this function. 2907221345Sdim ExceptionSpecificationType getExceptionSpecType() const { 2908221345Sdim return static_cast<ExceptionSpecificationType>(ExceptionSpecType); 2909221345Sdim } 2910221345Sdim /// \brief Return whether this function has any kind of exception spec. 2911221345Sdim bool hasExceptionSpec() const { 2912221345Sdim return getExceptionSpecType() != EST_None; 2913221345Sdim } 2914221345Sdim /// \brief Return whether this function has a dynamic (throw) exception spec. 2915221345Sdim bool hasDynamicExceptionSpec() const { 2916221345Sdim return isDynamicExceptionSpec(getExceptionSpecType()); 2917221345Sdim } 2918221345Sdim /// \brief Return whether this function has a noexcept exception spec. 2919221345Sdim bool hasNoexceptExceptionSpec() const { 2920221345Sdim return isNoexceptExceptionSpec(getExceptionSpecType()); 2921221345Sdim } 2922221345Sdim /// \brief Result type of getNoexceptSpec(). 2923221345Sdim enum NoexceptResult { 2924221345Sdim NR_NoNoexcept, ///< There is no noexcept specifier. 2925221345Sdim NR_BadNoexcept, ///< The noexcept specifier has a bad expression. 2926221345Sdim NR_Dependent, ///< The noexcept specifier is dependent. 2927221345Sdim NR_Throw, ///< The noexcept specifier evaluates to false. 2928221345Sdim NR_Nothrow ///< The noexcept specifier evaluates to true. 2929221345Sdim }; 2930221345Sdim /// \brief Get the meaning of the noexcept spec on this function, if any. 2931221345Sdim NoexceptResult getNoexceptSpec(ASTContext &Ctx) const; 2932193326Sed unsigned getNumExceptions() const { return NumExceptions; } 2933193326Sed QualType getExceptionType(unsigned i) const { 2934193326Sed assert(i < NumExceptions && "Invalid exception number!"); 2935193326Sed return exception_begin()[i]; 2936193326Sed } 2937221345Sdim Expr *getNoexceptExpr() const { 2938221345Sdim if (getExceptionSpecType() != EST_ComputedNoexcept) 2939221345Sdim return 0; 2940221345Sdim // NoexceptExpr sits where the arguments end. 2941221345Sdim return *reinterpret_cast<Expr *const *>(arg_type_end()); 2942193326Sed } 2943239462Sdim /// \brief If this function type has an exception specification which hasn't 2944239462Sdim /// been determined yet (either because it has not been evaluated or because 2945239462Sdim /// it has not been instantiated), this is the function whose exception 2946239462Sdim /// specification is represented by this type. 2947234982Sdim FunctionDecl *getExceptionSpecDecl() const { 2948239462Sdim if (getExceptionSpecType() != EST_Uninstantiated && 2949239462Sdim getExceptionSpecType() != EST_Unevaluated) 2950234982Sdim return 0; 2951234982Sdim return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0]; 2952234982Sdim } 2953234982Sdim /// \brief If this function type has an uninstantiated exception 2954234982Sdim /// specification, this is the function whose exception specification 2955234982Sdim /// should be instantiated to find the exception specification for 2956234982Sdim /// this type. 2957234982Sdim FunctionDecl *getExceptionSpecTemplate() const { 2958234982Sdim if (getExceptionSpecType() != EST_Uninstantiated) 2959234982Sdim return 0; 2960234982Sdim return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1]; 2961234982Sdim } 2962221345Sdim bool isNothrow(ASTContext &Ctx) const { 2963221345Sdim ExceptionSpecificationType EST = getExceptionSpecType(); 2964239462Sdim assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); 2965221345Sdim if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) 2966221345Sdim return true; 2967221345Sdim if (EST != EST_ComputedNoexcept) 2968221345Sdim return false; 2969221345Sdim return getNoexceptSpec(Ctx) == NR_Nothrow; 2970221345Sdim } 2971193326Sed 2972234353Sdim bool isVariadic() const { return Variadic; } 2973221345Sdim 2974218893Sdim /// \brief Determines whether this function prototype contains a 2975218893Sdim /// parameter pack at the end. 2976218893Sdim /// 2977218893Sdim /// A function template whose last parameter is a parameter pack can be 2978218893Sdim /// called with an arbitrary number of arguments, much like a variadic 2979234353Sdim /// function. 2980218893Sdim bool isTemplateVariadic() const; 2981234353Sdim 2982234353Sdim bool hasTrailingReturn() const { return HasTrailingReturn; } 2983234353Sdim 2984193326Sed unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); } 2985198092Srdivacky 2986234353Sdim 2987218893Sdim /// \brief Retrieve the ref-qualifier associated with this function type. 2988218893Sdim RefQualifierKind getRefQualifier() const { 2989249423Sdim return static_cast<RefQualifierKind>(RefQualifier); 2990218893Sdim } 2991234353Sdim 2992193326Sed typedef const QualType *arg_type_iterator; 2993193326Sed arg_type_iterator arg_type_begin() const { 2994193326Sed return reinterpret_cast<const QualType *>(this+1); 2995193326Sed } 2996193326Sed arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; } 2997193326Sed 2998193326Sed typedef const QualType *exception_iterator; 2999193326Sed exception_iterator exception_begin() const { 3000193326Sed // exceptions begin where arguments end 3001193326Sed return arg_type_end(); 3002193326Sed } 3003193326Sed exception_iterator exception_end() const { 3004221345Sdim if (getExceptionSpecType() != EST_Dynamic) 3005221345Sdim return exception_begin(); 3006193326Sed return exception_begin() + NumExceptions; 3007193326Sed } 3008193326Sed 3009224145Sdim bool hasAnyConsumedArgs() const { 3010224145Sdim return HasAnyConsumedArgs; 3011224145Sdim } 3012224145Sdim bool isArgConsumed(unsigned I) const { 3013224145Sdim assert(I < getNumArgs() && "argument index out of range!"); 3014224145Sdim if (hasAnyConsumedArgs()) 3015224145Sdim return getConsumedArgsBuffer()[I]; 3016224145Sdim return false; 3017224145Sdim } 3018224145Sdim 3019198092Srdivacky bool isSugared() const { return false; } 3020198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3021198092Srdivacky 3022239462Sdim void printExceptionSpecification(raw_ostream &OS, 3023243830Sdim const PrintingPolicy &Policy) const; 3024234353Sdim 3025193326Sed static bool classof(const Type *T) { 3026193326Sed return T->getTypeClass() == FunctionProto; 3027193326Sed } 3028193326Sed 3029221345Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); 3030193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, 3031193326Sed arg_type_iterator ArgTys, unsigned NumArgs, 3032221345Sdim const ExtProtoInfo &EPI, const ASTContext &Context); 3033193326Sed}; 3034193326Sed 3035193326Sed 3036200583Srdivacky/// \brief Represents the dependent type named by a dependently-scoped 3037200583Srdivacky/// typename using declaration, e.g. 3038200583Srdivacky/// using typename Base<T>::foo; 3039200583Srdivacky/// Template instantiation turns these into the underlying type. 3040200583Srdivackyclass UnresolvedUsingType : public Type { 3041200583Srdivacky UnresolvedUsingTypenameDecl *Decl; 3042200583Srdivacky 3043203955Srdivacky UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) 3044234353Sdim : Type(UnresolvedUsing, QualType(), true, true, false, 3045218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3046203955Srdivacky Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {} 3047200583Srdivacky friend class ASTContext; // ASTContext creates these. 3048200583Srdivackypublic: 3049200583Srdivacky 3050200583Srdivacky UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } 3051200583Srdivacky 3052200583Srdivacky bool isSugared() const { return false; } 3053200583Srdivacky QualType desugar() const { return QualType(this, 0); } 3054200583Srdivacky 3055200583Srdivacky static bool classof(const Type *T) { 3056200583Srdivacky return T->getTypeClass() == UnresolvedUsing; 3057200583Srdivacky } 3058200583Srdivacky 3059200583Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3060200583Srdivacky return Profile(ID, Decl); 3061200583Srdivacky } 3062200583Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 3063200583Srdivacky UnresolvedUsingTypenameDecl *D) { 3064200583Srdivacky ID.AddPointer(D); 3065200583Srdivacky } 3066200583Srdivacky}; 3067200583Srdivacky 3068200583Srdivacky 3069193326Sedclass TypedefType : public Type { 3070221345Sdim TypedefNameDecl *Decl; 3071193326Sedprotected: 3072221345Sdim TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) 3073234353Sdim : Type(tc, can, can->isDependentType(), 3074224145Sdim can->isInstantiationDependentType(), 3075234353Sdim can->isVariablyModifiedType(), 3076218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3077221345Sdim Decl(const_cast<TypedefNameDecl*>(D)) { 3078193326Sed assert(!isa<TypedefType>(can) && "Invalid canonical type"); 3079193326Sed } 3080193326Sed friend class ASTContext; // ASTContext creates these. 3081193326Sedpublic: 3082198092Srdivacky 3083221345Sdim TypedefNameDecl *getDecl() const { return Decl; } 3084198092Srdivacky 3085198092Srdivacky bool isSugared() const { return true; } 3086198092Srdivacky QualType desugar() const; 3087198092Srdivacky 3088193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } 3089193326Sed}; 3090193326Sed 3091193326Sed/// TypeOfExprType (GCC extension). 3092193326Sedclass TypeOfExprType : public Type { 3093193326Sed Expr *TOExpr; 3094198092Srdivacky 3095198092Srdivackyprotected: 3096198092Srdivacky TypeOfExprType(Expr *E, QualType can = QualType()); 3097193326Sed friend class ASTContext; // ASTContext creates these. 3098193326Sedpublic: 3099193326Sed Expr *getUnderlyingExpr() const { return TOExpr; } 3100193326Sed 3101198092Srdivacky /// \brief Remove a single level of sugar. 3102198092Srdivacky QualType desugar() const; 3103198092Srdivacky 3104198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3105224145Sdim bool isSugared() const; 3106198092Srdivacky 3107193326Sed static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } 3108193326Sed}; 3109193326Sed 3110203955Srdivacky/// \brief Internal representation of canonical, dependent 3111198092Srdivacky/// typeof(expr) types. 3112203955Srdivacky/// 3113203955Srdivacky/// This class is used internally by the ASTContext to manage 3114203955Srdivacky/// canonical, dependent types, only. Clients will only see instances 3115203955Srdivacky/// of this class via TypeOfExprType nodes. 3116198092Srdivackyclass DependentTypeOfExprType 3117198092Srdivacky : public TypeOfExprType, public llvm::FoldingSetNode { 3118218893Sdim const ASTContext &Context; 3119198092Srdivacky 3120198092Srdivackypublic: 3121218893Sdim DependentTypeOfExprType(const ASTContext &Context, Expr *E) 3122198092Srdivacky : TypeOfExprType(E), Context(Context) { } 3123198092Srdivacky 3124198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3125198092Srdivacky Profile(ID, Context, getUnderlyingExpr()); 3126198092Srdivacky } 3127198092Srdivacky 3128218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 3129198092Srdivacky Expr *E); 3130198092Srdivacky}; 3131198092Srdivacky 3132193326Sed/// TypeOfType (GCC extension). 3133193326Sedclass TypeOfType : public Type { 3134193326Sed QualType TOType; 3135198092Srdivacky TypeOfType(QualType T, QualType can) 3136234353Sdim : Type(TypeOf, can, T->isDependentType(), 3137224145Sdim T->isInstantiationDependentType(), 3138234353Sdim T->isVariablyModifiedType(), 3139234353Sdim T->containsUnexpandedParameterPack()), 3140218893Sdim TOType(T) { 3141193326Sed assert(!isa<TypedefType>(can) && "Invalid canonical type"); 3142193326Sed } 3143193326Sed friend class ASTContext; // ASTContext creates these. 3144193326Sedpublic: 3145193326Sed QualType getUnderlyingType() const { return TOType; } 3146193326Sed 3147198092Srdivacky /// \brief Remove a single level of sugar. 3148198092Srdivacky QualType desugar() const { return getUnderlyingType(); } 3149198092Srdivacky 3150198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3151198092Srdivacky bool isSugared() const { return true; } 3152198092Srdivacky 3153193326Sed static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } 3154193326Sed}; 3155193326Sed 3156195099Sed/// DecltypeType (C++0x) 3157195099Sedclass DecltypeType : public Type { 3158195099Sed Expr *E; 3159198092Srdivacky QualType UnderlyingType; 3160198092Srdivacky 3161198092Srdivackyprotected: 3162198092Srdivacky DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); 3163195099Sed friend class ASTContext; // ASTContext creates these. 3164195099Sedpublic: 3165195099Sed Expr *getUnderlyingExpr() const { return E; } 3166198092Srdivacky QualType getUnderlyingType() const { return UnderlyingType; } 3167198092Srdivacky 3168198092Srdivacky /// \brief Remove a single level of sugar. 3169224145Sdim QualType desugar() const; 3170198092Srdivacky 3171198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3172224145Sdim bool isSugared() const; 3173198092Srdivacky 3174195099Sed static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } 3175195099Sed}; 3176198092Srdivacky 3177203955Srdivacky/// \brief Internal representation of canonical, dependent 3178203955Srdivacky/// decltype(expr) types. 3179203955Srdivacky/// 3180203955Srdivacky/// This class is used internally by the ASTContext to manage 3181203955Srdivacky/// canonical, dependent types, only. Clients will only see instances 3182203955Srdivacky/// of this class via DecltypeType nodes. 3183198092Srdivackyclass DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { 3184218893Sdim const ASTContext &Context; 3185198092Srdivacky 3186198092Srdivackypublic: 3187218893Sdim DependentDecltypeType(const ASTContext &Context, Expr *E); 3188198092Srdivacky 3189198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3190198092Srdivacky Profile(ID, Context, getUnderlyingExpr()); 3191198092Srdivacky } 3192198092Srdivacky 3193218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 3194198092Srdivacky Expr *E); 3195198092Srdivacky}; 3196198092Srdivacky 3197223017Sdim/// \brief A unary type transform, which is a type constructed from another 3198223017Sdimclass UnaryTransformType : public Type { 3199223017Sdimpublic: 3200223017Sdim enum UTTKind { 3201223017Sdim EnumUnderlyingType 3202223017Sdim }; 3203223017Sdim 3204223017Sdimprivate: 3205223017Sdim /// The untransformed type. 3206223017Sdim QualType BaseType; 3207223017Sdim /// The transformed type if not dependent, otherwise the same as BaseType. 3208223017Sdim QualType UnderlyingType; 3209223017Sdim 3210223017Sdim UTTKind UKind; 3211223017Sdimprotected: 3212223017Sdim UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, 3213223017Sdim QualType CanonicalTy); 3214223017Sdim friend class ASTContext; 3215223017Sdimpublic: 3216223017Sdim bool isSugared() const { return !isDependentType(); } 3217223017Sdim QualType desugar() const { return UnderlyingType; } 3218223017Sdim 3219223017Sdim QualType getUnderlyingType() const { return UnderlyingType; } 3220223017Sdim QualType getBaseType() const { return BaseType; } 3221223017Sdim 3222223017Sdim UTTKind getUTTKind() const { return UKind; } 3223234353Sdim 3224223017Sdim static bool classof(const Type *T) { 3225223017Sdim return T->getTypeClass() == UnaryTransform; 3226223017Sdim } 3227223017Sdim}; 3228223017Sdim 3229193326Sedclass TagType : public Type { 3230212904Sdim /// Stores the TagDecl associated with this type. The decl may point to any 3231212904Sdim /// TagDecl that declares the entity. 3232212904Sdim TagDecl * decl; 3233193326Sed 3234234353Sdim friend class ASTReader; 3235234353Sdim 3236193326Sedprotected: 3237203955Srdivacky TagType(TypeClass TC, const TagDecl *D, QualType can); 3238193326Sed 3239198092Srdivackypublic: 3240212904Sdim TagDecl *getDecl() const; 3241198092Srdivacky 3242193326Sed /// @brief Determines whether this type is in the process of being 3243198092Srdivacky /// defined. 3244212904Sdim bool isBeingDefined() const; 3245193326Sed 3246198092Srdivacky static bool classof(const Type *T) { 3247193326Sed return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; 3248193326Sed } 3249193326Sed}; 3250193326Sed 3251193326Sed/// RecordType - This is a helper class that allows the use of isa/cast/dyncast 3252193326Sed/// to detect TagType objects of structs/unions/classes. 3253193326Sedclass RecordType : public TagType { 3254193326Sedprotected: 3255203955Srdivacky explicit RecordType(const RecordDecl *D) 3256203955Srdivacky : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3257193326Sed explicit RecordType(TypeClass TC, RecordDecl *D) 3258203955Srdivacky : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3259193326Sed friend class ASTContext; // ASTContext creates these. 3260193326Sedpublic: 3261198092Srdivacky 3262193326Sed RecordDecl *getDecl() const { 3263193326Sed return reinterpret_cast<RecordDecl*>(TagType::getDecl()); 3264193326Sed } 3265198092Srdivacky 3266198092Srdivacky // FIXME: This predicate is a helper to QualType/Type. It needs to 3267193326Sed // recursively check all fields for const-ness. If any field is declared 3268198092Srdivacky // const, it needs to return false. 3269193326Sed bool hasConstFields() const { return false; } 3270193326Sed 3271198092Srdivacky bool isSugared() const { return false; } 3272198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3273198092Srdivacky 3274234353Sdim static bool classof(const Type *T) { return T->getTypeClass() == Record; } 3275193326Sed}; 3276193326Sed 3277193326Sed/// EnumType - This is a helper class that allows the use of isa/cast/dyncast 3278193326Sed/// to detect TagType objects of enums. 3279193326Sedclass EnumType : public TagType { 3280203955Srdivacky explicit EnumType(const EnumDecl *D) 3281203955Srdivacky : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3282193326Sed friend class ASTContext; // ASTContext creates these. 3283193326Sedpublic: 3284198092Srdivacky 3285193326Sed EnumDecl *getDecl() const { 3286193326Sed return reinterpret_cast<EnumDecl*>(TagType::getDecl()); 3287193326Sed } 3288198092Srdivacky 3289198092Srdivacky bool isSugared() const { return false; } 3290198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3291198092Srdivacky 3292234353Sdim static bool classof(const Type *T) { return T->getTypeClass() == Enum; } 3293193326Sed}; 3294193326Sed 3295218893Sdim/// AttributedType - An attributed type is a type to which a type 3296218893Sdim/// attribute has been applied. The "modified type" is the 3297218893Sdim/// fully-sugared type to which the attributed type was applied; 3298218893Sdim/// generally it is not canonically equivalent to the attributed type. 3299218893Sdim/// The "equivalent type" is the minimally-desugared type which the 3300218893Sdim/// type is canonically equivalent to. 3301218893Sdim/// 3302218893Sdim/// For example, in the following attributed type: 3303218893Sdim/// int32_t __attribute__((vector_size(16))) 3304218893Sdim/// - the modified type is the TypedefType for int32_t 3305218893Sdim/// - the equivalent type is VectorType(16, int32_t) 3306218893Sdim/// - the canonical type is VectorType(16, int) 3307218893Sdimclass AttributedType : public Type, public llvm::FoldingSetNode { 3308218893Sdimpublic: 3309218893Sdim // It is really silly to have yet another attribute-kind enum, but 3310218893Sdim // clang::attr::Kind doesn't currently cover the pure type attrs. 3311218893Sdim enum Kind { 3312218893Sdim // Expression operand. 3313218893Sdim attr_address_space, 3314218893Sdim attr_regparm, 3315218893Sdim attr_vector_size, 3316218893Sdim attr_neon_vector_type, 3317218893Sdim attr_neon_polyvector_type, 3318218893Sdim 3319218893Sdim FirstExprOperandKind = attr_address_space, 3320218893Sdim LastExprOperandKind = attr_neon_polyvector_type, 3321218893Sdim 3322218893Sdim // Enumerated operand (string or keyword). 3323218893Sdim attr_objc_gc, 3324224145Sdim attr_objc_ownership, 3325221345Sdim attr_pcs, 3326218893Sdim 3327218893Sdim FirstEnumOperandKind = attr_objc_gc, 3328221345Sdim LastEnumOperandKind = attr_pcs, 3329218893Sdim 3330218893Sdim // No operand. 3331218893Sdim attr_noreturn, 3332218893Sdim attr_cdecl, 3333218893Sdim attr_fastcall, 3334218893Sdim attr_stdcall, 3335218893Sdim attr_thiscall, 3336243830Sdim attr_pascal, 3337249423Sdim attr_pnaclcall, 3338249423Sdim attr_inteloclbicc 3339218893Sdim }; 3340218893Sdim 3341218893Sdimprivate: 3342218893Sdim QualType ModifiedType; 3343218893Sdim QualType EquivalentType; 3344218893Sdim 3345218893Sdim friend class ASTContext; // creates these 3346218893Sdim 3347218893Sdim AttributedType(QualType canon, Kind attrKind, 3348218893Sdim QualType modified, QualType equivalent) 3349218893Sdim : Type(Attributed, canon, canon->isDependentType(), 3350224145Sdim canon->isInstantiationDependentType(), 3351218893Sdim canon->isVariablyModifiedType(), 3352218893Sdim canon->containsUnexpandedParameterPack()), 3353218893Sdim ModifiedType(modified), EquivalentType(equivalent) { 3354218893Sdim AttributedTypeBits.AttrKind = attrKind; 3355218893Sdim } 3356218893Sdim 3357218893Sdimpublic: 3358218893Sdim Kind getAttrKind() const { 3359218893Sdim return static_cast<Kind>(AttributedTypeBits.AttrKind); 3360218893Sdim } 3361218893Sdim 3362218893Sdim QualType getModifiedType() const { return ModifiedType; } 3363218893Sdim QualType getEquivalentType() const { return EquivalentType; } 3364218893Sdim 3365218893Sdim bool isSugared() const { return true; } 3366218893Sdim QualType desugar() const { return getEquivalentType(); } 3367218893Sdim 3368218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 3369218893Sdim Profile(ID, getAttrKind(), ModifiedType, EquivalentType); 3370218893Sdim } 3371218893Sdim 3372218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, 3373218893Sdim QualType modified, QualType equivalent) { 3374218893Sdim ID.AddInteger(attrKind); 3375218893Sdim ID.AddPointer(modified.getAsOpaquePtr()); 3376218893Sdim ID.AddPointer(equivalent.getAsOpaquePtr()); 3377218893Sdim } 3378218893Sdim 3379218893Sdim static bool classof(const Type *T) { 3380218893Sdim return T->getTypeClass() == Attributed; 3381218893Sdim } 3382218893Sdim}; 3383218893Sdim 3384193326Sedclass TemplateTypeParmType : public Type, public llvm::FoldingSetNode { 3385221345Sdim // Helper data collector for canonical types. 3386221345Sdim struct CanonicalTTPTInfo { 3387221345Sdim unsigned Depth : 15; 3388221345Sdim unsigned ParameterPack : 1; 3389221345Sdim unsigned Index : 16; 3390221345Sdim }; 3391193326Sed 3392221345Sdim union { 3393221345Sdim // Info for the canonical type. 3394221345Sdim CanonicalTTPTInfo CanTTPTInfo; 3395221345Sdim // Info for the non-canonical type. 3396221345Sdim TemplateTypeParmDecl *TTPDecl; 3397221345Sdim }; 3398221345Sdim 3399221345Sdim /// Build a non-canonical type. 3400221345Sdim TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) 3401218893Sdim : Type(TemplateTypeParm, Canon, /*Dependent=*/true, 3402224145Sdim /*InstantiationDependent=*/true, 3403221345Sdim /*VariablyModified=*/false, 3404221345Sdim Canon->containsUnexpandedParameterPack()), 3405221345Sdim TTPDecl(TTPDecl) { } 3406193326Sed 3407221345Sdim /// Build the canonical type. 3408198092Srdivacky TemplateTypeParmType(unsigned D, unsigned I, bool PP) 3409234353Sdim : Type(TemplateTypeParm, QualType(this, 0), 3410224145Sdim /*Dependent=*/true, 3411224145Sdim /*InstantiationDependent=*/true, 3412221345Sdim /*VariablyModified=*/false, PP) { 3413221345Sdim CanTTPTInfo.Depth = D; 3414221345Sdim CanTTPTInfo.Index = I; 3415221345Sdim CanTTPTInfo.ParameterPack = PP; 3416221345Sdim } 3417193326Sed 3418193326Sed friend class ASTContext; // ASTContext creates these 3419193326Sed 3420221345Sdim const CanonicalTTPTInfo& getCanTTPTInfo() const { 3421221345Sdim QualType Can = getCanonicalTypeInternal(); 3422221345Sdim return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo; 3423221345Sdim } 3424221345Sdim 3425193326Sedpublic: 3426221345Sdim unsigned getDepth() const { return getCanTTPTInfo().Depth; } 3427221345Sdim unsigned getIndex() const { return getCanTTPTInfo().Index; } 3428221345Sdim bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; } 3429193326Sed 3430221345Sdim TemplateTypeParmDecl *getDecl() const { 3431221345Sdim return isCanonicalUnqualified() ? 0 : TTPDecl; 3432221345Sdim } 3433221345Sdim 3434221345Sdim IdentifierInfo *getIdentifier() const; 3435221345Sdim 3436198092Srdivacky bool isSugared() const { return false; } 3437198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3438198092Srdivacky 3439193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 3440221345Sdim Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); 3441193326Sed } 3442193326Sed 3443198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, 3444198092Srdivacky unsigned Index, bool ParameterPack, 3445221345Sdim TemplateTypeParmDecl *TTPDecl) { 3446193326Sed ID.AddInteger(Depth); 3447193326Sed ID.AddInteger(Index); 3448194613Sed ID.AddBoolean(ParameterPack); 3449221345Sdim ID.AddPointer(TTPDecl); 3450193326Sed } 3451193326Sed 3452198092Srdivacky static bool classof(const Type *T) { 3453198092Srdivacky return T->getTypeClass() == TemplateTypeParm; 3454193326Sed } 3455193326Sed}; 3456193326Sed 3457198398Srdivacky/// \brief Represents the result of substituting a type for a template 3458198398Srdivacky/// type parameter. 3459198398Srdivacky/// 3460198398Srdivacky/// Within an instantiated template, all template type parameters have 3461198398Srdivacky/// been replaced with these. They are used solely to record that a 3462198398Srdivacky/// type was originally written as a template type parameter; 3463198398Srdivacky/// therefore they are never canonical. 3464198398Srdivackyclass SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { 3465198398Srdivacky // The original type parameter. 3466198398Srdivacky const TemplateTypeParmType *Replaced; 3467198398Srdivacky 3468198398Srdivacky SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) 3469218893Sdim : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), 3470224145Sdim Canon->isInstantiationDependentType(), 3471218893Sdim Canon->isVariablyModifiedType(), 3472218893Sdim Canon->containsUnexpandedParameterPack()), 3473198398Srdivacky Replaced(Param) { } 3474198398Srdivacky 3475198398Srdivacky friend class ASTContext; 3476198398Srdivacky 3477198398Srdivackypublic: 3478198398Srdivacky /// Gets the template parameter that was substituted for. 3479198398Srdivacky const TemplateTypeParmType *getReplacedParameter() const { 3480198398Srdivacky return Replaced; 3481198398Srdivacky } 3482198398Srdivacky 3483198398Srdivacky /// Gets the type that was substituted for the template 3484198398Srdivacky /// parameter. 3485198398Srdivacky QualType getReplacementType() const { 3486198398Srdivacky return getCanonicalTypeInternal(); 3487198398Srdivacky } 3488198398Srdivacky 3489198398Srdivacky bool isSugared() const { return true; } 3490198398Srdivacky QualType desugar() const { return getReplacementType(); } 3491198398Srdivacky 3492198398Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3493198398Srdivacky Profile(ID, getReplacedParameter(), getReplacementType()); 3494198398Srdivacky } 3495198398Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 3496198398Srdivacky const TemplateTypeParmType *Replaced, 3497198398Srdivacky QualType Replacement) { 3498198398Srdivacky ID.AddPointer(Replaced); 3499198398Srdivacky ID.AddPointer(Replacement.getAsOpaquePtr()); 3500198398Srdivacky } 3501198398Srdivacky 3502198398Srdivacky static bool classof(const Type *T) { 3503198398Srdivacky return T->getTypeClass() == SubstTemplateTypeParm; 3504198398Srdivacky } 3505198398Srdivacky}; 3506198398Srdivacky 3507218893Sdim/// \brief Represents the result of substituting a set of types for a template 3508218893Sdim/// type parameter pack. 3509218893Sdim/// 3510218893Sdim/// When a pack expansion in the source code contains multiple parameter packs 3511218893Sdim/// and those parameter packs correspond to different levels of template 3512234353Sdim/// parameter lists, this type node is used to represent a template type 3513218893Sdim/// parameter pack from an outer level, which has already had its argument pack 3514218893Sdim/// substituted but that still lives within a pack expansion that itself 3515218893Sdim/// could not be instantiated. When actually performing a substitution into 3516218893Sdim/// that pack expansion (e.g., when all template parameters have corresponding 3517218893Sdim/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType 3518218893Sdim/// at the current pack substitution index. 3519218893Sdimclass SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { 3520218893Sdim /// \brief The original type parameter. 3521218893Sdim const TemplateTypeParmType *Replaced; 3522234353Sdim 3523218893Sdim /// \brief A pointer to the set of template arguments that this 3524218893Sdim /// parameter pack is instantiated with. 3525218893Sdim const TemplateArgument *Arguments; 3526234353Sdim 3527218893Sdim /// \brief The number of template arguments in \c Arguments. 3528218893Sdim unsigned NumArguments; 3529234353Sdim 3530234353Sdim SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, 3531218893Sdim QualType Canon, 3532218893Sdim const TemplateArgument &ArgPack); 3533234353Sdim 3534218893Sdim friend class ASTContext; 3535234353Sdim 3536218893Sdimpublic: 3537221345Sdim IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } 3538234353Sdim 3539218893Sdim /// Gets the template parameter that was substituted for. 3540218893Sdim const TemplateTypeParmType *getReplacedParameter() const { 3541218893Sdim return Replaced; 3542218893Sdim } 3543234353Sdim 3544218893Sdim bool isSugared() const { return false; } 3545218893Sdim QualType desugar() const { return QualType(this, 0); } 3546234353Sdim 3547218893Sdim TemplateArgument getArgumentPack() const; 3548234353Sdim 3549218893Sdim void Profile(llvm::FoldingSetNodeID &ID); 3550218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, 3551218893Sdim const TemplateTypeParmType *Replaced, 3552218893Sdim const TemplateArgument &ArgPack); 3553234353Sdim 3554218893Sdim static bool classof(const Type *T) { 3555218893Sdim return T->getTypeClass() == SubstTemplateTypeParmPack; 3556218893Sdim } 3557218893Sdim}; 3558218893Sdim 3559251662Sdim/// \brief Represents a C++11 auto or C++1y decltype(auto) type. 3560218893Sdim/// 3561251662Sdim/// These types are usually a placeholder for a deduced type. However, before 3562251662Sdim/// the initializer is attached, or if the initializer is type-dependent, there 3563251662Sdim/// is no deduced type and an auto type is canonical. In the latter case, it is 3564251662Sdim/// also a dependent type. 3565218893Sdimclass AutoType : public Type, public llvm::FoldingSetNode { 3566251662Sdim AutoType(QualType DeducedType, bool IsDecltypeAuto, bool IsDependent) 3567218893Sdim : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, 3568251662Sdim /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent, 3569218893Sdim /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { 3570251662Sdim assert((DeducedType.isNull() || !IsDependent) && 3571251662Sdim "auto deduced to dependent type"); 3572251662Sdim AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto; 3573218893Sdim } 3574218893Sdim 3575218893Sdim friend class ASTContext; // ASTContext creates these 3576218893Sdim 3577218893Sdimpublic: 3578251662Sdim bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; } 3579251662Sdim 3580251662Sdim bool isSugared() const { return !isCanonicalUnqualified(); } 3581218893Sdim QualType desugar() const { return getCanonicalTypeInternal(); } 3582218893Sdim 3583251662Sdim /// \brief Get the type deduced for this auto type, or null if it's either 3584251662Sdim /// not been deduced or was deduced to a dependent type. 3585218893Sdim QualType getDeducedType() const { 3586251662Sdim return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType(); 3587218893Sdim } 3588218893Sdim bool isDeduced() const { 3589251662Sdim return !isCanonicalUnqualified() || isDependentType(); 3590218893Sdim } 3591218893Sdim 3592218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 3593251662Sdim Profile(ID, getDeducedType(), isDecltypeAuto(), isDependentType()); 3594218893Sdim } 3595218893Sdim 3596251662Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, 3597251662Sdim bool IsDecltypeAuto, bool IsDependent) { 3598218893Sdim ID.AddPointer(Deduced.getAsOpaquePtr()); 3599251662Sdim ID.AddBoolean(IsDecltypeAuto); 3600251662Sdim ID.AddBoolean(IsDependent); 3601218893Sdim } 3602218893Sdim 3603218893Sdim static bool classof(const Type *T) { 3604218893Sdim return T->getTypeClass() == Auto; 3605218893Sdim } 3606218893Sdim}; 3607218893Sdim 3608224145Sdim/// \brief Represents a type template specialization; the template 3609224145Sdim/// must be a class template, a type alias template, or a template 3610224145Sdim/// template parameter. A template which cannot be resolved to one of 3611224145Sdim/// these, e.g. because it is written with a dependent scope 3612224145Sdim/// specifier, is instead represented as a 3613224145Sdim/// @c DependentTemplateSpecializationType. 3614193326Sed/// 3615224145Sdim/// A non-dependent template specialization type is always "sugar", 3616224145Sdim/// typically for a @c RecordType. For example, a class template 3617224145Sdim/// specialization type of @c vector<int> will refer to a tag type for 3618224145Sdim/// the instantiation @c std::vector<int, std::allocator<int>> 3619193326Sed/// 3620224145Sdim/// Template specializations are dependent if either the template or 3621224145Sdim/// any of the template arguments are dependent, in which case the 3622224145Sdim/// type may also be canonical. 3623223017Sdim/// 3624224145Sdim/// Instances of this type are allocated with a trailing array of 3625224145Sdim/// TemplateArguments, followed by a QualType representing the 3626224145Sdim/// non-canonical aliased type when the template is a type alias 3627224145Sdim/// template. 3628198092Srdivackyclass TemplateSpecializationType 3629193326Sed : public Type, public llvm::FoldingSetNode { 3630224145Sdim /// \brief The name of the template being specialized. This is 3631224145Sdim /// either a TemplateName::Template (in which case it is a 3632224145Sdim /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a 3633224145Sdim /// TypeAliasTemplateDecl*), a 3634224145Sdim /// TemplateName::SubstTemplateTemplateParmPack, or a 3635224145Sdim /// TemplateName::SubstTemplateTemplateParm (in which case the 3636224145Sdim /// replacement must, recursively, be one of these). 3637193326Sed TemplateName Template; 3638193326Sed 3639193326Sed /// \brief - The number of template arguments named in this class 3640193326Sed /// template specialization. 3641234353Sdim unsigned NumArgs : 31; 3642193326Sed 3643234353Sdim /// \brief Whether this template specialization type is a substituted 3644234353Sdim /// type alias. 3645234353Sdim bool TypeAlias : 1; 3646234353Sdim 3647210299Sed TemplateSpecializationType(TemplateName T, 3648193326Sed const TemplateArgument *Args, 3649223017Sdim unsigned NumArgs, QualType Canon, 3650223017Sdim QualType Aliased); 3651193326Sed 3652193326Sed friend class ASTContext; // ASTContext creates these 3653193326Sed 3654193326Sedpublic: 3655193326Sed /// \brief Determine whether any of the given template arguments are 3656193326Sed /// dependent. 3657193326Sed static bool anyDependentTemplateArguments(const TemplateArgument *Args, 3658224145Sdim unsigned NumArgs, 3659224145Sdim bool &InstantiationDependent); 3660193326Sed 3661198893Srdivacky static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, 3662224145Sdim unsigned NumArgs, 3663224145Sdim bool &InstantiationDependent); 3664198893Srdivacky 3665224145Sdim static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, 3666224145Sdim bool &InstantiationDependent); 3667199990Srdivacky 3668193326Sed /// \brief Print a template argument list, including the '<' and '>' 3669193326Sed /// enclosing the template arguments. 3670239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3671239462Sdim const TemplateArgument *Args, 3672239462Sdim unsigned NumArgs, 3673239462Sdim const PrintingPolicy &Policy, 3674239462Sdim bool SkipBrackets = false); 3675239462Sdim 3676239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3677239462Sdim const TemplateArgumentLoc *Args, 3678239462Sdim unsigned NumArgs, 3679239462Sdim const PrintingPolicy &Policy); 3680239462Sdim 3681239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3682239462Sdim const TemplateArgumentListInfo &, 3683239462Sdim const PrintingPolicy &Policy); 3684239462Sdim 3685207619Srdivacky /// True if this template specialization type matches a current 3686207619Srdivacky /// instantiation in the context in which it is found. 3687207619Srdivacky bool isCurrentInstantiation() const { 3688210299Sed return isa<InjectedClassNameType>(getCanonicalTypeInternal()); 3689207619Srdivacky } 3690207619Srdivacky 3691234353Sdim /// \brief Determine if this template specialization type is for a type alias 3692234353Sdim /// template that has been substituted. 3693234353Sdim /// 3694234353Sdim /// Nearly every template specialization type whose template is an alias 3695234353Sdim /// template will be substituted. However, this is not the case when 3696234353Sdim /// the specialization contains a pack expansion but the template alias 3697234353Sdim /// does not have a corresponding parameter pack, e.g., 3698234353Sdim /// 3699234353Sdim /// \code 3700234353Sdim /// template<typename T, typename U, typename V> struct S; 3701234353Sdim /// template<typename T, typename U> using A = S<T, int, U>; 3702234353Sdim /// template<typename... Ts> struct X { 3703234353Sdim /// typedef A<Ts...> type; // not a type alias 3704234353Sdim /// }; 3705234353Sdim /// \endcode 3706234353Sdim bool isTypeAlias() const { return TypeAlias; } 3707234353Sdim 3708223017Sdim /// Get the aliased type, if this is a specialization of a type alias 3709223017Sdim /// template. 3710223017Sdim QualType getAliasedType() const { 3711223017Sdim assert(isTypeAlias() && "not a type alias template specialization"); 3712223017Sdim return *reinterpret_cast<const QualType*>(end()); 3713223017Sdim } 3714223017Sdim 3715193326Sed typedef const TemplateArgument * iterator; 3716193326Sed 3717193326Sed iterator begin() const { return getArgs(); } 3718210299Sed iterator end() const; // defined inline in TemplateBase.h 3719193326Sed 3720193326Sed /// \brief Retrieve the name of the template that we are specializing. 3721193326Sed TemplateName getTemplateName() const { return Template; } 3722193326Sed 3723193326Sed /// \brief Retrieve the template arguments. 3724198092Srdivacky const TemplateArgument *getArgs() const { 3725193326Sed return reinterpret_cast<const TemplateArgument *>(this + 1); 3726193326Sed } 3727193326Sed 3728193326Sed /// \brief Retrieve the number of template arguments. 3729193326Sed unsigned getNumArgs() const { return NumArgs; } 3730193326Sed 3731193326Sed /// \brief Retrieve a specific template argument as a type. 3732239462Sdim /// \pre @c isArgType(Arg) 3733210299Sed const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h 3734193326Sed 3735207619Srdivacky bool isSugared() const { 3736223017Sdim return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); 3737207619Srdivacky } 3738198092Srdivacky QualType desugar() const { return getCanonicalTypeInternal(); } 3739198092Srdivacky 3740218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { 3741210299Sed Profile(ID, Template, getArgs(), NumArgs, Ctx); 3742223017Sdim if (isTypeAlias()) 3743223017Sdim getAliasedType().Profile(ID); 3744193326Sed } 3745193326Sed 3746193326Sed static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, 3747207619Srdivacky const TemplateArgument *Args, 3748207619Srdivacky unsigned NumArgs, 3749218893Sdim const ASTContext &Context); 3750193326Sed 3751198092Srdivacky static bool classof(const Type *T) { 3752198092Srdivacky return T->getTypeClass() == TemplateSpecialization; 3753193326Sed } 3754193326Sed}; 3755193326Sed 3756207619Srdivacky/// \brief The injected class name of a C++ class template or class 3757207619Srdivacky/// template partial specialization. Used to record that a type was 3758207619Srdivacky/// spelled with a bare identifier rather than as a template-id; the 3759207619Srdivacky/// equivalent for non-templated classes is just RecordType. 3760204962Srdivacky/// 3761207619Srdivacky/// Injected class name types are always dependent. Template 3762207619Srdivacky/// instantiation turns these into RecordTypes. 3763204962Srdivacky/// 3764207619Srdivacky/// Injected class name types are always canonical. This works 3765207619Srdivacky/// because it is impossible to compare an injected class name type 3766207619Srdivacky/// with the corresponding non-injected template type, for the same 3767207619Srdivacky/// reason that it is impossible to directly compare template 3768207619Srdivacky/// parameters from different dependent contexts: injected class name 3769207619Srdivacky/// types can only occur within the scope of a particular templated 3770207619Srdivacky/// declaration, and within that scope every template specialization 3771207619Srdivacky/// will canonicalize to the injected class name (when appropriate 3772207619Srdivacky/// according to the rules of the language). 3773204962Srdivackyclass InjectedClassNameType : public Type { 3774204962Srdivacky CXXRecordDecl *Decl; 3775204962Srdivacky 3776207619Srdivacky /// The template specialization which this type represents. 3777207619Srdivacky /// For example, in 3778207619Srdivacky /// template <class T> class A { ... }; 3779207619Srdivacky /// this is A<T>, whereas in 3780207619Srdivacky /// template <class X, class Y> class A<B<X,Y> > { ... }; 3781207619Srdivacky /// this is A<B<X,Y> >. 3782207619Srdivacky /// 3783207619Srdivacky /// It is always unqualified, always a template specialization type, 3784207619Srdivacky /// and always dependent. 3785207619Srdivacky QualType InjectedType; 3786204962Srdivacky 3787204962Srdivacky friend class ASTContext; // ASTContext creates these. 3788212904Sdim friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not 3789212904Sdim // currently suitable for AST reading, too much 3790210299Sed // interdependencies. 3791207619Srdivacky InjectedClassNameType(CXXRecordDecl *D, QualType TST) 3792218893Sdim : Type(InjectedClassName, QualType(), /*Dependent=*/true, 3793224145Sdim /*InstantiationDependent=*/true, 3794234353Sdim /*VariablyModified=*/false, 3795218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3796207619Srdivacky Decl(D), InjectedType(TST) { 3797204962Srdivacky assert(isa<TemplateSpecializationType>(TST)); 3798204962Srdivacky assert(!TST.hasQualifiers()); 3799207619Srdivacky assert(TST->isDependentType()); 3800204962Srdivacky } 3801204962Srdivacky 3802204962Srdivackypublic: 3803207619Srdivacky QualType getInjectedSpecializationType() const { return InjectedType; } 3804207619Srdivacky const TemplateSpecializationType *getInjectedTST() const { 3805207619Srdivacky return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); 3806204962Srdivacky } 3807204962Srdivacky 3808212904Sdim CXXRecordDecl *getDecl() const; 3809204962Srdivacky 3810207619Srdivacky bool isSugared() const { return false; } 3811207619Srdivacky QualType desugar() const { return QualType(this, 0); } 3812204962Srdivacky 3813204962Srdivacky static bool classof(const Type *T) { 3814204962Srdivacky return T->getTypeClass() == InjectedClassName; 3815204962Srdivacky } 3816204962Srdivacky}; 3817204962Srdivacky 3818208600Srdivacky/// \brief The kind of a tag type. 3819208600Srdivackyenum TagTypeKind { 3820208600Srdivacky /// \brief The "struct" keyword. 3821208600Srdivacky TTK_Struct, 3822243830Sdim /// \brief The "__interface" keyword. 3823243830Sdim TTK_Interface, 3824208600Srdivacky /// \brief The "union" keyword. 3825208600Srdivacky TTK_Union, 3826208600Srdivacky /// \brief The "class" keyword. 3827208600Srdivacky TTK_Class, 3828208600Srdivacky /// \brief The "enum" keyword. 3829208600Srdivacky TTK_Enum 3830208600Srdivacky}; 3831208600Srdivacky 3832206084Srdivacky/// \brief The elaboration keyword that precedes a qualified type name or 3833206084Srdivacky/// introduces an elaborated-type-specifier. 3834206084Srdivackyenum ElaboratedTypeKeyword { 3835206084Srdivacky /// \brief The "struct" keyword introduces the elaborated-type-specifier. 3836206084Srdivacky ETK_Struct, 3837243830Sdim /// \brief The "__interface" keyword introduces the elaborated-type-specifier. 3838243830Sdim ETK_Interface, 3839206084Srdivacky /// \brief The "union" keyword introduces the elaborated-type-specifier. 3840206084Srdivacky ETK_Union, 3841208600Srdivacky /// \brief The "class" keyword introduces the elaborated-type-specifier. 3842208600Srdivacky ETK_Class, 3843206084Srdivacky /// \brief The "enum" keyword introduces the elaborated-type-specifier. 3844208600Srdivacky ETK_Enum, 3845208600Srdivacky /// \brief The "typename" keyword precedes the qualified type name, e.g., 3846208600Srdivacky /// \c typename T::type. 3847208600Srdivacky ETK_Typename, 3848208600Srdivacky /// \brief No keyword precedes the qualified type name. 3849208600Srdivacky ETK_None 3850206084Srdivacky}; 3851208600Srdivacky 3852208600Srdivacky/// A helper class for Type nodes having an ElaboratedTypeKeyword. 3853208600Srdivacky/// The keyword in stored in the free bits of the base class. 3854208600Srdivacky/// Also provides a few static helpers for converting and printing 3855208600Srdivacky/// elaborated type keyword and tag type kind enumerations. 3856208600Srdivackyclass TypeWithKeyword : public Type { 3857208600Srdivackyprotected: 3858208600Srdivacky TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, 3859234353Sdim QualType Canonical, bool Dependent, 3860234353Sdim bool InstantiationDependent, bool VariablyModified, 3861218893Sdim bool ContainsUnexpandedParameterPack) 3862234353Sdim : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, 3863218893Sdim ContainsUnexpandedParameterPack) { 3864218893Sdim TypeWithKeywordBits.Keyword = Keyword; 3865218893Sdim } 3866208600Srdivacky 3867208600Srdivackypublic: 3868208600Srdivacky ElaboratedTypeKeyword getKeyword() const { 3869218893Sdim return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); 3870208600Srdivacky } 3871208600Srdivacky 3872208600Srdivacky /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST) 3873208600Srdivacky /// into an elaborated type keyword. 3874208600Srdivacky static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); 3875208600Srdivacky 3876208600Srdivacky /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST) 3877208600Srdivacky /// into a tag type kind. It is an error to provide a type specifier 3878208600Srdivacky /// which *isn't* a tag kind here. 3879208600Srdivacky static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); 3880208600Srdivacky 3881208600Srdivacky /// getKeywordForTagDeclKind - Converts a TagTypeKind into an 3882208600Srdivacky /// elaborated type keyword. 3883208600Srdivacky static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); 3884208600Srdivacky 3885208600Srdivacky /// getTagTypeKindForKeyword - Converts an elaborated type keyword into 3886208600Srdivacky // a TagTypeKind. It is an error to provide an elaborated type keyword 3887208600Srdivacky /// which *isn't* a tag kind here. 3888208600Srdivacky static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); 3889208600Srdivacky 3890208600Srdivacky static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); 3891208600Srdivacky 3892208600Srdivacky static const char *getKeywordName(ElaboratedTypeKeyword Keyword); 3893208600Srdivacky 3894208600Srdivacky static const char *getTagTypeKindName(TagTypeKind Kind) { 3895208600Srdivacky return getKeywordName(getKeywordForTagTypeKind(Kind)); 3896208600Srdivacky } 3897208600Srdivacky 3898208600Srdivacky class CannotCastToThisType {}; 3899208600Srdivacky static CannotCastToThisType classof(const Type *); 3900208600Srdivacky}; 3901208600Srdivacky 3902208600Srdivacky/// \brief Represents a type that was referred to using an elaborated type 3903208600Srdivacky/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, 3904208600Srdivacky/// or both. 3905193326Sed/// 3906193326Sed/// This type is used to keep track of a type name as written in the 3907208600Srdivacky/// source code, including tag keywords and any nested-name-specifiers. 3908208600Srdivacky/// The type itself is always "sugar", used to express what was written 3909208600Srdivacky/// in the source code but containing no additional semantic information. 3910208600Srdivackyclass ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { 3911208600Srdivacky 3912193326Sed /// \brief The nested name specifier containing the qualifier. 3913193326Sed NestedNameSpecifier *NNS; 3914193326Sed 3915193326Sed /// \brief The type that this qualified name refers to. 3916193326Sed QualType NamedType; 3917193326Sed 3918208600Srdivacky ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 3919208600Srdivacky QualType NamedType, QualType CanonType) 3920208600Srdivacky : TypeWithKeyword(Keyword, Elaborated, CanonType, 3921218893Sdim NamedType->isDependentType(), 3922224145Sdim NamedType->isInstantiationDependentType(), 3923218893Sdim NamedType->isVariablyModifiedType(), 3924218893Sdim NamedType->containsUnexpandedParameterPack()), 3925208600Srdivacky NNS(NNS), NamedType(NamedType) { 3926208600Srdivacky assert(!(Keyword == ETK_None && NNS == 0) && 3927208600Srdivacky "ElaboratedType cannot have elaborated type keyword " 3928208600Srdivacky "and name qualifier both null."); 3929208600Srdivacky } 3930193326Sed 3931193326Sed friend class ASTContext; // ASTContext creates these 3932193326Sed 3933193326Sedpublic: 3934210299Sed ~ElaboratedType(); 3935208600Srdivacky 3936193326Sed /// \brief Retrieve the qualification on this type. 3937193326Sed NestedNameSpecifier *getQualifier() const { return NNS; } 3938193326Sed 3939193326Sed /// \brief Retrieve the type named by the qualified-id. 3940193326Sed QualType getNamedType() const { return NamedType; } 3941193326Sed 3942198092Srdivacky /// \brief Remove a single level of sugar. 3943198092Srdivacky QualType desugar() const { return getNamedType(); } 3944193326Sed 3945198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3946198092Srdivacky bool isSugared() const { return true; } 3947198092Srdivacky 3948193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 3949208600Srdivacky Profile(ID, getKeyword(), NNS, NamedType); 3950193326Sed } 3951193326Sed 3952208600Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, 3953208600Srdivacky NestedNameSpecifier *NNS, QualType NamedType) { 3954208600Srdivacky ID.AddInteger(Keyword); 3955193326Sed ID.AddPointer(NNS); 3956193326Sed NamedType.Profile(ID); 3957193326Sed } 3958193326Sed 3959198092Srdivacky static bool classof(const Type *T) { 3960208600Srdivacky return T->getTypeClass() == Elaborated; 3961193326Sed } 3962193326Sed}; 3963193326Sed 3964206084Srdivacky/// \brief Represents a qualified type name for which the type name is 3965234353Sdim/// dependent. 3966193326Sed/// 3967234353Sdim/// DependentNameType represents a class of dependent types that involve a 3968234353Sdim/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent) 3969206084Srdivacky/// name of a type. The DependentNameType may start with a "typename" (for a 3970234353Sdim/// typename-specifier), "class", "struct", "union", or "enum" (for a 3971206084Srdivacky/// dependent elaborated-type-specifier), or nothing (in contexts where we 3972206084Srdivacky/// know that we must be referring to a type, e.g., in a base class specifier). 3973208600Srdivackyclass DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { 3974208600Srdivacky 3975193326Sed /// \brief The nested name specifier containing the qualifier. 3976193326Sed NestedNameSpecifier *NNS; 3977193326Sed 3978193326Sed /// \brief The type that this typename specifier refers to. 3979210299Sed const IdentifierInfo *Name; 3980193326Sed 3981234353Sdim DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 3982206084Srdivacky const IdentifierInfo *Name, QualType CanonType) 3983218893Sdim : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, 3984224145Sdim /*InstantiationDependent=*/true, 3985218893Sdim /*VariablyModified=*/false, 3986218893Sdim NNS->containsUnexpandedParameterPack()), 3987208600Srdivacky NNS(NNS), Name(Name) { 3988198092Srdivacky assert(NNS->isDependent() && 3989206084Srdivacky "DependentNameType requires a dependent nested-name-specifier"); 3990193326Sed } 3991193326Sed 3992193326Sed friend class ASTContext; // ASTContext creates these 3993193326Sed 3994193326Sedpublic: 3995193326Sed /// \brief Retrieve the qualification on this type. 3996193326Sed NestedNameSpecifier *getQualifier() const { return NNS; } 3997193326Sed 3998193326Sed /// \brief Retrieve the type named by the typename specifier as an 3999193326Sed /// identifier. 4000193326Sed /// 4001193326Sed /// This routine will return a non-NULL identifier pointer when the 4002193326Sed /// form of the original typename was terminated by an identifier, 4003193326Sed /// e.g., "typename T::type". 4004198092Srdivacky const IdentifierInfo *getIdentifier() const { 4005210299Sed return Name; 4006193326Sed } 4007193326Sed 4008198092Srdivacky bool isSugared() const { return false; } 4009198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4010198092Srdivacky 4011193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 4012208600Srdivacky Profile(ID, getKeyword(), NNS, Name); 4013193326Sed } 4014193326Sed 4015206084Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, 4016210299Sed NestedNameSpecifier *NNS, const IdentifierInfo *Name) { 4017206084Srdivacky ID.AddInteger(Keyword); 4018193326Sed ID.AddPointer(NNS); 4019210299Sed ID.AddPointer(Name); 4020193326Sed } 4021193326Sed 4022198092Srdivacky static bool classof(const Type *T) { 4023206084Srdivacky return T->getTypeClass() == DependentName; 4024193326Sed } 4025193326Sed}; 4026193326Sed 4027210299Sed/// DependentTemplateSpecializationType - Represents a template 4028210299Sed/// specialization type whose template cannot be resolved, e.g. 4029210299Sed/// A<T>::template B<T> 4030210299Sedclass DependentTemplateSpecializationType : 4031210299Sed public TypeWithKeyword, public llvm::FoldingSetNode { 4032210299Sed 4033210299Sed /// \brief The nested name specifier containing the qualifier. 4034210299Sed NestedNameSpecifier *NNS; 4035210299Sed 4036210299Sed /// \brief The identifier of the template. 4037210299Sed const IdentifierInfo *Name; 4038210299Sed 4039210299Sed /// \brief - The number of template arguments named in this class 4040210299Sed /// template specialization. 4041210299Sed unsigned NumArgs; 4042210299Sed 4043210299Sed const TemplateArgument *getArgBuffer() const { 4044210299Sed return reinterpret_cast<const TemplateArgument*>(this+1); 4045210299Sed } 4046210299Sed TemplateArgument *getArgBuffer() { 4047210299Sed return reinterpret_cast<TemplateArgument*>(this+1); 4048210299Sed } 4049210299Sed 4050210299Sed DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, 4051210299Sed NestedNameSpecifier *NNS, 4052210299Sed const IdentifierInfo *Name, 4053210299Sed unsigned NumArgs, 4054210299Sed const TemplateArgument *Args, 4055210299Sed QualType Canon); 4056210299Sed 4057210299Sed friend class ASTContext; // ASTContext creates these 4058210299Sed 4059210299Sedpublic: 4060210299Sed NestedNameSpecifier *getQualifier() const { return NNS; } 4061210299Sed const IdentifierInfo *getIdentifier() const { return Name; } 4062210299Sed 4063210299Sed /// \brief Retrieve the template arguments. 4064210299Sed const TemplateArgument *getArgs() const { 4065210299Sed return getArgBuffer(); 4066210299Sed } 4067210299Sed 4068210299Sed /// \brief Retrieve the number of template arguments. 4069210299Sed unsigned getNumArgs() const { return NumArgs; } 4070210299Sed 4071210299Sed const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h 4072210299Sed 4073210299Sed typedef const TemplateArgument * iterator; 4074210299Sed iterator begin() const { return getArgs(); } 4075210299Sed iterator end() const; // inline in TemplateBase.h 4076210299Sed 4077210299Sed bool isSugared() const { return false; } 4078210299Sed QualType desugar() const { return QualType(this, 0); } 4079210299Sed 4080218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { 4081210299Sed Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs()); 4082210299Sed } 4083210299Sed 4084210299Sed static void Profile(llvm::FoldingSetNodeID &ID, 4085218893Sdim const ASTContext &Context, 4086210299Sed ElaboratedTypeKeyword Keyword, 4087210299Sed NestedNameSpecifier *Qualifier, 4088210299Sed const IdentifierInfo *Name, 4089210299Sed unsigned NumArgs, 4090210299Sed const TemplateArgument *Args); 4091210299Sed 4092210299Sed static bool classof(const Type *T) { 4093210299Sed return T->getTypeClass() == DependentTemplateSpecialization; 4094210299Sed } 4095210299Sed}; 4096210299Sed 4097218893Sdim/// \brief Represents a pack expansion of types. 4098218893Sdim/// 4099218893Sdim/// Pack expansions are part of C++0x variadic templates. A pack 4100218893Sdim/// expansion contains a pattern, which itself contains one or more 4101218893Sdim/// "unexpanded" parameter packs. When instantiated, a pack expansion 4102218893Sdim/// produces a series of types, each instantiated from the pattern of 4103218893Sdim/// the expansion, where the Ith instantiation of the pattern uses the 4104218893Sdim/// Ith arguments bound to each of the unexpanded parameter packs. The 4105218893Sdim/// pack expansion is considered to "expand" these unexpanded 4106218893Sdim/// parameter packs. 4107218893Sdim/// 4108218893Sdim/// \code 4109218893Sdim/// template<typename ...Types> struct tuple; 4110218893Sdim/// 4111234353Sdim/// template<typename ...Types> 4112218893Sdim/// struct tuple_of_references { 4113218893Sdim/// typedef tuple<Types&...> type; 4114218893Sdim/// }; 4115218893Sdim/// \endcode 4116218893Sdim/// 4117218893Sdim/// Here, the pack expansion \c Types&... is represented via a 4118218893Sdim/// PackExpansionType whose pattern is Types&. 4119218893Sdimclass PackExpansionType : public Type, public llvm::FoldingSetNode { 4120218893Sdim /// \brief The pattern of the pack expansion. 4121218893Sdim QualType Pattern; 4122218893Sdim 4123218893Sdim /// \brief The number of expansions that this pack expansion will 4124234353Sdim /// generate when substituted (+1), or indicates that 4125218893Sdim /// 4126234353Sdim /// This field will only have a non-zero value when some of the parameter 4127234353Sdim /// packs that occur within the pattern have been substituted but others have 4128218893Sdim /// not. 4129218893Sdim unsigned NumExpansions; 4130234353Sdim 4131218893Sdim PackExpansionType(QualType Pattern, QualType Canon, 4132249423Sdim Optional<unsigned> NumExpansions) 4133239462Sdim : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), 4134224145Sdim /*InstantiationDependent=*/true, 4135218893Sdim /*VariableModified=*/Pattern->isVariablyModifiedType(), 4136218893Sdim /*ContainsUnexpandedParameterPack=*/false), 4137234353Sdim Pattern(Pattern), 4138218893Sdim NumExpansions(NumExpansions? *NumExpansions + 1: 0) { } 4139218893Sdim 4140218893Sdim friend class ASTContext; // ASTContext creates these 4141234353Sdim 4142218893Sdimpublic: 4143218893Sdim /// \brief Retrieve the pattern of this pack expansion, which is the 4144218893Sdim /// type that will be repeatedly instantiated when instantiating the 4145218893Sdim /// pack expansion itself. 4146218893Sdim QualType getPattern() const { return Pattern; } 4147218893Sdim 4148218893Sdim /// \brief Retrieve the number of expansions that this pack expansion will 4149218893Sdim /// generate, if known. 4150249423Sdim Optional<unsigned> getNumExpansions() const { 4151218893Sdim if (NumExpansions) 4152218893Sdim return NumExpansions - 1; 4153234353Sdim 4154249423Sdim return None; 4155218893Sdim } 4156234353Sdim 4157218893Sdim bool isSugared() const { return false; } 4158218893Sdim QualType desugar() const { return QualType(this, 0); } 4159218893Sdim 4160218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 4161218893Sdim Profile(ID, getPattern(), getNumExpansions()); 4162218893Sdim } 4163218893Sdim 4164218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, 4165249423Sdim Optional<unsigned> NumExpansions) { 4166218893Sdim ID.AddPointer(Pattern.getAsOpaquePtr()); 4167249423Sdim ID.AddBoolean(NumExpansions.hasValue()); 4168218893Sdim if (NumExpansions) 4169218893Sdim ID.AddInteger(*NumExpansions); 4170218893Sdim } 4171218893Sdim 4172218893Sdim static bool classof(const Type *T) { 4173218893Sdim return T->getTypeClass() == PackExpansion; 4174218893Sdim } 4175218893Sdim}; 4176218893Sdim 4177208600Srdivacky/// ObjCObjectType - Represents a class type in Objective C. 4178208600Srdivacky/// Every Objective C type is a combination of a base type and a 4179208600Srdivacky/// list of protocols. 4180208600Srdivacky/// 4181208600Srdivacky/// Given the following declarations: 4182239462Sdim/// \code 4183239462Sdim/// \@class C; 4184239462Sdim/// \@protocol P; 4185239462Sdim/// \endcode 4186208600Srdivacky/// 4187208600Srdivacky/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType 4188208600Srdivacky/// with base C and no protocols. 4189208600Srdivacky/// 4190208600Srdivacky/// 'C<P>' is an ObjCObjectType with base C and protocol list [P]. 4191208600Srdivacky/// 4192208600Srdivacky/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose 4193208600Srdivacky/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType 4194208600Srdivacky/// and no protocols. 4195208600Srdivacky/// 4196208600Srdivacky/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType 4197208600Srdivacky/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually 4198208600Srdivacky/// this should get its own sugar class to better represent the source. 4199208600Srdivackyclass ObjCObjectType : public Type { 4200218893Sdim // ObjCObjectType.NumProtocols - the number of protocols stored 4201218893Sdim // after the ObjCObjectPointerType node. 4202218893Sdim // 4203218893Sdim // These protocols are those written directly on the type. If 4204218893Sdim // protocol qualifiers ever become additive, the iterators will need 4205218893Sdim // to get kindof complicated. 4206218893Sdim // 4207218893Sdim // In the canonical object type, these are sorted alphabetically 4208218893Sdim // and uniqued. 4209198092Srdivacky 4210208600Srdivacky /// Either a BuiltinType or an InterfaceType or sugar for either. 4211208600Srdivacky QualType BaseType; 4212208600Srdivacky 4213208600Srdivacky ObjCProtocolDecl * const *getProtocolStorage() const { 4214208600Srdivacky return const_cast<ObjCObjectType*>(this)->getProtocolStorage(); 4215208600Srdivacky } 4216208600Srdivacky 4217208600Srdivacky ObjCProtocolDecl **getProtocolStorage(); 4218208600Srdivacky 4219208600Srdivackyprotected: 4220234353Sdim ObjCObjectType(QualType Canonical, QualType Base, 4221208600Srdivacky ObjCProtocolDecl * const *Protocols, unsigned NumProtocols); 4222208600Srdivacky 4223208600Srdivacky enum Nonce_ObjCInterface { Nonce_ObjCInterface }; 4224208600Srdivacky ObjCObjectType(enum Nonce_ObjCInterface) 4225224145Sdim : Type(ObjCInterface, QualType(), false, false, false, false), 4226218893Sdim BaseType(QualType(this_(), 0)) { 4227218893Sdim ObjCObjectTypeBits.NumProtocols = 0; 4228218893Sdim } 4229208600Srdivacky 4230198092Srdivackypublic: 4231208600Srdivacky /// getBaseType - Gets the base type of this object type. This is 4232208600Srdivacky /// always (possibly sugar for) one of: 4233208600Srdivacky /// - the 'id' builtin type (as opposed to the 'id' type visible to the 4234208600Srdivacky /// user, which is a typedef for an ObjCPointerType) 4235208600Srdivacky /// - the 'Class' builtin type (same caveat) 4236208600Srdivacky /// - an ObjCObjectType (currently always an ObjCInterfaceType) 4237208600Srdivacky QualType getBaseType() const { return BaseType; } 4238202879Srdivacky 4239208600Srdivacky bool isObjCId() const { 4240208600Srdivacky return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); 4241208600Srdivacky } 4242208600Srdivacky bool isObjCClass() const { 4243208600Srdivacky return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); 4244208600Srdivacky } 4245208600Srdivacky bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } 4246208600Srdivacky bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } 4247208600Srdivacky bool isObjCUnqualifiedIdOrClass() const { 4248208600Srdivacky if (!qual_empty()) return false; 4249208600Srdivacky if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) 4250208600Srdivacky return T->getKind() == BuiltinType::ObjCId || 4251208600Srdivacky T->getKind() == BuiltinType::ObjCClass; 4252208600Srdivacky return false; 4253208600Srdivacky } 4254208600Srdivacky bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } 4255208600Srdivacky bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } 4256198092Srdivacky 4257208600Srdivacky /// Gets the interface declaration for this object type, if the base type 4258208600Srdivacky /// really is an interface. 4259208600Srdivacky ObjCInterfaceDecl *getInterface() const; 4260208600Srdivacky 4261208600Srdivacky typedef ObjCProtocolDecl * const *qual_iterator; 4262208600Srdivacky 4263208600Srdivacky qual_iterator qual_begin() const { return getProtocolStorage(); } 4264208600Srdivacky qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } 4265208600Srdivacky 4266208600Srdivacky bool qual_empty() const { return getNumProtocols() == 0; } 4267208600Srdivacky 4268198092Srdivacky /// getNumProtocols - Return the number of qualifying protocols in this 4269198092Srdivacky /// interface type, or 0 if there are none. 4270218893Sdim unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; } 4271198092Srdivacky 4272208600Srdivacky /// \brief Fetch a protocol by index. 4273203955Srdivacky ObjCProtocolDecl *getProtocol(unsigned I) const { 4274203955Srdivacky assert(I < getNumProtocols() && "Out-of-range protocol access"); 4275203955Srdivacky return qual_begin()[I]; 4276203955Srdivacky } 4277234353Sdim 4278198092Srdivacky bool isSugared() const { return false; } 4279198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4280198092Srdivacky 4281208600Srdivacky static bool classof(const Type *T) { 4282208600Srdivacky return T->getTypeClass() == ObjCObject || 4283208600Srdivacky T->getTypeClass() == ObjCInterface; 4284208600Srdivacky } 4285208600Srdivacky}; 4286208600Srdivacky 4287208600Srdivacky/// ObjCObjectTypeImpl - A class providing a concrete implementation 4288208600Srdivacky/// of ObjCObjectType, so as to not increase the footprint of 4289208600Srdivacky/// ObjCInterfaceType. Code outside of ASTContext and the core type 4290208600Srdivacky/// system should not reference this type. 4291208600Srdivackyclass ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { 4292208600Srdivacky friend class ASTContext; 4293208600Srdivacky 4294208600Srdivacky // If anyone adds fields here, ObjCObjectType::getProtocolStorage() 4295208600Srdivacky // will need to be modified. 4296208600Srdivacky 4297234353Sdim ObjCObjectTypeImpl(QualType Canonical, QualType Base, 4298208600Srdivacky ObjCProtocolDecl * const *Protocols, 4299208600Srdivacky unsigned NumProtocols) 4300208600Srdivacky : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {} 4301208600Srdivacky 4302208600Srdivackypublic: 4303198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID); 4304198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 4305208600Srdivacky QualType Base, 4306234353Sdim ObjCProtocolDecl *const *protocols, 4307234353Sdim unsigned NumProtocols); 4308208600Srdivacky}; 4309198092Srdivacky 4310208600Srdivackyinline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { 4311208600Srdivacky return reinterpret_cast<ObjCProtocolDecl**>( 4312208600Srdivacky static_cast<ObjCObjectTypeImpl*>(this) + 1); 4313208600Srdivacky} 4314203955Srdivacky 4315208600Srdivacky/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for 4316208600Srdivacky/// object oriented design. They basically correspond to C++ classes. There 4317208600Srdivacky/// are two kinds of interface types, normal interfaces like "NSString" and 4318208600Srdivacky/// qualified interfaces, which are qualified with a protocol list like 4319208600Srdivacky/// "NSString<NSCopyable, NSAmazing>". 4320208600Srdivacky/// 4321208600Srdivacky/// ObjCInterfaceType guarantees the following properties when considered 4322208600Srdivacky/// as a subtype of its superclass, ObjCObjectType: 4323208600Srdivacky/// - There are no protocol qualifiers. To reinforce this, code which 4324208600Srdivacky/// tries to invoke the protocol methods via an ObjCInterfaceType will 4325208600Srdivacky/// fail to compile. 4326208600Srdivacky/// - It is its own base type. That is, if T is an ObjCInterfaceType*, 4327208600Srdivacky/// T->getBaseType() == QualType(T, 0). 4328208600Srdivackyclass ObjCInterfaceType : public ObjCObjectType { 4329234353Sdim mutable ObjCInterfaceDecl *Decl; 4330208600Srdivacky 4331208600Srdivacky ObjCInterfaceType(const ObjCInterfaceDecl *D) 4332208600Srdivacky : ObjCObjectType(Nonce_ObjCInterface), 4333208600Srdivacky Decl(const_cast<ObjCInterfaceDecl*>(D)) {} 4334208600Srdivacky friend class ASTContext; // ASTContext creates these. 4335234353Sdim friend class ASTReader; 4336234353Sdim friend class ObjCInterfaceDecl; 4337218893Sdim 4338208600Srdivackypublic: 4339208600Srdivacky /// getDecl - Get the declaration of this interface. 4340208600Srdivacky ObjCInterfaceDecl *getDecl() const { return Decl; } 4341208600Srdivacky 4342208600Srdivacky bool isSugared() const { return false; } 4343208600Srdivacky QualType desugar() const { return QualType(this, 0); } 4344208600Srdivacky 4345198092Srdivacky static bool classof(const Type *T) { 4346198092Srdivacky return T->getTypeClass() == ObjCInterface; 4347198092Srdivacky } 4348208600Srdivacky 4349208600Srdivacky // Nonsense to "hide" certain members of ObjCObjectType within this 4350208600Srdivacky // class. People asking for protocols on an ObjCInterfaceType are 4351208600Srdivacky // not going to get what they want: ObjCInterfaceTypes are 4352208600Srdivacky // guaranteed to have no protocols. 4353208600Srdivacky enum { 4354208600Srdivacky qual_iterator, 4355208600Srdivacky qual_begin, 4356208600Srdivacky qual_end, 4357208600Srdivacky getNumProtocols, 4358208600Srdivacky getProtocol 4359208600Srdivacky }; 4360198092Srdivacky}; 4361198092Srdivacky 4362208600Srdivackyinline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { 4363208600Srdivacky if (const ObjCInterfaceType *T = 4364208600Srdivacky getBaseType()->getAs<ObjCInterfaceType>()) 4365208600Srdivacky return T->getDecl(); 4366208600Srdivacky return 0; 4367208600Srdivacky} 4368208600Srdivacky 4369208600Srdivacky/// ObjCObjectPointerType - Used to represent a pointer to an 4370208600Srdivacky/// Objective C object. These are constructed from pointer 4371208600Srdivacky/// declarators when the pointee type is an ObjCObjectType (or sugar 4372208600Srdivacky/// for one). In addition, the 'id' and 'Class' types are typedefs 4373208600Srdivacky/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>' 4374208600Srdivacky/// are translated into these. 4375194613Sed/// 4376208600Srdivacky/// Pointers to pointers to Objective C objects are still PointerTypes; 4377208600Srdivacky/// only the first level of pointer gets it own type implementation. 4378194613Sedclass ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { 4379208600Srdivacky QualType PointeeType; 4380198092Srdivacky 4381208600Srdivacky ObjCObjectPointerType(QualType Canonical, QualType Pointee) 4382224145Sdim : Type(ObjCObjectPointer, Canonical, false, false, false, false), 4383208600Srdivacky PointeeType(Pointee) {} 4384194613Sed friend class ASTContext; // ASTContext creates these. 4385194613Sed 4386194613Sedpublic: 4387208600Srdivacky /// getPointeeType - Gets the type pointed to by this ObjC pointer. 4388208600Srdivacky /// The result will always be an ObjCObjectType or sugar thereof. 4389198092Srdivacky QualType getPointeeType() const { return PointeeType; } 4390198092Srdivacky 4391208600Srdivacky /// getObjCObjectType - Gets the type pointed to by this ObjC 4392208600Srdivacky /// pointer. This method always returns non-null. 4393208600Srdivacky /// 4394208600Srdivacky /// This method is equivalent to getPointeeType() except that 4395208600Srdivacky /// it discards any typedefs (or other sugar) between this 4396208600Srdivacky /// type and the "outermost" object type. So for: 4397239462Sdim /// \code 4398239462Sdim /// \@class A; \@protocol P; \@protocol Q; 4399208600Srdivacky /// typedef A<P> AP; 4400208600Srdivacky /// typedef A A1; 4401208600Srdivacky /// typedef A1<P> A1P; 4402208600Srdivacky /// typedef A1P<Q> A1PQ; 4403239462Sdim /// \endcode 4404208600Srdivacky /// For 'A*', getObjectType() will return 'A'. 4405208600Srdivacky /// For 'A<P>*', getObjectType() will return 'A<P>'. 4406208600Srdivacky /// For 'AP*', getObjectType() will return 'A<P>'. 4407208600Srdivacky /// For 'A1*', getObjectType() will return 'A'. 4408208600Srdivacky /// For 'A1<P>*', getObjectType() will return 'A1<P>'. 4409208600Srdivacky /// For 'A1P*', getObjectType() will return 'A1<P>'. 4410208600Srdivacky /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because 4411208600Srdivacky /// adding protocols to a protocol-qualified base discards the 4412208600Srdivacky /// old qualifiers (for now). But if it didn't, getObjectType() 4413208600Srdivacky /// would return 'A1P<Q>' (and we'd have to make iterating over 4414208600Srdivacky /// qualifiers more complicated). 4415208600Srdivacky const ObjCObjectType *getObjectType() const { 4416218893Sdim return PointeeType->castAs<ObjCObjectType>(); 4417208600Srdivacky } 4418208600Srdivacky 4419208600Srdivacky /// getInterfaceType - If this pointer points to an Objective C 4420239462Sdim /// \@interface type, gets the type for that interface. Any protocol 4421208600Srdivacky /// qualifiers on the interface are ignored. 4422208600Srdivacky /// 4423208600Srdivacky /// \return null if the base type for this pointer is 'id' or 'Class' 4424198092Srdivacky const ObjCInterfaceType *getInterfaceType() const { 4425208600Srdivacky return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>(); 4426198092Srdivacky } 4427208600Srdivacky 4428239462Sdim /// getInterfaceDecl - If this pointer points to an Objective \@interface 4429208600Srdivacky /// type, gets the declaration for that interface. 4430208600Srdivacky /// 4431208600Srdivacky /// \return null if the base type for this pointer is 'id' or 'Class' 4432198092Srdivacky ObjCInterfaceDecl *getInterfaceDecl() const { 4433208600Srdivacky return getObjectType()->getInterface(); 4434198092Srdivacky } 4435208600Srdivacky 4436208600Srdivacky /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if 4437208600Srdivacky /// its object type is the primitive 'id' type with no protocols. 4438198092Srdivacky bool isObjCIdType() const { 4439208600Srdivacky return getObjectType()->isObjCUnqualifiedId(); 4440198092Srdivacky } 4441208600Srdivacky 4442208600Srdivacky /// isObjCClassType - True if this is equivalent to the 'Class' type, 4443208600Srdivacky /// i.e. if its object tive is the primitive 'Class' type with no protocols. 4444198092Srdivacky bool isObjCClassType() const { 4445208600Srdivacky return getObjectType()->isObjCUnqualifiedClass(); 4446198092Srdivacky } 4447234353Sdim 4448208600Srdivacky /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some 4449208600Srdivacky /// non-empty set of protocols. 4450198092Srdivacky bool isObjCQualifiedIdType() const { 4451208600Srdivacky return getObjectType()->isObjCQualifiedId(); 4452198092Srdivacky } 4453208600Srdivacky 4454208600Srdivacky /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for 4455208600Srdivacky /// some non-empty set of protocols. 4456198092Srdivacky bool isObjCQualifiedClassType() const { 4457208600Srdivacky return getObjectType()->isObjCQualifiedClass(); 4458198092Srdivacky } 4459194613Sed 4460208600Srdivacky /// An iterator over the qualifiers on the object type. Provided 4461208600Srdivacky /// for convenience. This will always iterate over the full set of 4462208600Srdivacky /// protocols on a type, not just those provided directly. 4463208600Srdivacky typedef ObjCObjectType::qual_iterator qual_iterator; 4464208600Srdivacky 4465202879Srdivacky qual_iterator qual_begin() const { 4466208600Srdivacky return getObjectType()->qual_begin(); 4467202879Srdivacky } 4468208600Srdivacky qual_iterator qual_end() const { 4469208600Srdivacky return getObjectType()->qual_end(); 4470202879Srdivacky } 4471208600Srdivacky bool qual_empty() const { return getObjectType()->qual_empty(); } 4472194613Sed 4473208600Srdivacky /// getNumProtocols - Return the number of qualifying protocols on 4474208600Srdivacky /// the object type. 4475208600Srdivacky unsigned getNumProtocols() const { 4476208600Srdivacky return getObjectType()->getNumProtocols(); 4477208600Srdivacky } 4478194613Sed 4479208600Srdivacky /// \brief Retrieve a qualifying protocol by index on the object 4480208600Srdivacky /// type. 4481203955Srdivacky ObjCProtocolDecl *getProtocol(unsigned I) const { 4482208600Srdivacky return getObjectType()->getProtocol(I); 4483203955Srdivacky } 4484234353Sdim 4485198092Srdivacky bool isSugared() const { return false; } 4486198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4487198092Srdivacky 4488208600Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 4489208600Srdivacky Profile(ID, getPointeeType()); 4490208600Srdivacky } 4491208600Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { 4492208600Srdivacky ID.AddPointer(T.getAsOpaquePtr()); 4493208600Srdivacky } 4494198092Srdivacky static bool classof(const Type *T) { 4495198092Srdivacky return T->getTypeClass() == ObjCObjectPointer; 4496194613Sed } 4497194613Sed}; 4498193326Sed 4499226633Sdimclass AtomicType : public Type, public llvm::FoldingSetNode { 4500226633Sdim QualType ValueType; 4501226633Sdim 4502226633Sdim AtomicType(QualType ValTy, QualType Canonical) 4503226633Sdim : Type(Atomic, Canonical, ValTy->isDependentType(), 4504226633Sdim ValTy->isInstantiationDependentType(), 4505226633Sdim ValTy->isVariablyModifiedType(), 4506226633Sdim ValTy->containsUnexpandedParameterPack()), 4507226633Sdim ValueType(ValTy) {} 4508226633Sdim friend class ASTContext; // ASTContext creates these. 4509226633Sdim 4510226633Sdim public: 4511226633Sdim /// getValueType - Gets the type contained by this atomic type, i.e. 4512226633Sdim /// the type returned by performing an atomic load of this atomic type. 4513226633Sdim QualType getValueType() const { return ValueType; } 4514226633Sdim 4515226633Sdim bool isSugared() const { return false; } 4516226633Sdim QualType desugar() const { return QualType(this, 0); } 4517226633Sdim 4518226633Sdim void Profile(llvm::FoldingSetNodeID &ID) { 4519226633Sdim Profile(ID, getValueType()); 4520226633Sdim } 4521226633Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { 4522226633Sdim ID.AddPointer(T.getAsOpaquePtr()); 4523226633Sdim } 4524226633Sdim static bool classof(const Type *T) { 4525226633Sdim return T->getTypeClass() == Atomic; 4526226633Sdim } 4527226633Sdim}; 4528226633Sdim 4529198092Srdivacky/// A qualifier set is used to build a set of qualifiers. 4530198092Srdivackyclass QualifierCollector : public Qualifiers { 4531198092Srdivackypublic: 4532218893Sdim QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {} 4533198092Srdivacky 4534198092Srdivacky /// Collect any qualifiers on the given type and return an 4535218893Sdim /// unqualified type. The qualifiers are assumed to be consistent 4536218893Sdim /// with those already in the type. 4537218893Sdim const Type *strip(QualType type) { 4538218893Sdim addFastQualifiers(type.getLocalFastQualifiers()); 4539218893Sdim if (!type.hasLocalNonFastQualifiers()) 4540218893Sdim return type.getTypePtrUnsafe(); 4541234353Sdim 4542218893Sdim const ExtQuals *extQuals = type.getExtQualsUnsafe(); 4543218893Sdim addConsistentQualifiers(extQuals->getQualifiers()); 4544218893Sdim return extQuals->getBaseType(); 4545198092Srdivacky } 4546198092Srdivacky 4547198092Srdivacky /// Apply the collected qualifiers to the given type. 4548218893Sdim QualType apply(const ASTContext &Context, QualType QT) const; 4549198092Srdivacky 4550198092Srdivacky /// Apply the collected qualifiers to the given type. 4551218893Sdim QualType apply(const ASTContext &Context, const Type* T) const; 4552198092Srdivacky}; 4553198092Srdivacky 4554198092Srdivacky 4555198092Srdivacky// Inline function definitions. 4556198092Srdivacky 4557234353Sdiminline SplitQualType SplitQualType::getSingleStepDesugaredType() const { 4558234353Sdim SplitQualType desugar = 4559234353Sdim Ty->getLocallyUnqualifiedSingleStepDesugaredType().split(); 4560234353Sdim desugar.Quals.addConsistentQualifiers(Quals); 4561234353Sdim return desugar; 4562234353Sdim} 4563234353Sdim 4564218893Sdiminline const Type *QualType::getTypePtr() const { 4565218893Sdim return getCommonPtr()->BaseType; 4566218893Sdim} 4567218893Sdim 4568218893Sdiminline const Type *QualType::getTypePtrOrNull() const { 4569218893Sdim return (isNull() ? 0 : getCommonPtr()->BaseType); 4570218893Sdim} 4571218893Sdim 4572218893Sdiminline SplitQualType QualType::split() const { 4573218893Sdim if (!hasLocalNonFastQualifiers()) 4574218893Sdim return SplitQualType(getTypePtrUnsafe(), 4575218893Sdim Qualifiers::fromFastMask(getLocalFastQualifiers())); 4576218893Sdim 4577218893Sdim const ExtQuals *eq = getExtQualsUnsafe(); 4578218893Sdim Qualifiers qs = eq->getQualifiers(); 4579218893Sdim qs.addFastQualifiers(getLocalFastQualifiers()); 4580218893Sdim return SplitQualType(eq->getBaseType(), qs); 4581218893Sdim} 4582218893Sdim 4583218893Sdiminline Qualifiers QualType::getLocalQualifiers() const { 4584218893Sdim Qualifiers Quals; 4585218893Sdim if (hasLocalNonFastQualifiers()) 4586218893Sdim Quals = getExtQualsUnsafe()->getQualifiers(); 4587218893Sdim Quals.addFastQualifiers(getLocalFastQualifiers()); 4588218893Sdim return Quals; 4589218893Sdim} 4590218893Sdim 4591218893Sdiminline Qualifiers QualType::getQualifiers() const { 4592218893Sdim Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers(); 4593218893Sdim quals.addFastQualifiers(getLocalFastQualifiers()); 4594218893Sdim return quals; 4595218893Sdim} 4596218893Sdim 4597218893Sdiminline unsigned QualType::getCVRQualifiers() const { 4598218893Sdim unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers(); 4599218893Sdim cvr |= getLocalCVRQualifiers(); 4600218893Sdim return cvr; 4601218893Sdim} 4602218893Sdim 4603218893Sdiminline QualType QualType::getCanonicalType() const { 4604218893Sdim QualType canon = getCommonPtr()->CanonicalType; 4605218893Sdim return canon.withFastQualifiers(getLocalFastQualifiers()); 4606218893Sdim} 4607218893Sdim 4608198398Srdivackyinline bool QualType::isCanonical() const { 4609218893Sdim return getTypePtr()->isCanonicalUnqualified(); 4610198398Srdivacky} 4611198398Srdivacky 4612198398Srdivackyinline bool QualType::isCanonicalAsParam() const { 4613218893Sdim if (!isCanonical()) return false; 4614199482Srdivacky if (hasLocalQualifiers()) return false; 4615234353Sdim 4616198398Srdivacky const Type *T = getTypePtr(); 4617218893Sdim if (T->isVariablyModifiedType() && T->hasSizedVLAType()) 4618218893Sdim return false; 4619218893Sdim 4620218893Sdim return !isa<FunctionType>(T) && !isa<ArrayType>(T); 4621198398Srdivacky} 4622198398Srdivacky 4623199482Srdivackyinline bool QualType::isConstQualified() const { 4624234353Sdim return isLocalConstQualified() || 4625218893Sdim getCommonPtr()->CanonicalType.isLocalConstQualified(); 4626199482Srdivacky} 4627199482Srdivacky 4628199482Srdivackyinline bool QualType::isRestrictQualified() const { 4629234353Sdim return isLocalRestrictQualified() || 4630218893Sdim getCommonPtr()->CanonicalType.isLocalRestrictQualified(); 4631199482Srdivacky} 4632199482Srdivacky 4633199482Srdivacky 4634199482Srdivackyinline bool QualType::isVolatileQualified() const { 4635234353Sdim return isLocalVolatileQualified() || 4636218893Sdim getCommonPtr()->CanonicalType.isLocalVolatileQualified(); 4637199482Srdivacky} 4638234353Sdim 4639199482Srdivackyinline bool QualType::hasQualifiers() const { 4640199482Srdivacky return hasLocalQualifiers() || 4641218893Sdim getCommonPtr()->CanonicalType.hasLocalQualifiers(); 4642199482Srdivacky} 4643201361Srdivacky 4644218893Sdiminline QualType QualType::getUnqualifiedType() const { 4645218893Sdim if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) 4646218893Sdim return QualType(getTypePtr(), 0); 4647218893Sdim 4648234353Sdim return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0); 4649201361Srdivacky} 4650251662Sdim 4651218893Sdiminline SplitQualType QualType::getSplitUnqualifiedType() const { 4652218893Sdim if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) 4653218893Sdim return split(); 4654218893Sdim 4655218893Sdim return getSplitUnqualifiedTypeImpl(*this); 4656193326Sed} 4657234353Sdim 4658218893Sdiminline void QualType::removeLocalConst() { 4659218893Sdim removeLocalFastQualifiers(Qualifiers::Const); 4660218893Sdim} 4661198092Srdivacky 4662218893Sdiminline void QualType::removeLocalRestrict() { 4663218893Sdim removeLocalFastQualifiers(Qualifiers::Restrict); 4664193326Sed} 4665193326Sed 4666218893Sdiminline void QualType::removeLocalVolatile() { 4667218893Sdim removeLocalFastQualifiers(Qualifiers::Volatile); 4668193326Sed} 4669193326Sed 4670218893Sdiminline void QualType::removeLocalCVRQualifiers(unsigned Mask) { 4671198092Srdivacky assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits"); 4672218893Sdim assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask); 4673193326Sed 4674198092Srdivacky // Fast path: we don't need to touch the slow qualifiers. 4675218893Sdim removeLocalFastQualifiers(Mask); 4676193326Sed} 4677193326Sed 4678193326Sed/// getAddressSpace - Return the address space of this type. 4679193326Sedinline unsigned QualType::getAddressSpace() const { 4680218893Sdim return getQualifiers().getAddressSpace(); 4681193326Sed} 4682251662Sdim 4683193326Sed/// getObjCGCAttr - Return the gc attribute of this type. 4684198092Srdivackyinline Qualifiers::GC QualType::getObjCGCAttr() const { 4685218893Sdim return getQualifiers().getObjCGCAttr(); 4686193326Sed} 4687198092Srdivacky 4688206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { 4689206084Srdivacky if (const PointerType *PT = t.getAs<PointerType>()) { 4690198092Srdivacky if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>()) 4691206084Srdivacky return FT->getExtInfo(); 4692206084Srdivacky } else if (const FunctionType *FT = t.getAs<FunctionType>()) 4693206084Srdivacky return FT->getExtInfo(); 4694198092Srdivacky 4695206084Srdivacky return FunctionType::ExtInfo(); 4696198092Srdivacky} 4697198092Srdivacky 4698206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { 4699206084Srdivacky return getFunctionExtInfo(*t); 4700202879Srdivacky} 4701202879Srdivacky 4702193326Sed/// isMoreQualifiedThan - Determine whether this type is more 4703193326Sed/// qualified than the Other type. For example, "const volatile int" 4704193326Sed/// is more qualified than "const int", "volatile int", and 4705193326Sed/// "int". However, it is not more qualified than "const volatile 4706193326Sed/// int". 4707218893Sdiminline bool QualType::isMoreQualifiedThan(QualType other) const { 4708218893Sdim Qualifiers myQuals = getQualifiers(); 4709218893Sdim Qualifiers otherQuals = other.getQualifiers(); 4710218893Sdim return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals)); 4711193326Sed} 4712193326Sed 4713193326Sed/// isAtLeastAsQualifiedAs - Determine whether this type is at last 4714193326Sed/// as qualified as the Other type. For example, "const volatile 4715193326Sed/// int" is at least as qualified as "const int", "volatile int", 4716193326Sed/// "int", and "const volatile int". 4717218893Sdiminline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { 4718218893Sdim return getQualifiers().compatiblyIncludes(other.getQualifiers()); 4719193326Sed} 4720193326Sed 4721193326Sed/// getNonReferenceType - If Type is a reference type (e.g., const 4722193326Sed/// int&), returns the type that the reference refers to ("const 4723193326Sed/// int"). Otherwise, returns the type itself. This routine is used 4724193326Sed/// throughout Sema to implement C++ 5p6: 4725193326Sed/// 4726193326Sed/// If an expression initially has the type "reference to T" (8.3.2, 4727193326Sed/// 8.5.3), the type is adjusted to "T" prior to any further 4728193326Sed/// analysis, the expression designates the object or function 4729193326Sed/// denoted by the reference, and the expression is an lvalue. 4730193326Sedinline QualType QualType::getNonReferenceType() const { 4731198092Srdivacky if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>()) 4732193326Sed return RefType->getPointeeType(); 4733193326Sed else 4734193326Sed return *this; 4735193326Sed} 4736193326Sed 4737224145Sdiminline bool QualType::isCForbiddenLValueType() const { 4738224145Sdim return ((getTypePtr()->isVoidType() && !hasQualifiers()) || 4739224145Sdim getTypePtr()->isFunctionType()); 4740224145Sdim} 4741224145Sdim 4742221345Sdim/// \brief Tests whether the type is categorized as a fundamental type. 4743221345Sdim/// 4744221345Sdim/// \returns True for types specified in C++0x [basic.fundamental]. 4745221345Sdiminline bool Type::isFundamentalType() const { 4746221345Sdim return isVoidType() || 4747221345Sdim // FIXME: It's really annoying that we don't have an 4748221345Sdim // 'isArithmeticType()' which agrees with the standard definition. 4749221345Sdim (isArithmeticType() && !isEnumeralType()); 4750221345Sdim} 4751221345Sdim 4752221345Sdim/// \brief Tests whether the type is categorized as a compound type. 4753221345Sdim/// 4754221345Sdim/// \returns True for types specified in C++0x [basic.compound]. 4755221345Sdiminline bool Type::isCompoundType() const { 4756221345Sdim // C++0x [basic.compound]p1: 4757221345Sdim // Compound types can be constructed in the following ways: 4758221345Sdim // -- arrays of objects of a given type [...]; 4759221345Sdim return isArrayType() || 4760221345Sdim // -- functions, which have parameters of given types [...]; 4761221345Sdim isFunctionType() || 4762221345Sdim // -- pointers to void or objects or functions [...]; 4763221345Sdim isPointerType() || 4764221345Sdim // -- references to objects or functions of a given type. [...] 4765221345Sdim isReferenceType() || 4766221345Sdim // -- classes containing a sequence of objects of various types, [...]; 4767221345Sdim isRecordType() || 4768234353Sdim // -- unions, which are classes capable of containing objects of different 4769234353Sdim // types at different times; 4770221345Sdim isUnionType() || 4771221345Sdim // -- enumerations, which comprise a set of named constant values. [...]; 4772221345Sdim isEnumeralType() || 4773221345Sdim // -- pointers to non-static class members, [...]. 4774221345Sdim isMemberPointerType(); 4775221345Sdim} 4776221345Sdim 4777193326Sedinline bool Type::isFunctionType() const { 4778199482Srdivacky return isa<FunctionType>(CanonicalType); 4779193326Sed} 4780193326Sedinline bool Type::isPointerType() const { 4781199482Srdivacky return isa<PointerType>(CanonicalType); 4782193326Sed} 4783198092Srdivackyinline bool Type::isAnyPointerType() const { 4784198092Srdivacky return isPointerType() || isObjCObjectPointerType(); 4785198092Srdivacky} 4786193326Sedinline bool Type::isBlockPointerType() const { 4787199482Srdivacky return isa<BlockPointerType>(CanonicalType); 4788193326Sed} 4789193326Sedinline bool Type::isReferenceType() const { 4790199482Srdivacky return isa<ReferenceType>(CanonicalType); 4791193326Sed} 4792193326Sedinline bool Type::isLValueReferenceType() const { 4793199482Srdivacky return isa<LValueReferenceType>(CanonicalType); 4794193326Sed} 4795193326Sedinline bool Type::isRValueReferenceType() const { 4796199482Srdivacky return isa<RValueReferenceType>(CanonicalType); 4797193326Sed} 4798193326Sedinline bool Type::isFunctionPointerType() const { 4799218893Sdim if (const PointerType *T = getAs<PointerType>()) 4800193326Sed return T->getPointeeType()->isFunctionType(); 4801193326Sed else 4802193326Sed return false; 4803193326Sed} 4804193326Sedinline bool Type::isMemberPointerType() const { 4805199482Srdivacky return isa<MemberPointerType>(CanonicalType); 4806193326Sed} 4807193326Sedinline bool Type::isMemberFunctionPointerType() const { 4808198092Srdivacky if (const MemberPointerType* T = getAs<MemberPointerType>()) 4809212904Sdim return T->isMemberFunctionPointer(); 4810193326Sed else 4811193326Sed return false; 4812193326Sed} 4813212904Sdiminline bool Type::isMemberDataPointerType() const { 4814212904Sdim if (const MemberPointerType* T = getAs<MemberPointerType>()) 4815212904Sdim return T->isMemberDataPointer(); 4816212904Sdim else 4817212904Sdim return false; 4818212904Sdim} 4819193326Sedinline bool Type::isArrayType() const { 4820199482Srdivacky return isa<ArrayType>(CanonicalType); 4821193326Sed} 4822193326Sedinline bool Type::isConstantArrayType() const { 4823199482Srdivacky return isa<ConstantArrayType>(CanonicalType); 4824193326Sed} 4825193326Sedinline bool Type::isIncompleteArrayType() const { 4826199482Srdivacky return isa<IncompleteArrayType>(CanonicalType); 4827193326Sed} 4828193326Sedinline bool Type::isVariableArrayType() const { 4829199482Srdivacky return isa<VariableArrayType>(CanonicalType); 4830193326Sed} 4831193326Sedinline bool Type::isDependentSizedArrayType() const { 4832199482Srdivacky return isa<DependentSizedArrayType>(CanonicalType); 4833193326Sed} 4834218893Sdiminline bool Type::isBuiltinType() const { 4835218893Sdim return isa<BuiltinType>(CanonicalType); 4836218893Sdim} 4837193326Sedinline bool Type::isRecordType() const { 4838199482Srdivacky return isa<RecordType>(CanonicalType); 4839193326Sed} 4840218893Sdiminline bool Type::isEnumeralType() const { 4841218893Sdim return isa<EnumType>(CanonicalType); 4842218893Sdim} 4843193326Sedinline bool Type::isAnyComplexType() const { 4844199482Srdivacky return isa<ComplexType>(CanonicalType); 4845193326Sed} 4846193326Sedinline bool Type::isVectorType() const { 4847199482Srdivacky return isa<VectorType>(CanonicalType); 4848193326Sed} 4849193326Sedinline bool Type::isExtVectorType() const { 4850199482Srdivacky return isa<ExtVectorType>(CanonicalType); 4851193326Sed} 4852194613Sedinline bool Type::isObjCObjectPointerType() const { 4853199482Srdivacky return isa<ObjCObjectPointerType>(CanonicalType); 4854194613Sed} 4855208600Srdivackyinline bool Type::isObjCObjectType() const { 4856208600Srdivacky return isa<ObjCObjectType>(CanonicalType); 4857193326Sed} 4858212904Sdiminline bool Type::isObjCObjectOrInterfaceType() const { 4859234353Sdim return isa<ObjCInterfaceType>(CanonicalType) || 4860212904Sdim isa<ObjCObjectType>(CanonicalType); 4861212904Sdim} 4862226633Sdiminline bool Type::isAtomicType() const { 4863226633Sdim return isa<AtomicType>(CanonicalType); 4864226633Sdim} 4865212904Sdim 4866193326Sedinline bool Type::isObjCQualifiedIdType() const { 4867198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4868194613Sed return OPT->isObjCQualifiedIdType(); 4869194613Sed return false; 4870193326Sed} 4871198092Srdivackyinline bool Type::isObjCQualifiedClassType() const { 4872198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4873198092Srdivacky return OPT->isObjCQualifiedClassType(); 4874198092Srdivacky return false; 4875198092Srdivacky} 4876198092Srdivackyinline bool Type::isObjCIdType() const { 4877198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4878198092Srdivacky return OPT->isObjCIdType(); 4879198092Srdivacky return false; 4880198092Srdivacky} 4881198092Srdivackyinline bool Type::isObjCClassType() const { 4882198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4883198092Srdivacky return OPT->isObjCClassType(); 4884198092Srdivacky return false; 4885198092Srdivacky} 4886199990Srdivackyinline bool Type::isObjCSelType() const { 4887199990Srdivacky if (const PointerType *OPT = getAs<PointerType>()) 4888199990Srdivacky return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); 4889199990Srdivacky return false; 4890199990Srdivacky} 4891198092Srdivackyinline bool Type::isObjCBuiltinType() const { 4892199990Srdivacky return isObjCIdType() || isObjCClassType() || isObjCSelType(); 4893198092Srdivacky} 4894249423Sdim 4895249423Sdiminline bool Type::isImage1dT() const { 4896249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage1d); 4897249423Sdim} 4898249423Sdim 4899249423Sdiminline bool Type::isImage1dArrayT() const { 4900249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage1dArray); 4901249423Sdim} 4902249423Sdim 4903249423Sdiminline bool Type::isImage1dBufferT() const { 4904249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer); 4905249423Sdim} 4906249423Sdim 4907249423Sdiminline bool Type::isImage2dT() const { 4908249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage2d); 4909249423Sdim} 4910249423Sdim 4911249423Sdiminline bool Type::isImage2dArrayT() const { 4912249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage2dArray); 4913249423Sdim} 4914249423Sdim 4915249423Sdiminline bool Type::isImage3dT() const { 4916249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage3d); 4917249423Sdim} 4918249423Sdim 4919249423Sdiminline bool Type::isSamplerT() const { 4920249423Sdim return isSpecificBuiltinType(BuiltinType::OCLSampler); 4921249423Sdim} 4922249423Sdim 4923249423Sdiminline bool Type::isEventT() const { 4924249423Sdim return isSpecificBuiltinType(BuiltinType::OCLEvent); 4925249423Sdim} 4926249423Sdim 4927249423Sdiminline bool Type::isImageType() const { 4928249423Sdim return isImage3dT() || 4929249423Sdim isImage2dT() || isImage2dArrayT() || 4930249423Sdim isImage1dT() || isImage1dArrayT() || isImage1dBufferT(); 4931249423Sdim} 4932249423Sdim 4933249423Sdiminline bool Type::isOpenCLSpecificType() const { 4934249423Sdim return isSamplerT() || isEventT() || isImageType(); 4935249423Sdim} 4936249423Sdim 4937193326Sedinline bool Type::isTemplateTypeParmType() const { 4938199482Srdivacky return isa<TemplateTypeParmType>(CanonicalType); 4939193326Sed} 4940193326Sed 4941193326Sedinline bool Type::isSpecificBuiltinType(unsigned K) const { 4942198092Srdivacky if (const BuiltinType *BT = getAs<BuiltinType>()) 4943193326Sed if (BT->getKind() == (BuiltinType::Kind) K) 4944193326Sed return true; 4945193326Sed return false; 4946193326Sed} 4947193326Sed 4948218893Sdiminline bool Type::isPlaceholderType() const { 4949226633Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4950218893Sdim return BT->isPlaceholderType(); 4951218893Sdim return false; 4952218893Sdim} 4953218893Sdim 4954226633Sdiminline const BuiltinType *Type::getAsPlaceholderType() const { 4955226633Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4956226633Sdim if (BT->isPlaceholderType()) 4957226633Sdim return BT; 4958226633Sdim return 0; 4959226633Sdim} 4960226633Sdim 4961221345Sdiminline bool Type::isSpecificPlaceholderType(unsigned K) const { 4962234353Sdim assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)); 4963221345Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4964221345Sdim return (BT->getKind() == (BuiltinType::Kind) K); 4965221345Sdim return false; 4966221345Sdim} 4967221345Sdim 4968234353Sdiminline bool Type::isNonOverloadPlaceholderType() const { 4969234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4970234353Sdim return BT->isNonOverloadPlaceholderType(); 4971234353Sdim return false; 4972234353Sdim} 4973234353Sdim 4974234353Sdiminline bool Type::isVoidType() const { 4975234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4976234353Sdim return BT->getKind() == BuiltinType::Void; 4977234353Sdim return false; 4978234353Sdim} 4979234353Sdim 4980234353Sdiminline bool Type::isHalfType() const { 4981234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4982234353Sdim return BT->getKind() == BuiltinType::Half; 4983234353Sdim // FIXME: Should we allow complex __fp16? Probably not. 4984234353Sdim return false; 4985234353Sdim} 4986234353Sdim 4987234353Sdiminline bool Type::isNullPtrType() const { 4988234353Sdim if (const BuiltinType *BT = getAs<BuiltinType>()) 4989234353Sdim return BT->getKind() == BuiltinType::NullPtr; 4990234353Sdim return false; 4991234353Sdim} 4992234353Sdim 4993234353Sdimextern bool IsEnumDeclComplete(EnumDecl *); 4994234353Sdimextern bool IsEnumDeclScoped(EnumDecl *); 4995234353Sdim 4996234353Sdiminline bool Type::isIntegerType() const { 4997234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4998234353Sdim return BT->getKind() >= BuiltinType::Bool && 4999234353Sdim BT->getKind() <= BuiltinType::Int128; 5000234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { 5001234353Sdim // Incomplete enum types are not treated as integer types. 5002234353Sdim // FIXME: In C++, enum types are never integer types. 5003234353Sdim return IsEnumDeclComplete(ET->getDecl()) && 5004234353Sdim !IsEnumDeclScoped(ET->getDecl()); 5005234353Sdim } 5006234353Sdim return false; 5007234353Sdim} 5008234353Sdim 5009234353Sdiminline bool Type::isScalarType() const { 5010234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5011234353Sdim return BT->getKind() > BuiltinType::Void && 5012234353Sdim BT->getKind() <= BuiltinType::NullPtr; 5013234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) 5014234353Sdim // Enums are scalar types, but only if they are defined. Incomplete enums 5015234353Sdim // are not treated as scalar types. 5016234353Sdim return IsEnumDeclComplete(ET->getDecl()); 5017234353Sdim return isa<PointerType>(CanonicalType) || 5018234353Sdim isa<BlockPointerType>(CanonicalType) || 5019234353Sdim isa<MemberPointerType>(CanonicalType) || 5020234353Sdim isa<ComplexType>(CanonicalType) || 5021234353Sdim isa<ObjCObjectPointerType>(CanonicalType); 5022234353Sdim} 5023234353Sdim 5024234353Sdiminline bool Type::isIntegralOrEnumerationType() const { 5025234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5026234353Sdim return BT->getKind() >= BuiltinType::Bool && 5027234353Sdim BT->getKind() <= BuiltinType::Int128; 5028234353Sdim 5029234353Sdim // Check for a complete enum type; incomplete enum types are not properly an 5030234353Sdim // enumeration type in the sense required here. 5031234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) 5032234353Sdim return IsEnumDeclComplete(ET->getDecl()); 5033234353Sdim 5034234353Sdim return false; 5035234353Sdim} 5036234353Sdim 5037234353Sdiminline bool Type::isBooleanType() const { 5038234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5039234353Sdim return BT->getKind() == BuiltinType::Bool; 5040234353Sdim return false; 5041234353Sdim} 5042234353Sdim 5043251662Sdiminline bool Type::isUndeducedType() const { 5044251662Sdim const AutoType *AT = getContainedAutoType(); 5045251662Sdim return AT && !AT->isDeduced(); 5046251662Sdim} 5047251662Sdim 5048193326Sed/// \brief Determines whether this is a type for which one can define 5049193326Sed/// an overloaded operator. 5050193326Sedinline bool Type::isOverloadableType() const { 5051193326Sed return isDependentType() || isRecordType() || isEnumeralType(); 5052193326Sed} 5053193326Sed 5054224145Sdim/// \brief Determines whether this type can decay to a pointer type. 5055224145Sdiminline bool Type::canDecayToPointerType() const { 5056224145Sdim return isFunctionType() || isArrayType(); 5057224145Sdim} 5058224145Sdim 5059193326Sedinline bool Type::hasPointerRepresentation() const { 5060193326Sed return (isPointerType() || isReferenceType() || isBlockPointerType() || 5061208600Srdivacky isObjCObjectPointerType() || isNullPtrType()); 5062193326Sed} 5063193326Sed 5064193326Sedinline bool Type::hasObjCPointerRepresentation() const { 5065208600Srdivacky return isObjCObjectPointerType(); 5066193326Sed} 5067193326Sed 5068218893Sdiminline const Type *Type::getBaseElementTypeUnsafe() const { 5069218893Sdim const Type *type = this; 5070218893Sdim while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) 5071218893Sdim type = arrayType->getElementType().getTypePtr(); 5072218893Sdim return type; 5073218893Sdim} 5074218893Sdim 5075193326Sed/// Insertion operator for diagnostics. This allows sending QualType's into a 5076193326Sed/// diagnostic with <<. 5077193326Sedinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 5078193326Sed QualType T) { 5079193326Sed DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), 5080226633Sdim DiagnosticsEngine::ak_qualtype); 5081193326Sed return DB; 5082193326Sed} 5083193326Sed 5084206084Srdivacky/// Insertion operator for partial diagnostics. This allows sending QualType's 5085206084Srdivacky/// into a diagnostic with <<. 5086206084Srdivackyinline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 5087206084Srdivacky QualType T) { 5088206084Srdivacky PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), 5089226633Sdim DiagnosticsEngine::ak_qualtype); 5090206084Srdivacky return PD; 5091206084Srdivacky} 5092206084Srdivacky 5093199482Srdivacky// Helper class template that is used by Type::getAs to ensure that one does 5094199482Srdivacky// not try to look through a qualified type to get to an array type. 5095199482Srdivackytemplate<typename T, 5096199482Srdivacky bool isArrayType = (llvm::is_same<T, ArrayType>::value || 5097199482Srdivacky llvm::is_base_of<ArrayType, T>::value)> 5098199482Srdivackystruct ArrayType_cannot_be_used_with_getAs { }; 5099234353Sdim 5100199482Srdivackytemplate<typename T> 5101199482Srdivackystruct ArrayType_cannot_be_used_with_getAs<T, true>; 5102234353Sdim 5103239462Sdim// Member-template getAs<specific type>'. 5104198092Srdivackytemplate <typename T> const T *Type::getAs() const { 5105199482Srdivacky ArrayType_cannot_be_used_with_getAs<T> at; 5106199482Srdivacky (void)at; 5107234353Sdim 5108198092Srdivacky // If this is directly a T type, return it. 5109198092Srdivacky if (const T *Ty = dyn_cast<T>(this)) 5110198092Srdivacky return Ty; 5111198092Srdivacky 5112198092Srdivacky // If the canonical form of this type isn't the right kind, reject it. 5113198092Srdivacky if (!isa<T>(CanonicalType)) 5114198092Srdivacky return 0; 5115198092Srdivacky 5116198092Srdivacky // If this is a typedef for the type, strip the typedef off without 5117198092Srdivacky // losing all typedef information. 5118198092Srdivacky return cast<T>(getUnqualifiedDesugaredType()); 5119198092Srdivacky} 5120198092Srdivacky 5121218893Sdiminline const ArrayType *Type::getAsArrayTypeUnsafe() const { 5122218893Sdim // If this is directly an array type, return it. 5123218893Sdim if (const ArrayType *arr = dyn_cast<ArrayType>(this)) 5124218893Sdim return arr; 5125218893Sdim 5126218893Sdim // If the canonical form of this type isn't the right kind, reject it. 5127218893Sdim if (!isa<ArrayType>(CanonicalType)) 5128218893Sdim return 0; 5129218893Sdim 5130218893Sdim // If this is a typedef for the type, strip the typedef off without 5131218893Sdim // losing all typedef information. 5132218893Sdim return cast<ArrayType>(getUnqualifiedDesugaredType()); 5133218893Sdim} 5134218893Sdim 5135218893Sdimtemplate <typename T> const T *Type::castAs() const { 5136218893Sdim ArrayType_cannot_be_used_with_getAs<T> at; 5137218893Sdim (void) at; 5138218893Sdim 5139218893Sdim assert(isa<T>(CanonicalType)); 5140218893Sdim if (const T *ty = dyn_cast<T>(this)) return ty; 5141218893Sdim return cast<T>(getUnqualifiedDesugaredType()); 5142218893Sdim} 5143218893Sdim 5144218893Sdiminline const ArrayType *Type::castAsArrayTypeUnsafe() const { 5145218893Sdim assert(isa<ArrayType>(CanonicalType)); 5146218893Sdim if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr; 5147218893Sdim return cast<ArrayType>(getUnqualifiedDesugaredType()); 5148218893Sdim} 5149218893Sdim 5150193326Sed} // end namespace clang 5151193326Sed 5152193326Sed#endif 5153