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 444263508Sdim LLVM_EXPLICIT 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). 821263508Sdim QualType getNonLValueExprType(const 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. 1197263508Sdim mutable unsigned CachedLinkage : 3; 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 }; 1217263508Sdim enum { NumTypeBits = 18 }; 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; 1318263508Sdim 1319263508Sdim enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; 1320218893Sdim }; 1321218893Sdim 1322218893Sdim class AttributedTypeBitfields { 1323218893Sdim friend class AttributedType; 1324218893Sdim 1325218893Sdim unsigned : NumTypeBits; 1326218893Sdim 1327218893Sdim /// AttrKind - an AttributedType::Kind 1328218893Sdim unsigned AttrKind : 32 - NumTypeBits; 1329218893Sdim }; 1330218893Sdim 1331251662Sdim class AutoTypeBitfields { 1332251662Sdim friend class AutoType; 1333251662Sdim 1334251662Sdim unsigned : NumTypeBits; 1335251662Sdim 1336251662Sdim /// Was this placeholder type spelled as 'decltype(auto)'? 1337251662Sdim unsigned IsDecltypeAuto : 1; 1338251662Sdim }; 1339251662Sdim 1340218893Sdim union { 1341218893Sdim TypeBitfields TypeBits; 1342218893Sdim ArrayTypeBitfields ArrayTypeBits; 1343218893Sdim AttributedTypeBitfields AttributedTypeBits; 1344251662Sdim AutoTypeBitfields AutoTypeBits; 1345218893Sdim BuiltinTypeBitfields BuiltinTypeBits; 1346218893Sdim FunctionTypeBitfields FunctionTypeBits; 1347218893Sdim ObjCObjectTypeBitfields ObjCObjectTypeBits; 1348218893Sdim ReferenceTypeBitfields ReferenceTypeBits; 1349218893Sdim TypeWithKeywordBitfields TypeWithKeywordBits; 1350218893Sdim VectorTypeBitfields VectorTypeBits; 1351218893Sdim }; 1352218893Sdim 1353218893Sdimprivate: 1354212904Sdim /// \brief Set whether this type comes from an AST file. 1355234353Sdim void setFromAST(bool V = true) const { 1356218893Sdim TypeBits.FromAST = V; 1357210299Sed } 1358210299Sed 1359218893Sdim template <class T> friend class TypePropertyCache; 1360218893Sdim 1361208600Srdivackyprotected: 1362193326Sed // silence VC++ warning C4355: 'this' : used in base member initializer list 1363193326Sed Type *this_() { return this; } 1364234353Sdim Type(TypeClass tc, QualType canon, bool Dependent, 1365224145Sdim bool InstantiationDependent, bool VariablyModified, 1366218893Sdim bool ContainsUnexpandedParameterPack) 1367218893Sdim : ExtQualsTypeCommonBase(this, 1368218893Sdim canon.isNull() ? QualType(this_(), 0) : canon) { 1369218893Sdim TypeBits.TC = tc; 1370218893Sdim TypeBits.Dependent = Dependent; 1371224145Sdim TypeBits.InstantiationDependent = Dependent || InstantiationDependent; 1372218893Sdim TypeBits.VariablyModified = VariablyModified; 1373218893Sdim TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; 1374249423Sdim TypeBits.CacheValid = false; 1375218893Sdim TypeBits.CachedLocalOrUnnamed = false; 1376218893Sdim TypeBits.CachedLinkage = NoLinkage; 1377218893Sdim TypeBits.FromAST = false; 1378218893Sdim } 1379193326Sed friend class ASTContext; 1380198092Srdivacky 1381234353Sdim void setDependent(bool D = true) { 1382234353Sdim TypeBits.Dependent = D; 1383224145Sdim if (D) 1384224145Sdim TypeBits.InstantiationDependent = true; 1385224145Sdim } 1386234353Sdim void setInstantiationDependent(bool D = true) { 1387224145Sdim TypeBits.InstantiationDependent = D; } 1388234353Sdim void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; 1389224145Sdim } 1390218893Sdim void setContainsUnexpandedParameterPack(bool PP = true) { 1391218893Sdim TypeBits.ContainsUnexpandedParameterPack = PP; 1392218893Sdim } 1393218893Sdim 1394193326Sedpublic: 1395218893Sdim TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } 1396198092Srdivacky 1397212904Sdim /// \brief Whether this type comes from an AST file. 1398218893Sdim bool isFromAST() const { return TypeBits.FromAST; } 1399210299Sed 1400218893Sdim /// \brief Whether this type is or contains an unexpanded parameter 1401218893Sdim /// pack, used to support C++0x variadic templates. 1402218893Sdim /// 1403218893Sdim /// A type that contains a parameter pack shall be expanded by the 1404218893Sdim /// ellipsis operator at some point. For example, the typedef in the 1405218893Sdim /// following example contains an unexpanded parameter pack 'T': 1406218893Sdim /// 1407218893Sdim /// \code 1408218893Sdim /// template<typename ...T> 1409218893Sdim /// struct X { 1410218893Sdim /// typedef T* pointer_types; // ill-formed; T is a parameter pack. 1411218893Sdim /// }; 1412218893Sdim /// \endcode 1413218893Sdim /// 1414234353Sdim /// Note that this routine does not specify which 1415234353Sdim bool containsUnexpandedParameterPack() const { 1416218893Sdim return TypeBits.ContainsUnexpandedParameterPack; 1417218893Sdim } 1418218893Sdim 1419218893Sdim /// Determines if this type would be canonical if it had no further 1420218893Sdim /// qualification. 1421198398Srdivacky bool isCanonicalUnqualified() const { 1422218893Sdim return CanonicalType == QualType(this, 0); 1423198398Srdivacky } 1424193326Sed 1425234353Sdim /// Pull a single level of sugar off of this locally-unqualified type. 1426234353Sdim /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() 1427234353Sdim /// or QualType::getSingleStepDesugaredType(const ASTContext&). 1428234353Sdim QualType getLocallyUnqualifiedSingleStepDesugaredType() const; 1429234353Sdim 1430198092Srdivacky /// Types are partitioned into 3 broad categories (C99 6.2.5p1): 1431193326Sed /// object types, function types, and incomplete types. 1432198092Srdivacky 1433193326Sed /// isIncompleteType - Return true if this is an incomplete type. 1434193326Sed /// A type that can describe objects, but which lacks information needed to 1435193326Sed /// determine its size (e.g. void, or a fwd declared struct). Clients of this 1436198092Srdivacky /// routine will need to determine if the size is actually required. 1437234353Sdim /// 1438234353Sdim /// \brief Def If non-NULL, and the type refers to some kind of declaration 1439234353Sdim /// that can be completed (such as a C struct, C++ class, or Objective-C 1440234353Sdim /// class), will be set to the declaration. 1441234353Sdim bool isIncompleteType(NamedDecl **Def = 0) const; 1442193326Sed 1443193326Sed /// isIncompleteOrObjectType - Return true if this is an incomplete or object 1444193326Sed /// type, in other words, not a function type. 1445193326Sed bool isIncompleteOrObjectType() const { 1446193326Sed return !isFunctionType(); 1447193326Sed } 1448234353Sdim 1449218893Sdim /// \brief Determine whether this type is an object type. 1450218893Sdim bool isObjectType() const { 1451218893Sdim // C++ [basic.types]p8: 1452234353Sdim // An object type is a (possibly cv-qualified) type that is not a 1453218893Sdim // function type, not a reference type, and not a void type. 1454218893Sdim return !isReferenceType() && !isFunctionType() && !isVoidType(); 1455218893Sdim } 1456193326Sed 1457200583Srdivacky /// isLiteralType - Return true if this is a literal type 1458251662Sdim /// (C++11 [basic.types]p10) 1459263508Sdim bool isLiteralType(const ASTContext &Ctx) const; 1460200583Srdivacky 1461221345Sdim /// \brief Test if this type is a standard-layout type. 1462221345Sdim /// (C++0x [basic.type]p9) 1463221345Sdim bool isStandardLayoutType() const; 1464221345Sdim 1465193326Sed /// Helper methods to distinguish type categories. All type predicates 1466193326Sed /// operate on the canonical type, ignoring typedefs and qualifiers. 1467193326Sed 1468210299Sed /// isBuiltinType - returns true if the type is a builtin type. 1469210299Sed bool isBuiltinType() const; 1470210299Sed 1471193326Sed /// isSpecificBuiltinType - Test for a particular builtin type. 1472193326Sed bool isSpecificBuiltinType(unsigned K) const; 1473198092Srdivacky 1474218893Sdim /// isPlaceholderType - Test for a type which does not represent an 1475218893Sdim /// actual type-system type but is instead used as a placeholder for 1476218893Sdim /// various convenient purposes within Clang. All such types are 1477218893Sdim /// BuiltinTypes. 1478218893Sdim bool isPlaceholderType() const; 1479226633Sdim const BuiltinType *getAsPlaceholderType() const; 1480218893Sdim 1481221345Sdim /// isSpecificPlaceholderType - Test for a specific placeholder type. 1482221345Sdim bool isSpecificPlaceholderType(unsigned K) const; 1483221345Sdim 1484234353Sdim /// isNonOverloadPlaceholderType - Test for a placeholder type 1485234353Sdim /// other than Overload; see BuiltinType::isNonOverloadPlaceholderType. 1486234353Sdim bool isNonOverloadPlaceholderType() const; 1487234353Sdim 1488193326Sed /// isIntegerType() does *not* include complex integers (a GCC extension). 1489193326Sed /// isComplexIntegerType() can be used to test for complex integers. 1490193326Sed bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) 1491193326Sed bool isEnumeralType() const; 1492193326Sed bool isBooleanType() const; 1493193326Sed bool isCharType() const; 1494193326Sed bool isWideCharType() const; 1495226633Sdim bool isChar16Type() const; 1496226633Sdim bool isChar32Type() const; 1497200583Srdivacky bool isAnyCharacterType() const; 1498210299Sed bool isIntegralType(ASTContext &Ctx) const; 1499234353Sdim 1500210299Sed /// \brief Determine whether this type is an integral or enumeration type. 1501210299Sed bool isIntegralOrEnumerationType() const; 1502218893Sdim /// \brief Determine whether this type is an integral or unscoped enumeration 1503218893Sdim /// type. 1504218893Sdim bool isIntegralOrUnscopedEnumerationType() const; 1505234353Sdim 1506193326Sed /// Floating point categories. 1507193326Sed bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) 1508193326Sed /// isComplexType() does *not* include complex integers (a GCC extension). 1509193326Sed /// isComplexIntegerType() can be used to test for complex integers. 1510193326Sed bool isComplexType() const; // C99 6.2.5p11 (complex) 1511193326Sed bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. 1512193326Sed bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) 1513226633Sdim bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) 1514193326Sed bool isRealType() const; // C99 6.2.5p17 (real floating + integer) 1515193326Sed bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) 1516193326Sed bool isVoidType() const; // C99 6.2.5p19 1517193326Sed bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) 1518193326Sed bool isAggregateType() const; 1519221345Sdim bool isFundamentalType() const; 1520221345Sdim bool isCompoundType() const; 1521198092Srdivacky 1522193326Sed // Type Predicates: Check to see if this type is structurally the specified 1523193326Sed // type, ignoring typedefs and qualifiers. 1524193326Sed bool isFunctionType() const; 1525198092Srdivacky bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } 1526198092Srdivacky bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } 1527193326Sed bool isPointerType() const; 1528198092Srdivacky bool isAnyPointerType() const; // Any C pointer or ObjC object pointer 1529193326Sed bool isBlockPointerType() const; 1530195341Sed bool isVoidPointerType() const; 1531193326Sed bool isReferenceType() const; 1532193326Sed bool isLValueReferenceType() const; 1533193326Sed bool isRValueReferenceType() const; 1534193326Sed bool isFunctionPointerType() const; 1535193326Sed bool isMemberPointerType() const; 1536193326Sed bool isMemberFunctionPointerType() const; 1537212904Sdim bool isMemberDataPointerType() const; 1538193326Sed bool isArrayType() const; 1539193326Sed bool isConstantArrayType() const; 1540193326Sed bool isIncompleteArrayType() const; 1541193326Sed bool isVariableArrayType() const; 1542193326Sed bool isDependentSizedArrayType() const; 1543193326Sed bool isRecordType() const; 1544198092Srdivacky bool isClassType() const; 1545198092Srdivacky bool isStructureType() const; 1546243830Sdim bool isInterfaceType() const; 1547207619Srdivacky bool isStructureOrClassType() const; 1548193326Sed bool isUnionType() const; 1549193326Sed bool isComplexIntegerType() const; // GCC _Complex integer type. 1550193326Sed bool isVectorType() const; // GCC vector type. 1551193326Sed bool isExtVectorType() const; // Extended vector type. 1552224145Sdim bool isObjCObjectPointerType() const; // pointer to ObjC object 1553224145Sdim bool isObjCRetainableType() const; // ObjC object or block pointer 1554224145Sdim bool isObjCLifetimeType() const; // (array of)* retainable type 1555224145Sdim bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type 1556224145Sdim bool isObjCNSObjectType() const; // __attribute__((NSObject)) 1557198092Srdivacky // FIXME: change this to 'raw' interface type, so we can used 'interface' type 1558198092Srdivacky // for the common case. 1559208600Srdivacky bool isObjCObjectType() const; // NSString or typeof(*(id)0) 1560193326Sed bool isObjCQualifiedInterfaceType() const; // NSString<foo> 1561193326Sed bool isObjCQualifiedIdType() const; // id<foo> 1562198092Srdivacky bool isObjCQualifiedClassType() const; // Class<foo> 1563212904Sdim bool isObjCObjectOrInterfaceType() const; 1564198092Srdivacky bool isObjCIdType() const; // id 1565198092Srdivacky bool isObjCClassType() const; // Class 1566199990Srdivacky bool isObjCSelType() const; // Class 1567198092Srdivacky bool isObjCBuiltinType() const; // 'id' or 'Class' 1568224145Sdim bool isObjCARCBridgableType() const; 1569224145Sdim bool isCARCBridgableType() const; 1570193326Sed bool isTemplateTypeParmType() const; // C++ template type parameter 1571193326Sed bool isNullPtrType() const; // C++0x nullptr_t 1572234353Sdim bool isAtomicType() const; // C11 _Atomic() 1573193326Sed 1574249423Sdim bool isImage1dT() const; // OpenCL image1d_t 1575249423Sdim bool isImage1dArrayT() const; // OpenCL image1d_array_t 1576249423Sdim bool isImage1dBufferT() const; // OpenCL image1d_buffer_t 1577249423Sdim bool isImage2dT() const; // OpenCL image2d_t 1578249423Sdim bool isImage2dArrayT() const; // OpenCL image2d_array_t 1579249423Sdim bool isImage3dT() const; // OpenCL image3d_t 1580249423Sdim 1581249423Sdim bool isImageType() const; // Any OpenCL image type 1582249423Sdim 1583249423Sdim bool isSamplerT() const; // OpenCL sampler_t 1584249423Sdim bool isEventT() const; // OpenCL event_t 1585249423Sdim 1586249423Sdim bool isOpenCLSpecificType() const; // Any OpenCL specific type 1587249423Sdim 1588224145Sdim /// Determines if this type, which must satisfy 1589224145Sdim /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather 1590224145Sdim /// than implicitly __strong. 1591224145Sdim bool isObjCARCImplicitlyUnretainedType() const; 1592224145Sdim 1593224145Sdim /// Return the implicit lifetime for this type, which must not be dependent. 1594224145Sdim Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; 1595224145Sdim 1596218893Sdim enum ScalarTypeKind { 1597226633Sdim STK_CPointer, 1598226633Sdim STK_BlockPointer, 1599226633Sdim STK_ObjCObjectPointer, 1600218893Sdim STK_MemberPointer, 1601218893Sdim STK_Bool, 1602218893Sdim STK_Integral, 1603218893Sdim STK_Floating, 1604218893Sdim STK_IntegralComplex, 1605218893Sdim STK_FloatingComplex 1606218893Sdim }; 1607218893Sdim /// getScalarTypeKind - Given that this is a scalar type, classify it. 1608218893Sdim ScalarTypeKind getScalarTypeKind() const; 1609218893Sdim 1610193326Sed /// isDependentType - Whether this type is a dependent type, meaning 1611198092Srdivacky /// that its definition somehow depends on a template parameter 1612193326Sed /// (C++ [temp.dep.type]). 1613218893Sdim bool isDependentType() const { return TypeBits.Dependent; } 1614234353Sdim 1615224145Sdim /// \brief Determine whether this type is an instantiation-dependent type, 1616224145Sdim /// meaning that the type involves a template parameter (even if the 1617224145Sdim /// definition does not actually depend on the type substituted for that 1618224145Sdim /// template parameter). 1619234353Sdim bool isInstantiationDependentType() const { 1620234353Sdim return TypeBits.InstantiationDependent; 1621224145Sdim } 1622234353Sdim 1623251662Sdim /// \brief Determine whether this type is an undeduced type, meaning that 1624251662Sdim /// it somehow involves a C++11 'auto' type which has not yet been deduced. 1625251662Sdim bool isUndeducedType() const; 1626251662Sdim 1627218893Sdim /// \brief Whether this type is a variably-modified type (C99 6.7.5). 1628218893Sdim bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } 1629218893Sdim 1630218893Sdim /// \brief Whether this type involves a variable-length array type 1631218893Sdim /// with a definite size. 1632218893Sdim bool hasSizedVLAType() const; 1633234353Sdim 1634218893Sdim /// \brief Whether this type is or contains a local or unnamed type. 1635218893Sdim bool hasUnnamedOrLocalType() const; 1636234353Sdim 1637193326Sed bool isOverloadableType() const; 1638193326Sed 1639206084Srdivacky /// \brief Determine wither this type is a C++ elaborated-type-specifier. 1640206084Srdivacky bool isElaboratedTypeSpecifier() const; 1641224145Sdim 1642224145Sdim bool canDecayToPointerType() const; 1643234353Sdim 1644193326Sed /// hasPointerRepresentation - Whether this type is represented 1645193326Sed /// natively as a pointer; this includes pointers, references, block 1646193326Sed /// pointers, and Objective-C interface, qualified id, and qualified 1647193326Sed /// interface types, as well as nullptr_t. 1648193326Sed bool hasPointerRepresentation() const; 1649193326Sed 1650193326Sed /// hasObjCPointerRepresentation - Whether this type can represent 1651193326Sed /// an objective pointer type for the purpose of GC'ability 1652198092Srdivacky bool hasObjCPointerRepresentation() const; 1653193326Sed 1654212904Sdim /// \brief Determine whether this type has an integer representation 1655212904Sdim /// of some sort, e.g., it is an integer type or a vector. 1656212904Sdim bool hasIntegerRepresentation() const; 1657212904Sdim 1658212904Sdim /// \brief Determine whether this type has an signed integer representation 1659212904Sdim /// of some sort, e.g., it is an signed integer type or a vector. 1660212904Sdim bool hasSignedIntegerRepresentation() const; 1661212904Sdim 1662212904Sdim /// \brief Determine whether this type has an unsigned integer representation 1663212904Sdim /// of some sort, e.g., it is an unsigned integer type or a vector. 1664212904Sdim bool hasUnsignedIntegerRepresentation() const; 1665212904Sdim 1666210299Sed /// \brief Determine whether this type has a floating-point representation 1667210299Sed /// of some sort, e.g., it is a floating-point type or a vector thereof. 1668210299Sed bool hasFloatingRepresentation() const; 1669212904Sdim 1670193326Sed // Type Checking Functions: Check to see if this type is structurally the 1671193326Sed // specified type, ignoring typedefs and qualifiers, and return a pointer to 1672193326Sed // the best type we can. 1673193326Sed const RecordType *getAsStructureType() const; 1674193326Sed /// NOTE: getAs*ArrayType are methods on ASTContext. 1675193326Sed const RecordType *getAsUnionType() const; 1676193326Sed const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. 1677198092Srdivacky // The following is a convenience method that returns an ObjCObjectPointerType 1678198092Srdivacky // for object declared using an interface. 1679198092Srdivacky const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; 1680194613Sed const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; 1681221345Sdim const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; 1682208600Srdivacky const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; 1683193326Sed 1684207619Srdivacky /// \brief Retrieves the CXXRecordDecl that this type refers to, either 1685234353Sdim /// because the type is a RecordType or because it is the injected-class-name 1686207619Srdivacky /// type of a class template or class template partial specialization. 1687207619Srdivacky CXXRecordDecl *getAsCXXRecordDecl() const; 1688218893Sdim 1689243830Sdim /// If this is a pointer or reference to a RecordType, return the 1690243830Sdim /// CXXRecordDecl that that type refers to. 1691243830Sdim /// 1692243830Sdim /// If this is not a pointer or reference, or the type being pointed to does 1693243830Sdim /// not refer to a CXXRecordDecl, returns NULL. 1694243830Sdim const CXXRecordDecl *getPointeeCXXRecordDecl() const; 1695243830Sdim 1696218893Sdim /// \brief Get the AutoType whose type will be deduced for a variable with 1697218893Sdim /// an initializer of this type. This looks through declarators like pointer 1698218893Sdim /// types, but not through decltype or typedefs. 1699218893Sdim AutoType *getContainedAutoType() const; 1700234353Sdim 1701218893Sdim /// Member-template getAs<specific type>'. Look through sugar for 1702239462Sdim /// an instance of \<specific type>. This scheme will eventually 1703218893Sdim /// replace the specific getAsXXXX methods above. 1704218893Sdim /// 1705218893Sdim /// There are some specializations of this member template listed 1706218893Sdim /// immediately following this class. 1707198092Srdivacky template <typename T> const T *getAs() const; 1708198092Srdivacky 1709218893Sdim /// A variant of getAs<> for array types which silently discards 1710218893Sdim /// qualifiers from the outermost type. 1711218893Sdim const ArrayType *getAsArrayTypeUnsafe() const; 1712218893Sdim 1713218893Sdim /// Member-template castAs<specific type>. Look through sugar for 1714239462Sdim /// the underlying instance of \<specific type>. 1715218893Sdim /// 1716218893Sdim /// This method has the same relationship to getAs<T> as cast<T> has 1717218893Sdim /// to dyn_cast<T>; which is to say, the underlying type *must* 1718218893Sdim /// have the intended type, and this method will never return null. 1719218893Sdim template <typename T> const T *castAs() const; 1720218893Sdim 1721218893Sdim /// A variant of castAs<> for array type which silently discards 1722218893Sdim /// qualifiers from the outermost type. 1723218893Sdim const ArrayType *castAsArrayTypeUnsafe() const; 1724218893Sdim 1725218893Sdim /// getBaseElementTypeUnsafe - Get the base element type of this 1726218893Sdim /// type, potentially discarding type qualifiers. This method 1727218893Sdim /// should never be used when type qualifiers are meaningful. 1728218893Sdim const Type *getBaseElementTypeUnsafe() const; 1729218893Sdim 1730193326Sed /// getArrayElementTypeNoTypeQual - If this is an array type, return the 1731193326Sed /// element type of the array, potentially with type qualifiers missing. 1732193326Sed /// This method should never be used when type qualifiers are meaningful. 1733193326Sed const Type *getArrayElementTypeNoTypeQual() const; 1734198092Srdivacky 1735198092Srdivacky /// getPointeeType - If this is a pointer, ObjC object pointer, or block 1736198092Srdivacky /// pointer, this returns the respective pointee. 1737198092Srdivacky QualType getPointeeType() const; 1738198092Srdivacky 1739198092Srdivacky /// getUnqualifiedDesugaredType() - Return the specified type with 1740198092Srdivacky /// any "sugar" removed from the type, removing any typedefs, 1741198092Srdivacky /// typeofs, etc., as well as any qualifiers. 1742198092Srdivacky const Type *getUnqualifiedDesugaredType() const; 1743198092Srdivacky 1744193326Sed /// More type predicates useful for type checking/promotion 1745193326Sed bool isPromotableIntegerType() const; // C99 6.3.1.1p2 1746193326Sed 1747193326Sed /// isSignedIntegerType - Return true if this is an integer type that is 1748193326Sed /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], 1749223017Sdim /// or an enum decl which has a signed representation. 1750193326Sed bool isSignedIntegerType() const; 1751193326Sed 1752193326Sed /// isUnsignedIntegerType - Return true if this is an integer type that is 1753234353Sdim /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], 1754223017Sdim /// or an enum decl which has an unsigned representation. 1755193326Sed bool isUnsignedIntegerType() const; 1756193326Sed 1757234353Sdim /// Determines whether this is an integer type that is signed or an 1758223017Sdim /// enumeration types whose underlying type is a signed integer type. 1759223017Sdim bool isSignedIntegerOrEnumerationType() const; 1760234353Sdim 1761234353Sdim /// Determines whether this is an integer type that is unsigned or an 1762223017Sdim /// enumeration types whose underlying type is a unsigned integer type. 1763223017Sdim bool isUnsignedIntegerOrEnumerationType() const; 1764223017Sdim 1765193326Sed /// isConstantSizeType - Return true if this is not a variable sized type, 1766193326Sed /// according to the rules of C99 6.7.5p3. It is not legal to call this on 1767193326Sed /// incomplete types. 1768193326Sed bool isConstantSizeType() const; 1769193326Sed 1770193326Sed /// isSpecifierType - Returns true if this type can be represented by some 1771193326Sed /// set of type specifiers. 1772193326Sed bool isSpecifierType() const; 1773193326Sed 1774208600Srdivacky /// \brief Determine the linkage of this type. 1775208600Srdivacky Linkage getLinkage() const; 1776218893Sdim 1777218893Sdim /// \brief Determine the visibility of this type. 1778249423Sdim Visibility getVisibility() const { 1779249423Sdim return getLinkageAndVisibility().getVisibility(); 1780249423Sdim } 1781218893Sdim 1782234353Sdim /// \brief Return true if the visibility was explicitly set is the code. 1783249423Sdim bool isVisibilityExplicit() const { 1784249423Sdim return getLinkageAndVisibility().isVisibilityExplicit(); 1785249423Sdim } 1786234353Sdim 1787218893Sdim /// \brief Determine the linkage and visibility of this type. 1788249423Sdim LinkageInfo getLinkageAndVisibility() const; 1789234353Sdim 1790249423Sdim /// \brief True if the computed linkage is valid. Used for consistency 1791249423Sdim /// checking. Should always return true. 1792249423Sdim bool isLinkageValid() const; 1793234353Sdim 1794198092Srdivacky const char *getTypeClassName() const; 1795198092Srdivacky 1796204643Srdivacky QualType getCanonicalTypeInternal() const { 1797204643Srdivacky return CanonicalType; 1798204643Srdivacky } 1799204643Srdivacky CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h 1800234353Sdim LLVM_ATTRIBUTE_USED void dump() const; 1801224145Sdim 1802212904Sdim friend class ASTReader; 1803212904Sdim friend class ASTWriter; 1804193326Sed}; 1805193326Sed 1806239462Sdim/// \brief This will check for a TypedefType by removing any existing sugar 1807239462Sdim/// until it reaches a TypedefType or a non-sugared type. 1808239462Sdimtemplate <> const TypedefType *Type::getAs() const; 1809193326Sed 1810243830Sdim/// \brief This will check for a TemplateSpecializationType by removing any 1811243830Sdim/// existing sugar until it reaches a TemplateSpecializationType or a 1812243830Sdim/// non-sugared type. 1813243830Sdimtemplate <> const TemplateSpecializationType *Type::getAs() const; 1814243830Sdim 1815263508Sdim/// \brief This will check for an AttributedType by removing any existing sugar 1816263508Sdim/// until it reaches an AttributedType or a non-sugared type. 1817263508Sdimtemplate <> const AttributedType *Type::getAs() const; 1818263508Sdim 1819198092Srdivacky// We can do canonical leaf types faster, because we don't have to 1820198092Srdivacky// worry about preserving child type decoration. 1821198092Srdivacky#define TYPE(Class, Base) 1822198092Srdivacky#define LEAF_TYPE(Class) \ 1823198092Srdivackytemplate <> inline const Class##Type *Type::getAs() const { \ 1824198092Srdivacky return dyn_cast<Class##Type>(CanonicalType); \ 1825218893Sdim} \ 1826218893Sdimtemplate <> inline const Class##Type *Type::castAs() const { \ 1827218893Sdim return cast<Class##Type>(CanonicalType); \ 1828198092Srdivacky} 1829198092Srdivacky#include "clang/AST/TypeNodes.def" 1830193326Sed 1831193326Sed 1832193326Sed/// BuiltinType - This class is used for builtin types like 'int'. Builtin 1833193326Sed/// types are always canonical and have a literal name field. 1834193326Sedclass BuiltinType : public Type { 1835193326Sedpublic: 1836193326Sed enum Kind { 1837234353Sdim#define BUILTIN_TYPE(Id, SingletonId) Id, 1838234353Sdim#define LAST_BUILTIN_TYPE(Id) LastKind = Id 1839234353Sdim#include "clang/AST/BuiltinTypes.def" 1840193326Sed }; 1841218893Sdim 1842193326Sedpublic: 1843198092Srdivacky BuiltinType(Kind K) 1844218893Sdim : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), 1845224145Sdim /*InstantiationDependent=*/(K == Dependent), 1846218893Sdim /*VariablyModified=*/false, 1847218893Sdim /*Unexpanded paramter pack=*/false) { 1848218893Sdim BuiltinTypeBits.Kind = K; 1849218893Sdim } 1850198092Srdivacky 1851218893Sdim Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } 1852239462Sdim StringRef getName(const PrintingPolicy &Policy) const; 1853239462Sdim const char *getNameAsCString(const PrintingPolicy &Policy) const { 1854239462Sdim // The StringRef is null-terminated. 1855239462Sdim StringRef str = getName(Policy); 1856239462Sdim assert(!str.empty() && str.data()[str.size()] == '\0'); 1857239462Sdim return str.data(); 1858239462Sdim } 1859198092Srdivacky 1860198092Srdivacky bool isSugared() const { return false; } 1861198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1862198092Srdivacky 1863199482Srdivacky bool isInteger() const { 1864218893Sdim return getKind() >= Bool && getKind() <= Int128; 1865199482Srdivacky } 1866198092Srdivacky 1867199482Srdivacky bool isSignedInteger() const { 1868218893Sdim return getKind() >= Char_S && getKind() <= Int128; 1869199482Srdivacky } 1870199482Srdivacky 1871199482Srdivacky bool isUnsignedInteger() const { 1872218893Sdim return getKind() >= Bool && getKind() <= UInt128; 1873199482Srdivacky } 1874199482Srdivacky 1875199482Srdivacky bool isFloatingPoint() const { 1876226633Sdim return getKind() >= Half && getKind() <= LongDouble; 1877199482Srdivacky } 1878199482Srdivacky 1879234353Sdim /// Determines whether the given kind corresponds to a placeholder type. 1880234353Sdim static bool isPlaceholderTypeKind(Kind K) { 1881234353Sdim return K >= Overload; 1882234353Sdim } 1883234353Sdim 1884221345Sdim /// Determines whether this type is a placeholder type, i.e. a type 1885221345Sdim /// which cannot appear in arbitrary positions in a fully-formed 1886221345Sdim /// expression. 1887218893Sdim bool isPlaceholderType() const { 1888234353Sdim return isPlaceholderTypeKind(getKind()); 1889218893Sdim } 1890218893Sdim 1891234353Sdim /// Determines whether this type is a placeholder type other than 1892234353Sdim /// Overload. Most placeholder types require only syntactic 1893234353Sdim /// information about their context in order to be resolved (e.g. 1894234353Sdim /// whether it is a call expression), which means they can (and 1895234353Sdim /// should) be resolved in an earlier "phase" of analysis. 1896234353Sdim /// Overload expressions sometimes pick up further information 1897234353Sdim /// from their context, like whether the context expects a 1898234353Sdim /// specific function-pointer type, and so frequently need 1899234353Sdim /// special treatment. 1900234353Sdim bool isNonOverloadPlaceholderType() const { 1901234353Sdim return getKind() > Overload; 1902234353Sdim } 1903234353Sdim 1904193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } 1905193326Sed}; 1906193326Sed 1907193326Sed/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex 1908193326Sed/// types (_Complex float etc) as well as the GCC integer complex extensions. 1909193326Sed/// 1910193326Sedclass ComplexType : public Type, public llvm::FoldingSetNode { 1911193326Sed QualType ElementType; 1912193326Sed ComplexType(QualType Element, QualType CanonicalPtr) : 1913218893Sdim Type(Complex, CanonicalPtr, Element->isDependentType(), 1914224145Sdim Element->isInstantiationDependentType(), 1915218893Sdim Element->isVariablyModifiedType(), 1916218893Sdim Element->containsUnexpandedParameterPack()), 1917193326Sed ElementType(Element) { 1918193326Sed } 1919193326Sed friend class ASTContext; // ASTContext creates these. 1920208600Srdivacky 1921193326Sedpublic: 1922193326Sed QualType getElementType() const { return ElementType; } 1923198092Srdivacky 1924198092Srdivacky bool isSugared() const { return false; } 1925198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1926198092Srdivacky 1927193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 1928193326Sed Profile(ID, getElementType()); 1929193326Sed } 1930193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { 1931193326Sed ID.AddPointer(Element.getAsOpaquePtr()); 1932193326Sed } 1933198092Srdivacky 1934193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Complex; } 1935193326Sed}; 1936193326Sed 1937218893Sdim/// ParenType - Sugar for parentheses used when specifying types. 1938218893Sdim/// 1939218893Sdimclass ParenType : public Type, public llvm::FoldingSetNode { 1940218893Sdim QualType Inner; 1941218893Sdim 1942218893Sdim ParenType(QualType InnerType, QualType CanonType) : 1943218893Sdim Type(Paren, CanonType, InnerType->isDependentType(), 1944224145Sdim InnerType->isInstantiationDependentType(), 1945218893Sdim InnerType->isVariablyModifiedType(), 1946218893Sdim InnerType->containsUnexpandedParameterPack()), 1947218893Sdim Inner(InnerType) { 1948218893Sdim } 1949218893Sdim friend class ASTContext; // ASTContext creates these. 1950218893Sdim 1951218893Sdimpublic: 1952218893Sdim 1953218893Sdim QualType getInnerType() const { return Inner; } 1954218893Sdim 1955218893Sdim bool isSugared() const { return true; } 1956218893Sdim QualType desugar() const { return getInnerType(); } 1957218893Sdim 1958218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 1959218893Sdim Profile(ID, getInnerType()); 1960218893Sdim } 1961218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { 1962218893Sdim Inner.Profile(ID); 1963218893Sdim } 1964218893Sdim 1965218893Sdim static bool classof(const Type *T) { return T->getTypeClass() == Paren; } 1966218893Sdim}; 1967218893Sdim 1968193326Sed/// PointerType - C99 6.7.5.1 - Pointer Declarators. 1969193326Sed/// 1970193326Sedclass PointerType : public Type, public llvm::FoldingSetNode { 1971193326Sed QualType PointeeType; 1972193326Sed 1973193326Sed PointerType(QualType Pointee, QualType CanonicalPtr) : 1974218893Sdim Type(Pointer, CanonicalPtr, Pointee->isDependentType(), 1975224145Sdim Pointee->isInstantiationDependentType(), 1976218893Sdim Pointee->isVariablyModifiedType(), 1977234353Sdim Pointee->containsUnexpandedParameterPack()), 1978218893Sdim PointeeType(Pointee) { 1979193326Sed } 1980193326Sed friend class ASTContext; // ASTContext creates these. 1981208600Srdivacky 1982193326Sedpublic: 1983198092Srdivacky 1984193326Sed QualType getPointeeType() const { return PointeeType; } 1985193326Sed 1986198092Srdivacky bool isSugared() const { return false; } 1987198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1988198092Srdivacky 1989193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 1990193326Sed Profile(ID, getPointeeType()); 1991193326Sed } 1992193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 1993193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 1994193326Sed } 1995198092Srdivacky 1996193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } 1997193326Sed}; 1998193326Sed 1999263508Sdim/// \brief Represents a pointer type decayed from an array or function type. 2000263508Sdimclass DecayedType : public Type, public llvm::FoldingSetNode { 2001263508Sdim QualType OriginalType; 2002263508Sdim QualType DecayedPointer; 2003263508Sdim 2004263508Sdim DecayedType(QualType OriginalType, QualType DecayedPointer, 2005263508Sdim QualType CanonicalPtr) 2006263508Sdim : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(), 2007263508Sdim OriginalType->isInstantiationDependentType(), 2008263508Sdim OriginalType->isVariablyModifiedType(), 2009263508Sdim OriginalType->containsUnexpandedParameterPack()), 2010263508Sdim OriginalType(OriginalType), DecayedPointer(DecayedPointer) { 2011263508Sdim assert(isa<PointerType>(DecayedPointer)); 2012263508Sdim } 2013263508Sdim 2014263508Sdim friend class ASTContext; // ASTContext creates these. 2015263508Sdim 2016263508Sdimpublic: 2017263508Sdim QualType getDecayedType() const { return DecayedPointer; } 2018263508Sdim QualType getOriginalType() const { return OriginalType; } 2019263508Sdim 2020263508Sdim QualType getPointeeType() const { 2021263508Sdim return cast<PointerType>(DecayedPointer)->getPointeeType(); 2022263508Sdim } 2023263508Sdim 2024263508Sdim bool isSugared() const { return true; } 2025263508Sdim QualType desugar() const { return DecayedPointer; } 2026263508Sdim 2027263508Sdim void Profile(llvm::FoldingSetNodeID &ID) { 2028263508Sdim Profile(ID, OriginalType); 2029263508Sdim } 2030263508Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) { 2031263508Sdim ID.AddPointer(OriginalType.getAsOpaquePtr()); 2032263508Sdim } 2033263508Sdim 2034263508Sdim static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } 2035263508Sdim}; 2036263508Sdim 2037193326Sed/// BlockPointerType - pointer to a block type. 2038193326Sed/// This type is to represent types syntactically represented as 2039193326Sed/// "void (^)(int)", etc. Pointee is required to always be a function type. 2040193326Sed/// 2041193326Sedclass BlockPointerType : public Type, public llvm::FoldingSetNode { 2042193326Sed QualType PointeeType; // Block is some kind of pointer type 2043193326Sed BlockPointerType(QualType Pointee, QualType CanonicalCls) : 2044218893Sdim Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), 2045224145Sdim Pointee->isInstantiationDependentType(), 2046218893Sdim Pointee->isVariablyModifiedType(), 2047218893Sdim Pointee->containsUnexpandedParameterPack()), 2048193326Sed PointeeType(Pointee) { 2049193326Sed } 2050193326Sed friend class ASTContext; // ASTContext creates these. 2051234353Sdim 2052193326Sedpublic: 2053198092Srdivacky 2054193326Sed // Get the pointee type. Pointee is required to always be a function type. 2055193326Sed QualType getPointeeType() const { return PointeeType; } 2056193326Sed 2057198092Srdivacky bool isSugared() const { return false; } 2058198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2059198092Srdivacky 2060193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2061193326Sed Profile(ID, getPointeeType()); 2062193326Sed } 2063193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 2064193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 2065193326Sed } 2066198092Srdivacky 2067198092Srdivacky static bool classof(const Type *T) { 2068198092Srdivacky return T->getTypeClass() == BlockPointer; 2069193326Sed } 2070193326Sed}; 2071193326Sed 2072193326Sed/// ReferenceType - Base for LValueReferenceType and RValueReferenceType 2073193326Sed/// 2074193326Sedclass ReferenceType : public Type, public llvm::FoldingSetNode { 2075193326Sed QualType PointeeType; 2076193326Sed 2077193326Sedprotected: 2078198398Srdivacky ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, 2079198398Srdivacky bool SpelledAsLValue) : 2080218893Sdim Type(tc, CanonicalRef, Referencee->isDependentType(), 2081224145Sdim Referencee->isInstantiationDependentType(), 2082218893Sdim Referencee->isVariablyModifiedType(), 2083234353Sdim Referencee->containsUnexpandedParameterPack()), 2084234353Sdim PointeeType(Referencee) 2085218893Sdim { 2086218893Sdim ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; 2087218893Sdim ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); 2088193326Sed } 2089234353Sdim 2090193326Sedpublic: 2091218893Sdim bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } 2092218893Sdim bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } 2093234353Sdim 2094198398Srdivacky QualType getPointeeTypeAsWritten() const { return PointeeType; } 2095198398Srdivacky QualType getPointeeType() const { 2096198398Srdivacky // FIXME: this might strip inner qualifiers; okay? 2097198398Srdivacky const ReferenceType *T = this; 2098218893Sdim while (T->isInnerRef()) 2099218893Sdim T = T->PointeeType->castAs<ReferenceType>(); 2100198398Srdivacky return T->PointeeType; 2101198398Srdivacky } 2102198398Srdivacky 2103193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2104218893Sdim Profile(ID, PointeeType, isSpelledAsLValue()); 2105193326Sed } 2106198398Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 2107198398Srdivacky QualType Referencee, 2108198398Srdivacky bool SpelledAsLValue) { 2109193326Sed ID.AddPointer(Referencee.getAsOpaquePtr()); 2110198398Srdivacky ID.AddBoolean(SpelledAsLValue); 2111193326Sed } 2112193326Sed 2113193326Sed static bool classof(const Type *T) { 2114193326Sed return T->getTypeClass() == LValueReference || 2115193326Sed T->getTypeClass() == RValueReference; 2116193326Sed } 2117193326Sed}; 2118193326Sed 2119193326Sed/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference 2120193326Sed/// 2121193326Sedclass LValueReferenceType : public ReferenceType { 2122198398Srdivacky LValueReferenceType(QualType Referencee, QualType CanonicalRef, 2123198398Srdivacky bool SpelledAsLValue) : 2124198398Srdivacky ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue) 2125198398Srdivacky {} 2126193326Sed friend class ASTContext; // ASTContext creates these 2127193326Sedpublic: 2128198092Srdivacky bool isSugared() const { return false; } 2129198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2130198092Srdivacky 2131193326Sed static bool classof(const Type *T) { 2132193326Sed return T->getTypeClass() == LValueReference; 2133193326Sed } 2134193326Sed}; 2135193326Sed 2136193326Sed/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference 2137193326Sed/// 2138193326Sedclass RValueReferenceType : public ReferenceType { 2139193326Sed RValueReferenceType(QualType Referencee, QualType CanonicalRef) : 2140198398Srdivacky ReferenceType(RValueReference, Referencee, CanonicalRef, false) { 2141193326Sed } 2142193326Sed friend class ASTContext; // ASTContext creates these 2143193326Sedpublic: 2144198092Srdivacky bool isSugared() const { return false; } 2145198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2146198092Srdivacky 2147193326Sed static bool classof(const Type *T) { 2148193326Sed return T->getTypeClass() == RValueReference; 2149193326Sed } 2150193326Sed}; 2151193326Sed 2152193326Sed/// MemberPointerType - C++ 8.3.3 - Pointers to members 2153193326Sed/// 2154193326Sedclass MemberPointerType : public Type, public llvm::FoldingSetNode { 2155193326Sed QualType PointeeType; 2156193326Sed /// The class of which the pointee is a member. Must ultimately be a 2157193326Sed /// RecordType, but could be a typedef or a template parameter too. 2158193326Sed const Type *Class; 2159193326Sed 2160193326Sed MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : 2161193326Sed Type(MemberPointer, CanonicalPtr, 2162218893Sdim Cls->isDependentType() || Pointee->isDependentType(), 2163234353Sdim (Cls->isInstantiationDependentType() || 2164224145Sdim Pointee->isInstantiationDependentType()), 2165218893Sdim Pointee->isVariablyModifiedType(), 2166234353Sdim (Cls->containsUnexpandedParameterPack() || 2167218893Sdim Pointee->containsUnexpandedParameterPack())), 2168193326Sed PointeeType(Pointee), Class(Cls) { 2169193326Sed } 2170193326Sed friend class ASTContext; // ASTContext creates these. 2171234353Sdim 2172193326Sedpublic: 2173193326Sed QualType getPointeeType() const { return PointeeType; } 2174193326Sed 2175212904Sdim /// Returns true if the member type (i.e. the pointee type) is a 2176212904Sdim /// function type rather than a data-member type. 2177212904Sdim bool isMemberFunctionPointer() const { 2178212904Sdim return PointeeType->isFunctionProtoType(); 2179212904Sdim } 2180212904Sdim 2181212904Sdim /// Returns true if the member type (i.e. the pointee type) is a 2182212904Sdim /// data type rather than a function type. 2183212904Sdim bool isMemberDataPointer() const { 2184212904Sdim return !PointeeType->isFunctionProtoType(); 2185212904Sdim } 2186212904Sdim 2187193326Sed const Type *getClass() const { return Class; } 2188193326Sed 2189198092Srdivacky bool isSugared() const { return false; } 2190198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2191198092Srdivacky 2192193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2193193326Sed Profile(ID, getPointeeType(), getClass()); 2194193326Sed } 2195193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, 2196193326Sed const Type *Class) { 2197193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 2198193326Sed ID.AddPointer(Class); 2199193326Sed } 2200193326Sed 2201193326Sed static bool classof(const Type *T) { 2202193326Sed return T->getTypeClass() == MemberPointer; 2203193326Sed } 2204193326Sed}; 2205193326Sed 2206193326Sed/// ArrayType - C99 6.7.5.2 - Array Declarators. 2207193326Sed/// 2208193326Sedclass ArrayType : public Type, public llvm::FoldingSetNode { 2209193326Sedpublic: 2210193326Sed /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4]) 2211193326Sed /// an array with a static size (e.g. int X[static 4]), or an array 2212193326Sed /// with a star size (e.g. int X[*]). 2213193326Sed /// 'static' is only allowed on function parameters. 2214193326Sed enum ArraySizeModifier { 2215193326Sed Normal, Static, Star 2216193326Sed }; 2217193326Sedprivate: 2218193326Sed /// ElementType - The element type of the array. 2219193326Sed QualType ElementType; 2220198092Srdivacky 2221193326Sedprotected: 2222193326Sed // C++ [temp.dep.type]p1: 2223193326Sed // A type is dependent if it is... 2224193326Sed // - an array type constructed from any dependent type or whose 2225193326Sed // size is specified by a constant expression that is 2226193326Sed // value-dependent, 2227193326Sed ArrayType(TypeClass tc, QualType et, QualType can, 2228218893Sdim ArraySizeModifier sm, unsigned tq, 2229218893Sdim bool ContainsUnexpandedParameterPack) 2230218893Sdim : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, 2231224145Sdim et->isInstantiationDependentType() || tc == DependentSizedArray, 2232218893Sdim (tc == VariableArray || et->isVariablyModifiedType()), 2233218893Sdim ContainsUnexpandedParameterPack), 2234218893Sdim ElementType(et) { 2235218893Sdim ArrayTypeBits.IndexTypeQuals = tq; 2236218893Sdim ArrayTypeBits.SizeModifier = sm; 2237218893Sdim } 2238193326Sed 2239193326Sed friend class ASTContext; // ASTContext creates these. 2240208600Srdivacky 2241193326Sedpublic: 2242193326Sed QualType getElementType() const { return ElementType; } 2243193326Sed ArraySizeModifier getSizeModifier() const { 2244218893Sdim return ArraySizeModifier(ArrayTypeBits.SizeModifier); 2245193326Sed } 2246198092Srdivacky Qualifiers getIndexTypeQualifiers() const { 2247218893Sdim return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); 2248198092Srdivacky } 2249218893Sdim unsigned getIndexTypeCVRQualifiers() const { 2250218893Sdim return ArrayTypeBits.IndexTypeQuals; 2251218893Sdim } 2252198092Srdivacky 2253193326Sed static bool classof(const Type *T) { 2254193326Sed return T->getTypeClass() == ConstantArray || 2255193326Sed T->getTypeClass() == VariableArray || 2256193326Sed T->getTypeClass() == IncompleteArray || 2257193326Sed T->getTypeClass() == DependentSizedArray; 2258193326Sed } 2259193326Sed}; 2260193326Sed 2261198092Srdivacky/// ConstantArrayType - This class represents the canonical version of 2262198092Srdivacky/// C arrays with a specified constant size. For example, the canonical 2263198092Srdivacky/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element 2264198092Srdivacky/// type is 'int' and the size is 404. 2265193326Sedclass ConstantArrayType : public ArrayType { 2266193326Sed llvm::APInt Size; // Allows us to unique the type. 2267198092Srdivacky 2268193326Sed ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, 2269193326Sed ArraySizeModifier sm, unsigned tq) 2270218893Sdim : ArrayType(ConstantArray, et, can, sm, tq, 2271218893Sdim et->containsUnexpandedParameterPack()), 2272198092Srdivacky Size(size) {} 2273198092Srdivackyprotected: 2274198092Srdivacky ConstantArrayType(TypeClass tc, QualType et, QualType can, 2275198092Srdivacky const llvm::APInt &size, ArraySizeModifier sm, unsigned tq) 2276234353Sdim : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()), 2277218893Sdim Size(size) {} 2278193326Sed friend class ASTContext; // ASTContext creates these. 2279193326Sedpublic: 2280193326Sed const llvm::APInt &getSize() const { return Size; } 2281198092Srdivacky bool isSugared() const { return false; } 2282198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2283198092Srdivacky 2284234353Sdim 2285212904Sdim /// \brief Determine the number of bits required to address a member of 2286212904Sdim // an array with the given element type and number of elements. 2287212904Sdim static unsigned getNumAddressingBits(ASTContext &Context, 2288212904Sdim QualType ElementType, 2289212904Sdim const llvm::APInt &NumElements); 2290234353Sdim 2291212904Sdim /// \brief Determine the maximum number of active bits that an array's size 2292212904Sdim /// can require, which limits the maximum size of the array. 2293212904Sdim static unsigned getMaxSizeBits(ASTContext &Context); 2294234353Sdim 2295193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2296198092Srdivacky Profile(ID, getElementType(), getSize(), 2297198092Srdivacky getSizeModifier(), getIndexTypeCVRQualifiers()); 2298193326Sed } 2299193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, 2300193326Sed const llvm::APInt &ArraySize, ArraySizeModifier SizeMod, 2301193326Sed unsigned TypeQuals) { 2302193326Sed ID.AddPointer(ET.getAsOpaquePtr()); 2303193326Sed ID.AddInteger(ArraySize.getZExtValue()); 2304193326Sed ID.AddInteger(SizeMod); 2305193326Sed ID.AddInteger(TypeQuals); 2306193326Sed } 2307198092Srdivacky static bool classof(const Type *T) { 2308198398Srdivacky return T->getTypeClass() == ConstantArray; 2309193326Sed } 2310193326Sed}; 2311193326Sed 2312193326Sed/// IncompleteArrayType - This class represents C arrays with an unspecified 2313193326Sed/// size. For example 'int A[]' has an IncompleteArrayType where the element 2314193326Sed/// type is 'int' and the size is unspecified. 2315193326Sedclass IncompleteArrayType : public ArrayType { 2316198092Srdivacky 2317193326Sed IncompleteArrayType(QualType et, QualType can, 2318198092Srdivacky ArraySizeModifier sm, unsigned tq) 2319234353Sdim : ArrayType(IncompleteArray, et, can, sm, tq, 2320218893Sdim et->containsUnexpandedParameterPack()) {} 2321193326Sed friend class ASTContext; // ASTContext creates these. 2322193326Sedpublic: 2323198092Srdivacky bool isSugared() const { return false; } 2324198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2325193326Sed 2326198092Srdivacky static bool classof(const Type *T) { 2327198092Srdivacky return T->getTypeClass() == IncompleteArray; 2328193326Sed } 2329198092Srdivacky 2330193326Sed friend class StmtIteratorBase; 2331198092Srdivacky 2332193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2333198092Srdivacky Profile(ID, getElementType(), getSizeModifier(), 2334198092Srdivacky getIndexTypeCVRQualifiers()); 2335193326Sed } 2336198092Srdivacky 2337193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, 2338193326Sed ArraySizeModifier SizeMod, unsigned TypeQuals) { 2339193326Sed ID.AddPointer(ET.getAsOpaquePtr()); 2340193326Sed ID.AddInteger(SizeMod); 2341193326Sed ID.AddInteger(TypeQuals); 2342193326Sed } 2343193326Sed}; 2344193326Sed 2345193326Sed/// VariableArrayType - This class represents C arrays with a specified size 2346193326Sed/// which is not an integer-constant-expression. For example, 'int s[x+foo()]'. 2347193326Sed/// Since the size expression is an arbitrary expression, we store it as such. 2348193326Sed/// 2349193326Sed/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and 2350193326Sed/// should not be: two lexically equivalent variable array types could mean 2351193326Sed/// different things, for example, these variables do not have the same type 2352193326Sed/// dynamically: 2353193326Sed/// 2354193326Sed/// void foo(int x) { 2355193326Sed/// int Y[x]; 2356193326Sed/// ++x; 2357193326Sed/// int Z[x]; 2358193326Sed/// } 2359193326Sed/// 2360193326Sedclass VariableArrayType : public ArrayType { 2361198092Srdivacky /// SizeExpr - An assignment expression. VLA's are only permitted within 2362198092Srdivacky /// a function block. 2363193326Sed Stmt *SizeExpr; 2364198092Srdivacky /// Brackets - The left and right array brackets. 2365198092Srdivacky SourceRange Brackets; 2366198092Srdivacky 2367193326Sed VariableArrayType(QualType et, QualType can, Expr *e, 2368198092Srdivacky ArraySizeModifier sm, unsigned tq, 2369198092Srdivacky SourceRange brackets) 2370234353Sdim : ArrayType(VariableArray, et, can, sm, tq, 2371218893Sdim et->containsUnexpandedParameterPack()), 2372198092Srdivacky SizeExpr((Stmt*) e), Brackets(brackets) {} 2373193326Sed friend class ASTContext; // ASTContext creates these. 2374193326Sed 2375193326Sedpublic: 2376198092Srdivacky Expr *getSizeExpr() const { 2377193326Sed // We use C-style casts instead of cast<> here because we do not wish 2378193326Sed // to have a dependency of Type.h on Stmt.h/Expr.h. 2379193326Sed return (Expr*) SizeExpr; 2380193326Sed } 2381198092Srdivacky SourceRange getBracketsRange() const { return Brackets; } 2382198092Srdivacky SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } 2383198092Srdivacky SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } 2384198092Srdivacky 2385198092Srdivacky bool isSugared() const { return false; } 2386198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2387198092Srdivacky 2388198092Srdivacky static bool classof(const Type *T) { 2389198092Srdivacky return T->getTypeClass() == VariableArray; 2390193326Sed } 2391198092Srdivacky 2392193326Sed friend class StmtIteratorBase; 2393198092Srdivacky 2394193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2395226633Sdim llvm_unreachable("Cannot unique VariableArrayTypes."); 2396193326Sed } 2397193326Sed}; 2398193326Sed 2399193326Sed/// DependentSizedArrayType - This type represents an array type in 2400193326Sed/// C++ whose size is a value-dependent expression. For example: 2401199990Srdivacky/// 2402199990Srdivacky/// \code 2403198092Srdivacky/// template<typename T, int Size> 2404193326Sed/// class array { 2405193326Sed/// T data[Size]; 2406193326Sed/// }; 2407199990Srdivacky/// \endcode 2408199990Srdivacky/// 2409193326Sed/// For these types, we won't actually know what the array bound is 2410193326Sed/// until template instantiation occurs, at which point this will 2411193326Sed/// become either a ConstantArrayType or a VariableArrayType. 2412193326Sedclass DependentSizedArrayType : public ArrayType { 2413218893Sdim const ASTContext &Context; 2414198092Srdivacky 2415199990Srdivacky /// \brief An assignment expression that will instantiate to the 2416193326Sed /// size of the array. 2417199990Srdivacky /// 2418199990Srdivacky /// The expression itself might be NULL, in which case the array 2419199990Srdivacky /// type will have its size deduced from an initializer. 2420193326Sed Stmt *SizeExpr; 2421199990Srdivacky 2422198092Srdivacky /// Brackets - The left and right array brackets. 2423198092Srdivacky SourceRange Brackets; 2424198092Srdivacky 2425218893Sdim DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, 2426198092Srdivacky Expr *e, ArraySizeModifier sm, unsigned tq, 2427218893Sdim SourceRange brackets); 2428218893Sdim 2429193326Sed friend class ASTContext; // ASTContext creates these. 2430193326Sed 2431193326Sedpublic: 2432198092Srdivacky Expr *getSizeExpr() const { 2433193326Sed // We use C-style casts instead of cast<> here because we do not wish 2434193326Sed // to have a dependency of Type.h on Stmt.h/Expr.h. 2435193326Sed return (Expr*) SizeExpr; 2436193326Sed } 2437198092Srdivacky SourceRange getBracketsRange() const { return Brackets; } 2438198092Srdivacky SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } 2439198092Srdivacky SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } 2440198092Srdivacky 2441198092Srdivacky bool isSugared() const { return false; } 2442198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2443198092Srdivacky 2444198092Srdivacky static bool classof(const Type *T) { 2445198092Srdivacky return T->getTypeClass() == DependentSizedArray; 2446193326Sed } 2447198092Srdivacky 2448193326Sed friend class StmtIteratorBase; 2449198092Srdivacky 2450198092Srdivacky 2451193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2452198092Srdivacky Profile(ID, Context, getElementType(), 2453198092Srdivacky getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); 2454193326Sed } 2455198092Srdivacky 2456218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 2457198092Srdivacky QualType ET, ArraySizeModifier SizeMod, 2458198092Srdivacky unsigned TypeQuals, Expr *E); 2459193326Sed}; 2460193326Sed 2461194613Sed/// DependentSizedExtVectorType - This type represent an extended vector type 2462194613Sed/// where either the type or size is dependent. For example: 2463194613Sed/// @code 2464194613Sed/// template<typename T, int Size> 2465194613Sed/// class vector { 2466194613Sed/// typedef T __attribute__((ext_vector_type(Size))) type; 2467194613Sed/// } 2468194613Sed/// @endcode 2469198092Srdivackyclass DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { 2470218893Sdim const ASTContext &Context; 2471194613Sed Expr *SizeExpr; 2472194613Sed /// ElementType - The element type of the array. 2473194613Sed QualType ElementType; 2474194613Sed SourceLocation loc; 2475198092Srdivacky 2476218893Sdim DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, 2477218893Sdim QualType can, Expr *SizeExpr, SourceLocation loc); 2478218893Sdim 2479194613Sed friend class ASTContext; 2480194613Sed 2481194613Sedpublic: 2482198092Srdivacky Expr *getSizeExpr() const { return SizeExpr; } 2483194613Sed QualType getElementType() const { return ElementType; } 2484194613Sed SourceLocation getAttributeLoc() const { return loc; } 2485194613Sed 2486198092Srdivacky bool isSugared() const { return false; } 2487198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2488198092Srdivacky 2489198092Srdivacky static bool classof(const Type *T) { 2490198092Srdivacky return T->getTypeClass() == DependentSizedExtVector; 2491194613Sed } 2492198092Srdivacky 2493198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 2494198092Srdivacky Profile(ID, Context, getElementType(), getSizeExpr()); 2495198092Srdivacky } 2496198092Srdivacky 2497218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 2498198092Srdivacky QualType ElementType, Expr *SizeExpr); 2499194613Sed}; 2500194613Sed 2501198092Srdivacky 2502193326Sed/// VectorType - GCC generic vector type. This type is created using 2503198092Srdivacky/// __attribute__((vector_size(n)), where "n" specifies the vector size in 2504203955Srdivacky/// bytes; or from an Altivec __vector or vector declaration. 2505203955Srdivacky/// Since the constructor takes the number of vector elements, the 2506193326Sed/// client is responsible for converting the size into the number of elements. 2507193326Sedclass VectorType : public Type, public llvm::FoldingSetNode { 2508210299Sedpublic: 2509218893Sdim enum VectorKind { 2510218893Sdim GenericVector, // not a target-specific vector type 2511218893Sdim AltiVecVector, // is AltiVec vector 2512218893Sdim AltiVecPixel, // is AltiVec 'vector Pixel' 2513218893Sdim AltiVecBool, // is AltiVec 'vector bool ...' 2514218893Sdim NeonVector, // is ARM Neon vector 2515218893Sdim NeonPolyVector // is ARM Neon polynomial vector 2516210299Sed }; 2517193326Sedprotected: 2518193326Sed /// ElementType - The element type of the vector. 2519193326Sed QualType ElementType; 2520198092Srdivacky 2521203955Srdivacky VectorType(QualType vecType, unsigned nElements, QualType canonType, 2522218893Sdim VectorKind vecKind); 2523234353Sdim 2524198092Srdivacky VectorType(TypeClass tc, QualType vecType, unsigned nElements, 2525218893Sdim QualType canonType, VectorKind vecKind); 2526218893Sdim 2527193326Sed friend class ASTContext; // ASTContext creates these. 2528234353Sdim 2529193326Sedpublic: 2530198092Srdivacky 2531193326Sed QualType getElementType() const { return ElementType; } 2532218893Sdim unsigned getNumElements() const { return VectorTypeBits.NumElements; } 2533263508Sdim static bool isVectorSizeTooLarge(unsigned NumElements) { 2534263508Sdim return NumElements > VectorTypeBitfields::MaxNumElements; 2535263508Sdim } 2536193326Sed 2537198092Srdivacky bool isSugared() const { return false; } 2538198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2539198092Srdivacky 2540218893Sdim VectorKind getVectorKind() const { 2541218893Sdim return VectorKind(VectorTypeBits.VecKind); 2542218893Sdim } 2543210299Sed 2544193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2545218893Sdim Profile(ID, getElementType(), getNumElements(), 2546218893Sdim getTypeClass(), getVectorKind()); 2547193326Sed } 2548198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, 2549203955Srdivacky unsigned NumElements, TypeClass TypeClass, 2550218893Sdim VectorKind VecKind) { 2551193326Sed ID.AddPointer(ElementType.getAsOpaquePtr()); 2552193326Sed ID.AddInteger(NumElements); 2553193326Sed ID.AddInteger(TypeClass); 2554218893Sdim ID.AddInteger(VecKind); 2555193326Sed } 2556203955Srdivacky 2557198092Srdivacky static bool classof(const Type *T) { 2558198092Srdivacky return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; 2559193326Sed } 2560193326Sed}; 2561193326Sed 2562193326Sed/// ExtVectorType - Extended vector type. This type is created using 2563193326Sed/// __attribute__((ext_vector_type(n)), where "n" is the number of elements. 2564193326Sed/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This 2565193326Sed/// class enables syntactic extensions, like Vector Components for accessing 2566193326Sed/// points, colors, and textures (modeled after OpenGL Shading Language). 2567193326Sedclass ExtVectorType : public VectorType { 2568193326Sed ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) : 2569218893Sdim VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} 2570193326Sed friend class ASTContext; // ASTContext creates these. 2571193326Sedpublic: 2572193326Sed static int getPointAccessorIdx(char c) { 2573193326Sed switch (c) { 2574193326Sed default: return -1; 2575193326Sed case 'x': return 0; 2576193326Sed case 'y': return 1; 2577193326Sed case 'z': return 2; 2578193326Sed case 'w': return 3; 2579193326Sed } 2580193326Sed } 2581193326Sed static int getNumericAccessorIdx(char c) { 2582193326Sed switch (c) { 2583193326Sed default: return -1; 2584193326Sed case '0': return 0; 2585193326Sed case '1': return 1; 2586193326Sed case '2': return 2; 2587193326Sed case '3': return 3; 2588193326Sed case '4': return 4; 2589193326Sed case '5': return 5; 2590193326Sed case '6': return 6; 2591193326Sed case '7': return 7; 2592193326Sed case '8': return 8; 2593193326Sed case '9': return 9; 2594195099Sed case 'A': 2595193326Sed case 'a': return 10; 2596195099Sed case 'B': 2597193326Sed case 'b': return 11; 2598195099Sed case 'C': 2599193326Sed case 'c': return 12; 2600195099Sed case 'D': 2601193326Sed case 'd': return 13; 2602195099Sed case 'E': 2603193326Sed case 'e': return 14; 2604195099Sed case 'F': 2605193326Sed case 'f': return 15; 2606193326Sed } 2607193326Sed } 2608198092Srdivacky 2609193326Sed static int getAccessorIdx(char c) { 2610193326Sed if (int idx = getPointAccessorIdx(c)+1) return idx-1; 2611193326Sed return getNumericAccessorIdx(c); 2612193326Sed } 2613198092Srdivacky 2614193326Sed bool isAccessorWithinNumElements(char c) const { 2615193326Sed if (int idx = getAccessorIdx(c)+1) 2616218893Sdim return unsigned(idx-1) < getNumElements(); 2617193326Sed return false; 2618193326Sed } 2619198092Srdivacky bool isSugared() const { return false; } 2620198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2621198092Srdivacky 2622198092Srdivacky static bool classof(const Type *T) { 2623198092Srdivacky return T->getTypeClass() == ExtVector; 2624193326Sed } 2625193326Sed}; 2626193326Sed 2627193326Sed/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base 2628193326Sed/// class of FunctionNoProtoType and FunctionProtoType. 2629193326Sed/// 2630193326Sedclass FunctionType : public Type { 2631193326Sed // The type returned by the function. 2632193326Sed QualType ResultType; 2633206084Srdivacky 2634206084Srdivacky public: 2635218893Sdim /// ExtInfo - A class which abstracts out some details necessary for 2636218893Sdim /// making a call. 2637218893Sdim /// 2638218893Sdim /// It is not actually used directly for storing this information in 2639218893Sdim /// a FunctionType, although FunctionType does currently use the 2640218893Sdim /// same bit-pattern. 2641218893Sdim /// 2642218893Sdim // If you add a field (say Foo), other than the obvious places (both, 2643218893Sdim // constructors, compile failures), what you need to update is 2644218893Sdim // * Operator== 2645206084Srdivacky // * getFoo 2646206084Srdivacky // * withFoo 2647206084Srdivacky // * functionType. Add Foo, getFoo. 2648206084Srdivacky // * ASTContext::getFooType 2649206084Srdivacky // * ASTContext::mergeFunctionTypes 2650206084Srdivacky // * FunctionNoProtoType::Profile 2651206084Srdivacky // * FunctionProtoType::Profile 2652206084Srdivacky // * TypePrinter::PrintFunctionProto 2653212904Sdim // * AST read and write 2654206084Srdivacky // * Codegen 2655218893Sdim class ExtInfo { 2656243830Sdim // Feel free to rearrange or add bits, but if you go over 9, 2657218893Sdim // you'll need to adjust both the Bits field below and 2658218893Sdim // Type::FunctionTypeBitfields. 2659206084Srdivacky 2660224145Sdim // | CC |noreturn|produces|regparm| 2661243830Sdim // |0 .. 3| 4 | 5 | 6 .. 8| 2662224145Sdim // 2663224145Sdim // regparm is either 0 (no regparm attribute) or the regparm value+1. 2664243830Sdim enum { CallConvMask = 0xF }; 2665243830Sdim enum { NoReturnMask = 0x10 }; 2666243830Sdim enum { ProducesResultMask = 0x20 }; 2667224145Sdim enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask), 2668243830Sdim RegParmOffset = 6 }; // Assumed to be the last field 2669218893Sdim 2670224145Sdim uint16_t Bits; 2671218893Sdim 2672224145Sdim ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} 2673218893Sdim 2674218893Sdim friend class FunctionType; 2675218893Sdim 2676206084Srdivacky public: 2677206084Srdivacky // Constructor with no defaults. Use this when you know that you 2678212904Sdim // have all the elements (when reading an AST file for example). 2679224145Sdim ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, 2680224145Sdim bool producesResult) { 2681224145Sdim assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); 2682218893Sdim Bits = ((unsigned) cc) | 2683218893Sdim (noReturn ? NoReturnMask : 0) | 2684224145Sdim (producesResult ? ProducesResultMask : 0) | 2685224145Sdim (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0); 2686218893Sdim } 2687206084Srdivacky 2688206084Srdivacky // Constructor with all defaults. Use when for example creating a 2689206084Srdivacky // function know to use defaults. 2690263508Sdim ExtInfo() : Bits(CC_C) { } 2691206084Srdivacky 2692263508Sdim // Constructor with just the calling convention, which is an important part 2693263508Sdim // of the canonical type. 2694263508Sdim ExtInfo(CallingConv CC) : Bits(CC) { } 2695263508Sdim 2696218893Sdim bool getNoReturn() const { return Bits & NoReturnMask; } 2697224145Sdim bool getProducesResult() const { return Bits & ProducesResultMask; } 2698224145Sdim bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } 2699234353Sdim unsigned getRegParm() const { 2700224145Sdim unsigned RegParm = Bits >> RegParmOffset; 2701224145Sdim if (RegParm > 0) 2702224145Sdim --RegParm; 2703224145Sdim return RegParm; 2704224145Sdim } 2705218893Sdim CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } 2706206084Srdivacky 2707218893Sdim bool operator==(ExtInfo Other) const { 2708218893Sdim return Bits == Other.Bits; 2709206084Srdivacky } 2710218893Sdim bool operator!=(ExtInfo Other) const { 2711218893Sdim return Bits != Other.Bits; 2712206084Srdivacky } 2713206084Srdivacky 2714206084Srdivacky // Note that we don't have setters. That is by design, use 2715206084Srdivacky // the following with methods instead of mutating these objects. 2716206084Srdivacky 2717206084Srdivacky ExtInfo withNoReturn(bool noReturn) const { 2718218893Sdim if (noReturn) 2719218893Sdim return ExtInfo(Bits | NoReturnMask); 2720218893Sdim else 2721218893Sdim return ExtInfo(Bits & ~NoReturnMask); 2722206084Srdivacky } 2723206084Srdivacky 2724224145Sdim ExtInfo withProducesResult(bool producesResult) const { 2725224145Sdim if (producesResult) 2726224145Sdim return ExtInfo(Bits | ProducesResultMask); 2727224145Sdim else 2728224145Sdim return ExtInfo(Bits & ~ProducesResultMask); 2729224145Sdim } 2730224145Sdim 2731206084Srdivacky ExtInfo withRegParm(unsigned RegParm) const { 2732224145Sdim assert(RegParm < 7 && "Invalid regparm value"); 2733224145Sdim return ExtInfo((Bits & ~RegParmMask) | 2734224145Sdim ((RegParm + 1) << RegParmOffset)); 2735206084Srdivacky } 2736206084Srdivacky 2737206084Srdivacky ExtInfo withCallingConv(CallingConv cc) const { 2738218893Sdim return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); 2739206084Srdivacky } 2740206084Srdivacky 2741218893Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 2742218893Sdim ID.AddInteger(Bits); 2743218893Sdim } 2744206084Srdivacky }; 2745206084Srdivacky 2746193326Sedprotected: 2747234353Sdim FunctionType(TypeClass tc, QualType res, 2748249423Sdim unsigned typeQuals, QualType Canonical, bool Dependent, 2749224145Sdim bool InstantiationDependent, 2750234353Sdim bool VariablyModified, bool ContainsUnexpandedParameterPack, 2751218893Sdim ExtInfo Info) 2752234353Sdim : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, 2753234353Sdim ContainsUnexpandedParameterPack), 2754218893Sdim ResultType(res) { 2755218893Sdim FunctionTypeBits.ExtInfo = Info.Bits; 2756218893Sdim FunctionTypeBits.TypeQuals = typeQuals; 2757218893Sdim } 2758218893Sdim unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; } 2759234353Sdim 2760193326Sedpublic: 2761198092Srdivacky 2762193326Sed QualType getResultType() const { return ResultType; } 2763221345Sdim 2764221345Sdim bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } 2765218893Sdim unsigned getRegParmType() const { return getExtInfo().getRegParm(); } 2766249423Sdim /// \brief Determine whether this function type includes the GNU noreturn 2767249423Sdim /// attribute. The C++11 [[noreturn]] attribute does not affect the function 2768249423Sdim /// type. 2769218893Sdim bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } 2770218893Sdim CallingConv getCallConv() const { return getExtInfo().getCC(); } 2771218893Sdim ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } 2772239462Sdim bool isConst() const { return getTypeQuals() & Qualifiers::Const; } 2773239462Sdim bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; } 2774239462Sdim bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; } 2775193326Sed 2776210299Sed /// \brief Determine the type of an expression that calls a function of 2777210299Sed /// this type. 2778234353Sdim QualType getCallResultType(ASTContext &Context) const { 2779210299Sed return getResultType().getNonLValueExprType(Context); 2780210299Sed } 2781210299Sed 2782226633Sdim static StringRef getNameForCallConv(CallingConv CC); 2783203955Srdivacky 2784193326Sed static bool classof(const Type *T) { 2785193326Sed return T->getTypeClass() == FunctionNoProto || 2786193326Sed T->getTypeClass() == FunctionProto; 2787193326Sed } 2788193326Sed}; 2789193326Sed 2790193326Sed/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has 2791193326Sed/// no information available about its arguments. 2792193326Sedclass FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { 2793218893Sdim FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) 2794249423Sdim : FunctionType(FunctionNoProto, Result, 0, Canonical, 2795224145Sdim /*Dependent=*/false, /*InstantiationDependent=*/false, 2796234353Sdim Result->isVariablyModifiedType(), 2797218893Sdim /*ContainsUnexpandedParameterPack=*/false, Info) {} 2798218893Sdim 2799193326Sed friend class ASTContext; // ASTContext creates these. 2800234353Sdim 2801193326Sedpublic: 2802193326Sed // No additional state past what FunctionType provides. 2803193326Sed 2804198092Srdivacky bool isSugared() const { return false; } 2805198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2806198092Srdivacky 2807193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2808206084Srdivacky Profile(ID, getResultType(), getExtInfo()); 2809193326Sed } 2810198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, 2811218893Sdim ExtInfo Info) { 2812218893Sdim Info.Profile(ID); 2813193326Sed ID.AddPointer(ResultType.getAsOpaquePtr()); 2814193326Sed } 2815198092Srdivacky 2816193326Sed static bool classof(const Type *T) { 2817193326Sed return T->getTypeClass() == FunctionNoProto; 2818193326Sed } 2819193326Sed}; 2820193326Sed 2821193326Sed/// FunctionProtoType - Represents a prototype with argument type info, e.g. 2822193326Sed/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no 2823193326Sed/// arguments, not as having a single void argument. Such a type can have an 2824193326Sed/// exception specification, but this specification is not part of the canonical 2825193326Sed/// type. 2826193326Sedclass FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { 2827218893Sdimpublic: 2828218893Sdim /// ExtProtoInfo - Extra information about a function prototype. 2829218893Sdim struct ExtProtoInfo { 2830218893Sdim ExtProtoInfo() : 2831234353Sdim Variadic(false), HasTrailingReturn(false), TypeQuals(0), 2832234353Sdim ExceptionSpecType(EST_None), RefQualifier(RQ_None), 2833234982Sdim NumExceptions(0), Exceptions(0), NoexceptExpr(0), 2834234982Sdim ExceptionSpecDecl(0), ExceptionSpecTemplate(0), 2835234982Sdim ConsumedArguments(0) {} 2836218893Sdim 2837263508Sdim ExtProtoInfo(CallingConv CC) 2838263508Sdim : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), 2839263508Sdim ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0), 2840263508Sdim Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0), 2841263508Sdim ExceptionSpecTemplate(0), ConsumedArguments(0) {} 2842263508Sdim 2843218893Sdim FunctionType::ExtInfo ExtInfo; 2844234353Sdim bool Variadic : 1; 2845234353Sdim bool HasTrailingReturn : 1; 2846234353Sdim unsigned char TypeQuals; 2847221345Sdim ExceptionSpecificationType ExceptionSpecType; 2848218893Sdim RefQualifierKind RefQualifier; 2849218893Sdim unsigned NumExceptions; 2850218893Sdim const QualType *Exceptions; 2851221345Sdim Expr *NoexceptExpr; 2852234982Sdim FunctionDecl *ExceptionSpecDecl; 2853234982Sdim FunctionDecl *ExceptionSpecTemplate; 2854224145Sdim const bool *ConsumedArguments; 2855218893Sdim }; 2856218893Sdim 2857218893Sdimprivate: 2858218893Sdim /// \brief Determine whether there are any argument types that 2859218893Sdim /// contain an unexpanded parameter pack. 2860234353Sdim static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, 2861218893Sdim unsigned numArgs) { 2862193326Sed for (unsigned Idx = 0; Idx < numArgs; ++Idx) 2863218893Sdim if (ArgArray[Idx]->containsUnexpandedParameterPack()) 2864218893Sdim return true; 2865193326Sed 2866193326Sed return false; 2867193326Sed } 2868193326Sed 2869249423Sdim FunctionProtoType(QualType result, ArrayRef<QualType> args, 2870218893Sdim QualType canonical, const ExtProtoInfo &epi); 2871193326Sed 2872193326Sed /// NumArgs - The number of arguments this function has, not counting '...'. 2873249423Sdim unsigned NumArgs : 15; 2874193326Sed 2875193326Sed /// NumExceptions - The number of types in the exception spec, if any. 2876221345Sdim unsigned NumExceptions : 9; 2877193326Sed 2878221345Sdim /// ExceptionSpecType - The type of exception specification this function has. 2879221345Sdim unsigned ExceptionSpecType : 3; 2880193326Sed 2881224145Sdim /// HasAnyConsumedArgs - Whether this function has any consumed arguments. 2882224145Sdim unsigned HasAnyConsumedArgs : 1; 2883224145Sdim 2884234353Sdim /// Variadic - Whether the function is variadic. 2885234353Sdim unsigned Variadic : 1; 2886234353Sdim 2887234353Sdim /// HasTrailingReturn - Whether this function has a trailing return type. 2888234353Sdim unsigned HasTrailingReturn : 1; 2889234353Sdim 2890249423Sdim /// \brief The ref-qualifier associated with a \c FunctionProtoType. 2891249423Sdim /// 2892249423Sdim /// This is a value of type \c RefQualifierKind. 2893249423Sdim unsigned RefQualifier : 2; 2894249423Sdim 2895234353Sdim // ArgInfo - There is an variable size array after the class in memory that 2896234353Sdim // holds the argument types. 2897234353Sdim 2898234353Sdim // Exceptions - There is another variable size array after ArgInfo that 2899234353Sdim // holds the exception types. 2900234353Sdim 2901234353Sdim // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing 2902234353Sdim // to the expression in the noexcept() specifier. 2903234353Sdim 2904234982Sdim // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may 2905234982Sdim // be a pair of FunctionDecl* pointing to the function which should be used to 2906234982Sdim // instantiate this function type's exception specification, and the function 2907234982Sdim // from which it should be instantiated. 2908234982Sdim 2909234353Sdim // ConsumedArgs - A variable size array, following Exceptions 2910234353Sdim // and of length NumArgs, holding flags indicating which arguments 2911234353Sdim // are consumed. This only appears if HasAnyConsumedArgs is true. 2912234353Sdim 2913193326Sed friend class ASTContext; // ASTContext creates these. 2914193326Sed 2915224145Sdim const bool *getConsumedArgsBuffer() const { 2916224145Sdim assert(hasAnyConsumedArgs()); 2917224145Sdim 2918224145Sdim // Find the end of the exceptions. 2919224145Sdim Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end()); 2920224145Sdim if (getExceptionSpecType() != EST_ComputedNoexcept) 2921224145Sdim eh_end += NumExceptions; 2922224145Sdim else 2923224145Sdim eh_end += 1; // NoexceptExpr 2924224145Sdim 2925224145Sdim return reinterpret_cast<const bool*>(eh_end); 2926224145Sdim } 2927224145Sdim 2928193326Sedpublic: 2929193326Sed unsigned getNumArgs() const { return NumArgs; } 2930193326Sed QualType getArgType(unsigned i) const { 2931193326Sed assert(i < NumArgs && "Invalid argument number!"); 2932193326Sed return arg_type_begin()[i]; 2933193326Sed } 2934249423Sdim ArrayRef<QualType> getArgTypes() const { 2935249423Sdim return ArrayRef<QualType>(arg_type_begin(), arg_type_end()); 2936249423Sdim } 2937193326Sed 2938218893Sdim ExtProtoInfo getExtProtoInfo() const { 2939218893Sdim ExtProtoInfo EPI; 2940218893Sdim EPI.ExtInfo = getExtInfo(); 2941218893Sdim EPI.Variadic = isVariadic(); 2942234353Sdim EPI.HasTrailingReturn = hasTrailingReturn(); 2943221345Sdim EPI.ExceptionSpecType = getExceptionSpecType(); 2944218893Sdim EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals()); 2945218893Sdim EPI.RefQualifier = getRefQualifier(); 2946221345Sdim if (EPI.ExceptionSpecType == EST_Dynamic) { 2947221345Sdim EPI.NumExceptions = NumExceptions; 2948221345Sdim EPI.Exceptions = exception_begin(); 2949221345Sdim } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 2950221345Sdim EPI.NoexceptExpr = getNoexceptExpr(); 2951234982Sdim } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { 2952234982Sdim EPI.ExceptionSpecDecl = getExceptionSpecDecl(); 2953234982Sdim EPI.ExceptionSpecTemplate = getExceptionSpecTemplate(); 2954239462Sdim } else if (EPI.ExceptionSpecType == EST_Unevaluated) { 2955239462Sdim EPI.ExceptionSpecDecl = getExceptionSpecDecl(); 2956221345Sdim } 2957224145Sdim if (hasAnyConsumedArgs()) 2958224145Sdim EPI.ConsumedArguments = getConsumedArgsBuffer(); 2959218893Sdim return EPI; 2960218893Sdim } 2961218893Sdim 2962221345Sdim /// \brief Get the kind of exception specification on this function. 2963221345Sdim ExceptionSpecificationType getExceptionSpecType() const { 2964221345Sdim return static_cast<ExceptionSpecificationType>(ExceptionSpecType); 2965221345Sdim } 2966221345Sdim /// \brief Return whether this function has any kind of exception spec. 2967221345Sdim bool hasExceptionSpec() const { 2968221345Sdim return getExceptionSpecType() != EST_None; 2969221345Sdim } 2970221345Sdim /// \brief Return whether this function has a dynamic (throw) exception spec. 2971221345Sdim bool hasDynamicExceptionSpec() const { 2972221345Sdim return isDynamicExceptionSpec(getExceptionSpecType()); 2973221345Sdim } 2974221345Sdim /// \brief Return whether this function has a noexcept exception spec. 2975221345Sdim bool hasNoexceptExceptionSpec() const { 2976221345Sdim return isNoexceptExceptionSpec(getExceptionSpecType()); 2977221345Sdim } 2978221345Sdim /// \brief Result type of getNoexceptSpec(). 2979221345Sdim enum NoexceptResult { 2980221345Sdim NR_NoNoexcept, ///< There is no noexcept specifier. 2981221345Sdim NR_BadNoexcept, ///< The noexcept specifier has a bad expression. 2982221345Sdim NR_Dependent, ///< The noexcept specifier is dependent. 2983221345Sdim NR_Throw, ///< The noexcept specifier evaluates to false. 2984221345Sdim NR_Nothrow ///< The noexcept specifier evaluates to true. 2985221345Sdim }; 2986221345Sdim /// \brief Get the meaning of the noexcept spec on this function, if any. 2987263508Sdim NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const; 2988193326Sed unsigned getNumExceptions() const { return NumExceptions; } 2989193326Sed QualType getExceptionType(unsigned i) const { 2990193326Sed assert(i < NumExceptions && "Invalid exception number!"); 2991193326Sed return exception_begin()[i]; 2992193326Sed } 2993221345Sdim Expr *getNoexceptExpr() const { 2994221345Sdim if (getExceptionSpecType() != EST_ComputedNoexcept) 2995221345Sdim return 0; 2996221345Sdim // NoexceptExpr sits where the arguments end. 2997221345Sdim return *reinterpret_cast<Expr *const *>(arg_type_end()); 2998193326Sed } 2999239462Sdim /// \brief If this function type has an exception specification which hasn't 3000239462Sdim /// been determined yet (either because it has not been evaluated or because 3001239462Sdim /// it has not been instantiated), this is the function whose exception 3002239462Sdim /// specification is represented by this type. 3003234982Sdim FunctionDecl *getExceptionSpecDecl() const { 3004239462Sdim if (getExceptionSpecType() != EST_Uninstantiated && 3005239462Sdim getExceptionSpecType() != EST_Unevaluated) 3006234982Sdim return 0; 3007234982Sdim return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0]; 3008234982Sdim } 3009234982Sdim /// \brief If this function type has an uninstantiated exception 3010234982Sdim /// specification, this is the function whose exception specification 3011234982Sdim /// should be instantiated to find the exception specification for 3012234982Sdim /// this type. 3013234982Sdim FunctionDecl *getExceptionSpecTemplate() const { 3014234982Sdim if (getExceptionSpecType() != EST_Uninstantiated) 3015234982Sdim return 0; 3016234982Sdim return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1]; 3017234982Sdim } 3018263508Sdim bool isNothrow(const ASTContext &Ctx) const { 3019221345Sdim ExceptionSpecificationType EST = getExceptionSpecType(); 3020239462Sdim assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); 3021221345Sdim if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) 3022221345Sdim return true; 3023221345Sdim if (EST != EST_ComputedNoexcept) 3024221345Sdim return false; 3025221345Sdim return getNoexceptSpec(Ctx) == NR_Nothrow; 3026221345Sdim } 3027193326Sed 3028234353Sdim bool isVariadic() const { return Variadic; } 3029221345Sdim 3030218893Sdim /// \brief Determines whether this function prototype contains a 3031218893Sdim /// parameter pack at the end. 3032218893Sdim /// 3033218893Sdim /// A function template whose last parameter is a parameter pack can be 3034218893Sdim /// called with an arbitrary number of arguments, much like a variadic 3035234353Sdim /// function. 3036218893Sdim bool isTemplateVariadic() const; 3037234353Sdim 3038234353Sdim bool hasTrailingReturn() const { return HasTrailingReturn; } 3039234353Sdim 3040193326Sed unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); } 3041198092Srdivacky 3042234353Sdim 3043218893Sdim /// \brief Retrieve the ref-qualifier associated with this function type. 3044218893Sdim RefQualifierKind getRefQualifier() const { 3045249423Sdim return static_cast<RefQualifierKind>(RefQualifier); 3046218893Sdim } 3047234353Sdim 3048193326Sed typedef const QualType *arg_type_iterator; 3049193326Sed arg_type_iterator arg_type_begin() const { 3050193326Sed return reinterpret_cast<const QualType *>(this+1); 3051193326Sed } 3052193326Sed arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; } 3053193326Sed 3054193326Sed typedef const QualType *exception_iterator; 3055193326Sed exception_iterator exception_begin() const { 3056193326Sed // exceptions begin where arguments end 3057193326Sed return arg_type_end(); 3058193326Sed } 3059193326Sed exception_iterator exception_end() const { 3060221345Sdim if (getExceptionSpecType() != EST_Dynamic) 3061221345Sdim return exception_begin(); 3062193326Sed return exception_begin() + NumExceptions; 3063193326Sed } 3064193326Sed 3065224145Sdim bool hasAnyConsumedArgs() const { 3066224145Sdim return HasAnyConsumedArgs; 3067224145Sdim } 3068224145Sdim bool isArgConsumed(unsigned I) const { 3069224145Sdim assert(I < getNumArgs() && "argument index out of range!"); 3070224145Sdim if (hasAnyConsumedArgs()) 3071224145Sdim return getConsumedArgsBuffer()[I]; 3072224145Sdim return false; 3073224145Sdim } 3074224145Sdim 3075198092Srdivacky bool isSugared() const { return false; } 3076198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3077198092Srdivacky 3078239462Sdim void printExceptionSpecification(raw_ostream &OS, 3079243830Sdim const PrintingPolicy &Policy) const; 3080234353Sdim 3081193326Sed static bool classof(const Type *T) { 3082193326Sed return T->getTypeClass() == FunctionProto; 3083193326Sed } 3084193326Sed 3085221345Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); 3086193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, 3087193326Sed arg_type_iterator ArgTys, unsigned NumArgs, 3088221345Sdim const ExtProtoInfo &EPI, const ASTContext &Context); 3089193326Sed}; 3090193326Sed 3091193326Sed 3092200583Srdivacky/// \brief Represents the dependent type named by a dependently-scoped 3093200583Srdivacky/// typename using declaration, e.g. 3094200583Srdivacky/// using typename Base<T>::foo; 3095200583Srdivacky/// Template instantiation turns these into the underlying type. 3096200583Srdivackyclass UnresolvedUsingType : public Type { 3097200583Srdivacky UnresolvedUsingTypenameDecl *Decl; 3098200583Srdivacky 3099203955Srdivacky UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) 3100234353Sdim : Type(UnresolvedUsing, QualType(), true, true, false, 3101218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3102203955Srdivacky Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {} 3103200583Srdivacky friend class ASTContext; // ASTContext creates these. 3104200583Srdivackypublic: 3105200583Srdivacky 3106200583Srdivacky UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } 3107200583Srdivacky 3108200583Srdivacky bool isSugared() const { return false; } 3109200583Srdivacky QualType desugar() const { return QualType(this, 0); } 3110200583Srdivacky 3111200583Srdivacky static bool classof(const Type *T) { 3112200583Srdivacky return T->getTypeClass() == UnresolvedUsing; 3113200583Srdivacky } 3114200583Srdivacky 3115200583Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3116200583Srdivacky return Profile(ID, Decl); 3117200583Srdivacky } 3118200583Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 3119200583Srdivacky UnresolvedUsingTypenameDecl *D) { 3120200583Srdivacky ID.AddPointer(D); 3121200583Srdivacky } 3122200583Srdivacky}; 3123200583Srdivacky 3124200583Srdivacky 3125193326Sedclass TypedefType : public Type { 3126221345Sdim TypedefNameDecl *Decl; 3127193326Sedprotected: 3128221345Sdim TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) 3129234353Sdim : Type(tc, can, can->isDependentType(), 3130224145Sdim can->isInstantiationDependentType(), 3131234353Sdim can->isVariablyModifiedType(), 3132218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3133221345Sdim Decl(const_cast<TypedefNameDecl*>(D)) { 3134193326Sed assert(!isa<TypedefType>(can) && "Invalid canonical type"); 3135193326Sed } 3136193326Sed friend class ASTContext; // ASTContext creates these. 3137193326Sedpublic: 3138198092Srdivacky 3139221345Sdim TypedefNameDecl *getDecl() const { return Decl; } 3140198092Srdivacky 3141198092Srdivacky bool isSugared() const { return true; } 3142198092Srdivacky QualType desugar() const; 3143198092Srdivacky 3144193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } 3145193326Sed}; 3146193326Sed 3147193326Sed/// TypeOfExprType (GCC extension). 3148193326Sedclass TypeOfExprType : public Type { 3149193326Sed Expr *TOExpr; 3150198092Srdivacky 3151198092Srdivackyprotected: 3152198092Srdivacky TypeOfExprType(Expr *E, QualType can = QualType()); 3153193326Sed friend class ASTContext; // ASTContext creates these. 3154193326Sedpublic: 3155193326Sed Expr *getUnderlyingExpr() const { return TOExpr; } 3156193326Sed 3157198092Srdivacky /// \brief Remove a single level of sugar. 3158198092Srdivacky QualType desugar() const; 3159198092Srdivacky 3160198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3161224145Sdim bool isSugared() const; 3162198092Srdivacky 3163193326Sed static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } 3164193326Sed}; 3165193326Sed 3166203955Srdivacky/// \brief Internal representation of canonical, dependent 3167198092Srdivacky/// typeof(expr) types. 3168203955Srdivacky/// 3169203955Srdivacky/// This class is used internally by the ASTContext to manage 3170203955Srdivacky/// canonical, dependent types, only. Clients will only see instances 3171203955Srdivacky/// of this class via TypeOfExprType nodes. 3172198092Srdivackyclass DependentTypeOfExprType 3173198092Srdivacky : public TypeOfExprType, public llvm::FoldingSetNode { 3174218893Sdim const ASTContext &Context; 3175198092Srdivacky 3176198092Srdivackypublic: 3177218893Sdim DependentTypeOfExprType(const ASTContext &Context, Expr *E) 3178198092Srdivacky : TypeOfExprType(E), Context(Context) { } 3179198092Srdivacky 3180198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3181198092Srdivacky Profile(ID, Context, getUnderlyingExpr()); 3182198092Srdivacky } 3183198092Srdivacky 3184218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 3185198092Srdivacky Expr *E); 3186198092Srdivacky}; 3187198092Srdivacky 3188193326Sed/// TypeOfType (GCC extension). 3189193326Sedclass TypeOfType : public Type { 3190193326Sed QualType TOType; 3191198092Srdivacky TypeOfType(QualType T, QualType can) 3192234353Sdim : Type(TypeOf, can, T->isDependentType(), 3193224145Sdim T->isInstantiationDependentType(), 3194234353Sdim T->isVariablyModifiedType(), 3195234353Sdim T->containsUnexpandedParameterPack()), 3196218893Sdim TOType(T) { 3197193326Sed assert(!isa<TypedefType>(can) && "Invalid canonical type"); 3198193326Sed } 3199193326Sed friend class ASTContext; // ASTContext creates these. 3200193326Sedpublic: 3201193326Sed QualType getUnderlyingType() const { return TOType; } 3202193326Sed 3203198092Srdivacky /// \brief Remove a single level of sugar. 3204198092Srdivacky QualType desugar() const { return getUnderlyingType(); } 3205198092Srdivacky 3206198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3207198092Srdivacky bool isSugared() const { return true; } 3208198092Srdivacky 3209193326Sed static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } 3210193326Sed}; 3211193326Sed 3212195099Sed/// DecltypeType (C++0x) 3213195099Sedclass DecltypeType : public Type { 3214195099Sed Expr *E; 3215198092Srdivacky QualType UnderlyingType; 3216198092Srdivacky 3217198092Srdivackyprotected: 3218198092Srdivacky DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); 3219195099Sed friend class ASTContext; // ASTContext creates these. 3220195099Sedpublic: 3221195099Sed Expr *getUnderlyingExpr() const { return E; } 3222198092Srdivacky QualType getUnderlyingType() const { return UnderlyingType; } 3223198092Srdivacky 3224198092Srdivacky /// \brief Remove a single level of sugar. 3225224145Sdim QualType desugar() const; 3226198092Srdivacky 3227198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3228224145Sdim bool isSugared() const; 3229198092Srdivacky 3230195099Sed static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } 3231195099Sed}; 3232198092Srdivacky 3233203955Srdivacky/// \brief Internal representation of canonical, dependent 3234203955Srdivacky/// decltype(expr) types. 3235203955Srdivacky/// 3236203955Srdivacky/// This class is used internally by the ASTContext to manage 3237203955Srdivacky/// canonical, dependent types, only. Clients will only see instances 3238203955Srdivacky/// of this class via DecltypeType nodes. 3239198092Srdivackyclass DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { 3240218893Sdim const ASTContext &Context; 3241198092Srdivacky 3242198092Srdivackypublic: 3243218893Sdim DependentDecltypeType(const ASTContext &Context, Expr *E); 3244198092Srdivacky 3245198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3246198092Srdivacky Profile(ID, Context, getUnderlyingExpr()); 3247198092Srdivacky } 3248198092Srdivacky 3249218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 3250198092Srdivacky Expr *E); 3251198092Srdivacky}; 3252198092Srdivacky 3253223017Sdim/// \brief A unary type transform, which is a type constructed from another 3254223017Sdimclass UnaryTransformType : public Type { 3255223017Sdimpublic: 3256223017Sdim enum UTTKind { 3257223017Sdim EnumUnderlyingType 3258223017Sdim }; 3259223017Sdim 3260223017Sdimprivate: 3261223017Sdim /// The untransformed type. 3262223017Sdim QualType BaseType; 3263223017Sdim /// The transformed type if not dependent, otherwise the same as BaseType. 3264223017Sdim QualType UnderlyingType; 3265223017Sdim 3266223017Sdim UTTKind UKind; 3267223017Sdimprotected: 3268223017Sdim UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, 3269223017Sdim QualType CanonicalTy); 3270223017Sdim friend class ASTContext; 3271223017Sdimpublic: 3272223017Sdim bool isSugared() const { return !isDependentType(); } 3273223017Sdim QualType desugar() const { return UnderlyingType; } 3274223017Sdim 3275223017Sdim QualType getUnderlyingType() const { return UnderlyingType; } 3276223017Sdim QualType getBaseType() const { return BaseType; } 3277223017Sdim 3278223017Sdim UTTKind getUTTKind() const { return UKind; } 3279234353Sdim 3280223017Sdim static bool classof(const Type *T) { 3281223017Sdim return T->getTypeClass() == UnaryTransform; 3282223017Sdim } 3283223017Sdim}; 3284223017Sdim 3285193326Sedclass TagType : public Type { 3286212904Sdim /// Stores the TagDecl associated with this type. The decl may point to any 3287212904Sdim /// TagDecl that declares the entity. 3288212904Sdim TagDecl * decl; 3289193326Sed 3290234353Sdim friend class ASTReader; 3291234353Sdim 3292193326Sedprotected: 3293203955Srdivacky TagType(TypeClass TC, const TagDecl *D, QualType can); 3294193326Sed 3295198092Srdivackypublic: 3296212904Sdim TagDecl *getDecl() const; 3297198092Srdivacky 3298193326Sed /// @brief Determines whether this type is in the process of being 3299198092Srdivacky /// defined. 3300212904Sdim bool isBeingDefined() const; 3301193326Sed 3302198092Srdivacky static bool classof(const Type *T) { 3303193326Sed return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; 3304193326Sed } 3305193326Sed}; 3306193326Sed 3307193326Sed/// RecordType - This is a helper class that allows the use of isa/cast/dyncast 3308193326Sed/// to detect TagType objects of structs/unions/classes. 3309193326Sedclass RecordType : public TagType { 3310193326Sedprotected: 3311203955Srdivacky explicit RecordType(const RecordDecl *D) 3312203955Srdivacky : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3313193326Sed explicit RecordType(TypeClass TC, RecordDecl *D) 3314203955Srdivacky : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3315193326Sed friend class ASTContext; // ASTContext creates these. 3316193326Sedpublic: 3317198092Srdivacky 3318193326Sed RecordDecl *getDecl() const { 3319193326Sed return reinterpret_cast<RecordDecl*>(TagType::getDecl()); 3320193326Sed } 3321198092Srdivacky 3322198092Srdivacky // FIXME: This predicate is a helper to QualType/Type. It needs to 3323193326Sed // recursively check all fields for const-ness. If any field is declared 3324198092Srdivacky // const, it needs to return false. 3325193326Sed bool hasConstFields() const { return false; } 3326193326Sed 3327198092Srdivacky bool isSugared() const { return false; } 3328198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3329198092Srdivacky 3330234353Sdim static bool classof(const Type *T) { return T->getTypeClass() == Record; } 3331193326Sed}; 3332193326Sed 3333193326Sed/// EnumType - This is a helper class that allows the use of isa/cast/dyncast 3334193326Sed/// to detect TagType objects of enums. 3335193326Sedclass EnumType : public TagType { 3336203955Srdivacky explicit EnumType(const EnumDecl *D) 3337203955Srdivacky : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3338193326Sed friend class ASTContext; // ASTContext creates these. 3339193326Sedpublic: 3340198092Srdivacky 3341193326Sed EnumDecl *getDecl() const { 3342193326Sed return reinterpret_cast<EnumDecl*>(TagType::getDecl()); 3343193326Sed } 3344198092Srdivacky 3345198092Srdivacky bool isSugared() const { return false; } 3346198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3347198092Srdivacky 3348234353Sdim static bool classof(const Type *T) { return T->getTypeClass() == Enum; } 3349193326Sed}; 3350193326Sed 3351218893Sdim/// AttributedType - An attributed type is a type to which a type 3352218893Sdim/// attribute has been applied. The "modified type" is the 3353218893Sdim/// fully-sugared type to which the attributed type was applied; 3354218893Sdim/// generally it is not canonically equivalent to the attributed type. 3355218893Sdim/// The "equivalent type" is the minimally-desugared type which the 3356218893Sdim/// type is canonically equivalent to. 3357218893Sdim/// 3358218893Sdim/// For example, in the following attributed type: 3359218893Sdim/// int32_t __attribute__((vector_size(16))) 3360218893Sdim/// - the modified type is the TypedefType for int32_t 3361218893Sdim/// - the equivalent type is VectorType(16, int32_t) 3362218893Sdim/// - the canonical type is VectorType(16, int) 3363218893Sdimclass AttributedType : public Type, public llvm::FoldingSetNode { 3364218893Sdimpublic: 3365218893Sdim // It is really silly to have yet another attribute-kind enum, but 3366218893Sdim // clang::attr::Kind doesn't currently cover the pure type attrs. 3367218893Sdim enum Kind { 3368218893Sdim // Expression operand. 3369218893Sdim attr_address_space, 3370218893Sdim attr_regparm, 3371218893Sdim attr_vector_size, 3372218893Sdim attr_neon_vector_type, 3373218893Sdim attr_neon_polyvector_type, 3374218893Sdim 3375218893Sdim FirstExprOperandKind = attr_address_space, 3376218893Sdim LastExprOperandKind = attr_neon_polyvector_type, 3377218893Sdim 3378218893Sdim // Enumerated operand (string or keyword). 3379218893Sdim attr_objc_gc, 3380224145Sdim attr_objc_ownership, 3381221345Sdim attr_pcs, 3382263508Sdim attr_pcs_vfp, 3383218893Sdim 3384218893Sdim FirstEnumOperandKind = attr_objc_gc, 3385263508Sdim LastEnumOperandKind = attr_pcs_vfp, 3386218893Sdim 3387218893Sdim // No operand. 3388218893Sdim attr_noreturn, 3389218893Sdim attr_cdecl, 3390218893Sdim attr_fastcall, 3391218893Sdim attr_stdcall, 3392218893Sdim attr_thiscall, 3393243830Sdim attr_pascal, 3394249423Sdim attr_pnaclcall, 3395256030Sdim attr_inteloclbicc, 3396256030Sdim attr_ms_abi, 3397263508Sdim attr_sysv_abi, 3398263508Sdim attr_ptr32, 3399263508Sdim attr_ptr64, 3400263508Sdim attr_sptr, 3401263508Sdim attr_uptr 3402218893Sdim }; 3403218893Sdim 3404218893Sdimprivate: 3405218893Sdim QualType ModifiedType; 3406218893Sdim QualType EquivalentType; 3407218893Sdim 3408218893Sdim friend class ASTContext; // creates these 3409218893Sdim 3410218893Sdim AttributedType(QualType canon, Kind attrKind, 3411218893Sdim QualType modified, QualType equivalent) 3412218893Sdim : Type(Attributed, canon, canon->isDependentType(), 3413224145Sdim canon->isInstantiationDependentType(), 3414218893Sdim canon->isVariablyModifiedType(), 3415218893Sdim canon->containsUnexpandedParameterPack()), 3416218893Sdim ModifiedType(modified), EquivalentType(equivalent) { 3417218893Sdim AttributedTypeBits.AttrKind = attrKind; 3418218893Sdim } 3419218893Sdim 3420218893Sdimpublic: 3421218893Sdim Kind getAttrKind() const { 3422218893Sdim return static_cast<Kind>(AttributedTypeBits.AttrKind); 3423218893Sdim } 3424218893Sdim 3425218893Sdim QualType getModifiedType() const { return ModifiedType; } 3426218893Sdim QualType getEquivalentType() const { return EquivalentType; } 3427218893Sdim 3428218893Sdim bool isSugared() const { return true; } 3429218893Sdim QualType desugar() const { return getEquivalentType(); } 3430218893Sdim 3431263508Sdim bool isMSTypeSpec() const; 3432263508Sdim 3433263508Sdim bool isCallingConv() const; 3434263508Sdim 3435218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 3436218893Sdim Profile(ID, getAttrKind(), ModifiedType, EquivalentType); 3437218893Sdim } 3438218893Sdim 3439218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, 3440218893Sdim QualType modified, QualType equivalent) { 3441218893Sdim ID.AddInteger(attrKind); 3442218893Sdim ID.AddPointer(modified.getAsOpaquePtr()); 3443218893Sdim ID.AddPointer(equivalent.getAsOpaquePtr()); 3444218893Sdim } 3445218893Sdim 3446218893Sdim static bool classof(const Type *T) { 3447218893Sdim return T->getTypeClass() == Attributed; 3448218893Sdim } 3449218893Sdim}; 3450218893Sdim 3451193326Sedclass TemplateTypeParmType : public Type, public llvm::FoldingSetNode { 3452221345Sdim // Helper data collector for canonical types. 3453221345Sdim struct CanonicalTTPTInfo { 3454221345Sdim unsigned Depth : 15; 3455221345Sdim unsigned ParameterPack : 1; 3456221345Sdim unsigned Index : 16; 3457221345Sdim }; 3458193326Sed 3459221345Sdim union { 3460221345Sdim // Info for the canonical type. 3461221345Sdim CanonicalTTPTInfo CanTTPTInfo; 3462221345Sdim // Info for the non-canonical type. 3463221345Sdim TemplateTypeParmDecl *TTPDecl; 3464221345Sdim }; 3465221345Sdim 3466221345Sdim /// Build a non-canonical type. 3467221345Sdim TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) 3468218893Sdim : Type(TemplateTypeParm, Canon, /*Dependent=*/true, 3469224145Sdim /*InstantiationDependent=*/true, 3470221345Sdim /*VariablyModified=*/false, 3471221345Sdim Canon->containsUnexpandedParameterPack()), 3472221345Sdim TTPDecl(TTPDecl) { } 3473193326Sed 3474221345Sdim /// Build the canonical type. 3475198092Srdivacky TemplateTypeParmType(unsigned D, unsigned I, bool PP) 3476234353Sdim : Type(TemplateTypeParm, QualType(this, 0), 3477224145Sdim /*Dependent=*/true, 3478224145Sdim /*InstantiationDependent=*/true, 3479221345Sdim /*VariablyModified=*/false, PP) { 3480221345Sdim CanTTPTInfo.Depth = D; 3481221345Sdim CanTTPTInfo.Index = I; 3482221345Sdim CanTTPTInfo.ParameterPack = PP; 3483221345Sdim } 3484193326Sed 3485193326Sed friend class ASTContext; // ASTContext creates these 3486193326Sed 3487221345Sdim const CanonicalTTPTInfo& getCanTTPTInfo() const { 3488221345Sdim QualType Can = getCanonicalTypeInternal(); 3489221345Sdim return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo; 3490221345Sdim } 3491221345Sdim 3492193326Sedpublic: 3493221345Sdim unsigned getDepth() const { return getCanTTPTInfo().Depth; } 3494221345Sdim unsigned getIndex() const { return getCanTTPTInfo().Index; } 3495221345Sdim bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; } 3496193326Sed 3497221345Sdim TemplateTypeParmDecl *getDecl() const { 3498221345Sdim return isCanonicalUnqualified() ? 0 : TTPDecl; 3499221345Sdim } 3500221345Sdim 3501221345Sdim IdentifierInfo *getIdentifier() const; 3502221345Sdim 3503198092Srdivacky bool isSugared() const { return false; } 3504198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3505198092Srdivacky 3506193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 3507221345Sdim Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); 3508193326Sed } 3509193326Sed 3510198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, 3511198092Srdivacky unsigned Index, bool ParameterPack, 3512221345Sdim TemplateTypeParmDecl *TTPDecl) { 3513193326Sed ID.AddInteger(Depth); 3514193326Sed ID.AddInteger(Index); 3515194613Sed ID.AddBoolean(ParameterPack); 3516221345Sdim ID.AddPointer(TTPDecl); 3517193326Sed } 3518193326Sed 3519198092Srdivacky static bool classof(const Type *T) { 3520198092Srdivacky return T->getTypeClass() == TemplateTypeParm; 3521193326Sed } 3522193326Sed}; 3523193326Sed 3524198398Srdivacky/// \brief Represents the result of substituting a type for a template 3525198398Srdivacky/// type parameter. 3526198398Srdivacky/// 3527198398Srdivacky/// Within an instantiated template, all template type parameters have 3528198398Srdivacky/// been replaced with these. They are used solely to record that a 3529198398Srdivacky/// type was originally written as a template type parameter; 3530198398Srdivacky/// therefore they are never canonical. 3531198398Srdivackyclass SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { 3532198398Srdivacky // The original type parameter. 3533198398Srdivacky const TemplateTypeParmType *Replaced; 3534198398Srdivacky 3535198398Srdivacky SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) 3536218893Sdim : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), 3537224145Sdim Canon->isInstantiationDependentType(), 3538218893Sdim Canon->isVariablyModifiedType(), 3539218893Sdim Canon->containsUnexpandedParameterPack()), 3540198398Srdivacky Replaced(Param) { } 3541198398Srdivacky 3542198398Srdivacky friend class ASTContext; 3543198398Srdivacky 3544198398Srdivackypublic: 3545198398Srdivacky /// Gets the template parameter that was substituted for. 3546198398Srdivacky const TemplateTypeParmType *getReplacedParameter() const { 3547198398Srdivacky return Replaced; 3548198398Srdivacky } 3549198398Srdivacky 3550198398Srdivacky /// Gets the type that was substituted for the template 3551198398Srdivacky /// parameter. 3552198398Srdivacky QualType getReplacementType() const { 3553198398Srdivacky return getCanonicalTypeInternal(); 3554198398Srdivacky } 3555198398Srdivacky 3556198398Srdivacky bool isSugared() const { return true; } 3557198398Srdivacky QualType desugar() const { return getReplacementType(); } 3558198398Srdivacky 3559198398Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3560198398Srdivacky Profile(ID, getReplacedParameter(), getReplacementType()); 3561198398Srdivacky } 3562198398Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 3563198398Srdivacky const TemplateTypeParmType *Replaced, 3564198398Srdivacky QualType Replacement) { 3565198398Srdivacky ID.AddPointer(Replaced); 3566198398Srdivacky ID.AddPointer(Replacement.getAsOpaquePtr()); 3567198398Srdivacky } 3568198398Srdivacky 3569198398Srdivacky static bool classof(const Type *T) { 3570198398Srdivacky return T->getTypeClass() == SubstTemplateTypeParm; 3571198398Srdivacky } 3572198398Srdivacky}; 3573198398Srdivacky 3574218893Sdim/// \brief Represents the result of substituting a set of types for a template 3575218893Sdim/// type parameter pack. 3576218893Sdim/// 3577218893Sdim/// When a pack expansion in the source code contains multiple parameter packs 3578218893Sdim/// and those parameter packs correspond to different levels of template 3579234353Sdim/// parameter lists, this type node is used to represent a template type 3580218893Sdim/// parameter pack from an outer level, which has already had its argument pack 3581218893Sdim/// substituted but that still lives within a pack expansion that itself 3582218893Sdim/// could not be instantiated. When actually performing a substitution into 3583218893Sdim/// that pack expansion (e.g., when all template parameters have corresponding 3584218893Sdim/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType 3585218893Sdim/// at the current pack substitution index. 3586218893Sdimclass SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { 3587218893Sdim /// \brief The original type parameter. 3588218893Sdim const TemplateTypeParmType *Replaced; 3589234353Sdim 3590218893Sdim /// \brief A pointer to the set of template arguments that this 3591218893Sdim /// parameter pack is instantiated with. 3592218893Sdim const TemplateArgument *Arguments; 3593234353Sdim 3594218893Sdim /// \brief The number of template arguments in \c Arguments. 3595218893Sdim unsigned NumArguments; 3596234353Sdim 3597234353Sdim SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, 3598218893Sdim QualType Canon, 3599218893Sdim const TemplateArgument &ArgPack); 3600234353Sdim 3601218893Sdim friend class ASTContext; 3602234353Sdim 3603218893Sdimpublic: 3604221345Sdim IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } 3605234353Sdim 3606218893Sdim /// Gets the template parameter that was substituted for. 3607218893Sdim const TemplateTypeParmType *getReplacedParameter() const { 3608218893Sdim return Replaced; 3609218893Sdim } 3610234353Sdim 3611218893Sdim bool isSugared() const { return false; } 3612218893Sdim QualType desugar() const { return QualType(this, 0); } 3613234353Sdim 3614218893Sdim TemplateArgument getArgumentPack() const; 3615234353Sdim 3616218893Sdim void Profile(llvm::FoldingSetNodeID &ID); 3617218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, 3618218893Sdim const TemplateTypeParmType *Replaced, 3619218893Sdim const TemplateArgument &ArgPack); 3620234353Sdim 3621218893Sdim static bool classof(const Type *T) { 3622218893Sdim return T->getTypeClass() == SubstTemplateTypeParmPack; 3623218893Sdim } 3624218893Sdim}; 3625218893Sdim 3626251662Sdim/// \brief Represents a C++11 auto or C++1y decltype(auto) type. 3627218893Sdim/// 3628251662Sdim/// These types are usually a placeholder for a deduced type. However, before 3629251662Sdim/// the initializer is attached, or if the initializer is type-dependent, there 3630251662Sdim/// is no deduced type and an auto type is canonical. In the latter case, it is 3631251662Sdim/// also a dependent type. 3632218893Sdimclass AutoType : public Type, public llvm::FoldingSetNode { 3633263508Sdim AutoType(QualType DeducedType, bool IsDecltypeAuto, 3634263508Sdim bool IsDependent) 3635218893Sdim : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, 3636251662Sdim /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent, 3637263508Sdim /*VariablyModified=*/false, 3638263508Sdim /*ContainsParameterPack=*/DeducedType.isNull() 3639263508Sdim ? false : DeducedType->containsUnexpandedParameterPack()) { 3640251662Sdim assert((DeducedType.isNull() || !IsDependent) && 3641251662Sdim "auto deduced to dependent type"); 3642251662Sdim AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto; 3643218893Sdim } 3644218893Sdim 3645218893Sdim friend class ASTContext; // ASTContext creates these 3646218893Sdim 3647218893Sdimpublic: 3648251662Sdim bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; } 3649251662Sdim 3650251662Sdim bool isSugared() const { return !isCanonicalUnqualified(); } 3651218893Sdim QualType desugar() const { return getCanonicalTypeInternal(); } 3652218893Sdim 3653251662Sdim /// \brief Get the type deduced for this auto type, or null if it's either 3654251662Sdim /// not been deduced or was deduced to a dependent type. 3655218893Sdim QualType getDeducedType() const { 3656251662Sdim return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType(); 3657218893Sdim } 3658218893Sdim bool isDeduced() const { 3659251662Sdim return !isCanonicalUnqualified() || isDependentType(); 3660218893Sdim } 3661218893Sdim 3662218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 3663263508Sdim Profile(ID, getDeducedType(), isDecltypeAuto(), 3664263508Sdim isDependentType()); 3665218893Sdim } 3666218893Sdim 3667251662Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, 3668251662Sdim bool IsDecltypeAuto, bool IsDependent) { 3669218893Sdim ID.AddPointer(Deduced.getAsOpaquePtr()); 3670251662Sdim ID.AddBoolean(IsDecltypeAuto); 3671251662Sdim ID.AddBoolean(IsDependent); 3672218893Sdim } 3673218893Sdim 3674218893Sdim static bool classof(const Type *T) { 3675218893Sdim return T->getTypeClass() == Auto; 3676218893Sdim } 3677218893Sdim}; 3678218893Sdim 3679224145Sdim/// \brief Represents a type template specialization; the template 3680224145Sdim/// must be a class template, a type alias template, or a template 3681224145Sdim/// template parameter. A template which cannot be resolved to one of 3682224145Sdim/// these, e.g. because it is written with a dependent scope 3683224145Sdim/// specifier, is instead represented as a 3684224145Sdim/// @c DependentTemplateSpecializationType. 3685193326Sed/// 3686224145Sdim/// A non-dependent template specialization type is always "sugar", 3687224145Sdim/// typically for a @c RecordType. For example, a class template 3688224145Sdim/// specialization type of @c vector<int> will refer to a tag type for 3689224145Sdim/// the instantiation @c std::vector<int, std::allocator<int>> 3690193326Sed/// 3691224145Sdim/// Template specializations are dependent if either the template or 3692224145Sdim/// any of the template arguments are dependent, in which case the 3693224145Sdim/// type may also be canonical. 3694223017Sdim/// 3695224145Sdim/// Instances of this type are allocated with a trailing array of 3696224145Sdim/// TemplateArguments, followed by a QualType representing the 3697224145Sdim/// non-canonical aliased type when the template is a type alias 3698224145Sdim/// template. 3699198092Srdivackyclass TemplateSpecializationType 3700193326Sed : public Type, public llvm::FoldingSetNode { 3701224145Sdim /// \brief The name of the template being specialized. This is 3702224145Sdim /// either a TemplateName::Template (in which case it is a 3703224145Sdim /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a 3704224145Sdim /// TypeAliasTemplateDecl*), a 3705224145Sdim /// TemplateName::SubstTemplateTemplateParmPack, or a 3706224145Sdim /// TemplateName::SubstTemplateTemplateParm (in which case the 3707224145Sdim /// replacement must, recursively, be one of these). 3708193326Sed TemplateName Template; 3709193326Sed 3710193326Sed /// \brief - The number of template arguments named in this class 3711193326Sed /// template specialization. 3712234353Sdim unsigned NumArgs : 31; 3713193326Sed 3714234353Sdim /// \brief Whether this template specialization type is a substituted 3715234353Sdim /// type alias. 3716234353Sdim bool TypeAlias : 1; 3717234353Sdim 3718210299Sed TemplateSpecializationType(TemplateName T, 3719193326Sed const TemplateArgument *Args, 3720223017Sdim unsigned NumArgs, QualType Canon, 3721223017Sdim QualType Aliased); 3722193326Sed 3723193326Sed friend class ASTContext; // ASTContext creates these 3724193326Sed 3725193326Sedpublic: 3726193326Sed /// \brief Determine whether any of the given template arguments are 3727193326Sed /// dependent. 3728198893Srdivacky static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, 3729224145Sdim unsigned NumArgs, 3730224145Sdim bool &InstantiationDependent); 3731198893Srdivacky 3732224145Sdim static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, 3733224145Sdim bool &InstantiationDependent); 3734199990Srdivacky 3735193326Sed /// \brief Print a template argument list, including the '<' and '>' 3736193326Sed /// enclosing the template arguments. 3737239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3738239462Sdim const TemplateArgument *Args, 3739239462Sdim unsigned NumArgs, 3740239462Sdim const PrintingPolicy &Policy, 3741239462Sdim bool SkipBrackets = false); 3742239462Sdim 3743239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3744239462Sdim const TemplateArgumentLoc *Args, 3745239462Sdim unsigned NumArgs, 3746239462Sdim const PrintingPolicy &Policy); 3747239462Sdim 3748239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3749239462Sdim const TemplateArgumentListInfo &, 3750239462Sdim const PrintingPolicy &Policy); 3751239462Sdim 3752207619Srdivacky /// True if this template specialization type matches a current 3753207619Srdivacky /// instantiation in the context in which it is found. 3754207619Srdivacky bool isCurrentInstantiation() const { 3755210299Sed return isa<InjectedClassNameType>(getCanonicalTypeInternal()); 3756207619Srdivacky } 3757207619Srdivacky 3758234353Sdim /// \brief Determine if this template specialization type is for a type alias 3759234353Sdim /// template that has been substituted. 3760234353Sdim /// 3761234353Sdim /// Nearly every template specialization type whose template is an alias 3762234353Sdim /// template will be substituted. However, this is not the case when 3763234353Sdim /// the specialization contains a pack expansion but the template alias 3764234353Sdim /// does not have a corresponding parameter pack, e.g., 3765234353Sdim /// 3766234353Sdim /// \code 3767234353Sdim /// template<typename T, typename U, typename V> struct S; 3768234353Sdim /// template<typename T, typename U> using A = S<T, int, U>; 3769234353Sdim /// template<typename... Ts> struct X { 3770234353Sdim /// typedef A<Ts...> type; // not a type alias 3771234353Sdim /// }; 3772234353Sdim /// \endcode 3773234353Sdim bool isTypeAlias() const { return TypeAlias; } 3774234353Sdim 3775223017Sdim /// Get the aliased type, if this is a specialization of a type alias 3776223017Sdim /// template. 3777223017Sdim QualType getAliasedType() const { 3778223017Sdim assert(isTypeAlias() && "not a type alias template specialization"); 3779223017Sdim return *reinterpret_cast<const QualType*>(end()); 3780223017Sdim } 3781223017Sdim 3782193326Sed typedef const TemplateArgument * iterator; 3783193326Sed 3784193326Sed iterator begin() const { return getArgs(); } 3785210299Sed iterator end() const; // defined inline in TemplateBase.h 3786193326Sed 3787193326Sed /// \brief Retrieve the name of the template that we are specializing. 3788193326Sed TemplateName getTemplateName() const { return Template; } 3789193326Sed 3790193326Sed /// \brief Retrieve the template arguments. 3791198092Srdivacky const TemplateArgument *getArgs() const { 3792193326Sed return reinterpret_cast<const TemplateArgument *>(this + 1); 3793193326Sed } 3794193326Sed 3795193326Sed /// \brief Retrieve the number of template arguments. 3796193326Sed unsigned getNumArgs() const { return NumArgs; } 3797193326Sed 3798193326Sed /// \brief Retrieve a specific template argument as a type. 3799239462Sdim /// \pre @c isArgType(Arg) 3800210299Sed const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h 3801193326Sed 3802207619Srdivacky bool isSugared() const { 3803223017Sdim return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); 3804207619Srdivacky } 3805198092Srdivacky QualType desugar() const { return getCanonicalTypeInternal(); } 3806198092Srdivacky 3807218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { 3808210299Sed Profile(ID, Template, getArgs(), NumArgs, Ctx); 3809223017Sdim if (isTypeAlias()) 3810223017Sdim getAliasedType().Profile(ID); 3811193326Sed } 3812193326Sed 3813193326Sed static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, 3814207619Srdivacky const TemplateArgument *Args, 3815207619Srdivacky unsigned NumArgs, 3816218893Sdim const ASTContext &Context); 3817193326Sed 3818198092Srdivacky static bool classof(const Type *T) { 3819198092Srdivacky return T->getTypeClass() == TemplateSpecialization; 3820193326Sed } 3821193326Sed}; 3822193326Sed 3823207619Srdivacky/// \brief The injected class name of a C++ class template or class 3824207619Srdivacky/// template partial specialization. Used to record that a type was 3825207619Srdivacky/// spelled with a bare identifier rather than as a template-id; the 3826207619Srdivacky/// equivalent for non-templated classes is just RecordType. 3827204962Srdivacky/// 3828207619Srdivacky/// Injected class name types are always dependent. Template 3829207619Srdivacky/// instantiation turns these into RecordTypes. 3830204962Srdivacky/// 3831207619Srdivacky/// Injected class name types are always canonical. This works 3832207619Srdivacky/// because it is impossible to compare an injected class name type 3833207619Srdivacky/// with the corresponding non-injected template type, for the same 3834207619Srdivacky/// reason that it is impossible to directly compare template 3835207619Srdivacky/// parameters from different dependent contexts: injected class name 3836207619Srdivacky/// types can only occur within the scope of a particular templated 3837207619Srdivacky/// declaration, and within that scope every template specialization 3838207619Srdivacky/// will canonicalize to the injected class name (when appropriate 3839207619Srdivacky/// according to the rules of the language). 3840204962Srdivackyclass InjectedClassNameType : public Type { 3841204962Srdivacky CXXRecordDecl *Decl; 3842204962Srdivacky 3843207619Srdivacky /// The template specialization which this type represents. 3844207619Srdivacky /// For example, in 3845207619Srdivacky /// template <class T> class A { ... }; 3846207619Srdivacky /// this is A<T>, whereas in 3847207619Srdivacky /// template <class X, class Y> class A<B<X,Y> > { ... }; 3848207619Srdivacky /// this is A<B<X,Y> >. 3849207619Srdivacky /// 3850207619Srdivacky /// It is always unqualified, always a template specialization type, 3851207619Srdivacky /// and always dependent. 3852207619Srdivacky QualType InjectedType; 3853204962Srdivacky 3854204962Srdivacky friend class ASTContext; // ASTContext creates these. 3855212904Sdim friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not 3856212904Sdim // currently suitable for AST reading, too much 3857210299Sed // interdependencies. 3858207619Srdivacky InjectedClassNameType(CXXRecordDecl *D, QualType TST) 3859218893Sdim : Type(InjectedClassName, QualType(), /*Dependent=*/true, 3860224145Sdim /*InstantiationDependent=*/true, 3861234353Sdim /*VariablyModified=*/false, 3862218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3863207619Srdivacky Decl(D), InjectedType(TST) { 3864204962Srdivacky assert(isa<TemplateSpecializationType>(TST)); 3865204962Srdivacky assert(!TST.hasQualifiers()); 3866207619Srdivacky assert(TST->isDependentType()); 3867204962Srdivacky } 3868204962Srdivacky 3869204962Srdivackypublic: 3870207619Srdivacky QualType getInjectedSpecializationType() const { return InjectedType; } 3871207619Srdivacky const TemplateSpecializationType *getInjectedTST() const { 3872207619Srdivacky return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); 3873204962Srdivacky } 3874204962Srdivacky 3875212904Sdim CXXRecordDecl *getDecl() const; 3876204962Srdivacky 3877207619Srdivacky bool isSugared() const { return false; } 3878207619Srdivacky QualType desugar() const { return QualType(this, 0); } 3879204962Srdivacky 3880204962Srdivacky static bool classof(const Type *T) { 3881204962Srdivacky return T->getTypeClass() == InjectedClassName; 3882204962Srdivacky } 3883204962Srdivacky}; 3884204962Srdivacky 3885208600Srdivacky/// \brief The kind of a tag type. 3886208600Srdivackyenum TagTypeKind { 3887208600Srdivacky /// \brief The "struct" keyword. 3888208600Srdivacky TTK_Struct, 3889243830Sdim /// \brief The "__interface" keyword. 3890243830Sdim TTK_Interface, 3891208600Srdivacky /// \brief The "union" keyword. 3892208600Srdivacky TTK_Union, 3893208600Srdivacky /// \brief The "class" keyword. 3894208600Srdivacky TTK_Class, 3895208600Srdivacky /// \brief The "enum" keyword. 3896208600Srdivacky TTK_Enum 3897208600Srdivacky}; 3898208600Srdivacky 3899206084Srdivacky/// \brief The elaboration keyword that precedes a qualified type name or 3900206084Srdivacky/// introduces an elaborated-type-specifier. 3901206084Srdivackyenum ElaboratedTypeKeyword { 3902206084Srdivacky /// \brief The "struct" keyword introduces the elaborated-type-specifier. 3903206084Srdivacky ETK_Struct, 3904243830Sdim /// \brief The "__interface" keyword introduces the elaborated-type-specifier. 3905243830Sdim ETK_Interface, 3906206084Srdivacky /// \brief The "union" keyword introduces the elaborated-type-specifier. 3907206084Srdivacky ETK_Union, 3908208600Srdivacky /// \brief The "class" keyword introduces the elaborated-type-specifier. 3909208600Srdivacky ETK_Class, 3910206084Srdivacky /// \brief The "enum" keyword introduces the elaborated-type-specifier. 3911208600Srdivacky ETK_Enum, 3912208600Srdivacky /// \brief The "typename" keyword precedes the qualified type name, e.g., 3913208600Srdivacky /// \c typename T::type. 3914208600Srdivacky ETK_Typename, 3915208600Srdivacky /// \brief No keyword precedes the qualified type name. 3916208600Srdivacky ETK_None 3917206084Srdivacky}; 3918208600Srdivacky 3919208600Srdivacky/// A helper class for Type nodes having an ElaboratedTypeKeyword. 3920208600Srdivacky/// The keyword in stored in the free bits of the base class. 3921208600Srdivacky/// Also provides a few static helpers for converting and printing 3922208600Srdivacky/// elaborated type keyword and tag type kind enumerations. 3923208600Srdivackyclass TypeWithKeyword : public Type { 3924208600Srdivackyprotected: 3925208600Srdivacky TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, 3926234353Sdim QualType Canonical, bool Dependent, 3927234353Sdim bool InstantiationDependent, bool VariablyModified, 3928218893Sdim bool ContainsUnexpandedParameterPack) 3929234353Sdim : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, 3930218893Sdim ContainsUnexpandedParameterPack) { 3931218893Sdim TypeWithKeywordBits.Keyword = Keyword; 3932218893Sdim } 3933208600Srdivacky 3934208600Srdivackypublic: 3935208600Srdivacky ElaboratedTypeKeyword getKeyword() const { 3936218893Sdim return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); 3937208600Srdivacky } 3938208600Srdivacky 3939208600Srdivacky /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST) 3940208600Srdivacky /// into an elaborated type keyword. 3941208600Srdivacky static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); 3942208600Srdivacky 3943208600Srdivacky /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST) 3944208600Srdivacky /// into a tag type kind. It is an error to provide a type specifier 3945208600Srdivacky /// which *isn't* a tag kind here. 3946208600Srdivacky static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); 3947208600Srdivacky 3948208600Srdivacky /// getKeywordForTagDeclKind - Converts a TagTypeKind into an 3949208600Srdivacky /// elaborated type keyword. 3950208600Srdivacky static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); 3951208600Srdivacky 3952208600Srdivacky /// getTagTypeKindForKeyword - Converts an elaborated type keyword into 3953208600Srdivacky // a TagTypeKind. It is an error to provide an elaborated type keyword 3954208600Srdivacky /// which *isn't* a tag kind here. 3955208600Srdivacky static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); 3956208600Srdivacky 3957208600Srdivacky static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); 3958208600Srdivacky 3959208600Srdivacky static const char *getKeywordName(ElaboratedTypeKeyword Keyword); 3960208600Srdivacky 3961208600Srdivacky static const char *getTagTypeKindName(TagTypeKind Kind) { 3962208600Srdivacky return getKeywordName(getKeywordForTagTypeKind(Kind)); 3963208600Srdivacky } 3964208600Srdivacky 3965208600Srdivacky class CannotCastToThisType {}; 3966208600Srdivacky static CannotCastToThisType classof(const Type *); 3967208600Srdivacky}; 3968208600Srdivacky 3969208600Srdivacky/// \brief Represents a type that was referred to using an elaborated type 3970208600Srdivacky/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, 3971208600Srdivacky/// or both. 3972193326Sed/// 3973193326Sed/// This type is used to keep track of a type name as written in the 3974208600Srdivacky/// source code, including tag keywords and any nested-name-specifiers. 3975208600Srdivacky/// The type itself is always "sugar", used to express what was written 3976208600Srdivacky/// in the source code but containing no additional semantic information. 3977208600Srdivackyclass ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { 3978208600Srdivacky 3979193326Sed /// \brief The nested name specifier containing the qualifier. 3980193326Sed NestedNameSpecifier *NNS; 3981193326Sed 3982193326Sed /// \brief The type that this qualified name refers to. 3983193326Sed QualType NamedType; 3984193326Sed 3985208600Srdivacky ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 3986208600Srdivacky QualType NamedType, QualType CanonType) 3987208600Srdivacky : TypeWithKeyword(Keyword, Elaborated, CanonType, 3988218893Sdim NamedType->isDependentType(), 3989224145Sdim NamedType->isInstantiationDependentType(), 3990218893Sdim NamedType->isVariablyModifiedType(), 3991218893Sdim NamedType->containsUnexpandedParameterPack()), 3992208600Srdivacky NNS(NNS), NamedType(NamedType) { 3993208600Srdivacky assert(!(Keyword == ETK_None && NNS == 0) && 3994208600Srdivacky "ElaboratedType cannot have elaborated type keyword " 3995208600Srdivacky "and name qualifier both null."); 3996208600Srdivacky } 3997193326Sed 3998193326Sed friend class ASTContext; // ASTContext creates these 3999193326Sed 4000193326Sedpublic: 4001210299Sed ~ElaboratedType(); 4002208600Srdivacky 4003193326Sed /// \brief Retrieve the qualification on this type. 4004193326Sed NestedNameSpecifier *getQualifier() const { return NNS; } 4005193326Sed 4006193326Sed /// \brief Retrieve the type named by the qualified-id. 4007193326Sed QualType getNamedType() const { return NamedType; } 4008193326Sed 4009198092Srdivacky /// \brief Remove a single level of sugar. 4010198092Srdivacky QualType desugar() const { return getNamedType(); } 4011193326Sed 4012198092Srdivacky /// \brief Returns whether this type directly provides sugar. 4013198092Srdivacky bool isSugared() const { return true; } 4014198092Srdivacky 4015193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 4016208600Srdivacky Profile(ID, getKeyword(), NNS, NamedType); 4017193326Sed } 4018193326Sed 4019208600Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, 4020208600Srdivacky NestedNameSpecifier *NNS, QualType NamedType) { 4021208600Srdivacky ID.AddInteger(Keyword); 4022193326Sed ID.AddPointer(NNS); 4023193326Sed NamedType.Profile(ID); 4024193326Sed } 4025193326Sed 4026198092Srdivacky static bool classof(const Type *T) { 4027208600Srdivacky return T->getTypeClass() == Elaborated; 4028193326Sed } 4029193326Sed}; 4030193326Sed 4031206084Srdivacky/// \brief Represents a qualified type name for which the type name is 4032234353Sdim/// dependent. 4033193326Sed/// 4034234353Sdim/// DependentNameType represents a class of dependent types that involve a 4035234353Sdim/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent) 4036206084Srdivacky/// name of a type. The DependentNameType may start with a "typename" (for a 4037234353Sdim/// typename-specifier), "class", "struct", "union", or "enum" (for a 4038206084Srdivacky/// dependent elaborated-type-specifier), or nothing (in contexts where we 4039206084Srdivacky/// know that we must be referring to a type, e.g., in a base class specifier). 4040208600Srdivackyclass DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { 4041208600Srdivacky 4042193326Sed /// \brief The nested name specifier containing the qualifier. 4043193326Sed NestedNameSpecifier *NNS; 4044193326Sed 4045193326Sed /// \brief The type that this typename specifier refers to. 4046210299Sed const IdentifierInfo *Name; 4047193326Sed 4048234353Sdim DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 4049206084Srdivacky const IdentifierInfo *Name, QualType CanonType) 4050218893Sdim : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, 4051224145Sdim /*InstantiationDependent=*/true, 4052218893Sdim /*VariablyModified=*/false, 4053218893Sdim NNS->containsUnexpandedParameterPack()), 4054208600Srdivacky NNS(NNS), Name(Name) { 4055198092Srdivacky assert(NNS->isDependent() && 4056206084Srdivacky "DependentNameType requires a dependent nested-name-specifier"); 4057193326Sed } 4058193326Sed 4059193326Sed friend class ASTContext; // ASTContext creates these 4060193326Sed 4061193326Sedpublic: 4062193326Sed /// \brief Retrieve the qualification on this type. 4063193326Sed NestedNameSpecifier *getQualifier() const { return NNS; } 4064193326Sed 4065193326Sed /// \brief Retrieve the type named by the typename specifier as an 4066193326Sed /// identifier. 4067193326Sed /// 4068193326Sed /// This routine will return a non-NULL identifier pointer when the 4069193326Sed /// form of the original typename was terminated by an identifier, 4070193326Sed /// e.g., "typename T::type". 4071198092Srdivacky const IdentifierInfo *getIdentifier() const { 4072210299Sed return Name; 4073193326Sed } 4074193326Sed 4075198092Srdivacky bool isSugared() const { return false; } 4076198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4077198092Srdivacky 4078193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 4079208600Srdivacky Profile(ID, getKeyword(), NNS, Name); 4080193326Sed } 4081193326Sed 4082206084Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, 4083210299Sed NestedNameSpecifier *NNS, const IdentifierInfo *Name) { 4084206084Srdivacky ID.AddInteger(Keyword); 4085193326Sed ID.AddPointer(NNS); 4086210299Sed ID.AddPointer(Name); 4087193326Sed } 4088193326Sed 4089198092Srdivacky static bool classof(const Type *T) { 4090206084Srdivacky return T->getTypeClass() == DependentName; 4091193326Sed } 4092193326Sed}; 4093193326Sed 4094210299Sed/// DependentTemplateSpecializationType - Represents a template 4095210299Sed/// specialization type whose template cannot be resolved, e.g. 4096210299Sed/// A<T>::template B<T> 4097210299Sedclass DependentTemplateSpecializationType : 4098210299Sed public TypeWithKeyword, public llvm::FoldingSetNode { 4099210299Sed 4100210299Sed /// \brief The nested name specifier containing the qualifier. 4101210299Sed NestedNameSpecifier *NNS; 4102210299Sed 4103210299Sed /// \brief The identifier of the template. 4104210299Sed const IdentifierInfo *Name; 4105210299Sed 4106210299Sed /// \brief - The number of template arguments named in this class 4107210299Sed /// template specialization. 4108210299Sed unsigned NumArgs; 4109210299Sed 4110210299Sed const TemplateArgument *getArgBuffer() const { 4111210299Sed return reinterpret_cast<const TemplateArgument*>(this+1); 4112210299Sed } 4113210299Sed TemplateArgument *getArgBuffer() { 4114210299Sed return reinterpret_cast<TemplateArgument*>(this+1); 4115210299Sed } 4116210299Sed 4117210299Sed DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, 4118210299Sed NestedNameSpecifier *NNS, 4119210299Sed const IdentifierInfo *Name, 4120210299Sed unsigned NumArgs, 4121210299Sed const TemplateArgument *Args, 4122210299Sed QualType Canon); 4123210299Sed 4124210299Sed friend class ASTContext; // ASTContext creates these 4125210299Sed 4126210299Sedpublic: 4127210299Sed NestedNameSpecifier *getQualifier() const { return NNS; } 4128210299Sed const IdentifierInfo *getIdentifier() const { return Name; } 4129210299Sed 4130210299Sed /// \brief Retrieve the template arguments. 4131210299Sed const TemplateArgument *getArgs() const { 4132210299Sed return getArgBuffer(); 4133210299Sed } 4134210299Sed 4135210299Sed /// \brief Retrieve the number of template arguments. 4136210299Sed unsigned getNumArgs() const { return NumArgs; } 4137210299Sed 4138210299Sed const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h 4139210299Sed 4140210299Sed typedef const TemplateArgument * iterator; 4141210299Sed iterator begin() const { return getArgs(); } 4142210299Sed iterator end() const; // inline in TemplateBase.h 4143210299Sed 4144210299Sed bool isSugared() const { return false; } 4145210299Sed QualType desugar() const { return QualType(this, 0); } 4146210299Sed 4147218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { 4148210299Sed Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs()); 4149210299Sed } 4150210299Sed 4151210299Sed static void Profile(llvm::FoldingSetNodeID &ID, 4152218893Sdim const ASTContext &Context, 4153210299Sed ElaboratedTypeKeyword Keyword, 4154210299Sed NestedNameSpecifier *Qualifier, 4155210299Sed const IdentifierInfo *Name, 4156210299Sed unsigned NumArgs, 4157210299Sed const TemplateArgument *Args); 4158210299Sed 4159210299Sed static bool classof(const Type *T) { 4160210299Sed return T->getTypeClass() == DependentTemplateSpecialization; 4161210299Sed } 4162210299Sed}; 4163210299Sed 4164218893Sdim/// \brief Represents a pack expansion of types. 4165218893Sdim/// 4166218893Sdim/// Pack expansions are part of C++0x variadic templates. A pack 4167218893Sdim/// expansion contains a pattern, which itself contains one or more 4168218893Sdim/// "unexpanded" parameter packs. When instantiated, a pack expansion 4169218893Sdim/// produces a series of types, each instantiated from the pattern of 4170218893Sdim/// the expansion, where the Ith instantiation of the pattern uses the 4171218893Sdim/// Ith arguments bound to each of the unexpanded parameter packs. The 4172218893Sdim/// pack expansion is considered to "expand" these unexpanded 4173218893Sdim/// parameter packs. 4174218893Sdim/// 4175218893Sdim/// \code 4176218893Sdim/// template<typename ...Types> struct tuple; 4177218893Sdim/// 4178234353Sdim/// template<typename ...Types> 4179218893Sdim/// struct tuple_of_references { 4180218893Sdim/// typedef tuple<Types&...> type; 4181218893Sdim/// }; 4182218893Sdim/// \endcode 4183218893Sdim/// 4184218893Sdim/// Here, the pack expansion \c Types&... is represented via a 4185218893Sdim/// PackExpansionType whose pattern is Types&. 4186218893Sdimclass PackExpansionType : public Type, public llvm::FoldingSetNode { 4187218893Sdim /// \brief The pattern of the pack expansion. 4188218893Sdim QualType Pattern; 4189218893Sdim 4190218893Sdim /// \brief The number of expansions that this pack expansion will 4191234353Sdim /// generate when substituted (+1), or indicates that 4192218893Sdim /// 4193234353Sdim /// This field will only have a non-zero value when some of the parameter 4194234353Sdim /// packs that occur within the pattern have been substituted but others have 4195218893Sdim /// not. 4196218893Sdim unsigned NumExpansions; 4197234353Sdim 4198218893Sdim PackExpansionType(QualType Pattern, QualType Canon, 4199249423Sdim Optional<unsigned> NumExpansions) 4200239462Sdim : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), 4201224145Sdim /*InstantiationDependent=*/true, 4202218893Sdim /*VariableModified=*/Pattern->isVariablyModifiedType(), 4203218893Sdim /*ContainsUnexpandedParameterPack=*/false), 4204234353Sdim Pattern(Pattern), 4205218893Sdim NumExpansions(NumExpansions? *NumExpansions + 1: 0) { } 4206218893Sdim 4207218893Sdim friend class ASTContext; // ASTContext creates these 4208234353Sdim 4209218893Sdimpublic: 4210218893Sdim /// \brief Retrieve the pattern of this pack expansion, which is the 4211218893Sdim /// type that will be repeatedly instantiated when instantiating the 4212218893Sdim /// pack expansion itself. 4213218893Sdim QualType getPattern() const { return Pattern; } 4214218893Sdim 4215218893Sdim /// \brief Retrieve the number of expansions that this pack expansion will 4216218893Sdim /// generate, if known. 4217249423Sdim Optional<unsigned> getNumExpansions() const { 4218218893Sdim if (NumExpansions) 4219218893Sdim return NumExpansions - 1; 4220234353Sdim 4221249423Sdim return None; 4222218893Sdim } 4223234353Sdim 4224263508Sdim bool isSugared() const { return !Pattern->isDependentType(); } 4225263508Sdim QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); } 4226218893Sdim 4227218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 4228218893Sdim Profile(ID, getPattern(), getNumExpansions()); 4229218893Sdim } 4230218893Sdim 4231218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, 4232249423Sdim Optional<unsigned> NumExpansions) { 4233218893Sdim ID.AddPointer(Pattern.getAsOpaquePtr()); 4234249423Sdim ID.AddBoolean(NumExpansions.hasValue()); 4235218893Sdim if (NumExpansions) 4236218893Sdim ID.AddInteger(*NumExpansions); 4237218893Sdim } 4238218893Sdim 4239218893Sdim static bool classof(const Type *T) { 4240218893Sdim return T->getTypeClass() == PackExpansion; 4241218893Sdim } 4242218893Sdim}; 4243218893Sdim 4244208600Srdivacky/// ObjCObjectType - Represents a class type in Objective C. 4245208600Srdivacky/// Every Objective C type is a combination of a base type and a 4246208600Srdivacky/// list of protocols. 4247208600Srdivacky/// 4248208600Srdivacky/// Given the following declarations: 4249239462Sdim/// \code 4250239462Sdim/// \@class C; 4251239462Sdim/// \@protocol P; 4252239462Sdim/// \endcode 4253208600Srdivacky/// 4254208600Srdivacky/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType 4255208600Srdivacky/// with base C and no protocols. 4256208600Srdivacky/// 4257208600Srdivacky/// 'C<P>' is an ObjCObjectType with base C and protocol list [P]. 4258208600Srdivacky/// 4259263508Sdim/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose 4260208600Srdivacky/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType 4261208600Srdivacky/// and no protocols. 4262208600Srdivacky/// 4263263508Sdim/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType 4264208600Srdivacky/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually 4265208600Srdivacky/// this should get its own sugar class to better represent the source. 4266208600Srdivackyclass ObjCObjectType : public Type { 4267218893Sdim // ObjCObjectType.NumProtocols - the number of protocols stored 4268218893Sdim // after the ObjCObjectPointerType node. 4269218893Sdim // 4270218893Sdim // These protocols are those written directly on the type. If 4271218893Sdim // protocol qualifiers ever become additive, the iterators will need 4272218893Sdim // to get kindof complicated. 4273218893Sdim // 4274218893Sdim // In the canonical object type, these are sorted alphabetically 4275218893Sdim // and uniqued. 4276198092Srdivacky 4277208600Srdivacky /// Either a BuiltinType or an InterfaceType or sugar for either. 4278208600Srdivacky QualType BaseType; 4279208600Srdivacky 4280208600Srdivacky ObjCProtocolDecl * const *getProtocolStorage() const { 4281208600Srdivacky return const_cast<ObjCObjectType*>(this)->getProtocolStorage(); 4282208600Srdivacky } 4283208600Srdivacky 4284208600Srdivacky ObjCProtocolDecl **getProtocolStorage(); 4285208600Srdivacky 4286208600Srdivackyprotected: 4287234353Sdim ObjCObjectType(QualType Canonical, QualType Base, 4288208600Srdivacky ObjCProtocolDecl * const *Protocols, unsigned NumProtocols); 4289208600Srdivacky 4290208600Srdivacky enum Nonce_ObjCInterface { Nonce_ObjCInterface }; 4291208600Srdivacky ObjCObjectType(enum Nonce_ObjCInterface) 4292224145Sdim : Type(ObjCInterface, QualType(), false, false, false, false), 4293218893Sdim BaseType(QualType(this_(), 0)) { 4294218893Sdim ObjCObjectTypeBits.NumProtocols = 0; 4295218893Sdim } 4296208600Srdivacky 4297198092Srdivackypublic: 4298208600Srdivacky /// getBaseType - Gets the base type of this object type. This is 4299208600Srdivacky /// always (possibly sugar for) one of: 4300208600Srdivacky /// - the 'id' builtin type (as opposed to the 'id' type visible to the 4301263508Sdim /// user, which is a typedef for an ObjCObjectPointerType) 4302208600Srdivacky /// - the 'Class' builtin type (same caveat) 4303208600Srdivacky /// - an ObjCObjectType (currently always an ObjCInterfaceType) 4304208600Srdivacky QualType getBaseType() const { return BaseType; } 4305202879Srdivacky 4306208600Srdivacky bool isObjCId() const { 4307208600Srdivacky return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); 4308208600Srdivacky } 4309208600Srdivacky bool isObjCClass() const { 4310208600Srdivacky return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); 4311208600Srdivacky } 4312208600Srdivacky bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } 4313208600Srdivacky bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } 4314208600Srdivacky bool isObjCUnqualifiedIdOrClass() const { 4315208600Srdivacky if (!qual_empty()) return false; 4316208600Srdivacky if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) 4317208600Srdivacky return T->getKind() == BuiltinType::ObjCId || 4318208600Srdivacky T->getKind() == BuiltinType::ObjCClass; 4319208600Srdivacky return false; 4320208600Srdivacky } 4321208600Srdivacky bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } 4322208600Srdivacky bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } 4323198092Srdivacky 4324208600Srdivacky /// Gets the interface declaration for this object type, if the base type 4325208600Srdivacky /// really is an interface. 4326208600Srdivacky ObjCInterfaceDecl *getInterface() const; 4327208600Srdivacky 4328208600Srdivacky typedef ObjCProtocolDecl * const *qual_iterator; 4329208600Srdivacky 4330208600Srdivacky qual_iterator qual_begin() const { return getProtocolStorage(); } 4331208600Srdivacky qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } 4332208600Srdivacky 4333208600Srdivacky bool qual_empty() const { return getNumProtocols() == 0; } 4334208600Srdivacky 4335198092Srdivacky /// getNumProtocols - Return the number of qualifying protocols in this 4336198092Srdivacky /// interface type, or 0 if there are none. 4337218893Sdim unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; } 4338198092Srdivacky 4339208600Srdivacky /// \brief Fetch a protocol by index. 4340203955Srdivacky ObjCProtocolDecl *getProtocol(unsigned I) const { 4341203955Srdivacky assert(I < getNumProtocols() && "Out-of-range protocol access"); 4342203955Srdivacky return qual_begin()[I]; 4343203955Srdivacky } 4344234353Sdim 4345198092Srdivacky bool isSugared() const { return false; } 4346198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4347198092Srdivacky 4348208600Srdivacky static bool classof(const Type *T) { 4349208600Srdivacky return T->getTypeClass() == ObjCObject || 4350208600Srdivacky T->getTypeClass() == ObjCInterface; 4351208600Srdivacky } 4352208600Srdivacky}; 4353208600Srdivacky 4354208600Srdivacky/// ObjCObjectTypeImpl - A class providing a concrete implementation 4355208600Srdivacky/// of ObjCObjectType, so as to not increase the footprint of 4356208600Srdivacky/// ObjCInterfaceType. Code outside of ASTContext and the core type 4357208600Srdivacky/// system should not reference this type. 4358208600Srdivackyclass ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { 4359208600Srdivacky friend class ASTContext; 4360208600Srdivacky 4361208600Srdivacky // If anyone adds fields here, ObjCObjectType::getProtocolStorage() 4362208600Srdivacky // will need to be modified. 4363208600Srdivacky 4364234353Sdim ObjCObjectTypeImpl(QualType Canonical, QualType Base, 4365208600Srdivacky ObjCProtocolDecl * const *Protocols, 4366208600Srdivacky unsigned NumProtocols) 4367208600Srdivacky : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {} 4368208600Srdivacky 4369208600Srdivackypublic: 4370198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID); 4371198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 4372208600Srdivacky QualType Base, 4373234353Sdim ObjCProtocolDecl *const *protocols, 4374234353Sdim unsigned NumProtocols); 4375208600Srdivacky}; 4376198092Srdivacky 4377208600Srdivackyinline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { 4378208600Srdivacky return reinterpret_cast<ObjCProtocolDecl**>( 4379208600Srdivacky static_cast<ObjCObjectTypeImpl*>(this) + 1); 4380208600Srdivacky} 4381203955Srdivacky 4382208600Srdivacky/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for 4383208600Srdivacky/// object oriented design. They basically correspond to C++ classes. There 4384208600Srdivacky/// are two kinds of interface types, normal interfaces like "NSString" and 4385208600Srdivacky/// qualified interfaces, which are qualified with a protocol list like 4386208600Srdivacky/// "NSString<NSCopyable, NSAmazing>". 4387208600Srdivacky/// 4388208600Srdivacky/// ObjCInterfaceType guarantees the following properties when considered 4389208600Srdivacky/// as a subtype of its superclass, ObjCObjectType: 4390208600Srdivacky/// - There are no protocol qualifiers. To reinforce this, code which 4391208600Srdivacky/// tries to invoke the protocol methods via an ObjCInterfaceType will 4392208600Srdivacky/// fail to compile. 4393208600Srdivacky/// - It is its own base type. That is, if T is an ObjCInterfaceType*, 4394208600Srdivacky/// T->getBaseType() == QualType(T, 0). 4395208600Srdivackyclass ObjCInterfaceType : public ObjCObjectType { 4396234353Sdim mutable ObjCInterfaceDecl *Decl; 4397208600Srdivacky 4398208600Srdivacky ObjCInterfaceType(const ObjCInterfaceDecl *D) 4399208600Srdivacky : ObjCObjectType(Nonce_ObjCInterface), 4400208600Srdivacky Decl(const_cast<ObjCInterfaceDecl*>(D)) {} 4401208600Srdivacky friend class ASTContext; // ASTContext creates these. 4402234353Sdim friend class ASTReader; 4403234353Sdim friend class ObjCInterfaceDecl; 4404218893Sdim 4405208600Srdivackypublic: 4406208600Srdivacky /// getDecl - Get the declaration of this interface. 4407208600Srdivacky ObjCInterfaceDecl *getDecl() const { return Decl; } 4408208600Srdivacky 4409208600Srdivacky bool isSugared() const { return false; } 4410208600Srdivacky QualType desugar() const { return QualType(this, 0); } 4411208600Srdivacky 4412198092Srdivacky static bool classof(const Type *T) { 4413198092Srdivacky return T->getTypeClass() == ObjCInterface; 4414198092Srdivacky } 4415208600Srdivacky 4416208600Srdivacky // Nonsense to "hide" certain members of ObjCObjectType within this 4417208600Srdivacky // class. People asking for protocols on an ObjCInterfaceType are 4418208600Srdivacky // not going to get what they want: ObjCInterfaceTypes are 4419208600Srdivacky // guaranteed to have no protocols. 4420208600Srdivacky enum { 4421208600Srdivacky qual_iterator, 4422208600Srdivacky qual_begin, 4423208600Srdivacky qual_end, 4424208600Srdivacky getNumProtocols, 4425208600Srdivacky getProtocol 4426208600Srdivacky }; 4427198092Srdivacky}; 4428198092Srdivacky 4429208600Srdivackyinline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { 4430208600Srdivacky if (const ObjCInterfaceType *T = 4431208600Srdivacky getBaseType()->getAs<ObjCInterfaceType>()) 4432208600Srdivacky return T->getDecl(); 4433208600Srdivacky return 0; 4434208600Srdivacky} 4435208600Srdivacky 4436208600Srdivacky/// ObjCObjectPointerType - Used to represent a pointer to an 4437208600Srdivacky/// Objective C object. These are constructed from pointer 4438208600Srdivacky/// declarators when the pointee type is an ObjCObjectType (or sugar 4439208600Srdivacky/// for one). In addition, the 'id' and 'Class' types are typedefs 4440208600Srdivacky/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>' 4441208600Srdivacky/// are translated into these. 4442194613Sed/// 4443208600Srdivacky/// Pointers to pointers to Objective C objects are still PointerTypes; 4444208600Srdivacky/// only the first level of pointer gets it own type implementation. 4445194613Sedclass ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { 4446208600Srdivacky QualType PointeeType; 4447198092Srdivacky 4448208600Srdivacky ObjCObjectPointerType(QualType Canonical, QualType Pointee) 4449224145Sdim : Type(ObjCObjectPointer, Canonical, false, false, false, false), 4450208600Srdivacky PointeeType(Pointee) {} 4451194613Sed friend class ASTContext; // ASTContext creates these. 4452194613Sed 4453194613Sedpublic: 4454208600Srdivacky /// getPointeeType - Gets the type pointed to by this ObjC pointer. 4455208600Srdivacky /// The result will always be an ObjCObjectType or sugar thereof. 4456198092Srdivacky QualType getPointeeType() const { return PointeeType; } 4457198092Srdivacky 4458208600Srdivacky /// getObjCObjectType - Gets the type pointed to by this ObjC 4459208600Srdivacky /// pointer. This method always returns non-null. 4460208600Srdivacky /// 4461208600Srdivacky /// This method is equivalent to getPointeeType() except that 4462208600Srdivacky /// it discards any typedefs (or other sugar) between this 4463208600Srdivacky /// type and the "outermost" object type. So for: 4464239462Sdim /// \code 4465239462Sdim /// \@class A; \@protocol P; \@protocol Q; 4466208600Srdivacky /// typedef A<P> AP; 4467208600Srdivacky /// typedef A A1; 4468208600Srdivacky /// typedef A1<P> A1P; 4469208600Srdivacky /// typedef A1P<Q> A1PQ; 4470239462Sdim /// \endcode 4471208600Srdivacky /// For 'A*', getObjectType() will return 'A'. 4472208600Srdivacky /// For 'A<P>*', getObjectType() will return 'A<P>'. 4473208600Srdivacky /// For 'AP*', getObjectType() will return 'A<P>'. 4474208600Srdivacky /// For 'A1*', getObjectType() will return 'A'. 4475208600Srdivacky /// For 'A1<P>*', getObjectType() will return 'A1<P>'. 4476208600Srdivacky /// For 'A1P*', getObjectType() will return 'A1<P>'. 4477208600Srdivacky /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because 4478208600Srdivacky /// adding protocols to a protocol-qualified base discards the 4479208600Srdivacky /// old qualifiers (for now). But if it didn't, getObjectType() 4480208600Srdivacky /// would return 'A1P<Q>' (and we'd have to make iterating over 4481208600Srdivacky /// qualifiers more complicated). 4482208600Srdivacky const ObjCObjectType *getObjectType() const { 4483218893Sdim return PointeeType->castAs<ObjCObjectType>(); 4484208600Srdivacky } 4485208600Srdivacky 4486208600Srdivacky /// getInterfaceType - If this pointer points to an Objective C 4487239462Sdim /// \@interface type, gets the type for that interface. Any protocol 4488208600Srdivacky /// qualifiers on the interface are ignored. 4489208600Srdivacky /// 4490208600Srdivacky /// \return null if the base type for this pointer is 'id' or 'Class' 4491198092Srdivacky const ObjCInterfaceType *getInterfaceType() const { 4492208600Srdivacky return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>(); 4493198092Srdivacky } 4494208600Srdivacky 4495239462Sdim /// getInterfaceDecl - If this pointer points to an Objective \@interface 4496208600Srdivacky /// type, gets the declaration for that interface. 4497208600Srdivacky /// 4498208600Srdivacky /// \return null if the base type for this pointer is 'id' or 'Class' 4499198092Srdivacky ObjCInterfaceDecl *getInterfaceDecl() const { 4500208600Srdivacky return getObjectType()->getInterface(); 4501198092Srdivacky } 4502208600Srdivacky 4503208600Srdivacky /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if 4504208600Srdivacky /// its object type is the primitive 'id' type with no protocols. 4505198092Srdivacky bool isObjCIdType() const { 4506208600Srdivacky return getObjectType()->isObjCUnqualifiedId(); 4507198092Srdivacky } 4508208600Srdivacky 4509208600Srdivacky /// isObjCClassType - True if this is equivalent to the 'Class' type, 4510208600Srdivacky /// i.e. if its object tive is the primitive 'Class' type with no protocols. 4511198092Srdivacky bool isObjCClassType() const { 4512208600Srdivacky return getObjectType()->isObjCUnqualifiedClass(); 4513198092Srdivacky } 4514234353Sdim 4515208600Srdivacky /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some 4516208600Srdivacky /// non-empty set of protocols. 4517198092Srdivacky bool isObjCQualifiedIdType() const { 4518208600Srdivacky return getObjectType()->isObjCQualifiedId(); 4519198092Srdivacky } 4520208600Srdivacky 4521208600Srdivacky /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for 4522208600Srdivacky /// some non-empty set of protocols. 4523198092Srdivacky bool isObjCQualifiedClassType() const { 4524208600Srdivacky return getObjectType()->isObjCQualifiedClass(); 4525198092Srdivacky } 4526194613Sed 4527208600Srdivacky /// An iterator over the qualifiers on the object type. Provided 4528208600Srdivacky /// for convenience. This will always iterate over the full set of 4529208600Srdivacky /// protocols on a type, not just those provided directly. 4530208600Srdivacky typedef ObjCObjectType::qual_iterator qual_iterator; 4531208600Srdivacky 4532202879Srdivacky qual_iterator qual_begin() const { 4533208600Srdivacky return getObjectType()->qual_begin(); 4534202879Srdivacky } 4535208600Srdivacky qual_iterator qual_end() const { 4536208600Srdivacky return getObjectType()->qual_end(); 4537202879Srdivacky } 4538208600Srdivacky bool qual_empty() const { return getObjectType()->qual_empty(); } 4539194613Sed 4540208600Srdivacky /// getNumProtocols - Return the number of qualifying protocols on 4541208600Srdivacky /// the object type. 4542208600Srdivacky unsigned getNumProtocols() const { 4543208600Srdivacky return getObjectType()->getNumProtocols(); 4544208600Srdivacky } 4545194613Sed 4546208600Srdivacky /// \brief Retrieve a qualifying protocol by index on the object 4547208600Srdivacky /// type. 4548203955Srdivacky ObjCProtocolDecl *getProtocol(unsigned I) const { 4549208600Srdivacky return getObjectType()->getProtocol(I); 4550203955Srdivacky } 4551234353Sdim 4552198092Srdivacky bool isSugared() const { return false; } 4553198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4554198092Srdivacky 4555208600Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 4556208600Srdivacky Profile(ID, getPointeeType()); 4557208600Srdivacky } 4558208600Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { 4559208600Srdivacky ID.AddPointer(T.getAsOpaquePtr()); 4560208600Srdivacky } 4561198092Srdivacky static bool classof(const Type *T) { 4562198092Srdivacky return T->getTypeClass() == ObjCObjectPointer; 4563194613Sed } 4564194613Sed}; 4565193326Sed 4566226633Sdimclass AtomicType : public Type, public llvm::FoldingSetNode { 4567226633Sdim QualType ValueType; 4568226633Sdim 4569226633Sdim AtomicType(QualType ValTy, QualType Canonical) 4570226633Sdim : Type(Atomic, Canonical, ValTy->isDependentType(), 4571226633Sdim ValTy->isInstantiationDependentType(), 4572226633Sdim ValTy->isVariablyModifiedType(), 4573226633Sdim ValTy->containsUnexpandedParameterPack()), 4574226633Sdim ValueType(ValTy) {} 4575226633Sdim friend class ASTContext; // ASTContext creates these. 4576226633Sdim 4577226633Sdim public: 4578226633Sdim /// getValueType - Gets the type contained by this atomic type, i.e. 4579226633Sdim /// the type returned by performing an atomic load of this atomic type. 4580226633Sdim QualType getValueType() const { return ValueType; } 4581226633Sdim 4582226633Sdim bool isSugared() const { return false; } 4583226633Sdim QualType desugar() const { return QualType(this, 0); } 4584226633Sdim 4585226633Sdim void Profile(llvm::FoldingSetNodeID &ID) { 4586226633Sdim Profile(ID, getValueType()); 4587226633Sdim } 4588226633Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { 4589226633Sdim ID.AddPointer(T.getAsOpaquePtr()); 4590226633Sdim } 4591226633Sdim static bool classof(const Type *T) { 4592226633Sdim return T->getTypeClass() == Atomic; 4593226633Sdim } 4594226633Sdim}; 4595226633Sdim 4596198092Srdivacky/// A qualifier set is used to build a set of qualifiers. 4597198092Srdivackyclass QualifierCollector : public Qualifiers { 4598198092Srdivackypublic: 4599218893Sdim QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {} 4600198092Srdivacky 4601198092Srdivacky /// Collect any qualifiers on the given type and return an 4602218893Sdim /// unqualified type. The qualifiers are assumed to be consistent 4603218893Sdim /// with those already in the type. 4604218893Sdim const Type *strip(QualType type) { 4605218893Sdim addFastQualifiers(type.getLocalFastQualifiers()); 4606218893Sdim if (!type.hasLocalNonFastQualifiers()) 4607218893Sdim return type.getTypePtrUnsafe(); 4608234353Sdim 4609218893Sdim const ExtQuals *extQuals = type.getExtQualsUnsafe(); 4610218893Sdim addConsistentQualifiers(extQuals->getQualifiers()); 4611218893Sdim return extQuals->getBaseType(); 4612198092Srdivacky } 4613198092Srdivacky 4614198092Srdivacky /// Apply the collected qualifiers to the given type. 4615218893Sdim QualType apply(const ASTContext &Context, QualType QT) const; 4616198092Srdivacky 4617198092Srdivacky /// Apply the collected qualifiers to the given type. 4618218893Sdim QualType apply(const ASTContext &Context, const Type* T) const; 4619198092Srdivacky}; 4620198092Srdivacky 4621198092Srdivacky 4622198092Srdivacky// Inline function definitions. 4623198092Srdivacky 4624234353Sdiminline SplitQualType SplitQualType::getSingleStepDesugaredType() const { 4625234353Sdim SplitQualType desugar = 4626234353Sdim Ty->getLocallyUnqualifiedSingleStepDesugaredType().split(); 4627234353Sdim desugar.Quals.addConsistentQualifiers(Quals); 4628234353Sdim return desugar; 4629234353Sdim} 4630234353Sdim 4631218893Sdiminline const Type *QualType::getTypePtr() const { 4632218893Sdim return getCommonPtr()->BaseType; 4633218893Sdim} 4634218893Sdim 4635218893Sdiminline const Type *QualType::getTypePtrOrNull() const { 4636218893Sdim return (isNull() ? 0 : getCommonPtr()->BaseType); 4637218893Sdim} 4638218893Sdim 4639218893Sdiminline SplitQualType QualType::split() const { 4640218893Sdim if (!hasLocalNonFastQualifiers()) 4641218893Sdim return SplitQualType(getTypePtrUnsafe(), 4642218893Sdim Qualifiers::fromFastMask(getLocalFastQualifiers())); 4643218893Sdim 4644218893Sdim const ExtQuals *eq = getExtQualsUnsafe(); 4645218893Sdim Qualifiers qs = eq->getQualifiers(); 4646218893Sdim qs.addFastQualifiers(getLocalFastQualifiers()); 4647218893Sdim return SplitQualType(eq->getBaseType(), qs); 4648218893Sdim} 4649218893Sdim 4650218893Sdiminline Qualifiers QualType::getLocalQualifiers() const { 4651218893Sdim Qualifiers Quals; 4652218893Sdim if (hasLocalNonFastQualifiers()) 4653218893Sdim Quals = getExtQualsUnsafe()->getQualifiers(); 4654218893Sdim Quals.addFastQualifiers(getLocalFastQualifiers()); 4655218893Sdim return Quals; 4656218893Sdim} 4657218893Sdim 4658218893Sdiminline Qualifiers QualType::getQualifiers() const { 4659218893Sdim Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers(); 4660218893Sdim quals.addFastQualifiers(getLocalFastQualifiers()); 4661218893Sdim return quals; 4662218893Sdim} 4663218893Sdim 4664218893Sdiminline unsigned QualType::getCVRQualifiers() const { 4665218893Sdim unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers(); 4666218893Sdim cvr |= getLocalCVRQualifiers(); 4667218893Sdim return cvr; 4668218893Sdim} 4669218893Sdim 4670218893Sdiminline QualType QualType::getCanonicalType() const { 4671218893Sdim QualType canon = getCommonPtr()->CanonicalType; 4672218893Sdim return canon.withFastQualifiers(getLocalFastQualifiers()); 4673218893Sdim} 4674218893Sdim 4675198398Srdivackyinline bool QualType::isCanonical() const { 4676218893Sdim return getTypePtr()->isCanonicalUnqualified(); 4677198398Srdivacky} 4678198398Srdivacky 4679198398Srdivackyinline bool QualType::isCanonicalAsParam() const { 4680218893Sdim if (!isCanonical()) return false; 4681199482Srdivacky if (hasLocalQualifiers()) return false; 4682234353Sdim 4683198398Srdivacky const Type *T = getTypePtr(); 4684218893Sdim if (T->isVariablyModifiedType() && T->hasSizedVLAType()) 4685218893Sdim return false; 4686218893Sdim 4687218893Sdim return !isa<FunctionType>(T) && !isa<ArrayType>(T); 4688198398Srdivacky} 4689198398Srdivacky 4690199482Srdivackyinline bool QualType::isConstQualified() const { 4691234353Sdim return isLocalConstQualified() || 4692218893Sdim getCommonPtr()->CanonicalType.isLocalConstQualified(); 4693199482Srdivacky} 4694199482Srdivacky 4695199482Srdivackyinline bool QualType::isRestrictQualified() const { 4696234353Sdim return isLocalRestrictQualified() || 4697218893Sdim getCommonPtr()->CanonicalType.isLocalRestrictQualified(); 4698199482Srdivacky} 4699199482Srdivacky 4700199482Srdivacky 4701199482Srdivackyinline bool QualType::isVolatileQualified() const { 4702234353Sdim return isLocalVolatileQualified() || 4703218893Sdim getCommonPtr()->CanonicalType.isLocalVolatileQualified(); 4704199482Srdivacky} 4705234353Sdim 4706199482Srdivackyinline bool QualType::hasQualifiers() const { 4707199482Srdivacky return hasLocalQualifiers() || 4708218893Sdim getCommonPtr()->CanonicalType.hasLocalQualifiers(); 4709199482Srdivacky} 4710201361Srdivacky 4711218893Sdiminline QualType QualType::getUnqualifiedType() const { 4712218893Sdim if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) 4713218893Sdim return QualType(getTypePtr(), 0); 4714218893Sdim 4715234353Sdim return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0); 4716201361Srdivacky} 4717251662Sdim 4718218893Sdiminline SplitQualType QualType::getSplitUnqualifiedType() const { 4719218893Sdim if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) 4720218893Sdim return split(); 4721218893Sdim 4722218893Sdim return getSplitUnqualifiedTypeImpl(*this); 4723193326Sed} 4724234353Sdim 4725218893Sdiminline void QualType::removeLocalConst() { 4726218893Sdim removeLocalFastQualifiers(Qualifiers::Const); 4727218893Sdim} 4728198092Srdivacky 4729218893Sdiminline void QualType::removeLocalRestrict() { 4730218893Sdim removeLocalFastQualifiers(Qualifiers::Restrict); 4731193326Sed} 4732193326Sed 4733218893Sdiminline void QualType::removeLocalVolatile() { 4734218893Sdim removeLocalFastQualifiers(Qualifiers::Volatile); 4735193326Sed} 4736193326Sed 4737218893Sdiminline void QualType::removeLocalCVRQualifiers(unsigned Mask) { 4738198092Srdivacky assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits"); 4739218893Sdim assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask); 4740193326Sed 4741198092Srdivacky // Fast path: we don't need to touch the slow qualifiers. 4742218893Sdim removeLocalFastQualifiers(Mask); 4743193326Sed} 4744193326Sed 4745193326Sed/// getAddressSpace - Return the address space of this type. 4746193326Sedinline unsigned QualType::getAddressSpace() const { 4747218893Sdim return getQualifiers().getAddressSpace(); 4748193326Sed} 4749251662Sdim 4750193326Sed/// getObjCGCAttr - Return the gc attribute of this type. 4751198092Srdivackyinline Qualifiers::GC QualType::getObjCGCAttr() const { 4752218893Sdim return getQualifiers().getObjCGCAttr(); 4753193326Sed} 4754198092Srdivacky 4755206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { 4756206084Srdivacky if (const PointerType *PT = t.getAs<PointerType>()) { 4757198092Srdivacky if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>()) 4758206084Srdivacky return FT->getExtInfo(); 4759206084Srdivacky } else if (const FunctionType *FT = t.getAs<FunctionType>()) 4760206084Srdivacky return FT->getExtInfo(); 4761198092Srdivacky 4762206084Srdivacky return FunctionType::ExtInfo(); 4763198092Srdivacky} 4764198092Srdivacky 4765206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { 4766206084Srdivacky return getFunctionExtInfo(*t); 4767202879Srdivacky} 4768202879Srdivacky 4769193326Sed/// isMoreQualifiedThan - Determine whether this type is more 4770193326Sed/// qualified than the Other type. For example, "const volatile int" 4771193326Sed/// is more qualified than "const int", "volatile int", and 4772193326Sed/// "int". However, it is not more qualified than "const volatile 4773193326Sed/// int". 4774218893Sdiminline bool QualType::isMoreQualifiedThan(QualType other) const { 4775218893Sdim Qualifiers myQuals = getQualifiers(); 4776218893Sdim Qualifiers otherQuals = other.getQualifiers(); 4777218893Sdim return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals)); 4778193326Sed} 4779193326Sed 4780193326Sed/// isAtLeastAsQualifiedAs - Determine whether this type is at last 4781193326Sed/// as qualified as the Other type. For example, "const volatile 4782193326Sed/// int" is at least as qualified as "const int", "volatile int", 4783193326Sed/// "int", and "const volatile int". 4784218893Sdiminline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { 4785218893Sdim return getQualifiers().compatiblyIncludes(other.getQualifiers()); 4786193326Sed} 4787193326Sed 4788193326Sed/// getNonReferenceType - If Type is a reference type (e.g., const 4789193326Sed/// int&), returns the type that the reference refers to ("const 4790193326Sed/// int"). Otherwise, returns the type itself. This routine is used 4791193326Sed/// throughout Sema to implement C++ 5p6: 4792193326Sed/// 4793193326Sed/// If an expression initially has the type "reference to T" (8.3.2, 4794193326Sed/// 8.5.3), the type is adjusted to "T" prior to any further 4795193326Sed/// analysis, the expression designates the object or function 4796193326Sed/// denoted by the reference, and the expression is an lvalue. 4797193326Sedinline QualType QualType::getNonReferenceType() const { 4798198092Srdivacky if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>()) 4799193326Sed return RefType->getPointeeType(); 4800193326Sed else 4801193326Sed return *this; 4802193326Sed} 4803193326Sed 4804224145Sdiminline bool QualType::isCForbiddenLValueType() const { 4805224145Sdim return ((getTypePtr()->isVoidType() && !hasQualifiers()) || 4806224145Sdim getTypePtr()->isFunctionType()); 4807224145Sdim} 4808224145Sdim 4809221345Sdim/// \brief Tests whether the type is categorized as a fundamental type. 4810221345Sdim/// 4811221345Sdim/// \returns True for types specified in C++0x [basic.fundamental]. 4812221345Sdiminline bool Type::isFundamentalType() const { 4813221345Sdim return isVoidType() || 4814221345Sdim // FIXME: It's really annoying that we don't have an 4815221345Sdim // 'isArithmeticType()' which agrees with the standard definition. 4816221345Sdim (isArithmeticType() && !isEnumeralType()); 4817221345Sdim} 4818221345Sdim 4819221345Sdim/// \brief Tests whether the type is categorized as a compound type. 4820221345Sdim/// 4821221345Sdim/// \returns True for types specified in C++0x [basic.compound]. 4822221345Sdiminline bool Type::isCompoundType() const { 4823221345Sdim // C++0x [basic.compound]p1: 4824221345Sdim // Compound types can be constructed in the following ways: 4825221345Sdim // -- arrays of objects of a given type [...]; 4826221345Sdim return isArrayType() || 4827221345Sdim // -- functions, which have parameters of given types [...]; 4828221345Sdim isFunctionType() || 4829221345Sdim // -- pointers to void or objects or functions [...]; 4830221345Sdim isPointerType() || 4831221345Sdim // -- references to objects or functions of a given type. [...] 4832221345Sdim isReferenceType() || 4833221345Sdim // -- classes containing a sequence of objects of various types, [...]; 4834221345Sdim isRecordType() || 4835234353Sdim // -- unions, which are classes capable of containing objects of different 4836234353Sdim // types at different times; 4837221345Sdim isUnionType() || 4838221345Sdim // -- enumerations, which comprise a set of named constant values. [...]; 4839221345Sdim isEnumeralType() || 4840221345Sdim // -- pointers to non-static class members, [...]. 4841221345Sdim isMemberPointerType(); 4842221345Sdim} 4843221345Sdim 4844193326Sedinline bool Type::isFunctionType() const { 4845199482Srdivacky return isa<FunctionType>(CanonicalType); 4846193326Sed} 4847193326Sedinline bool Type::isPointerType() const { 4848199482Srdivacky return isa<PointerType>(CanonicalType); 4849193326Sed} 4850198092Srdivackyinline bool Type::isAnyPointerType() const { 4851198092Srdivacky return isPointerType() || isObjCObjectPointerType(); 4852198092Srdivacky} 4853193326Sedinline bool Type::isBlockPointerType() const { 4854199482Srdivacky return isa<BlockPointerType>(CanonicalType); 4855193326Sed} 4856193326Sedinline bool Type::isReferenceType() const { 4857199482Srdivacky return isa<ReferenceType>(CanonicalType); 4858193326Sed} 4859193326Sedinline bool Type::isLValueReferenceType() const { 4860199482Srdivacky return isa<LValueReferenceType>(CanonicalType); 4861193326Sed} 4862193326Sedinline bool Type::isRValueReferenceType() const { 4863199482Srdivacky return isa<RValueReferenceType>(CanonicalType); 4864193326Sed} 4865193326Sedinline bool Type::isFunctionPointerType() const { 4866218893Sdim if (const PointerType *T = getAs<PointerType>()) 4867193326Sed return T->getPointeeType()->isFunctionType(); 4868193326Sed else 4869193326Sed return false; 4870193326Sed} 4871193326Sedinline bool Type::isMemberPointerType() const { 4872199482Srdivacky return isa<MemberPointerType>(CanonicalType); 4873193326Sed} 4874193326Sedinline bool Type::isMemberFunctionPointerType() const { 4875198092Srdivacky if (const MemberPointerType* T = getAs<MemberPointerType>()) 4876212904Sdim return T->isMemberFunctionPointer(); 4877193326Sed else 4878193326Sed return false; 4879193326Sed} 4880212904Sdiminline bool Type::isMemberDataPointerType() const { 4881212904Sdim if (const MemberPointerType* T = getAs<MemberPointerType>()) 4882212904Sdim return T->isMemberDataPointer(); 4883212904Sdim else 4884212904Sdim return false; 4885212904Sdim} 4886193326Sedinline bool Type::isArrayType() const { 4887199482Srdivacky return isa<ArrayType>(CanonicalType); 4888193326Sed} 4889193326Sedinline bool Type::isConstantArrayType() const { 4890199482Srdivacky return isa<ConstantArrayType>(CanonicalType); 4891193326Sed} 4892193326Sedinline bool Type::isIncompleteArrayType() const { 4893199482Srdivacky return isa<IncompleteArrayType>(CanonicalType); 4894193326Sed} 4895193326Sedinline bool Type::isVariableArrayType() const { 4896199482Srdivacky return isa<VariableArrayType>(CanonicalType); 4897193326Sed} 4898193326Sedinline bool Type::isDependentSizedArrayType() const { 4899199482Srdivacky return isa<DependentSizedArrayType>(CanonicalType); 4900193326Sed} 4901218893Sdiminline bool Type::isBuiltinType() const { 4902218893Sdim return isa<BuiltinType>(CanonicalType); 4903218893Sdim} 4904193326Sedinline bool Type::isRecordType() const { 4905199482Srdivacky return isa<RecordType>(CanonicalType); 4906193326Sed} 4907218893Sdiminline bool Type::isEnumeralType() const { 4908218893Sdim return isa<EnumType>(CanonicalType); 4909218893Sdim} 4910193326Sedinline bool Type::isAnyComplexType() const { 4911199482Srdivacky return isa<ComplexType>(CanonicalType); 4912193326Sed} 4913193326Sedinline bool Type::isVectorType() const { 4914199482Srdivacky return isa<VectorType>(CanonicalType); 4915193326Sed} 4916193326Sedinline bool Type::isExtVectorType() const { 4917199482Srdivacky return isa<ExtVectorType>(CanonicalType); 4918193326Sed} 4919194613Sedinline bool Type::isObjCObjectPointerType() const { 4920199482Srdivacky return isa<ObjCObjectPointerType>(CanonicalType); 4921194613Sed} 4922208600Srdivackyinline bool Type::isObjCObjectType() const { 4923208600Srdivacky return isa<ObjCObjectType>(CanonicalType); 4924193326Sed} 4925212904Sdiminline bool Type::isObjCObjectOrInterfaceType() const { 4926234353Sdim return isa<ObjCInterfaceType>(CanonicalType) || 4927212904Sdim isa<ObjCObjectType>(CanonicalType); 4928212904Sdim} 4929226633Sdiminline bool Type::isAtomicType() const { 4930226633Sdim return isa<AtomicType>(CanonicalType); 4931226633Sdim} 4932212904Sdim 4933193326Sedinline bool Type::isObjCQualifiedIdType() const { 4934198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4935194613Sed return OPT->isObjCQualifiedIdType(); 4936194613Sed return false; 4937193326Sed} 4938198092Srdivackyinline bool Type::isObjCQualifiedClassType() const { 4939198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4940198092Srdivacky return OPT->isObjCQualifiedClassType(); 4941198092Srdivacky return false; 4942198092Srdivacky} 4943198092Srdivackyinline bool Type::isObjCIdType() const { 4944198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4945198092Srdivacky return OPT->isObjCIdType(); 4946198092Srdivacky return false; 4947198092Srdivacky} 4948198092Srdivackyinline bool Type::isObjCClassType() const { 4949198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4950198092Srdivacky return OPT->isObjCClassType(); 4951198092Srdivacky return false; 4952198092Srdivacky} 4953199990Srdivackyinline bool Type::isObjCSelType() const { 4954199990Srdivacky if (const PointerType *OPT = getAs<PointerType>()) 4955199990Srdivacky return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); 4956199990Srdivacky return false; 4957199990Srdivacky} 4958198092Srdivackyinline bool Type::isObjCBuiltinType() const { 4959199990Srdivacky return isObjCIdType() || isObjCClassType() || isObjCSelType(); 4960198092Srdivacky} 4961249423Sdim 4962249423Sdiminline bool Type::isImage1dT() const { 4963249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage1d); 4964249423Sdim} 4965249423Sdim 4966249423Sdiminline bool Type::isImage1dArrayT() const { 4967249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage1dArray); 4968249423Sdim} 4969249423Sdim 4970249423Sdiminline bool Type::isImage1dBufferT() const { 4971249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer); 4972249423Sdim} 4973249423Sdim 4974249423Sdiminline bool Type::isImage2dT() const { 4975249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage2d); 4976249423Sdim} 4977249423Sdim 4978249423Sdiminline bool Type::isImage2dArrayT() const { 4979249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage2dArray); 4980249423Sdim} 4981249423Sdim 4982249423Sdiminline bool Type::isImage3dT() const { 4983249423Sdim return isSpecificBuiltinType(BuiltinType::OCLImage3d); 4984249423Sdim} 4985249423Sdim 4986249423Sdiminline bool Type::isSamplerT() const { 4987249423Sdim return isSpecificBuiltinType(BuiltinType::OCLSampler); 4988249423Sdim} 4989249423Sdim 4990249423Sdiminline bool Type::isEventT() const { 4991249423Sdim return isSpecificBuiltinType(BuiltinType::OCLEvent); 4992249423Sdim} 4993249423Sdim 4994249423Sdiminline bool Type::isImageType() const { 4995249423Sdim return isImage3dT() || 4996249423Sdim isImage2dT() || isImage2dArrayT() || 4997249423Sdim isImage1dT() || isImage1dArrayT() || isImage1dBufferT(); 4998249423Sdim} 4999249423Sdim 5000249423Sdiminline bool Type::isOpenCLSpecificType() const { 5001249423Sdim return isSamplerT() || isEventT() || isImageType(); 5002249423Sdim} 5003249423Sdim 5004193326Sedinline bool Type::isTemplateTypeParmType() const { 5005199482Srdivacky return isa<TemplateTypeParmType>(CanonicalType); 5006193326Sed} 5007193326Sed 5008193326Sedinline bool Type::isSpecificBuiltinType(unsigned K) const { 5009198092Srdivacky if (const BuiltinType *BT = getAs<BuiltinType>()) 5010193326Sed if (BT->getKind() == (BuiltinType::Kind) K) 5011193326Sed return true; 5012193326Sed return false; 5013193326Sed} 5014193326Sed 5015218893Sdiminline bool Type::isPlaceholderType() const { 5016226633Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 5017218893Sdim return BT->isPlaceholderType(); 5018218893Sdim return false; 5019218893Sdim} 5020218893Sdim 5021226633Sdiminline const BuiltinType *Type::getAsPlaceholderType() const { 5022226633Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 5023226633Sdim if (BT->isPlaceholderType()) 5024226633Sdim return BT; 5025226633Sdim return 0; 5026226633Sdim} 5027226633Sdim 5028221345Sdiminline bool Type::isSpecificPlaceholderType(unsigned K) const { 5029234353Sdim assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)); 5030221345Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 5031221345Sdim return (BT->getKind() == (BuiltinType::Kind) K); 5032221345Sdim return false; 5033221345Sdim} 5034221345Sdim 5035234353Sdiminline bool Type::isNonOverloadPlaceholderType() const { 5036234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 5037234353Sdim return BT->isNonOverloadPlaceholderType(); 5038234353Sdim return false; 5039234353Sdim} 5040234353Sdim 5041234353Sdiminline bool Type::isVoidType() const { 5042234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5043234353Sdim return BT->getKind() == BuiltinType::Void; 5044234353Sdim return false; 5045234353Sdim} 5046234353Sdim 5047234353Sdiminline bool Type::isHalfType() const { 5048234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5049234353Sdim return BT->getKind() == BuiltinType::Half; 5050234353Sdim // FIXME: Should we allow complex __fp16? Probably not. 5051234353Sdim return false; 5052234353Sdim} 5053234353Sdim 5054234353Sdiminline bool Type::isNullPtrType() const { 5055234353Sdim if (const BuiltinType *BT = getAs<BuiltinType>()) 5056234353Sdim return BT->getKind() == BuiltinType::NullPtr; 5057234353Sdim return false; 5058234353Sdim} 5059234353Sdim 5060234353Sdimextern bool IsEnumDeclComplete(EnumDecl *); 5061234353Sdimextern bool IsEnumDeclScoped(EnumDecl *); 5062234353Sdim 5063234353Sdiminline bool Type::isIntegerType() const { 5064234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5065234353Sdim return BT->getKind() >= BuiltinType::Bool && 5066234353Sdim BT->getKind() <= BuiltinType::Int128; 5067234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { 5068234353Sdim // Incomplete enum types are not treated as integer types. 5069234353Sdim // FIXME: In C++, enum types are never integer types. 5070234353Sdim return IsEnumDeclComplete(ET->getDecl()) && 5071234353Sdim !IsEnumDeclScoped(ET->getDecl()); 5072234353Sdim } 5073234353Sdim return false; 5074234353Sdim} 5075234353Sdim 5076234353Sdiminline bool Type::isScalarType() const { 5077234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5078234353Sdim return BT->getKind() > BuiltinType::Void && 5079234353Sdim BT->getKind() <= BuiltinType::NullPtr; 5080234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) 5081234353Sdim // Enums are scalar types, but only if they are defined. Incomplete enums 5082234353Sdim // are not treated as scalar types. 5083234353Sdim return IsEnumDeclComplete(ET->getDecl()); 5084234353Sdim return isa<PointerType>(CanonicalType) || 5085234353Sdim isa<BlockPointerType>(CanonicalType) || 5086234353Sdim isa<MemberPointerType>(CanonicalType) || 5087234353Sdim isa<ComplexType>(CanonicalType) || 5088234353Sdim isa<ObjCObjectPointerType>(CanonicalType); 5089234353Sdim} 5090234353Sdim 5091234353Sdiminline bool Type::isIntegralOrEnumerationType() const { 5092234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5093234353Sdim return BT->getKind() >= BuiltinType::Bool && 5094234353Sdim BT->getKind() <= BuiltinType::Int128; 5095234353Sdim 5096234353Sdim // Check for a complete enum type; incomplete enum types are not properly an 5097234353Sdim // enumeration type in the sense required here. 5098234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) 5099234353Sdim return IsEnumDeclComplete(ET->getDecl()); 5100234353Sdim 5101234353Sdim return false; 5102234353Sdim} 5103234353Sdim 5104234353Sdiminline bool Type::isBooleanType() const { 5105234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 5106234353Sdim return BT->getKind() == BuiltinType::Bool; 5107234353Sdim return false; 5108234353Sdim} 5109234353Sdim 5110251662Sdiminline bool Type::isUndeducedType() const { 5111251662Sdim const AutoType *AT = getContainedAutoType(); 5112251662Sdim return AT && !AT->isDeduced(); 5113251662Sdim} 5114251662Sdim 5115193326Sed/// \brief Determines whether this is a type for which one can define 5116193326Sed/// an overloaded operator. 5117193326Sedinline bool Type::isOverloadableType() const { 5118193326Sed return isDependentType() || isRecordType() || isEnumeralType(); 5119193326Sed} 5120193326Sed 5121224145Sdim/// \brief Determines whether this type can decay to a pointer type. 5122224145Sdiminline bool Type::canDecayToPointerType() const { 5123224145Sdim return isFunctionType() || isArrayType(); 5124224145Sdim} 5125224145Sdim 5126193326Sedinline bool Type::hasPointerRepresentation() const { 5127193326Sed return (isPointerType() || isReferenceType() || isBlockPointerType() || 5128208600Srdivacky isObjCObjectPointerType() || isNullPtrType()); 5129193326Sed} 5130193326Sed 5131193326Sedinline bool Type::hasObjCPointerRepresentation() const { 5132208600Srdivacky return isObjCObjectPointerType(); 5133193326Sed} 5134193326Sed 5135218893Sdiminline const Type *Type::getBaseElementTypeUnsafe() const { 5136218893Sdim const Type *type = this; 5137218893Sdim while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) 5138218893Sdim type = arrayType->getElementType().getTypePtr(); 5139218893Sdim return type; 5140218893Sdim} 5141218893Sdim 5142193326Sed/// Insertion operator for diagnostics. This allows sending QualType's into a 5143193326Sed/// diagnostic with <<. 5144193326Sedinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 5145193326Sed QualType T) { 5146193326Sed DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), 5147226633Sdim DiagnosticsEngine::ak_qualtype); 5148193326Sed return DB; 5149193326Sed} 5150193326Sed 5151206084Srdivacky/// Insertion operator for partial diagnostics. This allows sending QualType's 5152206084Srdivacky/// into a diagnostic with <<. 5153206084Srdivackyinline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 5154206084Srdivacky QualType T) { 5155206084Srdivacky PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), 5156226633Sdim DiagnosticsEngine::ak_qualtype); 5157206084Srdivacky return PD; 5158206084Srdivacky} 5159206084Srdivacky 5160199482Srdivacky// Helper class template that is used by Type::getAs to ensure that one does 5161199482Srdivacky// not try to look through a qualified type to get to an array type. 5162199482Srdivackytemplate<typename T, 5163199482Srdivacky bool isArrayType = (llvm::is_same<T, ArrayType>::value || 5164199482Srdivacky llvm::is_base_of<ArrayType, T>::value)> 5165199482Srdivackystruct ArrayType_cannot_be_used_with_getAs { }; 5166234353Sdim 5167199482Srdivackytemplate<typename T> 5168199482Srdivackystruct ArrayType_cannot_be_used_with_getAs<T, true>; 5169234353Sdim 5170239462Sdim// Member-template getAs<specific type>'. 5171198092Srdivackytemplate <typename T> const T *Type::getAs() const { 5172199482Srdivacky ArrayType_cannot_be_used_with_getAs<T> at; 5173199482Srdivacky (void)at; 5174234353Sdim 5175198092Srdivacky // If this is directly a T type, return it. 5176198092Srdivacky if (const T *Ty = dyn_cast<T>(this)) 5177198092Srdivacky return Ty; 5178198092Srdivacky 5179198092Srdivacky // If the canonical form of this type isn't the right kind, reject it. 5180198092Srdivacky if (!isa<T>(CanonicalType)) 5181198092Srdivacky return 0; 5182198092Srdivacky 5183198092Srdivacky // If this is a typedef for the type, strip the typedef off without 5184198092Srdivacky // losing all typedef information. 5185198092Srdivacky return cast<T>(getUnqualifiedDesugaredType()); 5186198092Srdivacky} 5187198092Srdivacky 5188218893Sdiminline const ArrayType *Type::getAsArrayTypeUnsafe() const { 5189218893Sdim // If this is directly an array type, return it. 5190218893Sdim if (const ArrayType *arr = dyn_cast<ArrayType>(this)) 5191218893Sdim return arr; 5192218893Sdim 5193218893Sdim // If the canonical form of this type isn't the right kind, reject it. 5194218893Sdim if (!isa<ArrayType>(CanonicalType)) 5195218893Sdim return 0; 5196218893Sdim 5197218893Sdim // If this is a typedef for the type, strip the typedef off without 5198218893Sdim // losing all typedef information. 5199218893Sdim return cast<ArrayType>(getUnqualifiedDesugaredType()); 5200218893Sdim} 5201218893Sdim 5202218893Sdimtemplate <typename T> const T *Type::castAs() const { 5203218893Sdim ArrayType_cannot_be_used_with_getAs<T> at; 5204218893Sdim (void) at; 5205218893Sdim 5206218893Sdim assert(isa<T>(CanonicalType)); 5207218893Sdim if (const T *ty = dyn_cast<T>(this)) return ty; 5208218893Sdim return cast<T>(getUnqualifiedDesugaredType()); 5209218893Sdim} 5210218893Sdim 5211218893Sdiminline const ArrayType *Type::castAsArrayTypeUnsafe() const { 5212218893Sdim assert(isa<ArrayType>(CanonicalType)); 5213218893Sdim if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr; 5214218893Sdim return cast<ArrayType>(getUnqualifiedDesugaredType()); 5215218893Sdim} 5216218893Sdim 5217193326Sed} // end namespace clang 5218193326Sed 5219193326Sed#endif 5220