Type.h revision 243830
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 17193326Sed#include "clang/Basic/Diagnostic.h" 18221345Sdim#include "clang/Basic/ExceptionSpecificationType.h" 19193326Sed#include "clang/Basic/IdentifierTable.h" 20203955Srdivacky#include "clang/Basic/Linkage.h" 21206084Srdivacky#include "clang/Basic/PartialDiagnostic.h" 22218893Sdim#include "clang/Basic/Visibility.h" 23243830Sdim#include "clang/Basic/Specifiers.h" 24193326Sed#include "clang/AST/NestedNameSpecifier.h" 25193326Sed#include "clang/AST/TemplateName.h" 26198092Srdivacky#include "llvm/Support/type_traits.h" 27226633Sdim#include "llvm/Support/ErrorHandling.h" 28193326Sed#include "llvm/ADT/APSInt.h" 29193326Sed#include "llvm/ADT/FoldingSet.h" 30218893Sdim#include "llvm/ADT/Optional.h" 31193326Sed#include "llvm/ADT/PointerIntPair.h" 32193326Sed#include "llvm/ADT/PointerUnion.h" 33239462Sdim#include "llvm/ADT/Twine.h" 34226633Sdim#include "clang/Basic/LLVM.h" 35193326Sed 36198092Srdivackynamespace clang { 37198092Srdivacky enum { 38218893Sdim TypeAlignmentInBits = 4, 39198092Srdivacky TypeAlignment = 1 << TypeAlignmentInBits 40198092Srdivacky }; 41200583Srdivacky class Type; 42200583Srdivacky class ExtQuals; 43200583Srdivacky class QualType; 44198092Srdivacky} 45193326Sed 46193326Sednamespace llvm { 47193326Sed template <typename T> 48193326Sed class PointerLikeTypeTraits; 49193326Sed template<> 50193326Sed class PointerLikeTypeTraits< ::clang::Type*> { 51193326Sed public: 52193326Sed static inline void *getAsVoidPointer(::clang::Type *P) { return P; } 53193326Sed static inline ::clang::Type *getFromVoidPointer(void *P) { 54193326Sed return static_cast< ::clang::Type*>(P); 55193326Sed } 56198092Srdivacky enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; 57193326Sed }; 58198092Srdivacky template<> 59198092Srdivacky class PointerLikeTypeTraits< ::clang::ExtQuals*> { 60198092Srdivacky public: 61198092Srdivacky static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } 62198092Srdivacky static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { 63198092Srdivacky return static_cast< ::clang::ExtQuals*>(P); 64198092Srdivacky } 65198092Srdivacky enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; 66198092Srdivacky }; 67200583Srdivacky 68200583Srdivacky template <> 69200583Srdivacky struct isPodLike<clang::QualType> { static const bool value = true; }; 70193326Sed} 71193326Sed 72193326Sednamespace clang { 73193326Sed class ASTContext; 74221345Sdim class TypedefNameDecl; 75193326Sed class TemplateDecl; 76193326Sed class TemplateTypeParmDecl; 77193326Sed class NonTypeTemplateParmDecl; 78193326Sed class TemplateTemplateParmDecl; 79193326Sed class TagDecl; 80193326Sed class RecordDecl; 81193326Sed class CXXRecordDecl; 82193326Sed class EnumDecl; 83193326Sed class FieldDecl; 84234982Sdim class FunctionDecl; 85193326Sed class ObjCInterfaceDecl; 86193326Sed class ObjCProtocolDecl; 87193326Sed class ObjCMethodDecl; 88200583Srdivacky class UnresolvedUsingTypenameDecl; 89193326Sed class Expr; 90193326Sed class Stmt; 91193326Sed class SourceLocation; 92193326Sed class StmtIteratorBase; 93193326Sed class TemplateArgument; 94198893Srdivacky class TemplateArgumentLoc; 95199990Srdivacky class TemplateArgumentListInfo; 96208600Srdivacky class ElaboratedType; 97218893Sdim class ExtQuals; 98218893Sdim class ExtQualsTypeCommonBase; 99198092Srdivacky struct PrintingPolicy; 100193326Sed 101234353Sdim template <typename> class CanQual; 102204643Srdivacky typedef CanQual<Type> CanQualType; 103204643Srdivacky 104193326Sed // Provide forward declarations for all of the *Type classes 105193326Sed#define TYPE(Class, Base) class Class##Type; 106193326Sed#include "clang/AST/TypeNodes.def" 107193326Sed 108198092Srdivacky/// Qualifiers - The collection of all-type qualifiers we support. 109198092Srdivacky/// Clang supports five independent qualifiers: 110198092Srdivacky/// * C99: const, volatile, and restrict 111198092Srdivacky/// * Embedded C (TR18037): address spaces 112198092Srdivacky/// * Objective C: the GC attributes (none, weak, or strong) 113198092Srdivackyclass Qualifiers { 114193326Sedpublic: 115198092Srdivacky enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. 116193326Sed Const = 0x1, 117193326Sed Restrict = 0x2, 118193326Sed Volatile = 0x4, 119198092Srdivacky CVRMask = Const | Volatile | Restrict 120193326Sed }; 121198092Srdivacky 122198092Srdivacky enum GC { 123193326Sed GCNone = 0, 124193326Sed Weak, 125193326Sed Strong 126193326Sed }; 127198092Srdivacky 128224145Sdim enum ObjCLifetime { 129224145Sdim /// There is no lifetime qualification on this type. 130224145Sdim OCL_None, 131224145Sdim 132224145Sdim /// This object can be modified without requiring retains or 133224145Sdim /// releases. 134224145Sdim OCL_ExplicitNone, 135224145Sdim 136224145Sdim /// Assigning into this object requires the old value to be 137224145Sdim /// released and the new value to be retained. The timing of the 138224145Sdim /// release of the old value is inexact: it may be moved to 139224145Sdim /// immediately after the last known point where the value is 140224145Sdim /// live. 141224145Sdim OCL_Strong, 142224145Sdim 143224145Sdim /// Reading or writing from this object requires a barrier call. 144224145Sdim OCL_Weak, 145224145Sdim 146224145Sdim /// Assigning into this object requires a lifetime extension. 147224145Sdim OCL_Autoreleasing 148224145Sdim }; 149224145Sdim 150198092Srdivacky enum { 151198092Srdivacky /// The maximum supported address space number. 152198092Srdivacky /// 24 bits should be enough for anyone. 153198092Srdivacky MaxAddressSpace = 0xffffffu, 154198092Srdivacky 155198092Srdivacky /// The width of the "fast" qualifier mask. 156218893Sdim FastWidth = 3, 157198092Srdivacky 158198092Srdivacky /// The fast qualifier mask. 159198092Srdivacky FastMask = (1 << FastWidth) - 1 160198092Srdivacky }; 161198092Srdivacky 162198092Srdivacky Qualifiers() : Mask(0) {} 163198092Srdivacky 164243830Sdim /// \brief Returns the common set of qualifiers while removing them from 165243830Sdim /// the given sets. 166243830Sdim static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { 167243830Sdim // If both are only CVR-qualified, bit operations are sufficient. 168243830Sdim if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { 169243830Sdim Qualifiers Q; 170243830Sdim Q.Mask = L.Mask & R.Mask; 171243830Sdim L.Mask &= ~Q.Mask; 172243830Sdim R.Mask &= ~Q.Mask; 173243830Sdim return Q; 174243830Sdim } 175243830Sdim 176243830Sdim Qualifiers Q; 177243830Sdim unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); 178243830Sdim Q.addCVRQualifiers(CommonCRV); 179243830Sdim L.removeCVRQualifiers(CommonCRV); 180243830Sdim R.removeCVRQualifiers(CommonCRV); 181243830Sdim 182243830Sdim if (L.getObjCGCAttr() == R.getObjCGCAttr()) { 183243830Sdim Q.setObjCGCAttr(L.getObjCGCAttr()); 184243830Sdim L.removeObjCGCAttr(); 185243830Sdim R.removeObjCGCAttr(); 186243830Sdim } 187243830Sdim 188243830Sdim if (L.getObjCLifetime() == R.getObjCLifetime()) { 189243830Sdim Q.setObjCLifetime(L.getObjCLifetime()); 190243830Sdim L.removeObjCLifetime(); 191243830Sdim R.removeObjCLifetime(); 192243830Sdim } 193243830Sdim 194243830Sdim if (L.getAddressSpace() == R.getAddressSpace()) { 195243830Sdim Q.setAddressSpace(L.getAddressSpace()); 196243830Sdim L.removeAddressSpace(); 197243830Sdim R.removeAddressSpace(); 198243830Sdim } 199243830Sdim return Q; 200243830Sdim } 201243830Sdim 202198092Srdivacky static Qualifiers fromFastMask(unsigned Mask) { 203198092Srdivacky Qualifiers Qs; 204198092Srdivacky Qs.addFastQualifiers(Mask); 205198092Srdivacky return Qs; 206198092Srdivacky } 207198092Srdivacky 208198092Srdivacky static Qualifiers fromCVRMask(unsigned CVR) { 209198092Srdivacky Qualifiers Qs; 210198092Srdivacky Qs.addCVRQualifiers(CVR); 211198092Srdivacky return Qs; 212198092Srdivacky } 213198092Srdivacky 214198092Srdivacky // Deserialize qualifiers from an opaque representation. 215198092Srdivacky static Qualifiers fromOpaqueValue(unsigned opaque) { 216198092Srdivacky Qualifiers Qs; 217198092Srdivacky Qs.Mask = opaque; 218198092Srdivacky return Qs; 219198092Srdivacky } 220198092Srdivacky 221198092Srdivacky // Serialize these qualifiers into an opaque representation. 222198092Srdivacky unsigned getAsOpaqueValue() const { 223198092Srdivacky return Mask; 224198092Srdivacky } 225198092Srdivacky 226198092Srdivacky bool hasConst() const { return Mask & Const; } 227198092Srdivacky void setConst(bool flag) { 228198092Srdivacky Mask = (Mask & ~Const) | (flag ? Const : 0); 229198092Srdivacky } 230198092Srdivacky void removeConst() { Mask &= ~Const; } 231198092Srdivacky void addConst() { Mask |= Const; } 232198092Srdivacky 233198092Srdivacky bool hasVolatile() const { return Mask & Volatile; } 234198092Srdivacky void setVolatile(bool flag) { 235198092Srdivacky Mask = (Mask & ~Volatile) | (flag ? Volatile : 0); 236198092Srdivacky } 237198092Srdivacky void removeVolatile() { Mask &= ~Volatile; } 238198092Srdivacky void addVolatile() { Mask |= Volatile; } 239198092Srdivacky 240198092Srdivacky bool hasRestrict() const { return Mask & Restrict; } 241198092Srdivacky void setRestrict(bool flag) { 242198092Srdivacky Mask = (Mask & ~Restrict) | (flag ? Restrict : 0); 243198092Srdivacky } 244198092Srdivacky void removeRestrict() { Mask &= ~Restrict; } 245198092Srdivacky void addRestrict() { Mask |= Restrict; } 246198092Srdivacky 247198092Srdivacky bool hasCVRQualifiers() const { return getCVRQualifiers(); } 248198092Srdivacky unsigned getCVRQualifiers() const { return Mask & CVRMask; } 249198092Srdivacky void setCVRQualifiers(unsigned mask) { 250198092Srdivacky assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); 251198092Srdivacky Mask = (Mask & ~CVRMask) | mask; 252198092Srdivacky } 253198092Srdivacky void removeCVRQualifiers(unsigned mask) { 254198092Srdivacky assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); 255198092Srdivacky Mask &= ~mask; 256198092Srdivacky } 257198092Srdivacky void removeCVRQualifiers() { 258198092Srdivacky removeCVRQualifiers(CVRMask); 259198092Srdivacky } 260198092Srdivacky void addCVRQualifiers(unsigned mask) { 261198092Srdivacky assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); 262198092Srdivacky Mask |= mask; 263198092Srdivacky } 264198092Srdivacky 265198092Srdivacky bool hasObjCGCAttr() const { return Mask & GCAttrMask; } 266198092Srdivacky GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } 267198092Srdivacky void setObjCGCAttr(GC type) { 268198092Srdivacky Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); 269198092Srdivacky } 270198092Srdivacky void removeObjCGCAttr() { setObjCGCAttr(GCNone); } 271198092Srdivacky void addObjCGCAttr(GC type) { 272198092Srdivacky assert(type); 273198092Srdivacky setObjCGCAttr(type); 274198092Srdivacky } 275221345Sdim Qualifiers withoutObjCGCAttr() const { 276221345Sdim Qualifiers qs = *this; 277221345Sdim qs.removeObjCGCAttr(); 278221345Sdim return qs; 279221345Sdim } 280234353Sdim Qualifiers withoutObjCLifetime() const { 281224145Sdim Qualifiers qs = *this; 282224145Sdim qs.removeObjCLifetime(); 283224145Sdim return qs; 284224145Sdim } 285198092Srdivacky 286224145Sdim bool hasObjCLifetime() const { return Mask & LifetimeMask; } 287224145Sdim ObjCLifetime getObjCLifetime() const { 288224145Sdim return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); 289224145Sdim } 290224145Sdim void setObjCLifetime(ObjCLifetime type) { 291224145Sdim Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); 292224145Sdim } 293224145Sdim void removeObjCLifetime() { setObjCLifetime(OCL_None); } 294224145Sdim void addObjCLifetime(ObjCLifetime type) { 295224145Sdim assert(type); 296234353Sdim assert(!hasObjCLifetime()); 297234353Sdim Mask |= (type << LifetimeShift); 298224145Sdim } 299224145Sdim 300224145Sdim /// True if the lifetime is neither None or ExplicitNone. 301224145Sdim bool hasNonTrivialObjCLifetime() const { 302224145Sdim ObjCLifetime lifetime = getObjCLifetime(); 303224145Sdim return (lifetime > OCL_ExplicitNone); 304224145Sdim } 305224145Sdim 306224145Sdim /// True if the lifetime is either strong or weak. 307224145Sdim bool hasStrongOrWeakObjCLifetime() const { 308224145Sdim ObjCLifetime lifetime = getObjCLifetime(); 309224145Sdim return (lifetime == OCL_Strong || lifetime == OCL_Weak); 310224145Sdim } 311234353Sdim 312198092Srdivacky bool hasAddressSpace() const { return Mask & AddressSpaceMask; } 313198092Srdivacky unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; } 314198092Srdivacky void setAddressSpace(unsigned space) { 315198092Srdivacky assert(space <= MaxAddressSpace); 316198092Srdivacky Mask = (Mask & ~AddressSpaceMask) 317198092Srdivacky | (((uint32_t) space) << AddressSpaceShift); 318198092Srdivacky } 319198092Srdivacky void removeAddressSpace() { setAddressSpace(0); } 320198092Srdivacky void addAddressSpace(unsigned space) { 321198092Srdivacky assert(space); 322198092Srdivacky setAddressSpace(space); 323198092Srdivacky } 324198092Srdivacky 325198092Srdivacky // Fast qualifiers are those that can be allocated directly 326198092Srdivacky // on a QualType object. 327198092Srdivacky bool hasFastQualifiers() const { return getFastQualifiers(); } 328198092Srdivacky unsigned getFastQualifiers() const { return Mask & FastMask; } 329198092Srdivacky void setFastQualifiers(unsigned mask) { 330198092Srdivacky assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); 331198092Srdivacky Mask = (Mask & ~FastMask) | mask; 332198092Srdivacky } 333198092Srdivacky void removeFastQualifiers(unsigned mask) { 334198092Srdivacky assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); 335198092Srdivacky Mask &= ~mask; 336198092Srdivacky } 337198092Srdivacky void removeFastQualifiers() { 338198092Srdivacky removeFastQualifiers(FastMask); 339198092Srdivacky } 340198092Srdivacky void addFastQualifiers(unsigned mask) { 341198092Srdivacky assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); 342198092Srdivacky Mask |= mask; 343198092Srdivacky } 344198092Srdivacky 345198092Srdivacky /// hasNonFastQualifiers - Return true if the set contains any 346198092Srdivacky /// qualifiers which require an ExtQuals node to be allocated. 347198092Srdivacky bool hasNonFastQualifiers() const { return Mask & ~FastMask; } 348198092Srdivacky Qualifiers getNonFastQualifiers() const { 349198092Srdivacky Qualifiers Quals = *this; 350198092Srdivacky Quals.setFastQualifiers(0); 351198092Srdivacky return Quals; 352198092Srdivacky } 353198092Srdivacky 354198092Srdivacky /// hasQualifiers - Return true if the set contains any qualifiers. 355198092Srdivacky bool hasQualifiers() const { return Mask; } 356198092Srdivacky bool empty() const { return !Mask; } 357198092Srdivacky 358198092Srdivacky /// \brief Add the qualifiers from the given set to this set. 359198092Srdivacky void addQualifiers(Qualifiers Q) { 360198092Srdivacky // If the other set doesn't have any non-boolean qualifiers, just 361198092Srdivacky // bit-or it in. 362198092Srdivacky if (!(Q.Mask & ~CVRMask)) 363198092Srdivacky Mask |= Q.Mask; 364198092Srdivacky else { 365198092Srdivacky Mask |= (Q.Mask & CVRMask); 366198092Srdivacky if (Q.hasAddressSpace()) 367198092Srdivacky addAddressSpace(Q.getAddressSpace()); 368198092Srdivacky if (Q.hasObjCGCAttr()) 369198092Srdivacky addObjCGCAttr(Q.getObjCGCAttr()); 370224145Sdim if (Q.hasObjCLifetime()) 371224145Sdim addObjCLifetime(Q.getObjCLifetime()); 372198092Srdivacky } 373198092Srdivacky } 374198092Srdivacky 375243830Sdim /// \brief Remove the qualifiers from the given set from this set. 376243830Sdim void removeQualifiers(Qualifiers Q) { 377243830Sdim // If the other set doesn't have any non-boolean qualifiers, just 378243830Sdim // bit-and the inverse in. 379243830Sdim if (!(Q.Mask & ~CVRMask)) 380243830Sdim Mask &= ~Q.Mask; 381243830Sdim else { 382243830Sdim Mask &= ~(Q.Mask & CVRMask); 383243830Sdim if (getObjCGCAttr() == Q.getObjCGCAttr()) 384243830Sdim removeObjCGCAttr(); 385243830Sdim if (getObjCLifetime() == Q.getObjCLifetime()) 386243830Sdim removeObjCLifetime(); 387243830Sdim if (getAddressSpace() == Q.getAddressSpace()) 388243830Sdim removeAddressSpace(); 389243830Sdim } 390243830Sdim } 391243830Sdim 392218893Sdim /// \brief Add the qualifiers from the given set to this set, given that 393218893Sdim /// they don't conflict. 394218893Sdim void addConsistentQualifiers(Qualifiers qs) { 395218893Sdim assert(getAddressSpace() == qs.getAddressSpace() || 396218893Sdim !hasAddressSpace() || !qs.hasAddressSpace()); 397218893Sdim assert(getObjCGCAttr() == qs.getObjCGCAttr() || 398218893Sdim !hasObjCGCAttr() || !qs.hasObjCGCAttr()); 399224145Sdim assert(getObjCLifetime() == qs.getObjCLifetime() || 400224145Sdim !hasObjCLifetime() || !qs.hasObjCLifetime()); 401218893Sdim Mask |= qs.Mask; 402218893Sdim } 403218893Sdim 404218893Sdim /// \brief Determines if these qualifiers compatibly include another set. 405218893Sdim /// Generally this answers the question of whether an object with the other 406218893Sdim /// qualifiers can be safely used as an object with these qualifiers. 407218893Sdim bool compatiblyIncludes(Qualifiers other) const { 408234353Sdim return 409223017Sdim // Address spaces must match exactly. 410223017Sdim getAddressSpace() == other.getAddressSpace() && 411223017Sdim // ObjC GC qualifiers can match, be added, or be removed, but can't be 412223017Sdim // changed. 413223017Sdim (getObjCGCAttr() == other.getObjCGCAttr() || 414223017Sdim !hasObjCGCAttr() || !other.hasObjCGCAttr()) && 415224145Sdim // ObjC lifetime qualifiers must match exactly. 416224145Sdim getObjCLifetime() == other.getObjCLifetime() && 417223017Sdim // CVR qualifiers may subset. 418223017Sdim (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); 419218893Sdim } 420218893Sdim 421224145Sdim /// \brief Determines if these qualifiers compatibly include another set of 422224145Sdim /// qualifiers from the narrow perspective of Objective-C ARC lifetime. 423224145Sdim /// 424224145Sdim /// One set of Objective-C lifetime qualifiers compatibly includes the other 425234353Sdim /// if the lifetime qualifiers match, or if both are non-__weak and the 426224145Sdim /// including set also contains the 'const' qualifier. 427224145Sdim bool compatiblyIncludesObjCLifetime(Qualifiers other) const { 428224145Sdim if (getObjCLifetime() == other.getObjCLifetime()) 429224145Sdim return true; 430234353Sdim 431224145Sdim if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) 432224145Sdim return false; 433234353Sdim 434224145Sdim return hasConst(); 435224145Sdim } 436234353Sdim 437221345Sdim /// \brief Determine whether this set of qualifiers is a strict superset of 438221345Sdim /// another set of qualifiers, not considering qualifier compatibility. 439221345Sdim bool isStrictSupersetOf(Qualifiers Other) const; 440234353Sdim 441198092Srdivacky bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } 442198092Srdivacky bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } 443198092Srdivacky 444198092Srdivacky operator bool() const { return hasQualifiers(); } 445198092Srdivacky 446198092Srdivacky Qualifiers &operator+=(Qualifiers R) { 447198092Srdivacky addQualifiers(R); 448198092Srdivacky return *this; 449198092Srdivacky } 450198092Srdivacky 451198092Srdivacky // Union two qualifier sets. If an enumerated qualifier appears 452198092Srdivacky // in both sets, use the one from the right. 453198092Srdivacky friend Qualifiers operator+(Qualifiers L, Qualifiers R) { 454198092Srdivacky L += R; 455198092Srdivacky return L; 456198092Srdivacky } 457234353Sdim 458212904Sdim Qualifiers &operator-=(Qualifiers R) { 459243830Sdim removeQualifiers(R); 460212904Sdim return *this; 461212904Sdim } 462198092Srdivacky 463212904Sdim /// \brief Compute the difference between two qualifier sets. 464212904Sdim friend Qualifiers operator-(Qualifiers L, Qualifiers R) { 465212904Sdim L -= R; 466212904Sdim return L; 467212904Sdim } 468234353Sdim 469198092Srdivacky std::string getAsString() const; 470239462Sdim std::string getAsString(const PrintingPolicy &Policy) const; 471198092Srdivacky 472239462Sdim bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; 473239462Sdim void print(raw_ostream &OS, const PrintingPolicy &Policy, 474239462Sdim bool appendSpaceIfNonEmpty = false) const; 475239462Sdim 476198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) const { 477198092Srdivacky ID.AddInteger(Mask); 478198092Srdivacky } 479198092Srdivacky 480198092Srdivackyprivate: 481198092Srdivacky 482224145Sdim // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31| 483224145Sdim // |C R V|GCAttr|Lifetime|AddressSpace| 484198092Srdivacky uint32_t Mask; 485198092Srdivacky 486198092Srdivacky static const uint32_t GCAttrMask = 0x18; 487198092Srdivacky static const uint32_t GCAttrShift = 3; 488224145Sdim static const uint32_t LifetimeMask = 0xE0; 489224145Sdim static const uint32_t LifetimeShift = 5; 490224145Sdim static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask); 491224145Sdim static const uint32_t AddressSpaceShift = 8; 492198092Srdivacky}; 493198092Srdivacky 494234353Sdim/// A std::pair-like structure for storing a qualified type split 495234353Sdim/// into its local qualifiers and its locally-unqualified type. 496234353Sdimstruct SplitQualType { 497234353Sdim /// The locally-unqualified type. 498234353Sdim const Type *Ty; 499202879Srdivacky 500234353Sdim /// The local qualifiers. 501234353Sdim Qualifiers Quals; 502234353Sdim 503234353Sdim SplitQualType() : Ty(0), Quals() {} 504234353Sdim SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} 505234353Sdim 506234353Sdim SplitQualType getSingleStepDesugaredType() const; // end of this file 507234353Sdim 508234353Sdim // Make llvm::tie work. 509234353Sdim operator std::pair<const Type *,Qualifiers>() const { 510234353Sdim return std::pair<const Type *,Qualifiers>(Ty, Quals); 511234353Sdim } 512234353Sdim 513234353Sdim friend bool operator==(SplitQualType a, SplitQualType b) { 514234353Sdim return a.Ty == b.Ty && a.Quals == b.Quals; 515234353Sdim } 516234353Sdim friend bool operator!=(SplitQualType a, SplitQualType b) { 517234353Sdim return a.Ty != b.Ty || a.Quals != b.Quals; 518234353Sdim } 519234353Sdim}; 520234353Sdim 521198092Srdivacky/// QualType - For efficiency, we don't store CV-qualified types as nodes on 522198092Srdivacky/// their own: instead each reference to a type stores the qualifiers. This 523198092Srdivacky/// greatly reduces the number of nodes we need to allocate for types (for 524198092Srdivacky/// example we only need one for 'int', 'const int', 'volatile int', 525198092Srdivacky/// 'const volatile int', etc). 526198092Srdivacky/// 527198092Srdivacky/// As an added efficiency bonus, instead of making this a pair, we 528198092Srdivacky/// just store the two bits we care about in the low bits of the 529198092Srdivacky/// pointer. To handle the packing/unpacking, we make QualType be a 530198092Srdivacky/// simple wrapper class that acts like a smart pointer. A third bit 531198092Srdivacky/// indicates whether there are extended qualifiers present, in which 532198092Srdivacky/// case the pointer points to a special structure. 533198092Srdivackyclass QualType { 534198092Srdivacky // Thankfully, these are efficiently composable. 535198092Srdivacky llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>, 536198092Srdivacky Qualifiers::FastWidth> Value; 537198092Srdivacky 538198092Srdivacky const ExtQuals *getExtQualsUnsafe() const { 539198092Srdivacky return Value.getPointer().get<const ExtQuals*>(); 540198092Srdivacky } 541198092Srdivacky 542198092Srdivacky const Type *getTypePtrUnsafe() const { 543198092Srdivacky return Value.getPointer().get<const Type*>(); 544198092Srdivacky } 545198092Srdivacky 546218893Sdim const ExtQualsTypeCommonBase *getCommonPtr() const { 547218893Sdim assert(!isNull() && "Cannot retrieve a NULL type pointer"); 548218893Sdim uintptr_t CommonPtrVal 549218893Sdim = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); 550218893Sdim CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); 551218893Sdim return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); 552218893Sdim } 553218893Sdim 554198092Srdivacky friend class QualifierCollector; 555198092Srdivackypublic: 556193326Sed QualType() {} 557198092Srdivacky 558193326Sed QualType(const Type *Ptr, unsigned Quals) 559198092Srdivacky : Value(Ptr, Quals) {} 560198092Srdivacky QualType(const ExtQuals *Ptr, unsigned Quals) 561198092Srdivacky : Value(Ptr, Quals) {} 562193326Sed 563199482Srdivacky unsigned getLocalFastQualifiers() const { return Value.getInt(); } 564199482Srdivacky void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } 565198092Srdivacky 566198092Srdivacky /// Retrieves a pointer to the underlying (unqualified) type. 567218893Sdim /// 568218893Sdim /// This function requires that the type not be NULL. If the type might be 569218893Sdim /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). 570218893Sdim const Type *getTypePtr() const; 571234353Sdim 572218893Sdim const Type *getTypePtrOrNull() const; 573198092Srdivacky 574226633Sdim /// Retrieves a pointer to the name of the base type. 575226633Sdim const IdentifierInfo *getBaseTypeIdentifier() const; 576226633Sdim 577218893Sdim /// Divides a QualType into its unqualified type and a set of local 578218893Sdim /// qualifiers. 579218893Sdim SplitQualType split() const; 580218893Sdim 581193326Sed void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } 582218893Sdim static QualType getFromOpaquePtr(const void *Ptr) { 583193326Sed QualType T; 584218893Sdim T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); 585193326Sed return T; 586193326Sed } 587198092Srdivacky 588218893Sdim const Type &operator*() const { 589193326Sed return *getTypePtr(); 590193326Sed } 591193326Sed 592218893Sdim const Type *operator->() const { 593193326Sed return getTypePtr(); 594193326Sed } 595198092Srdivacky 596198398Srdivacky bool isCanonical() const; 597198398Srdivacky bool isCanonicalAsParam() const; 598198398Srdivacky 599193326Sed /// isNull - Return true if this QualType doesn't point to a type yet. 600193326Sed bool isNull() const { 601198092Srdivacky return Value.getPointer().isNull(); 602193326Sed } 603193326Sed 604234353Sdim /// \brief Determine whether this particular QualType instance has the 605199482Srdivacky /// "const" qualifier set, without looking through typedefs that may have 606199482Srdivacky /// added "const" at a different level. 607199482Srdivacky bool isLocalConstQualified() const { 608199482Srdivacky return (getLocalFastQualifiers() & Qualifiers::Const); 609193326Sed } 610234353Sdim 611199482Srdivacky /// \brief Determine whether this type is const-qualified. 612199482Srdivacky bool isConstQualified() const; 613234353Sdim 614234353Sdim /// \brief Determine whether this particular QualType instance has the 615199482Srdivacky /// "restrict" qualifier set, without looking through typedefs that may have 616199482Srdivacky /// added "restrict" at a different level. 617199482Srdivacky bool isLocalRestrictQualified() const { 618199482Srdivacky return (getLocalFastQualifiers() & Qualifiers::Restrict); 619198092Srdivacky } 620234353Sdim 621199482Srdivacky /// \brief Determine whether this type is restrict-qualified. 622199482Srdivacky bool isRestrictQualified() const; 623234353Sdim 624234353Sdim /// \brief Determine whether this particular QualType instance has the 625199482Srdivacky /// "volatile" qualifier set, without looking through typedefs that may have 626199482Srdivacky /// added "volatile" at a different level. 627199482Srdivacky bool isLocalVolatileQualified() const { 628218893Sdim return (getLocalFastQualifiers() & Qualifiers::Volatile); 629193326Sed } 630198092Srdivacky 631199482Srdivacky /// \brief Determine whether this type is volatile-qualified. 632199482Srdivacky bool isVolatileQualified() const; 633234353Sdim 634199482Srdivacky /// \brief Determine whether this particular QualType instance has any 635234353Sdim /// qualifiers, without looking through any typedefs that might add 636199482Srdivacky /// qualifiers at a different level. 637199482Srdivacky bool hasLocalQualifiers() const { 638199482Srdivacky return getLocalFastQualifiers() || hasLocalNonFastQualifiers(); 639193326Sed } 640193326Sed 641199482Srdivacky /// \brief Determine whether this type has any qualifiers. 642199482Srdivacky bool hasQualifiers() const; 643234353Sdim 644199482Srdivacky /// \brief Determine whether this particular QualType instance has any 645199482Srdivacky /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType 646199482Srdivacky /// instance. 647199482Srdivacky bool hasLocalNonFastQualifiers() const { 648199482Srdivacky return Value.getPointer().is<const ExtQuals*>(); 649198092Srdivacky } 650193326Sed 651199482Srdivacky /// \brief Retrieve the set of qualifiers local to this particular QualType 652199482Srdivacky /// instance, not including any qualifiers acquired through typedefs or 653199482Srdivacky /// other sugar. 654218893Sdim Qualifiers getLocalQualifiers() const; 655193326Sed 656199482Srdivacky /// \brief Retrieve the set of qualifiers applied to this type. 657199482Srdivacky Qualifiers getQualifiers() const; 658234353Sdim 659234353Sdim /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 660199482Srdivacky /// local to this particular QualType instance, not including any qualifiers 661199482Srdivacky /// acquired through typedefs or other sugar. 662199482Srdivacky unsigned getLocalCVRQualifiers() const { 663218893Sdim return getLocalFastQualifiers(); 664193326Sed } 665198092Srdivacky 666234353Sdim /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers 667199482Srdivacky /// applied to this type. 668199482Srdivacky unsigned getCVRQualifiers() const; 669201361Srdivacky 670198092Srdivacky bool isConstant(ASTContext& Ctx) const { 671198092Srdivacky return QualType::isConstant(*this, Ctx); 672193326Sed } 673193326Sed 674224145Sdim /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). 675224145Sdim bool isPODType(ASTContext &Context) const; 676224145Sdim 677239462Sdim /// isCXX98PODType() - Return true if this is a POD type according to the 678239462Sdim /// rules of the C++98 standard, regardless of the current compilation's 679239462Sdim /// language. 680239462Sdim bool isCXX98PODType(ASTContext &Context) const; 681239462Sdim 682224145Sdim /// isCXX11PODType() - Return true if this is a POD type according to the 683224145Sdim /// more relaxed rules of the C++11 standard, regardless of the current 684224145Sdim /// compilation's language. 685224145Sdim /// (C++0x [basic.types]p9) 686224145Sdim bool isCXX11PODType(ASTContext &Context) const; 687234353Sdim 688224145Sdim /// isTrivialType - Return true if this is a trivial type 689224145Sdim /// (C++0x [basic.types]p9) 690234353Sdim bool isTrivialType(ASTContext &Context) const; 691224145Sdim 692224145Sdim /// isTriviallyCopyableType - Return true if this is a trivially 693224145Sdim /// copyable type (C++0x [basic.types]p9) 694224145Sdim bool isTriviallyCopyableType(ASTContext &Context) const; 695224145Sdim 696198092Srdivacky // Don't promise in the API that anything besides 'const' can be 697198092Srdivacky // easily added. 698198092Srdivacky 699234353Sdim /// addConst - add the specified type qualifier to this QualType. 700198092Srdivacky void addConst() { 701198092Srdivacky addFastQualifiers(Qualifiers::Const); 702198092Srdivacky } 703198092Srdivacky QualType withConst() const { 704198092Srdivacky return withFastQualifiers(Qualifiers::Const); 705198092Srdivacky } 706198092Srdivacky 707234353Sdim /// addVolatile - add the specified type qualifier to this QualType. 708223017Sdim void addVolatile() { 709223017Sdim addFastQualifiers(Qualifiers::Volatile); 710223017Sdim } 711223017Sdim QualType withVolatile() const { 712223017Sdim return withFastQualifiers(Qualifiers::Volatile); 713223017Sdim } 714234353Sdim 715234353Sdim /// Add the restrict qualifier to this QualType. 716234353Sdim void addRestrict() { 717234353Sdim addFastQualifiers(Qualifiers::Restrict); 718234353Sdim } 719234353Sdim QualType withRestrict() const { 720234353Sdim return withFastQualifiers(Qualifiers::Restrict); 721234353Sdim } 722223017Sdim 723224145Sdim QualType withCVRQualifiers(unsigned CVR) const { 724224145Sdim return withFastQualifiers(CVR); 725224145Sdim } 726224145Sdim 727198092Srdivacky void addFastQualifiers(unsigned TQs) { 728198092Srdivacky assert(!(TQs & ~Qualifiers::FastMask) 729198092Srdivacky && "non-fast qualifier bits set in mask!"); 730198092Srdivacky Value.setInt(Value.getInt() | TQs); 731198092Srdivacky } 732198092Srdivacky 733218893Sdim void removeLocalConst(); 734218893Sdim void removeLocalVolatile(); 735218893Sdim void removeLocalRestrict(); 736218893Sdim void removeLocalCVRQualifiers(unsigned Mask); 737198092Srdivacky 738218893Sdim void removeLocalFastQualifiers() { Value.setInt(0); } 739218893Sdim void removeLocalFastQualifiers(unsigned Mask) { 740198092Srdivacky assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers"); 741198092Srdivacky Value.setInt(Value.getInt() & ~Mask); 742198092Srdivacky } 743198092Srdivacky 744198092Srdivacky // Creates a type with the given qualifiers in addition to any 745198092Srdivacky // qualifiers already on this type. 746198092Srdivacky QualType withFastQualifiers(unsigned TQs) const { 747198092Srdivacky QualType T = *this; 748198092Srdivacky T.addFastQualifiers(TQs); 749198092Srdivacky return T; 750198092Srdivacky } 751198092Srdivacky 752198092Srdivacky // Creates a type with exactly the given fast qualifiers, removing 753198092Srdivacky // any existing fast qualifiers. 754218893Sdim QualType withExactLocalFastQualifiers(unsigned TQs) const { 755218893Sdim return withoutLocalFastQualifiers().withFastQualifiers(TQs); 756198092Srdivacky } 757198092Srdivacky 758198092Srdivacky // Removes fast qualifiers, but leaves any extended qualifiers in place. 759218893Sdim QualType withoutLocalFastQualifiers() const { 760198092Srdivacky QualType T = *this; 761218893Sdim T.removeLocalFastQualifiers(); 762198092Srdivacky return T; 763198092Srdivacky } 764198092Srdivacky 765218893Sdim QualType getCanonicalType() const; 766218893Sdim 767199482Srdivacky /// \brief Return this type with all of the instance-specific qualifiers 768199482Srdivacky /// removed, but without removing any qualifiers that may have been applied 769199482Srdivacky /// through typedefs. 770199482Srdivacky QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } 771198092Srdivacky 772218893Sdim /// \brief Retrieve the unqualified variant of the given type, 773218893Sdim /// removing as little sugar as possible. 774218893Sdim /// 775218893Sdim /// This routine looks through various kinds of sugar to find the 776218893Sdim /// least-desugared type that is unqualified. For example, given: 777218893Sdim /// 778218893Sdim /// \code 779218893Sdim /// typedef int Integer; 780218893Sdim /// typedef const Integer CInteger; 781218893Sdim /// typedef CInteger DifferenceType; 782218893Sdim /// \endcode 783218893Sdim /// 784218893Sdim /// Executing \c getUnqualifiedType() on the type \c DifferenceType will 785218893Sdim /// desugar until we hit the type \c Integer, which has no qualifiers on it. 786218893Sdim /// 787218893Sdim /// The resulting type might still be qualified if it's an array 788218893Sdim /// type. To strip qualifiers even from within an 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 /// 798218893Sdim /// The resulting type might still be qualified if it's an array 799218893Sdim /// type. To strip qualifiers even from within an array type, use 800218893Sdim /// ASTContext::getUnqualifiedArrayType. 801218893Sdim inline SplitQualType getSplitUnqualifiedType() const; 802234353Sdim 803221345Sdim /// \brief Determine whether this type is more qualified than the other 804221345Sdim /// given type, requiring exact equality for non-CVR qualifiers. 805193326Sed bool isMoreQualifiedThan(QualType Other) const; 806221345Sdim 807221345Sdim /// \brief Determine whether this type is at least as qualified as the other 808221345Sdim /// given type, requiring exact equality for non-CVR qualifiers. 809193326Sed bool isAtLeastAsQualifiedAs(QualType Other) const; 810234353Sdim 811193326Sed QualType getNonReferenceType() const; 812198092Srdivacky 813210299Sed /// \brief Determine the type of a (typically non-lvalue) expression with the 814210299Sed /// specified result type. 815234353Sdim /// 816210299Sed /// This routine should be used for expressions for which the return type is 817210299Sed /// explicitly specified (e.g., in a cast or call) and isn't necessarily 818234353Sdim /// an lvalue. It removes a top-level reference (since there are no 819210299Sed /// expressions of reference type) and deletes top-level cvr-qualifiers 820210299Sed /// from non-class types (in C++) or all types (in C). 821210299Sed QualType getNonLValueExprType(ASTContext &Context) const; 822234353Sdim 823193326Sed /// getDesugaredType - Return the specified type with any "sugar" removed from 824193326Sed /// the type. This takes off typedefs, typeof's etc. If the outer level of 825193326Sed /// the type is already concrete, it returns it unmodified. This is similar 826193326Sed /// to getting the canonical type, but it doesn't remove *all* typedefs. For 827193326Sed /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is 828193326Sed /// concrete. 829198092Srdivacky /// 830198092Srdivacky /// Qualifiers are left in place. 831218893Sdim QualType getDesugaredType(const ASTContext &Context) const { 832218893Sdim return getDesugaredType(*this, Context); 833198092Srdivacky } 834193326Sed 835218893Sdim SplitQualType getSplitDesugaredType() const { 836218893Sdim return getSplitDesugaredType(*this); 837218893Sdim } 838218893Sdim 839224145Sdim /// \brief Return the specified type with one level of "sugar" removed from 840234353Sdim /// the type. 841224145Sdim /// 842224145Sdim /// This routine takes off the first typedef, typeof, etc. If the outer level 843224145Sdim /// of the type is already concrete, it returns it unmodified. 844234353Sdim QualType getSingleStepDesugaredType(const ASTContext &Context) const { 845234353Sdim return getSingleStepDesugaredTypeImpl(*this, Context); 846234353Sdim } 847234353Sdim 848218893Sdim /// IgnoreParens - Returns the specified type after dropping any 849218893Sdim /// outer-level parentheses. 850218893Sdim QualType IgnoreParens() const { 851218893Sdim if (isa<ParenType>(*this)) 852218893Sdim return QualType::IgnoreParens(*this); 853218893Sdim return *this; 854218893Sdim } 855218893Sdim 856193326Sed /// operator==/!= - Indicate whether the specified types and qualifiers are 857193326Sed /// identical. 858198092Srdivacky friend bool operator==(const QualType &LHS, const QualType &RHS) { 859198092Srdivacky return LHS.Value == RHS.Value; 860193326Sed } 861198092Srdivacky friend bool operator!=(const QualType &LHS, const QualType &RHS) { 862198092Srdivacky return LHS.Value != RHS.Value; 863193326Sed } 864218893Sdim std::string getAsString() const { 865218893Sdim return getAsString(split()); 866218893Sdim } 867218893Sdim static std::string getAsString(SplitQualType split) { 868234353Sdim return getAsString(split.Ty, split.Quals); 869218893Sdim } 870218893Sdim static std::string getAsString(const Type *ty, Qualifiers qs); 871193326Sed 872239462Sdim std::string getAsString(const PrintingPolicy &Policy) const; 873239462Sdim 874239462Sdim void print(raw_ostream &OS, const PrintingPolicy &Policy, 875239462Sdim const Twine &PlaceHolder = Twine()) const { 876239462Sdim print(split(), OS, Policy, PlaceHolder); 877193326Sed } 878239462Sdim static void print(SplitQualType split, raw_ostream &OS, 879239462Sdim const PrintingPolicy &policy, const Twine &PlaceHolder) { 880239462Sdim return print(split.Ty, split.Quals, OS, policy, PlaceHolder); 881239462Sdim } 882239462Sdim static void print(const Type *ty, Qualifiers qs, 883239462Sdim raw_ostream &OS, const PrintingPolicy &policy, 884239462Sdim const Twine &PlaceHolder); 885239462Sdim 886195341Sed void getAsStringInternal(std::string &Str, 887218893Sdim const PrintingPolicy &Policy) const { 888218893Sdim return getAsStringInternal(split(), Str, Policy); 889218893Sdim } 890218893Sdim static void getAsStringInternal(SplitQualType split, std::string &out, 891218893Sdim const PrintingPolicy &policy) { 892234353Sdim return getAsStringInternal(split.Ty, split.Quals, out, policy); 893218893Sdim } 894218893Sdim static void getAsStringInternal(const Type *ty, Qualifiers qs, 895218893Sdim std::string &out, 896218893Sdim const PrintingPolicy &policy); 897198092Srdivacky 898239462Sdim class StreamedQualTypeHelper { 899239462Sdim const QualType &T; 900239462Sdim const PrintingPolicy &Policy; 901239462Sdim const Twine &PlaceHolder; 902239462Sdim public: 903239462Sdim StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, 904239462Sdim const Twine &PlaceHolder) 905239462Sdim : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { } 906239462Sdim 907239462Sdim friend raw_ostream &operator<<(raw_ostream &OS, 908239462Sdim const StreamedQualTypeHelper &SQT) { 909239462Sdim SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder); 910239462Sdim return OS; 911239462Sdim } 912239462Sdim }; 913239462Sdim 914239462Sdim StreamedQualTypeHelper stream(const PrintingPolicy &Policy, 915239462Sdim const Twine &PlaceHolder = Twine()) const { 916239462Sdim return StreamedQualTypeHelper(*this, Policy, PlaceHolder); 917239462Sdim } 918239462Sdim 919193326Sed void dump(const char *s) const; 920193326Sed void dump() const; 921198092Srdivacky 922193326Sed void Profile(llvm::FoldingSetNodeID &ID) const { 923193326Sed ID.AddPointer(getAsOpaquePtr()); 924193326Sed } 925193326Sed 926193326Sed /// getAddressSpace - Return the address space of this type. 927193326Sed inline unsigned getAddressSpace() const; 928198092Srdivacky 929224145Sdim /// getObjCGCAttr - Returns gc attribute of this type. 930198092Srdivacky inline Qualifiers::GC getObjCGCAttr() const; 931193326Sed 932193326Sed /// isObjCGCWeak true when Type is objc's weak. 933193326Sed bool isObjCGCWeak() const { 934198092Srdivacky return getObjCGCAttr() == Qualifiers::Weak; 935193326Sed } 936193326Sed 937193326Sed /// isObjCGCStrong true when Type is objc's strong. 938193326Sed bool isObjCGCStrong() const { 939198092Srdivacky return getObjCGCAttr() == Qualifiers::Strong; 940193326Sed } 941198092Srdivacky 942224145Sdim /// getObjCLifetime - Returns lifetime attribute of this type. 943224145Sdim Qualifiers::ObjCLifetime getObjCLifetime() const { 944224145Sdim return getQualifiers().getObjCLifetime(); 945224145Sdim } 946224145Sdim 947224145Sdim bool hasNonTrivialObjCLifetime() const { 948224145Sdim return getQualifiers().hasNonTrivialObjCLifetime(); 949224145Sdim } 950224145Sdim 951224145Sdim bool hasStrongOrWeakObjCLifetime() const { 952224145Sdim return getQualifiers().hasStrongOrWeakObjCLifetime(); 953224145Sdim } 954224145Sdim 955218893Sdim enum DestructionKind { 956218893Sdim DK_none, 957224145Sdim DK_cxx_destructor, 958224145Sdim DK_objc_strong_lifetime, 959224145Sdim DK_objc_weak_lifetime 960218893Sdim }; 961218893Sdim 962218893Sdim /// isDestructedType - nonzero if objects of this type require 963218893Sdim /// non-trivial work to clean up after. Non-zero because it's 964218893Sdim /// conceivable that qualifiers (objc_gc(weak)?) could make 965218893Sdim /// something require destruction. 966218893Sdim DestructionKind isDestructedType() const { 967218893Sdim return isDestructedTypeImpl(*this); 968218893Sdim } 969218893Sdim 970234353Sdim /// \brief Determine whether expressions of the given type are forbidden 971224145Sdim /// from being lvalues in C. 972224145Sdim /// 973224145Sdim /// The expression types that are forbidden to be lvalues are: 974224145Sdim /// - 'void', but not qualified void 975224145Sdim /// - function types 976224145Sdim /// 977224145Sdim /// The exact rule here is C99 6.3.2.1: 978224145Sdim /// An lvalue is an expression with an object type or an incomplete 979224145Sdim /// type other than void. 980224145Sdim bool isCForbiddenLValueType() const; 981224145Sdim 982226633Sdim /// \brief Determine whether this type has trivial copy/move-assignment 983226633Sdim /// semantics. 984226633Sdim bool hasTrivialAssignment(ASTContext &Context, bool Copying) const; 985234353Sdim 986198092Srdivackyprivate: 987198092Srdivacky // These methods are implemented in a separate translation unit; 988198092Srdivacky // "static"-ize them to avoid creating temporary QualTypes in the 989198092Srdivacky // caller. 990198092Srdivacky static bool isConstant(QualType T, ASTContext& Ctx); 991218893Sdim static QualType getDesugaredType(QualType T, const ASTContext &Context); 992218893Sdim static SplitQualType getSplitDesugaredType(QualType T); 993218893Sdim static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); 994234353Sdim static QualType getSingleStepDesugaredTypeImpl(QualType type, 995234353Sdim const ASTContext &C); 996218893Sdim static QualType IgnoreParens(QualType T); 997218893Sdim static DestructionKind isDestructedTypeImpl(QualType type); 998193326Sed}; 999193326Sed 1000193326Sed} // end clang. 1001193326Sed 1002193326Sednamespace llvm { 1003193326Sed/// Implement simplify_type for QualType, so that we can dyn_cast from QualType 1004193326Sed/// to a specific Type class. 1005193326Sedtemplate<> struct simplify_type<const ::clang::QualType> { 1006218893Sdim typedef const ::clang::Type *SimpleType; 1007193326Sed static SimpleType getSimplifiedValue(const ::clang::QualType &Val) { 1008193326Sed return Val.getTypePtr(); 1009193326Sed } 1010193326Sed}; 1011193326Sedtemplate<> struct simplify_type< ::clang::QualType> 1012193326Sed : public simplify_type<const ::clang::QualType> {}; 1013198092Srdivacky 1014193326Sed// Teach SmallPtrSet that QualType is "basically a pointer". 1015193326Sedtemplate<> 1016193326Sedclass PointerLikeTypeTraits<clang::QualType> { 1017193326Sedpublic: 1018193326Sed static inline void *getAsVoidPointer(clang::QualType P) { 1019193326Sed return P.getAsOpaquePtr(); 1020193326Sed } 1021193326Sed static inline clang::QualType getFromVoidPointer(void *P) { 1022193326Sed return clang::QualType::getFromOpaquePtr(P); 1023193326Sed } 1024198092Srdivacky // Various qualifiers go in low bits. 1025193326Sed enum { NumLowBitsAvailable = 0 }; 1026193326Sed}; 1027198092Srdivacky 1028193326Sed} // end namespace llvm 1029193326Sed 1030193326Sednamespace clang { 1031193326Sed 1032234353Sdim/// \brief Base class that is common to both the \c ExtQuals and \c Type 1033218893Sdim/// classes, which allows \c QualType to access the common fields between the 1034218893Sdim/// two. 1035218893Sdim/// 1036218893Sdimclass ExtQualsTypeCommonBase { 1037218893Sdim ExtQualsTypeCommonBase(const Type *baseType, QualType canon) 1038218893Sdim : BaseType(baseType), CanonicalType(canon) {} 1039218893Sdim 1040218893Sdim /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or 1041218893Sdim /// a self-referential pointer (for \c Type). 1042218893Sdim /// 1043234353Sdim /// This pointer allows an efficient mapping from a QualType to its 1044218893Sdim /// underlying type pointer. 1045218893Sdim const Type *const BaseType; 1046218893Sdim 1047218893Sdim /// \brief The canonical type of this type. A QualType. 1048218893Sdim QualType CanonicalType; 1049218893Sdim 1050218893Sdim friend class QualType; 1051218893Sdim friend class Type; 1052218893Sdim friend class ExtQuals; 1053218893Sdim}; 1054234353Sdim 1055218893Sdim/// ExtQuals - We can encode up to four bits in the low bits of a 1056218893Sdim/// type pointer, but there are many more type qualifiers that we want 1057218893Sdim/// to be able to apply to an arbitrary type. Therefore we have this 1058218893Sdim/// struct, intended to be heap-allocated and used by QualType to 1059218893Sdim/// store qualifiers. 1060218893Sdim/// 1061234353Sdim/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers 1062218893Sdim/// in three low bits on the QualType pointer; a fourth bit records whether 1063218893Sdim/// the pointer is an ExtQuals node. The extended qualifiers (address spaces, 1064218893Sdim/// Objective-C GC attributes) are much more rare. 1065218893Sdimclass ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { 1066218893Sdim // NOTE: changing the fast qualifiers should be straightforward as 1067218893Sdim // long as you don't make 'const' non-fast. 1068218893Sdim // 1. Qualifiers: 1069218893Sdim // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). 1070218893Sdim // Fast qualifiers must occupy the low-order bits. 1071218893Sdim // b) Update Qualifiers::FastWidth and FastMask. 1072218893Sdim // 2. QualType: 1073218893Sdim // a) Update is{Volatile,Restrict}Qualified(), defined inline. 1074218893Sdim // b) Update remove{Volatile,Restrict}, defined near the end of 1075218893Sdim // this header. 1076218893Sdim // 3. ASTContext: 1077218893Sdim // a) Update get{Volatile,Restrict}Type. 1078218893Sdim 1079218893Sdim /// Quals - the immutable set of qualifiers applied by this 1080218893Sdim /// node; always contains extended qualifiers. 1081218893Sdim Qualifiers Quals; 1082218893Sdim 1083218893Sdim ExtQuals *this_() { return this; } 1084218893Sdim 1085218893Sdimpublic: 1086234353Sdim ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) 1087218893Sdim : ExtQualsTypeCommonBase(baseType, 1088218893Sdim canon.isNull() ? QualType(this_(), 0) : canon), 1089218893Sdim Quals(quals) 1090218893Sdim { 1091218893Sdim assert(Quals.hasNonFastQualifiers() 1092218893Sdim && "ExtQuals created with no fast qualifiers"); 1093218893Sdim assert(!Quals.hasFastQualifiers() 1094218893Sdim && "ExtQuals created with fast qualifiers"); 1095218893Sdim } 1096218893Sdim 1097218893Sdim Qualifiers getQualifiers() const { return Quals; } 1098218893Sdim 1099218893Sdim bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } 1100218893Sdim Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } 1101218893Sdim 1102224145Sdim bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } 1103224145Sdim Qualifiers::ObjCLifetime getObjCLifetime() const { 1104224145Sdim return Quals.getObjCLifetime(); 1105224145Sdim } 1106224145Sdim 1107218893Sdim bool hasAddressSpace() const { return Quals.hasAddressSpace(); } 1108218893Sdim unsigned getAddressSpace() const { return Quals.getAddressSpace(); } 1109218893Sdim 1110218893Sdim const Type *getBaseType() const { return BaseType; } 1111218893Sdim 1112218893Sdimpublic: 1113218893Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 1114218893Sdim Profile(ID, getBaseType(), Quals); 1115218893Sdim } 1116218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, 1117218893Sdim const Type *BaseType, 1118218893Sdim Qualifiers Quals) { 1119218893Sdim assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!"); 1120218893Sdim ID.AddPointer(BaseType); 1121218893Sdim Quals.Profile(ID); 1122218893Sdim } 1123218893Sdim}; 1124218893Sdim 1125234353Sdim/// \brief The kind of C++0x ref-qualifier associated with a function type, 1126234353Sdim/// which determines whether a member function's "this" object can be an 1127218893Sdim/// lvalue, rvalue, or neither. 1128218893Sdimenum RefQualifierKind { 1129218893Sdim /// \brief No ref-qualifier was provided. 1130218893Sdim RQ_None = 0, 1131218893Sdim /// \brief An lvalue ref-qualifier was provided (\c &). 1132218893Sdim RQ_LValue, 1133218893Sdim /// \brief An rvalue ref-qualifier was provided (\c &&). 1134218893Sdim RQ_RValue 1135218893Sdim}; 1136234353Sdim 1137193326Sed/// Type - This is the base class of the type hierarchy. A central concept 1138193326Sed/// with types is that each type always has a canonical type. A canonical type 1139193326Sed/// is the type with any typedef names stripped out of it or the types it 1140193326Sed/// references. For example, consider: 1141193326Sed/// 1142193326Sed/// typedef int foo; 1143193326Sed/// typedef foo* bar; 1144193326Sed/// 'int *' 'foo *' 'bar' 1145193326Sed/// 1146193326Sed/// There will be a Type object created for 'int'. Since int is canonical, its 1147193326Sed/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a 1148193326Sed/// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next 1149193326Sed/// there is a PointerType that represents 'int*', which, like 'int', is 1150193326Sed/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical 1151193326Sed/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type 1152193326Sed/// is also 'int*'. 1153193326Sed/// 1154193326Sed/// Non-canonical types are useful for emitting diagnostics, without losing 1155193326Sed/// information about typedefs being used. Canonical types are useful for type 1156193326Sed/// comparisons (they allow by-pointer equality tests) and useful for reasoning 1157193326Sed/// about whether something has a particular form (e.g. is a function type), 1158193326Sed/// because they implicitly, recursively, strip all typedefs out of a type. 1159193326Sed/// 1160193326Sed/// Types, once created, are immutable. 1161193326Sed/// 1162218893Sdimclass Type : public ExtQualsTypeCommonBase { 1163193326Sedpublic: 1164193326Sed enum TypeClass { 1165193326Sed#define TYPE(Class, Base) Class, 1166203955Srdivacky#define LAST_TYPE(Class) TypeLast = Class, 1167193326Sed#define ABSTRACT_TYPE(Class, Base) 1168193326Sed#include "clang/AST/TypeNodes.def" 1169193326Sed TagFirst = Record, TagLast = Enum 1170193326Sed }; 1171198092Srdivacky 1172193326Sedprivate: 1173243830Sdim Type(const Type &) LLVM_DELETED_FUNCTION; 1174243830Sdim void operator=(const Type &) LLVM_DELETED_FUNCTION; 1175208600Srdivacky 1176218893Sdim /// Bitfields required by the Type class. 1177218893Sdim class TypeBitfields { 1178218893Sdim friend class Type; 1179218893Sdim template <class T> friend class TypePropertyCache; 1180193326Sed 1181218893Sdim /// TypeClass bitfield - Enum that specifies what subclass this belongs to. 1182218893Sdim unsigned TC : 8; 1183203955Srdivacky 1184218893Sdim /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]). 1185218893Sdim unsigned Dependent : 1; 1186234353Sdim 1187234353Sdim /// \brief Whether this type somehow involves a template parameter, even 1188224145Sdim /// if the resolution of the type does not depend on a template parameter. 1189224145Sdim unsigned InstantiationDependent : 1; 1190234353Sdim 1191218893Sdim /// \brief Whether this type is a variably-modified type (C99 6.7.5). 1192218893Sdim unsigned VariablyModified : 1; 1193218893Sdim 1194218893Sdim /// \brief Whether this type contains an unexpanded parameter pack 1195218893Sdim /// (for C++0x variadic templates). 1196218893Sdim unsigned ContainsUnexpandedParameterPack : 1; 1197234353Sdim 1198218893Sdim /// \brief Nonzero if the cache (i.e. the bitfields here starting 1199218893Sdim /// with 'Cache') is valid. If so, then this is a 1200218893Sdim /// LangOptions::VisibilityMode+1. 1201218893Sdim mutable unsigned CacheValidAndVisibility : 2; 1202234353Sdim 1203234353Sdim /// \brief True if the visibility was set explicitly in the source code. 1204234353Sdim mutable unsigned CachedExplicitVisibility : 1; 1205234353Sdim 1206218893Sdim /// \brief Linkage of this type. 1207218893Sdim mutable unsigned CachedLinkage : 2; 1208210299Sed 1209234353Sdim /// \brief Whether this type involves and local or unnamed types. 1210218893Sdim mutable unsigned CachedLocalOrUnnamed : 1; 1211234353Sdim 1212218893Sdim /// \brief FromAST - Whether this type comes from an AST file. 1213218893Sdim mutable unsigned FromAST : 1; 1214210299Sed 1215218893Sdim bool isCacheValid() const { 1216218893Sdim return (CacheValidAndVisibility != 0); 1217218893Sdim } 1218218893Sdim Visibility getVisibility() const { 1219218893Sdim assert(isCacheValid() && "getting linkage from invalid cache"); 1220218893Sdim return static_cast<Visibility>(CacheValidAndVisibility-1); 1221218893Sdim } 1222234353Sdim bool isVisibilityExplicit() const { 1223234353Sdim assert(isCacheValid() && "getting linkage from invalid cache"); 1224234353Sdim return CachedExplicitVisibility; 1225234353Sdim } 1226218893Sdim Linkage getLinkage() const { 1227218893Sdim assert(isCacheValid() && "getting linkage from invalid cache"); 1228218893Sdim return static_cast<Linkage>(CachedLinkage); 1229218893Sdim } 1230218893Sdim bool hasLocalOrUnnamedType() const { 1231218893Sdim assert(isCacheValid() && "getting linkage from invalid cache"); 1232218893Sdim return CachedLocalOrUnnamed; 1233218893Sdim } 1234218893Sdim }; 1235234353Sdim enum { NumTypeBits = 19 }; 1236218893Sdim 1237218893Sdimprotected: 1238218893Sdim // These classes allow subclasses to somewhat cleanly pack bitfields 1239218893Sdim // into Type. 1240218893Sdim 1241218893Sdim class ArrayTypeBitfields { 1242218893Sdim friend class ArrayType; 1243218893Sdim 1244218893Sdim unsigned : NumTypeBits; 1245218893Sdim 1246218893Sdim /// IndexTypeQuals - CVR qualifiers from declarations like 1247218893Sdim /// 'int X[static restrict 4]'. For function parameters only. 1248218893Sdim unsigned IndexTypeQuals : 3; 1249218893Sdim 1250218893Sdim /// SizeModifier - storage class qualifiers from declarations like 1251218893Sdim /// 'int X[static restrict 4]'. For function parameters only. 1252218893Sdim /// Actually an ArrayType::ArraySizeModifier. 1253218893Sdim unsigned SizeModifier : 3; 1254218893Sdim }; 1255218893Sdim 1256218893Sdim class BuiltinTypeBitfields { 1257218893Sdim friend class BuiltinType; 1258218893Sdim 1259218893Sdim unsigned : NumTypeBits; 1260218893Sdim 1261218893Sdim /// The kind (BuiltinType::Kind) of builtin type this is. 1262218893Sdim unsigned Kind : 8; 1263218893Sdim }; 1264218893Sdim 1265218893Sdim class FunctionTypeBitfields { 1266218893Sdim friend class FunctionType; 1267218893Sdim 1268218893Sdim unsigned : NumTypeBits; 1269218893Sdim 1270218893Sdim /// Extra information which affects how the function is called, like 1271218893Sdim /// regparm and the calling convention. 1272243830Sdim unsigned ExtInfo : 9; 1273218893Sdim 1274218893Sdim /// TypeQuals - Used only by FunctionProtoType, put here to pack with the 1275218893Sdim /// other bitfields. 1276218893Sdim /// The qualifiers are part of FunctionProtoType because... 1277218893Sdim /// 1278218893Sdim /// C++ 8.3.5p4: The return type, the parameter type list and the 1279218893Sdim /// cv-qualifier-seq, [...], are part of the function type. 1280218893Sdim unsigned TypeQuals : 3; 1281234353Sdim 1282218893Sdim /// \brief The ref-qualifier associated with a \c FunctionProtoType. 1283218893Sdim /// 1284218893Sdim /// This is a value of type \c RefQualifierKind. 1285218893Sdim unsigned RefQualifier : 2; 1286218893Sdim }; 1287218893Sdim 1288218893Sdim class ObjCObjectTypeBitfields { 1289218893Sdim friend class ObjCObjectType; 1290218893Sdim 1291218893Sdim unsigned : NumTypeBits; 1292218893Sdim 1293218893Sdim /// NumProtocols - The number of protocols stored directly on this 1294218893Sdim /// object type. 1295218893Sdim unsigned NumProtocols : 32 - NumTypeBits; 1296218893Sdim }; 1297218893Sdim 1298218893Sdim class ReferenceTypeBitfields { 1299218893Sdim friend class ReferenceType; 1300218893Sdim 1301218893Sdim unsigned : NumTypeBits; 1302218893Sdim 1303218893Sdim /// True if the type was originally spelled with an lvalue sigil. 1304218893Sdim /// This is never true of rvalue references but can also be false 1305218893Sdim /// on lvalue references because of C++0x [dcl.typedef]p9, 1306218893Sdim /// as follows: 1307218893Sdim /// 1308218893Sdim /// typedef int &ref; // lvalue, spelled lvalue 1309218893Sdim /// typedef int &&rvref; // rvalue 1310218893Sdim /// ref &a; // lvalue, inner ref, spelled lvalue 1311218893Sdim /// ref &&a; // lvalue, inner ref 1312218893Sdim /// rvref &a; // lvalue, inner ref, spelled lvalue 1313218893Sdim /// rvref &&a; // rvalue, inner ref 1314218893Sdim unsigned SpelledAsLValue : 1; 1315218893Sdim 1316218893Sdim /// True if the inner type is a reference type. This only happens 1317218893Sdim /// in non-canonical forms. 1318218893Sdim unsigned InnerRef : 1; 1319218893Sdim }; 1320218893Sdim 1321218893Sdim class TypeWithKeywordBitfields { 1322218893Sdim friend class TypeWithKeyword; 1323218893Sdim 1324218893Sdim unsigned : NumTypeBits; 1325218893Sdim 1326218893Sdim /// An ElaboratedTypeKeyword. 8 bits for efficient access. 1327218893Sdim unsigned Keyword : 8; 1328218893Sdim }; 1329218893Sdim 1330218893Sdim class VectorTypeBitfields { 1331218893Sdim friend class VectorType; 1332218893Sdim 1333218893Sdim unsigned : NumTypeBits; 1334218893Sdim 1335218893Sdim /// VecKind - The kind of vector, either a generic vector type or some 1336218893Sdim /// target-specific vector type such as for AltiVec or Neon. 1337218893Sdim unsigned VecKind : 3; 1338218893Sdim 1339218893Sdim /// NumElements - The number of elements in the vector. 1340218893Sdim unsigned NumElements : 29 - NumTypeBits; 1341218893Sdim }; 1342218893Sdim 1343218893Sdim class AttributedTypeBitfields { 1344218893Sdim friend class AttributedType; 1345218893Sdim 1346218893Sdim unsigned : NumTypeBits; 1347218893Sdim 1348218893Sdim /// AttrKind - an AttributedType::Kind 1349218893Sdim unsigned AttrKind : 32 - NumTypeBits; 1350218893Sdim }; 1351218893Sdim 1352218893Sdim union { 1353218893Sdim TypeBitfields TypeBits; 1354218893Sdim ArrayTypeBitfields ArrayTypeBits; 1355218893Sdim AttributedTypeBitfields AttributedTypeBits; 1356218893Sdim BuiltinTypeBitfields BuiltinTypeBits; 1357218893Sdim FunctionTypeBitfields FunctionTypeBits; 1358218893Sdim ObjCObjectTypeBitfields ObjCObjectTypeBits; 1359218893Sdim ReferenceTypeBitfields ReferenceTypeBits; 1360218893Sdim TypeWithKeywordBitfields TypeWithKeywordBits; 1361218893Sdim VectorTypeBitfields VectorTypeBits; 1362218893Sdim }; 1363218893Sdim 1364218893Sdimprivate: 1365212904Sdim /// \brief Set whether this type comes from an AST file. 1366234353Sdim void setFromAST(bool V = true) const { 1367218893Sdim TypeBits.FromAST = V; 1368210299Sed } 1369210299Sed 1370218893Sdim template <class T> friend class TypePropertyCache; 1371218893Sdim 1372208600Srdivackyprotected: 1373193326Sed // silence VC++ warning C4355: 'this' : used in base member initializer list 1374193326Sed Type *this_() { return this; } 1375234353Sdim Type(TypeClass tc, QualType canon, bool Dependent, 1376224145Sdim bool InstantiationDependent, bool VariablyModified, 1377218893Sdim bool ContainsUnexpandedParameterPack) 1378218893Sdim : ExtQualsTypeCommonBase(this, 1379218893Sdim canon.isNull() ? QualType(this_(), 0) : canon) { 1380218893Sdim TypeBits.TC = tc; 1381218893Sdim TypeBits.Dependent = Dependent; 1382224145Sdim TypeBits.InstantiationDependent = Dependent || InstantiationDependent; 1383218893Sdim TypeBits.VariablyModified = VariablyModified; 1384218893Sdim TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; 1385218893Sdim TypeBits.CacheValidAndVisibility = 0; 1386234353Sdim TypeBits.CachedExplicitVisibility = false; 1387218893Sdim TypeBits.CachedLocalOrUnnamed = false; 1388218893Sdim TypeBits.CachedLinkage = NoLinkage; 1389218893Sdim TypeBits.FromAST = false; 1390218893Sdim } 1391193326Sed friend class ASTContext; 1392198092Srdivacky 1393234353Sdim void setDependent(bool D = true) { 1394234353Sdim TypeBits.Dependent = D; 1395224145Sdim if (D) 1396224145Sdim TypeBits.InstantiationDependent = true; 1397224145Sdim } 1398234353Sdim void setInstantiationDependent(bool D = true) { 1399224145Sdim TypeBits.InstantiationDependent = D; } 1400234353Sdim void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; 1401224145Sdim } 1402218893Sdim void setContainsUnexpandedParameterPack(bool PP = true) { 1403218893Sdim TypeBits.ContainsUnexpandedParameterPack = PP; 1404218893Sdim } 1405218893Sdim 1406193326Sedpublic: 1407218893Sdim TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } 1408198092Srdivacky 1409212904Sdim /// \brief Whether this type comes from an AST file. 1410218893Sdim bool isFromAST() const { return TypeBits.FromAST; } 1411210299Sed 1412218893Sdim /// \brief Whether this type is or contains an unexpanded parameter 1413218893Sdim /// pack, used to support C++0x variadic templates. 1414218893Sdim /// 1415218893Sdim /// A type that contains a parameter pack shall be expanded by the 1416218893Sdim /// ellipsis operator at some point. For example, the typedef in the 1417218893Sdim /// following example contains an unexpanded parameter pack 'T': 1418218893Sdim /// 1419218893Sdim /// \code 1420218893Sdim /// template<typename ...T> 1421218893Sdim /// struct X { 1422218893Sdim /// typedef T* pointer_types; // ill-formed; T is a parameter pack. 1423218893Sdim /// }; 1424218893Sdim /// \endcode 1425218893Sdim /// 1426234353Sdim /// Note that this routine does not specify which 1427234353Sdim bool containsUnexpandedParameterPack() const { 1428218893Sdim return TypeBits.ContainsUnexpandedParameterPack; 1429218893Sdim } 1430218893Sdim 1431218893Sdim /// Determines if this type would be canonical if it had no further 1432218893Sdim /// qualification. 1433198398Srdivacky bool isCanonicalUnqualified() const { 1434218893Sdim return CanonicalType == QualType(this, 0); 1435198398Srdivacky } 1436193326Sed 1437234353Sdim /// Pull a single level of sugar off of this locally-unqualified type. 1438234353Sdim /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() 1439234353Sdim /// or QualType::getSingleStepDesugaredType(const ASTContext&). 1440234353Sdim QualType getLocallyUnqualifiedSingleStepDesugaredType() const; 1441234353Sdim 1442198092Srdivacky /// Types are partitioned into 3 broad categories (C99 6.2.5p1): 1443193326Sed /// object types, function types, and incomplete types. 1444198092Srdivacky 1445193326Sed /// isIncompleteType - Return true if this is an incomplete type. 1446193326Sed /// A type that can describe objects, but which lacks information needed to 1447193326Sed /// determine its size (e.g. void, or a fwd declared struct). Clients of this 1448198092Srdivacky /// routine will need to determine if the size is actually required. 1449234353Sdim /// 1450234353Sdim /// \brief Def If non-NULL, and the type refers to some kind of declaration 1451234353Sdim /// that can be completed (such as a C struct, C++ class, or Objective-C 1452234353Sdim /// class), will be set to the declaration. 1453234353Sdim bool isIncompleteType(NamedDecl **Def = 0) const; 1454193326Sed 1455193326Sed /// isIncompleteOrObjectType - Return true if this is an incomplete or object 1456193326Sed /// type, in other words, not a function type. 1457193326Sed bool isIncompleteOrObjectType() const { 1458193326Sed return !isFunctionType(); 1459193326Sed } 1460234353Sdim 1461218893Sdim /// \brief Determine whether this type is an object type. 1462218893Sdim bool isObjectType() const { 1463218893Sdim // C++ [basic.types]p8: 1464234353Sdim // An object type is a (possibly cv-qualified) type that is not a 1465218893Sdim // function type, not a reference type, and not a void type. 1466218893Sdim return !isReferenceType() && !isFunctionType() && !isVoidType(); 1467218893Sdim } 1468193326Sed 1469200583Srdivacky /// isLiteralType - Return true if this is a literal type 1470200583Srdivacky /// (C++0x [basic.types]p10) 1471200583Srdivacky bool isLiteralType() const; 1472200583Srdivacky 1473221345Sdim /// \brief Test if this type is a standard-layout type. 1474221345Sdim /// (C++0x [basic.type]p9) 1475221345Sdim bool isStandardLayoutType() const; 1476221345Sdim 1477193326Sed /// Helper methods to distinguish type categories. All type predicates 1478193326Sed /// operate on the canonical type, ignoring typedefs and qualifiers. 1479193326Sed 1480210299Sed /// isBuiltinType - returns true if the type is a builtin type. 1481210299Sed bool isBuiltinType() const; 1482210299Sed 1483193326Sed /// isSpecificBuiltinType - Test for a particular builtin type. 1484193326Sed bool isSpecificBuiltinType(unsigned K) const; 1485198092Srdivacky 1486218893Sdim /// isPlaceholderType - Test for a type which does not represent an 1487218893Sdim /// actual type-system type but is instead used as a placeholder for 1488218893Sdim /// various convenient purposes within Clang. All such types are 1489218893Sdim /// BuiltinTypes. 1490218893Sdim bool isPlaceholderType() const; 1491226633Sdim const BuiltinType *getAsPlaceholderType() const; 1492218893Sdim 1493221345Sdim /// isSpecificPlaceholderType - Test for a specific placeholder type. 1494221345Sdim bool isSpecificPlaceholderType(unsigned K) const; 1495221345Sdim 1496234353Sdim /// isNonOverloadPlaceholderType - Test for a placeholder type 1497234353Sdim /// other than Overload; see BuiltinType::isNonOverloadPlaceholderType. 1498234353Sdim bool isNonOverloadPlaceholderType() const; 1499234353Sdim 1500193326Sed /// isIntegerType() does *not* include complex integers (a GCC extension). 1501193326Sed /// isComplexIntegerType() can be used to test for complex integers. 1502193326Sed bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) 1503193326Sed bool isEnumeralType() const; 1504193326Sed bool isBooleanType() const; 1505193326Sed bool isCharType() const; 1506193326Sed bool isWideCharType() const; 1507226633Sdim bool isChar16Type() const; 1508226633Sdim bool isChar32Type() const; 1509200583Srdivacky bool isAnyCharacterType() const; 1510210299Sed bool isIntegralType(ASTContext &Ctx) const; 1511234353Sdim 1512210299Sed /// \brief Determine whether this type is an integral or enumeration type. 1513210299Sed bool isIntegralOrEnumerationType() const; 1514218893Sdim /// \brief Determine whether this type is an integral or unscoped enumeration 1515218893Sdim /// type. 1516218893Sdim bool isIntegralOrUnscopedEnumerationType() const; 1517234353Sdim 1518193326Sed /// Floating point categories. 1519193326Sed bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) 1520193326Sed /// isComplexType() does *not* include complex integers (a GCC extension). 1521193326Sed /// isComplexIntegerType() can be used to test for complex integers. 1522193326Sed bool isComplexType() const; // C99 6.2.5p11 (complex) 1523193326Sed bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. 1524193326Sed bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) 1525226633Sdim bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) 1526193326Sed bool isRealType() const; // C99 6.2.5p17 (real floating + integer) 1527193326Sed bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) 1528193326Sed bool isVoidType() const; // C99 6.2.5p19 1529193326Sed bool isDerivedType() const; // C99 6.2.5p20 1530193326Sed bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) 1531193326Sed bool isAggregateType() const; 1532221345Sdim bool isFundamentalType() const; 1533221345Sdim bool isCompoundType() const; 1534198092Srdivacky 1535193326Sed // Type Predicates: Check to see if this type is structurally the specified 1536193326Sed // type, ignoring typedefs and qualifiers. 1537193326Sed bool isFunctionType() const; 1538198092Srdivacky bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } 1539198092Srdivacky bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } 1540193326Sed bool isPointerType() const; 1541198092Srdivacky bool isAnyPointerType() const; // Any C pointer or ObjC object pointer 1542193326Sed bool isBlockPointerType() const; 1543195341Sed bool isVoidPointerType() const; 1544193326Sed bool isReferenceType() const; 1545193326Sed bool isLValueReferenceType() const; 1546193326Sed bool isRValueReferenceType() const; 1547193326Sed bool isFunctionPointerType() const; 1548193326Sed bool isMemberPointerType() const; 1549193326Sed bool isMemberFunctionPointerType() const; 1550212904Sdim bool isMemberDataPointerType() const; 1551193326Sed bool isArrayType() const; 1552193326Sed bool isConstantArrayType() const; 1553193326Sed bool isIncompleteArrayType() const; 1554193326Sed bool isVariableArrayType() const; 1555193326Sed bool isDependentSizedArrayType() const; 1556193326Sed bool isRecordType() const; 1557198092Srdivacky bool isClassType() const; 1558198092Srdivacky bool isStructureType() const; 1559243830Sdim bool isInterfaceType() const; 1560207619Srdivacky bool isStructureOrClassType() const; 1561193326Sed bool isUnionType() const; 1562193326Sed bool isComplexIntegerType() const; // GCC _Complex integer type. 1563193326Sed bool isVectorType() const; // GCC vector type. 1564193326Sed bool isExtVectorType() const; // Extended vector type. 1565224145Sdim bool isObjCObjectPointerType() const; // pointer to ObjC object 1566224145Sdim bool isObjCRetainableType() const; // ObjC object or block pointer 1567224145Sdim bool isObjCLifetimeType() const; // (array of)* retainable type 1568224145Sdim bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type 1569224145Sdim bool isObjCNSObjectType() const; // __attribute__((NSObject)) 1570198092Srdivacky // FIXME: change this to 'raw' interface type, so we can used 'interface' type 1571198092Srdivacky // for the common case. 1572208600Srdivacky bool isObjCObjectType() const; // NSString or typeof(*(id)0) 1573193326Sed bool isObjCQualifiedInterfaceType() const; // NSString<foo> 1574193326Sed bool isObjCQualifiedIdType() const; // id<foo> 1575198092Srdivacky bool isObjCQualifiedClassType() const; // Class<foo> 1576212904Sdim bool isObjCObjectOrInterfaceType() const; 1577198092Srdivacky bool isObjCIdType() const; // id 1578198092Srdivacky bool isObjCClassType() const; // Class 1579199990Srdivacky bool isObjCSelType() const; // Class 1580198092Srdivacky bool isObjCBuiltinType() const; // 'id' or 'Class' 1581224145Sdim bool isObjCARCBridgableType() const; 1582224145Sdim bool isCARCBridgableType() const; 1583193326Sed bool isTemplateTypeParmType() const; // C++ template type parameter 1584193326Sed bool isNullPtrType() const; // C++0x nullptr_t 1585234353Sdim bool isAtomicType() const; // C11 _Atomic() 1586193326Sed 1587224145Sdim /// Determines if this type, which must satisfy 1588224145Sdim /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather 1589224145Sdim /// than implicitly __strong. 1590224145Sdim bool isObjCARCImplicitlyUnretainedType() const; 1591224145Sdim 1592224145Sdim /// Return the implicit lifetime for this type, which must not be dependent. 1593224145Sdim Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; 1594224145Sdim 1595218893Sdim enum ScalarTypeKind { 1596226633Sdim STK_CPointer, 1597226633Sdim STK_BlockPointer, 1598226633Sdim STK_ObjCObjectPointer, 1599218893Sdim STK_MemberPointer, 1600218893Sdim STK_Bool, 1601218893Sdim STK_Integral, 1602218893Sdim STK_Floating, 1603218893Sdim STK_IntegralComplex, 1604218893Sdim STK_FloatingComplex 1605218893Sdim }; 1606218893Sdim /// getScalarTypeKind - Given that this is a scalar type, classify it. 1607218893Sdim ScalarTypeKind getScalarTypeKind() const; 1608218893Sdim 1609193326Sed /// isDependentType - Whether this type is a dependent type, meaning 1610198092Srdivacky /// that its definition somehow depends on a template parameter 1611193326Sed /// (C++ [temp.dep.type]). 1612218893Sdim bool isDependentType() const { return TypeBits.Dependent; } 1613234353Sdim 1614224145Sdim /// \brief Determine whether this type is an instantiation-dependent type, 1615224145Sdim /// meaning that the type involves a template parameter (even if the 1616224145Sdim /// definition does not actually depend on the type substituted for that 1617224145Sdim /// template parameter). 1618234353Sdim bool isInstantiationDependentType() const { 1619234353Sdim return TypeBits.InstantiationDependent; 1620224145Sdim } 1621234353Sdim 1622218893Sdim /// \brief Whether this type is a variably-modified type (C99 6.7.5). 1623218893Sdim bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } 1624218893Sdim 1625218893Sdim /// \brief Whether this type involves a variable-length array type 1626218893Sdim /// with a definite size. 1627218893Sdim bool hasSizedVLAType() const; 1628234353Sdim 1629218893Sdim /// \brief Whether this type is or contains a local or unnamed type. 1630218893Sdim bool hasUnnamedOrLocalType() const; 1631234353Sdim 1632193326Sed bool isOverloadableType() const; 1633193326Sed 1634206084Srdivacky /// \brief Determine wither this type is a C++ elaborated-type-specifier. 1635206084Srdivacky bool isElaboratedTypeSpecifier() const; 1636224145Sdim 1637224145Sdim bool canDecayToPointerType() const; 1638234353Sdim 1639193326Sed /// hasPointerRepresentation - Whether this type is represented 1640193326Sed /// natively as a pointer; this includes pointers, references, block 1641193326Sed /// pointers, and Objective-C interface, qualified id, and qualified 1642193326Sed /// interface types, as well as nullptr_t. 1643193326Sed bool hasPointerRepresentation() const; 1644193326Sed 1645193326Sed /// hasObjCPointerRepresentation - Whether this type can represent 1646193326Sed /// an objective pointer type for the purpose of GC'ability 1647198092Srdivacky bool hasObjCPointerRepresentation() const; 1648193326Sed 1649212904Sdim /// \brief Determine whether this type has an integer representation 1650212904Sdim /// of some sort, e.g., it is an integer type or a vector. 1651212904Sdim bool hasIntegerRepresentation() const; 1652212904Sdim 1653212904Sdim /// \brief Determine whether this type has an signed integer representation 1654212904Sdim /// of some sort, e.g., it is an signed integer type or a vector. 1655212904Sdim bool hasSignedIntegerRepresentation() const; 1656212904Sdim 1657212904Sdim /// \brief Determine whether this type has an unsigned integer representation 1658212904Sdim /// of some sort, e.g., it is an unsigned integer type or a vector. 1659212904Sdim bool hasUnsignedIntegerRepresentation() const; 1660212904Sdim 1661210299Sed /// \brief Determine whether this type has a floating-point representation 1662210299Sed /// of some sort, e.g., it is a floating-point type or a vector thereof. 1663210299Sed bool hasFloatingRepresentation() const; 1664212904Sdim 1665193326Sed // Type Checking Functions: Check to see if this type is structurally the 1666193326Sed // specified type, ignoring typedefs and qualifiers, and return a pointer to 1667193326Sed // the best type we can. 1668193326Sed const RecordType *getAsStructureType() const; 1669193326Sed /// NOTE: getAs*ArrayType are methods on ASTContext. 1670193326Sed const RecordType *getAsUnionType() const; 1671193326Sed const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. 1672198092Srdivacky // The following is a convenience method that returns an ObjCObjectPointerType 1673198092Srdivacky // for object declared using an interface. 1674198092Srdivacky const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; 1675194613Sed const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; 1676221345Sdim const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; 1677208600Srdivacky const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; 1678193326Sed 1679207619Srdivacky /// \brief Retrieves the CXXRecordDecl that this type refers to, either 1680234353Sdim /// because the type is a RecordType or because it is the injected-class-name 1681207619Srdivacky /// type of a class template or class template partial specialization. 1682207619Srdivacky CXXRecordDecl *getAsCXXRecordDecl() const; 1683218893Sdim 1684243830Sdim /// If this is a pointer or reference to a RecordType, return the 1685243830Sdim /// CXXRecordDecl that that type refers to. 1686243830Sdim /// 1687243830Sdim /// If this is not a pointer or reference, or the type being pointed to does 1688243830Sdim /// not refer to a CXXRecordDecl, returns NULL. 1689243830Sdim const CXXRecordDecl *getPointeeCXXRecordDecl() const; 1690243830Sdim 1691218893Sdim /// \brief Get the AutoType whose type will be deduced for a variable with 1692218893Sdim /// an initializer of this type. This looks through declarators like pointer 1693218893Sdim /// types, but not through decltype or typedefs. 1694218893Sdim AutoType *getContainedAutoType() const; 1695234353Sdim 1696218893Sdim /// Member-template getAs<specific type>'. Look through sugar for 1697239462Sdim /// an instance of \<specific type>. This scheme will eventually 1698218893Sdim /// replace the specific getAsXXXX methods above. 1699218893Sdim /// 1700218893Sdim /// There are some specializations of this member template listed 1701218893Sdim /// immediately following this class. 1702198092Srdivacky template <typename T> const T *getAs() const; 1703198092Srdivacky 1704218893Sdim /// A variant of getAs<> for array types which silently discards 1705218893Sdim /// qualifiers from the outermost type. 1706218893Sdim const ArrayType *getAsArrayTypeUnsafe() const; 1707218893Sdim 1708218893Sdim /// Member-template castAs<specific type>. Look through sugar for 1709239462Sdim /// the underlying instance of \<specific type>. 1710218893Sdim /// 1711218893Sdim /// This method has the same relationship to getAs<T> as cast<T> has 1712218893Sdim /// to dyn_cast<T>; which is to say, the underlying type *must* 1713218893Sdim /// have the intended type, and this method will never return null. 1714218893Sdim template <typename T> const T *castAs() const; 1715218893Sdim 1716218893Sdim /// A variant of castAs<> for array type which silently discards 1717218893Sdim /// qualifiers from the outermost type. 1718218893Sdim const ArrayType *castAsArrayTypeUnsafe() const; 1719218893Sdim 1720218893Sdim /// getBaseElementTypeUnsafe - Get the base element type of this 1721218893Sdim /// type, potentially discarding type qualifiers. This method 1722218893Sdim /// should never be used when type qualifiers are meaningful. 1723218893Sdim const Type *getBaseElementTypeUnsafe() const; 1724218893Sdim 1725193326Sed /// getArrayElementTypeNoTypeQual - If this is an array type, return the 1726193326Sed /// element type of the array, potentially with type qualifiers missing. 1727193326Sed /// This method should never be used when type qualifiers are meaningful. 1728193326Sed const Type *getArrayElementTypeNoTypeQual() const; 1729198092Srdivacky 1730198092Srdivacky /// getPointeeType - If this is a pointer, ObjC object pointer, or block 1731198092Srdivacky /// pointer, this returns the respective pointee. 1732198092Srdivacky QualType getPointeeType() const; 1733198092Srdivacky 1734198092Srdivacky /// getUnqualifiedDesugaredType() - Return the specified type with 1735198092Srdivacky /// any "sugar" removed from the type, removing any typedefs, 1736198092Srdivacky /// typeofs, etc., as well as any qualifiers. 1737198092Srdivacky const Type *getUnqualifiedDesugaredType() const; 1738198092Srdivacky 1739193326Sed /// More type predicates useful for type checking/promotion 1740193326Sed bool isPromotableIntegerType() const; // C99 6.3.1.1p2 1741193326Sed 1742193326Sed /// isSignedIntegerType - Return true if this is an integer type that is 1743193326Sed /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], 1744223017Sdim /// or an enum decl which has a signed representation. 1745193326Sed bool isSignedIntegerType() const; 1746193326Sed 1747193326Sed /// isUnsignedIntegerType - Return true if this is an integer type that is 1748234353Sdim /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], 1749223017Sdim /// or an enum decl which has an unsigned representation. 1750193326Sed bool isUnsignedIntegerType() const; 1751193326Sed 1752234353Sdim /// Determines whether this is an integer type that is signed or an 1753223017Sdim /// enumeration types whose underlying type is a signed integer type. 1754223017Sdim bool isSignedIntegerOrEnumerationType() const; 1755234353Sdim 1756234353Sdim /// Determines whether this is an integer type that is unsigned or an 1757223017Sdim /// enumeration types whose underlying type is a unsigned integer type. 1758223017Sdim bool isUnsignedIntegerOrEnumerationType() const; 1759223017Sdim 1760193326Sed /// isConstantSizeType - Return true if this is not a variable sized type, 1761193326Sed /// according to the rules of C99 6.7.5p3. It is not legal to call this on 1762193326Sed /// incomplete types. 1763193326Sed bool isConstantSizeType() const; 1764193326Sed 1765193326Sed /// isSpecifierType - Returns true if this type can be represented by some 1766193326Sed /// set of type specifiers. 1767193326Sed bool isSpecifierType() const; 1768193326Sed 1769208600Srdivacky /// \brief Determine the linkage of this type. 1770208600Srdivacky Linkage getLinkage() const; 1771218893Sdim 1772218893Sdim /// \brief Determine the visibility of this type. 1773218893Sdim Visibility getVisibility() const; 1774218893Sdim 1775234353Sdim /// \brief Return true if the visibility was explicitly set is the code. 1776234353Sdim bool isVisibilityExplicit() const; 1777234353Sdim 1778218893Sdim /// \brief Determine the linkage and visibility of this type. 1779218893Sdim std::pair<Linkage,Visibility> getLinkageAndVisibility() const; 1780234353Sdim 1781208600Srdivacky /// \brief Note that the linkage is no longer known. 1782208600Srdivacky void ClearLinkageCache(); 1783234353Sdim 1784198092Srdivacky const char *getTypeClassName() const; 1785198092Srdivacky 1786204643Srdivacky QualType getCanonicalTypeInternal() const { 1787204643Srdivacky return CanonicalType; 1788204643Srdivacky } 1789204643Srdivacky CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h 1790234353Sdim LLVM_ATTRIBUTE_USED void dump() const; 1791224145Sdim 1792212904Sdim friend class ASTReader; 1793212904Sdim friend class ASTWriter; 1794193326Sed}; 1795193326Sed 1796239462Sdim/// \brief This will check for a TypedefType by removing any existing sugar 1797239462Sdim/// until it reaches a TypedefType or a non-sugared type. 1798239462Sdimtemplate <> const TypedefType *Type::getAs() const; 1799193326Sed 1800243830Sdim/// \brief This will check for a TemplateSpecializationType by removing any 1801243830Sdim/// existing sugar until it reaches a TemplateSpecializationType or a 1802243830Sdim/// non-sugared type. 1803243830Sdimtemplate <> const TemplateSpecializationType *Type::getAs() const; 1804243830Sdim 1805198092Srdivacky// We can do canonical leaf types faster, because we don't have to 1806198092Srdivacky// worry about preserving child type decoration. 1807198092Srdivacky#define TYPE(Class, Base) 1808198092Srdivacky#define LEAF_TYPE(Class) \ 1809198092Srdivackytemplate <> inline const Class##Type *Type::getAs() const { \ 1810198092Srdivacky return dyn_cast<Class##Type>(CanonicalType); \ 1811218893Sdim} \ 1812218893Sdimtemplate <> inline const Class##Type *Type::castAs() const { \ 1813218893Sdim return cast<Class##Type>(CanonicalType); \ 1814198092Srdivacky} 1815198092Srdivacky#include "clang/AST/TypeNodes.def" 1816193326Sed 1817193326Sed 1818193326Sed/// BuiltinType - This class is used for builtin types like 'int'. Builtin 1819193326Sed/// types are always canonical and have a literal name field. 1820193326Sedclass BuiltinType : public Type { 1821193326Sedpublic: 1822193326Sed enum Kind { 1823234353Sdim#define BUILTIN_TYPE(Id, SingletonId) Id, 1824234353Sdim#define LAST_BUILTIN_TYPE(Id) LastKind = Id 1825234353Sdim#include "clang/AST/BuiltinTypes.def" 1826193326Sed }; 1827218893Sdim 1828193326Sedpublic: 1829198092Srdivacky BuiltinType(Kind K) 1830218893Sdim : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), 1831224145Sdim /*InstantiationDependent=*/(K == Dependent), 1832218893Sdim /*VariablyModified=*/false, 1833218893Sdim /*Unexpanded paramter pack=*/false) { 1834218893Sdim BuiltinTypeBits.Kind = K; 1835218893Sdim } 1836198092Srdivacky 1837218893Sdim Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } 1838239462Sdim StringRef getName(const PrintingPolicy &Policy) const; 1839239462Sdim const char *getNameAsCString(const PrintingPolicy &Policy) const { 1840239462Sdim // The StringRef is null-terminated. 1841239462Sdim StringRef str = getName(Policy); 1842239462Sdim assert(!str.empty() && str.data()[str.size()] == '\0'); 1843239462Sdim return str.data(); 1844239462Sdim } 1845198092Srdivacky 1846198092Srdivacky bool isSugared() const { return false; } 1847198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1848198092Srdivacky 1849199482Srdivacky bool isInteger() const { 1850218893Sdim return getKind() >= Bool && getKind() <= Int128; 1851199482Srdivacky } 1852198092Srdivacky 1853199482Srdivacky bool isSignedInteger() const { 1854218893Sdim return getKind() >= Char_S && getKind() <= Int128; 1855199482Srdivacky } 1856199482Srdivacky 1857199482Srdivacky bool isUnsignedInteger() const { 1858218893Sdim return getKind() >= Bool && getKind() <= UInt128; 1859199482Srdivacky } 1860199482Srdivacky 1861199482Srdivacky bool isFloatingPoint() const { 1862226633Sdim return getKind() >= Half && getKind() <= LongDouble; 1863199482Srdivacky } 1864199482Srdivacky 1865234353Sdim /// Determines whether the given kind corresponds to a placeholder type. 1866234353Sdim static bool isPlaceholderTypeKind(Kind K) { 1867234353Sdim return K >= Overload; 1868234353Sdim } 1869234353Sdim 1870221345Sdim /// Determines whether this type is a placeholder type, i.e. a type 1871221345Sdim /// which cannot appear in arbitrary positions in a fully-formed 1872221345Sdim /// expression. 1873218893Sdim bool isPlaceholderType() const { 1874234353Sdim return isPlaceholderTypeKind(getKind()); 1875218893Sdim } 1876218893Sdim 1877234353Sdim /// Determines whether this type is a placeholder type other than 1878234353Sdim /// Overload. Most placeholder types require only syntactic 1879234353Sdim /// information about their context in order to be resolved (e.g. 1880234353Sdim /// whether it is a call expression), which means they can (and 1881234353Sdim /// should) be resolved in an earlier "phase" of analysis. 1882234353Sdim /// Overload expressions sometimes pick up further information 1883234353Sdim /// from their context, like whether the context expects a 1884234353Sdim /// specific function-pointer type, and so frequently need 1885234353Sdim /// special treatment. 1886234353Sdim bool isNonOverloadPlaceholderType() const { 1887234353Sdim return getKind() > Overload; 1888234353Sdim } 1889234353Sdim 1890193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } 1891193326Sed}; 1892193326Sed 1893193326Sed/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex 1894193326Sed/// types (_Complex float etc) as well as the GCC integer complex extensions. 1895193326Sed/// 1896193326Sedclass ComplexType : public Type, public llvm::FoldingSetNode { 1897193326Sed QualType ElementType; 1898193326Sed ComplexType(QualType Element, QualType CanonicalPtr) : 1899218893Sdim Type(Complex, CanonicalPtr, Element->isDependentType(), 1900224145Sdim Element->isInstantiationDependentType(), 1901218893Sdim Element->isVariablyModifiedType(), 1902218893Sdim Element->containsUnexpandedParameterPack()), 1903193326Sed ElementType(Element) { 1904193326Sed } 1905193326Sed friend class ASTContext; // ASTContext creates these. 1906208600Srdivacky 1907193326Sedpublic: 1908193326Sed QualType getElementType() const { return ElementType; } 1909198092Srdivacky 1910198092Srdivacky bool isSugared() const { return false; } 1911198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1912198092Srdivacky 1913193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 1914193326Sed Profile(ID, getElementType()); 1915193326Sed } 1916193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { 1917193326Sed ID.AddPointer(Element.getAsOpaquePtr()); 1918193326Sed } 1919198092Srdivacky 1920193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Complex; } 1921193326Sed}; 1922193326Sed 1923218893Sdim/// ParenType - Sugar for parentheses used when specifying types. 1924218893Sdim/// 1925218893Sdimclass ParenType : public Type, public llvm::FoldingSetNode { 1926218893Sdim QualType Inner; 1927218893Sdim 1928218893Sdim ParenType(QualType InnerType, QualType CanonType) : 1929218893Sdim Type(Paren, CanonType, InnerType->isDependentType(), 1930224145Sdim InnerType->isInstantiationDependentType(), 1931218893Sdim InnerType->isVariablyModifiedType(), 1932218893Sdim InnerType->containsUnexpandedParameterPack()), 1933218893Sdim Inner(InnerType) { 1934218893Sdim } 1935218893Sdim friend class ASTContext; // ASTContext creates these. 1936218893Sdim 1937218893Sdimpublic: 1938218893Sdim 1939218893Sdim QualType getInnerType() const { return Inner; } 1940218893Sdim 1941218893Sdim bool isSugared() const { return true; } 1942218893Sdim QualType desugar() const { return getInnerType(); } 1943218893Sdim 1944218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 1945218893Sdim Profile(ID, getInnerType()); 1946218893Sdim } 1947218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { 1948218893Sdim Inner.Profile(ID); 1949218893Sdim } 1950218893Sdim 1951218893Sdim static bool classof(const Type *T) { return T->getTypeClass() == Paren; } 1952218893Sdim}; 1953218893Sdim 1954193326Sed/// PointerType - C99 6.7.5.1 - Pointer Declarators. 1955193326Sed/// 1956193326Sedclass PointerType : public Type, public llvm::FoldingSetNode { 1957193326Sed QualType PointeeType; 1958193326Sed 1959193326Sed PointerType(QualType Pointee, QualType CanonicalPtr) : 1960218893Sdim Type(Pointer, CanonicalPtr, Pointee->isDependentType(), 1961224145Sdim Pointee->isInstantiationDependentType(), 1962218893Sdim Pointee->isVariablyModifiedType(), 1963234353Sdim Pointee->containsUnexpandedParameterPack()), 1964218893Sdim PointeeType(Pointee) { 1965193326Sed } 1966193326Sed friend class ASTContext; // ASTContext creates these. 1967208600Srdivacky 1968193326Sedpublic: 1969198092Srdivacky 1970193326Sed QualType getPointeeType() const { return PointeeType; } 1971193326Sed 1972198092Srdivacky bool isSugared() const { return false; } 1973198092Srdivacky QualType desugar() const { return QualType(this, 0); } 1974198092Srdivacky 1975193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 1976193326Sed Profile(ID, getPointeeType()); 1977193326Sed } 1978193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 1979193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 1980193326Sed } 1981198092Srdivacky 1982193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } 1983193326Sed}; 1984193326Sed 1985193326Sed/// BlockPointerType - pointer to a block type. 1986193326Sed/// This type is to represent types syntactically represented as 1987193326Sed/// "void (^)(int)", etc. Pointee is required to always be a function type. 1988193326Sed/// 1989193326Sedclass BlockPointerType : public Type, public llvm::FoldingSetNode { 1990193326Sed QualType PointeeType; // Block is some kind of pointer type 1991193326Sed BlockPointerType(QualType Pointee, QualType CanonicalCls) : 1992218893Sdim Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), 1993224145Sdim Pointee->isInstantiationDependentType(), 1994218893Sdim Pointee->isVariablyModifiedType(), 1995218893Sdim Pointee->containsUnexpandedParameterPack()), 1996193326Sed PointeeType(Pointee) { 1997193326Sed } 1998193326Sed friend class ASTContext; // ASTContext creates these. 1999234353Sdim 2000193326Sedpublic: 2001198092Srdivacky 2002193326Sed // Get the pointee type. Pointee is required to always be a function type. 2003193326Sed QualType getPointeeType() const { return PointeeType; } 2004193326Sed 2005198092Srdivacky bool isSugared() const { return false; } 2006198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2007198092Srdivacky 2008193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2009193326Sed Profile(ID, getPointeeType()); 2010193326Sed } 2011193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 2012193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 2013193326Sed } 2014198092Srdivacky 2015198092Srdivacky static bool classof(const Type *T) { 2016198092Srdivacky return T->getTypeClass() == BlockPointer; 2017193326Sed } 2018193326Sed}; 2019193326Sed 2020193326Sed/// ReferenceType - Base for LValueReferenceType and RValueReferenceType 2021193326Sed/// 2022193326Sedclass ReferenceType : public Type, public llvm::FoldingSetNode { 2023193326Sed QualType PointeeType; 2024193326Sed 2025193326Sedprotected: 2026198398Srdivacky ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, 2027198398Srdivacky bool SpelledAsLValue) : 2028218893Sdim Type(tc, CanonicalRef, Referencee->isDependentType(), 2029224145Sdim Referencee->isInstantiationDependentType(), 2030218893Sdim Referencee->isVariablyModifiedType(), 2031234353Sdim Referencee->containsUnexpandedParameterPack()), 2032234353Sdim PointeeType(Referencee) 2033218893Sdim { 2034218893Sdim ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; 2035218893Sdim ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); 2036193326Sed } 2037234353Sdim 2038193326Sedpublic: 2039218893Sdim bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } 2040218893Sdim bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } 2041234353Sdim 2042198398Srdivacky QualType getPointeeTypeAsWritten() const { return PointeeType; } 2043198398Srdivacky QualType getPointeeType() const { 2044198398Srdivacky // FIXME: this might strip inner qualifiers; okay? 2045198398Srdivacky const ReferenceType *T = this; 2046218893Sdim while (T->isInnerRef()) 2047218893Sdim T = T->PointeeType->castAs<ReferenceType>(); 2048198398Srdivacky return T->PointeeType; 2049198398Srdivacky } 2050198398Srdivacky 2051193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2052218893Sdim Profile(ID, PointeeType, isSpelledAsLValue()); 2053193326Sed } 2054198398Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 2055198398Srdivacky QualType Referencee, 2056198398Srdivacky bool SpelledAsLValue) { 2057193326Sed ID.AddPointer(Referencee.getAsOpaquePtr()); 2058198398Srdivacky ID.AddBoolean(SpelledAsLValue); 2059193326Sed } 2060193326Sed 2061193326Sed static bool classof(const Type *T) { 2062193326Sed return T->getTypeClass() == LValueReference || 2063193326Sed T->getTypeClass() == RValueReference; 2064193326Sed } 2065193326Sed}; 2066193326Sed 2067193326Sed/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference 2068193326Sed/// 2069193326Sedclass LValueReferenceType : public ReferenceType { 2070198398Srdivacky LValueReferenceType(QualType Referencee, QualType CanonicalRef, 2071198398Srdivacky bool SpelledAsLValue) : 2072198398Srdivacky ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue) 2073198398Srdivacky {} 2074193326Sed friend class ASTContext; // ASTContext creates these 2075193326Sedpublic: 2076198092Srdivacky bool isSugared() const { return false; } 2077198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2078198092Srdivacky 2079193326Sed static bool classof(const Type *T) { 2080193326Sed return T->getTypeClass() == LValueReference; 2081193326Sed } 2082193326Sed}; 2083193326Sed 2084193326Sed/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference 2085193326Sed/// 2086193326Sedclass RValueReferenceType : public ReferenceType { 2087193326Sed RValueReferenceType(QualType Referencee, QualType CanonicalRef) : 2088198398Srdivacky ReferenceType(RValueReference, Referencee, CanonicalRef, false) { 2089193326Sed } 2090193326Sed friend class ASTContext; // ASTContext creates these 2091193326Sedpublic: 2092198092Srdivacky bool isSugared() const { return false; } 2093198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2094198092Srdivacky 2095193326Sed static bool classof(const Type *T) { 2096193326Sed return T->getTypeClass() == RValueReference; 2097193326Sed } 2098193326Sed}; 2099193326Sed 2100193326Sed/// MemberPointerType - C++ 8.3.3 - Pointers to members 2101193326Sed/// 2102193326Sedclass MemberPointerType : public Type, public llvm::FoldingSetNode { 2103193326Sed QualType PointeeType; 2104193326Sed /// The class of which the pointee is a member. Must ultimately be a 2105193326Sed /// RecordType, but could be a typedef or a template parameter too. 2106193326Sed const Type *Class; 2107193326Sed 2108193326Sed MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : 2109193326Sed Type(MemberPointer, CanonicalPtr, 2110218893Sdim Cls->isDependentType() || Pointee->isDependentType(), 2111234353Sdim (Cls->isInstantiationDependentType() || 2112224145Sdim Pointee->isInstantiationDependentType()), 2113218893Sdim Pointee->isVariablyModifiedType(), 2114234353Sdim (Cls->containsUnexpandedParameterPack() || 2115218893Sdim Pointee->containsUnexpandedParameterPack())), 2116193326Sed PointeeType(Pointee), Class(Cls) { 2117193326Sed } 2118193326Sed friend class ASTContext; // ASTContext creates these. 2119234353Sdim 2120193326Sedpublic: 2121193326Sed QualType getPointeeType() const { return PointeeType; } 2122193326Sed 2123212904Sdim /// Returns true if the member type (i.e. the pointee type) is a 2124212904Sdim /// function type rather than a data-member type. 2125212904Sdim bool isMemberFunctionPointer() const { 2126212904Sdim return PointeeType->isFunctionProtoType(); 2127212904Sdim } 2128212904Sdim 2129212904Sdim /// Returns true if the member type (i.e. the pointee type) is a 2130212904Sdim /// data type rather than a function type. 2131212904Sdim bool isMemberDataPointer() const { 2132212904Sdim return !PointeeType->isFunctionProtoType(); 2133212904Sdim } 2134212904Sdim 2135193326Sed const Type *getClass() const { return Class; } 2136193326Sed 2137198092Srdivacky bool isSugared() const { return false; } 2138198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2139198092Srdivacky 2140193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2141193326Sed Profile(ID, getPointeeType(), getClass()); 2142193326Sed } 2143193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, 2144193326Sed const Type *Class) { 2145193326Sed ID.AddPointer(Pointee.getAsOpaquePtr()); 2146193326Sed ID.AddPointer(Class); 2147193326Sed } 2148193326Sed 2149193326Sed static bool classof(const Type *T) { 2150193326Sed return T->getTypeClass() == MemberPointer; 2151193326Sed } 2152193326Sed}; 2153193326Sed 2154193326Sed/// ArrayType - C99 6.7.5.2 - Array Declarators. 2155193326Sed/// 2156193326Sedclass ArrayType : public Type, public llvm::FoldingSetNode { 2157193326Sedpublic: 2158193326Sed /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4]) 2159193326Sed /// an array with a static size (e.g. int X[static 4]), or an array 2160193326Sed /// with a star size (e.g. int X[*]). 2161193326Sed /// 'static' is only allowed on function parameters. 2162193326Sed enum ArraySizeModifier { 2163193326Sed Normal, Static, Star 2164193326Sed }; 2165193326Sedprivate: 2166193326Sed /// ElementType - The element type of the array. 2167193326Sed QualType ElementType; 2168198092Srdivacky 2169193326Sedprotected: 2170193326Sed // C++ [temp.dep.type]p1: 2171193326Sed // A type is dependent if it is... 2172193326Sed // - an array type constructed from any dependent type or whose 2173193326Sed // size is specified by a constant expression that is 2174193326Sed // value-dependent, 2175193326Sed ArrayType(TypeClass tc, QualType et, QualType can, 2176218893Sdim ArraySizeModifier sm, unsigned tq, 2177218893Sdim bool ContainsUnexpandedParameterPack) 2178218893Sdim : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, 2179224145Sdim et->isInstantiationDependentType() || tc == DependentSizedArray, 2180218893Sdim (tc == VariableArray || et->isVariablyModifiedType()), 2181218893Sdim ContainsUnexpandedParameterPack), 2182218893Sdim ElementType(et) { 2183218893Sdim ArrayTypeBits.IndexTypeQuals = tq; 2184218893Sdim ArrayTypeBits.SizeModifier = sm; 2185218893Sdim } 2186193326Sed 2187193326Sed friend class ASTContext; // ASTContext creates these. 2188208600Srdivacky 2189193326Sedpublic: 2190193326Sed QualType getElementType() const { return ElementType; } 2191193326Sed ArraySizeModifier getSizeModifier() const { 2192218893Sdim return ArraySizeModifier(ArrayTypeBits.SizeModifier); 2193193326Sed } 2194198092Srdivacky Qualifiers getIndexTypeQualifiers() const { 2195218893Sdim return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); 2196198092Srdivacky } 2197218893Sdim unsigned getIndexTypeCVRQualifiers() const { 2198218893Sdim return ArrayTypeBits.IndexTypeQuals; 2199218893Sdim } 2200198092Srdivacky 2201193326Sed static bool classof(const Type *T) { 2202193326Sed return T->getTypeClass() == ConstantArray || 2203193326Sed T->getTypeClass() == VariableArray || 2204193326Sed T->getTypeClass() == IncompleteArray || 2205193326Sed T->getTypeClass() == DependentSizedArray; 2206193326Sed } 2207193326Sed}; 2208193326Sed 2209198092Srdivacky/// ConstantArrayType - This class represents the canonical version of 2210198092Srdivacky/// C arrays with a specified constant size. For example, the canonical 2211198092Srdivacky/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element 2212198092Srdivacky/// type is 'int' and the size is 404. 2213193326Sedclass ConstantArrayType : public ArrayType { 2214193326Sed llvm::APInt Size; // Allows us to unique the type. 2215198092Srdivacky 2216193326Sed ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, 2217193326Sed ArraySizeModifier sm, unsigned tq) 2218218893Sdim : ArrayType(ConstantArray, et, can, sm, tq, 2219218893Sdim et->containsUnexpandedParameterPack()), 2220198092Srdivacky Size(size) {} 2221198092Srdivackyprotected: 2222198092Srdivacky ConstantArrayType(TypeClass tc, QualType et, QualType can, 2223198092Srdivacky const llvm::APInt &size, ArraySizeModifier sm, unsigned tq) 2224234353Sdim : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()), 2225218893Sdim Size(size) {} 2226193326Sed friend class ASTContext; // ASTContext creates these. 2227193326Sedpublic: 2228193326Sed const llvm::APInt &getSize() const { return Size; } 2229198092Srdivacky bool isSugared() const { return false; } 2230198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2231198092Srdivacky 2232234353Sdim 2233212904Sdim /// \brief Determine the number of bits required to address a member of 2234212904Sdim // an array with the given element type and number of elements. 2235212904Sdim static unsigned getNumAddressingBits(ASTContext &Context, 2236212904Sdim QualType ElementType, 2237212904Sdim const llvm::APInt &NumElements); 2238234353Sdim 2239212904Sdim /// \brief Determine the maximum number of active bits that an array's size 2240212904Sdim /// can require, which limits the maximum size of the array. 2241212904Sdim static unsigned getMaxSizeBits(ASTContext &Context); 2242234353Sdim 2243193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2244198092Srdivacky Profile(ID, getElementType(), getSize(), 2245198092Srdivacky getSizeModifier(), getIndexTypeCVRQualifiers()); 2246193326Sed } 2247193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, 2248193326Sed const llvm::APInt &ArraySize, ArraySizeModifier SizeMod, 2249193326Sed unsigned TypeQuals) { 2250193326Sed ID.AddPointer(ET.getAsOpaquePtr()); 2251193326Sed ID.AddInteger(ArraySize.getZExtValue()); 2252193326Sed ID.AddInteger(SizeMod); 2253193326Sed ID.AddInteger(TypeQuals); 2254193326Sed } 2255198092Srdivacky static bool classof(const Type *T) { 2256198398Srdivacky return T->getTypeClass() == ConstantArray; 2257193326Sed } 2258193326Sed}; 2259193326Sed 2260193326Sed/// IncompleteArrayType - This class represents C arrays with an unspecified 2261193326Sed/// size. For example 'int A[]' has an IncompleteArrayType where the element 2262193326Sed/// type is 'int' and the size is unspecified. 2263193326Sedclass IncompleteArrayType : public ArrayType { 2264198092Srdivacky 2265193326Sed IncompleteArrayType(QualType et, QualType can, 2266198092Srdivacky ArraySizeModifier sm, unsigned tq) 2267234353Sdim : ArrayType(IncompleteArray, et, can, sm, tq, 2268218893Sdim et->containsUnexpandedParameterPack()) {} 2269193326Sed friend class ASTContext; // ASTContext creates these. 2270193326Sedpublic: 2271198092Srdivacky bool isSugared() const { return false; } 2272198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2273193326Sed 2274198092Srdivacky static bool classof(const Type *T) { 2275198092Srdivacky return T->getTypeClass() == IncompleteArray; 2276193326Sed } 2277198092Srdivacky 2278193326Sed friend class StmtIteratorBase; 2279198092Srdivacky 2280193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2281198092Srdivacky Profile(ID, getElementType(), getSizeModifier(), 2282198092Srdivacky getIndexTypeCVRQualifiers()); 2283193326Sed } 2284198092Srdivacky 2285193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, 2286193326Sed ArraySizeModifier SizeMod, unsigned TypeQuals) { 2287193326Sed ID.AddPointer(ET.getAsOpaquePtr()); 2288193326Sed ID.AddInteger(SizeMod); 2289193326Sed ID.AddInteger(TypeQuals); 2290193326Sed } 2291193326Sed}; 2292193326Sed 2293193326Sed/// VariableArrayType - This class represents C arrays with a specified size 2294193326Sed/// which is not an integer-constant-expression. For example, 'int s[x+foo()]'. 2295193326Sed/// Since the size expression is an arbitrary expression, we store it as such. 2296193326Sed/// 2297193326Sed/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and 2298193326Sed/// should not be: two lexically equivalent variable array types could mean 2299193326Sed/// different things, for example, these variables do not have the same type 2300193326Sed/// dynamically: 2301193326Sed/// 2302193326Sed/// void foo(int x) { 2303193326Sed/// int Y[x]; 2304193326Sed/// ++x; 2305193326Sed/// int Z[x]; 2306193326Sed/// } 2307193326Sed/// 2308193326Sedclass VariableArrayType : public ArrayType { 2309198092Srdivacky /// SizeExpr - An assignment expression. VLA's are only permitted within 2310198092Srdivacky /// a function block. 2311193326Sed Stmt *SizeExpr; 2312198092Srdivacky /// Brackets - The left and right array brackets. 2313198092Srdivacky SourceRange Brackets; 2314198092Srdivacky 2315193326Sed VariableArrayType(QualType et, QualType can, Expr *e, 2316198092Srdivacky ArraySizeModifier sm, unsigned tq, 2317198092Srdivacky SourceRange brackets) 2318234353Sdim : ArrayType(VariableArray, et, can, sm, tq, 2319218893Sdim et->containsUnexpandedParameterPack()), 2320198092Srdivacky SizeExpr((Stmt*) e), Brackets(brackets) {} 2321193326Sed friend class ASTContext; // ASTContext creates these. 2322193326Sed 2323193326Sedpublic: 2324198092Srdivacky Expr *getSizeExpr() const { 2325193326Sed // We use C-style casts instead of cast<> here because we do not wish 2326193326Sed // to have a dependency of Type.h on Stmt.h/Expr.h. 2327193326Sed return (Expr*) SizeExpr; 2328193326Sed } 2329198092Srdivacky SourceRange getBracketsRange() const { return Brackets; } 2330198092Srdivacky SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } 2331198092Srdivacky SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } 2332198092Srdivacky 2333198092Srdivacky bool isSugared() const { return false; } 2334198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2335198092Srdivacky 2336198092Srdivacky static bool classof(const Type *T) { 2337198092Srdivacky return T->getTypeClass() == VariableArray; 2338193326Sed } 2339198092Srdivacky 2340193326Sed friend class StmtIteratorBase; 2341198092Srdivacky 2342193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2343226633Sdim llvm_unreachable("Cannot unique VariableArrayTypes."); 2344193326Sed } 2345193326Sed}; 2346193326Sed 2347193326Sed/// DependentSizedArrayType - This type represents an array type in 2348193326Sed/// C++ whose size is a value-dependent expression. For example: 2349199990Srdivacky/// 2350199990Srdivacky/// \code 2351198092Srdivacky/// template<typename T, int Size> 2352193326Sed/// class array { 2353193326Sed/// T data[Size]; 2354193326Sed/// }; 2355199990Srdivacky/// \endcode 2356199990Srdivacky/// 2357193326Sed/// For these types, we won't actually know what the array bound is 2358193326Sed/// until template instantiation occurs, at which point this will 2359193326Sed/// become either a ConstantArrayType or a VariableArrayType. 2360193326Sedclass DependentSizedArrayType : public ArrayType { 2361218893Sdim const ASTContext &Context; 2362198092Srdivacky 2363199990Srdivacky /// \brief An assignment expression that will instantiate to the 2364193326Sed /// size of the array. 2365199990Srdivacky /// 2366199990Srdivacky /// The expression itself might be NULL, in which case the array 2367199990Srdivacky /// type will have its size deduced from an initializer. 2368193326Sed Stmt *SizeExpr; 2369199990Srdivacky 2370198092Srdivacky /// Brackets - The left and right array brackets. 2371198092Srdivacky SourceRange Brackets; 2372198092Srdivacky 2373218893Sdim DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, 2374198092Srdivacky Expr *e, ArraySizeModifier sm, unsigned tq, 2375218893Sdim SourceRange brackets); 2376218893Sdim 2377193326Sed friend class ASTContext; // ASTContext creates these. 2378193326Sed 2379193326Sedpublic: 2380198092Srdivacky Expr *getSizeExpr() const { 2381193326Sed // We use C-style casts instead of cast<> here because we do not wish 2382193326Sed // to have a dependency of Type.h on Stmt.h/Expr.h. 2383193326Sed return (Expr*) SizeExpr; 2384193326Sed } 2385198092Srdivacky SourceRange getBracketsRange() const { return Brackets; } 2386198092Srdivacky SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } 2387198092Srdivacky SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } 2388198092Srdivacky 2389198092Srdivacky bool isSugared() const { return false; } 2390198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2391198092Srdivacky 2392198092Srdivacky static bool classof(const Type *T) { 2393198092Srdivacky return T->getTypeClass() == DependentSizedArray; 2394193326Sed } 2395198092Srdivacky 2396193326Sed friend class StmtIteratorBase; 2397198092Srdivacky 2398198092Srdivacky 2399193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2400198092Srdivacky Profile(ID, Context, getElementType(), 2401198092Srdivacky getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); 2402193326Sed } 2403198092Srdivacky 2404218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 2405198092Srdivacky QualType ET, ArraySizeModifier SizeMod, 2406198092Srdivacky unsigned TypeQuals, Expr *E); 2407193326Sed}; 2408193326Sed 2409194613Sed/// DependentSizedExtVectorType - This type represent an extended vector type 2410194613Sed/// where either the type or size is dependent. For example: 2411194613Sed/// @code 2412194613Sed/// template<typename T, int Size> 2413194613Sed/// class vector { 2414194613Sed/// typedef T __attribute__((ext_vector_type(Size))) type; 2415194613Sed/// } 2416194613Sed/// @endcode 2417198092Srdivackyclass DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { 2418218893Sdim const ASTContext &Context; 2419194613Sed Expr *SizeExpr; 2420194613Sed /// ElementType - The element type of the array. 2421194613Sed QualType ElementType; 2422194613Sed SourceLocation loc; 2423198092Srdivacky 2424218893Sdim DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, 2425218893Sdim QualType can, Expr *SizeExpr, SourceLocation loc); 2426218893Sdim 2427194613Sed friend class ASTContext; 2428194613Sed 2429194613Sedpublic: 2430198092Srdivacky Expr *getSizeExpr() const { return SizeExpr; } 2431194613Sed QualType getElementType() const { return ElementType; } 2432194613Sed SourceLocation getAttributeLoc() const { return loc; } 2433194613Sed 2434198092Srdivacky bool isSugared() const { return false; } 2435198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2436198092Srdivacky 2437198092Srdivacky static bool classof(const Type *T) { 2438198092Srdivacky return T->getTypeClass() == DependentSizedExtVector; 2439194613Sed } 2440198092Srdivacky 2441198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 2442198092Srdivacky Profile(ID, Context, getElementType(), getSizeExpr()); 2443198092Srdivacky } 2444198092Srdivacky 2445218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 2446198092Srdivacky QualType ElementType, Expr *SizeExpr); 2447194613Sed}; 2448194613Sed 2449198092Srdivacky 2450193326Sed/// VectorType - GCC generic vector type. This type is created using 2451198092Srdivacky/// __attribute__((vector_size(n)), where "n" specifies the vector size in 2452203955Srdivacky/// bytes; or from an Altivec __vector or vector declaration. 2453203955Srdivacky/// Since the constructor takes the number of vector elements, the 2454193326Sed/// client is responsible for converting the size into the number of elements. 2455193326Sedclass VectorType : public Type, public llvm::FoldingSetNode { 2456210299Sedpublic: 2457218893Sdim enum VectorKind { 2458218893Sdim GenericVector, // not a target-specific vector type 2459218893Sdim AltiVecVector, // is AltiVec vector 2460218893Sdim AltiVecPixel, // is AltiVec 'vector Pixel' 2461218893Sdim AltiVecBool, // is AltiVec 'vector bool ...' 2462218893Sdim NeonVector, // is ARM Neon vector 2463218893Sdim NeonPolyVector // is ARM Neon polynomial vector 2464210299Sed }; 2465193326Sedprotected: 2466193326Sed /// ElementType - The element type of the vector. 2467193326Sed QualType ElementType; 2468198092Srdivacky 2469203955Srdivacky VectorType(QualType vecType, unsigned nElements, QualType canonType, 2470218893Sdim VectorKind vecKind); 2471234353Sdim 2472198092Srdivacky VectorType(TypeClass tc, QualType vecType, unsigned nElements, 2473218893Sdim QualType canonType, VectorKind vecKind); 2474218893Sdim 2475193326Sed friend class ASTContext; // ASTContext creates these. 2476234353Sdim 2477193326Sedpublic: 2478198092Srdivacky 2479193326Sed QualType getElementType() const { return ElementType; } 2480218893Sdim unsigned getNumElements() const { return VectorTypeBits.NumElements; } 2481193326Sed 2482198092Srdivacky bool isSugared() const { return false; } 2483198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2484198092Srdivacky 2485218893Sdim VectorKind getVectorKind() const { 2486218893Sdim return VectorKind(VectorTypeBits.VecKind); 2487218893Sdim } 2488210299Sed 2489193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2490218893Sdim Profile(ID, getElementType(), getNumElements(), 2491218893Sdim getTypeClass(), getVectorKind()); 2492193326Sed } 2493198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, 2494203955Srdivacky unsigned NumElements, TypeClass TypeClass, 2495218893Sdim VectorKind VecKind) { 2496193326Sed ID.AddPointer(ElementType.getAsOpaquePtr()); 2497193326Sed ID.AddInteger(NumElements); 2498193326Sed ID.AddInteger(TypeClass); 2499218893Sdim ID.AddInteger(VecKind); 2500193326Sed } 2501203955Srdivacky 2502198092Srdivacky static bool classof(const Type *T) { 2503198092Srdivacky return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; 2504193326Sed } 2505193326Sed}; 2506193326Sed 2507193326Sed/// ExtVectorType - Extended vector type. This type is created using 2508193326Sed/// __attribute__((ext_vector_type(n)), where "n" is the number of elements. 2509193326Sed/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This 2510193326Sed/// class enables syntactic extensions, like Vector Components for accessing 2511193326Sed/// points, colors, and textures (modeled after OpenGL Shading Language). 2512193326Sedclass ExtVectorType : public VectorType { 2513193326Sed ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) : 2514218893Sdim VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} 2515193326Sed friend class ASTContext; // ASTContext creates these. 2516193326Sedpublic: 2517193326Sed static int getPointAccessorIdx(char c) { 2518193326Sed switch (c) { 2519193326Sed default: return -1; 2520193326Sed case 'x': return 0; 2521193326Sed case 'y': return 1; 2522193326Sed case 'z': return 2; 2523193326Sed case 'w': return 3; 2524193326Sed } 2525193326Sed } 2526193326Sed static int getNumericAccessorIdx(char c) { 2527193326Sed switch (c) { 2528193326Sed default: return -1; 2529193326Sed case '0': return 0; 2530193326Sed case '1': return 1; 2531193326Sed case '2': return 2; 2532193326Sed case '3': return 3; 2533193326Sed case '4': return 4; 2534193326Sed case '5': return 5; 2535193326Sed case '6': return 6; 2536193326Sed case '7': return 7; 2537193326Sed case '8': return 8; 2538193326Sed case '9': return 9; 2539195099Sed case 'A': 2540193326Sed case 'a': return 10; 2541195099Sed case 'B': 2542193326Sed case 'b': return 11; 2543195099Sed case 'C': 2544193326Sed case 'c': return 12; 2545195099Sed case 'D': 2546193326Sed case 'd': return 13; 2547195099Sed case 'E': 2548193326Sed case 'e': return 14; 2549195099Sed case 'F': 2550193326Sed case 'f': return 15; 2551193326Sed } 2552193326Sed } 2553198092Srdivacky 2554193326Sed static int getAccessorIdx(char c) { 2555193326Sed if (int idx = getPointAccessorIdx(c)+1) return idx-1; 2556193326Sed return getNumericAccessorIdx(c); 2557193326Sed } 2558198092Srdivacky 2559193326Sed bool isAccessorWithinNumElements(char c) const { 2560193326Sed if (int idx = getAccessorIdx(c)+1) 2561218893Sdim return unsigned(idx-1) < getNumElements(); 2562193326Sed return false; 2563193326Sed } 2564198092Srdivacky bool isSugared() const { return false; } 2565198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2566198092Srdivacky 2567198092Srdivacky static bool classof(const Type *T) { 2568198092Srdivacky return T->getTypeClass() == ExtVector; 2569193326Sed } 2570193326Sed}; 2571193326Sed 2572193326Sed/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base 2573193326Sed/// class of FunctionNoProtoType and FunctionProtoType. 2574193326Sed/// 2575193326Sedclass FunctionType : public Type { 2576193326Sed // The type returned by the function. 2577193326Sed QualType ResultType; 2578206084Srdivacky 2579206084Srdivacky public: 2580218893Sdim /// ExtInfo - A class which abstracts out some details necessary for 2581218893Sdim /// making a call. 2582218893Sdim /// 2583218893Sdim /// It is not actually used directly for storing this information in 2584218893Sdim /// a FunctionType, although FunctionType does currently use the 2585218893Sdim /// same bit-pattern. 2586218893Sdim /// 2587218893Sdim // If you add a field (say Foo), other than the obvious places (both, 2588218893Sdim // constructors, compile failures), what you need to update is 2589218893Sdim // * Operator== 2590206084Srdivacky // * getFoo 2591206084Srdivacky // * withFoo 2592206084Srdivacky // * functionType. Add Foo, getFoo. 2593206084Srdivacky // * ASTContext::getFooType 2594206084Srdivacky // * ASTContext::mergeFunctionTypes 2595206084Srdivacky // * FunctionNoProtoType::Profile 2596206084Srdivacky // * FunctionProtoType::Profile 2597206084Srdivacky // * TypePrinter::PrintFunctionProto 2598212904Sdim // * AST read and write 2599206084Srdivacky // * Codegen 2600218893Sdim class ExtInfo { 2601243830Sdim // Feel free to rearrange or add bits, but if you go over 9, 2602218893Sdim // you'll need to adjust both the Bits field below and 2603218893Sdim // Type::FunctionTypeBitfields. 2604206084Srdivacky 2605224145Sdim // | CC |noreturn|produces|regparm| 2606243830Sdim // |0 .. 3| 4 | 5 | 6 .. 8| 2607224145Sdim // 2608224145Sdim // regparm is either 0 (no regparm attribute) or the regparm value+1. 2609243830Sdim enum { CallConvMask = 0xF }; 2610243830Sdim enum { NoReturnMask = 0x10 }; 2611243830Sdim enum { ProducesResultMask = 0x20 }; 2612224145Sdim enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask), 2613243830Sdim RegParmOffset = 6 }; // Assumed to be the last field 2614218893Sdim 2615224145Sdim uint16_t Bits; 2616218893Sdim 2617224145Sdim ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} 2618218893Sdim 2619218893Sdim friend class FunctionType; 2620218893Sdim 2621206084Srdivacky public: 2622206084Srdivacky // Constructor with no defaults. Use this when you know that you 2623212904Sdim // have all the elements (when reading an AST file for example). 2624224145Sdim ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, 2625224145Sdim bool producesResult) { 2626224145Sdim assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); 2627218893Sdim Bits = ((unsigned) cc) | 2628218893Sdim (noReturn ? NoReturnMask : 0) | 2629224145Sdim (producesResult ? ProducesResultMask : 0) | 2630224145Sdim (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0); 2631218893Sdim } 2632206084Srdivacky 2633206084Srdivacky // Constructor with all defaults. Use when for example creating a 2634206084Srdivacky // function know to use defaults. 2635218893Sdim ExtInfo() : Bits(0) {} 2636206084Srdivacky 2637218893Sdim bool getNoReturn() const { return Bits & NoReturnMask; } 2638224145Sdim bool getProducesResult() const { return Bits & ProducesResultMask; } 2639224145Sdim bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } 2640234353Sdim unsigned getRegParm() const { 2641224145Sdim unsigned RegParm = Bits >> RegParmOffset; 2642224145Sdim if (RegParm > 0) 2643224145Sdim --RegParm; 2644224145Sdim return RegParm; 2645224145Sdim } 2646218893Sdim CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } 2647206084Srdivacky 2648218893Sdim bool operator==(ExtInfo Other) const { 2649218893Sdim return Bits == Other.Bits; 2650206084Srdivacky } 2651218893Sdim bool operator!=(ExtInfo Other) const { 2652218893Sdim return Bits != Other.Bits; 2653206084Srdivacky } 2654206084Srdivacky 2655206084Srdivacky // Note that we don't have setters. That is by design, use 2656206084Srdivacky // the following with methods instead of mutating these objects. 2657206084Srdivacky 2658206084Srdivacky ExtInfo withNoReturn(bool noReturn) const { 2659218893Sdim if (noReturn) 2660218893Sdim return ExtInfo(Bits | NoReturnMask); 2661218893Sdim else 2662218893Sdim return ExtInfo(Bits & ~NoReturnMask); 2663206084Srdivacky } 2664206084Srdivacky 2665224145Sdim ExtInfo withProducesResult(bool producesResult) const { 2666224145Sdim if (producesResult) 2667224145Sdim return ExtInfo(Bits | ProducesResultMask); 2668224145Sdim else 2669224145Sdim return ExtInfo(Bits & ~ProducesResultMask); 2670224145Sdim } 2671224145Sdim 2672206084Srdivacky ExtInfo withRegParm(unsigned RegParm) const { 2673224145Sdim assert(RegParm < 7 && "Invalid regparm value"); 2674224145Sdim return ExtInfo((Bits & ~RegParmMask) | 2675224145Sdim ((RegParm + 1) << RegParmOffset)); 2676206084Srdivacky } 2677206084Srdivacky 2678206084Srdivacky ExtInfo withCallingConv(CallingConv cc) const { 2679218893Sdim return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); 2680206084Srdivacky } 2681206084Srdivacky 2682218893Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 2683218893Sdim ID.AddInteger(Bits); 2684218893Sdim } 2685206084Srdivacky }; 2686206084Srdivacky 2687193326Sedprotected: 2688234353Sdim FunctionType(TypeClass tc, QualType res, 2689218893Sdim unsigned typeQuals, RefQualifierKind RefQualifier, 2690218893Sdim QualType Canonical, bool Dependent, 2691224145Sdim bool InstantiationDependent, 2692234353Sdim bool VariablyModified, bool ContainsUnexpandedParameterPack, 2693218893Sdim ExtInfo Info) 2694234353Sdim : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, 2695234353Sdim ContainsUnexpandedParameterPack), 2696218893Sdim ResultType(res) { 2697218893Sdim FunctionTypeBits.ExtInfo = Info.Bits; 2698218893Sdim FunctionTypeBits.TypeQuals = typeQuals; 2699218893Sdim FunctionTypeBits.RefQualifier = static_cast<unsigned>(RefQualifier); 2700218893Sdim } 2701218893Sdim unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; } 2702234353Sdim 2703218893Sdim RefQualifierKind getRefQualifier() const { 2704218893Sdim return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); 2705218893Sdim } 2706218893Sdim 2707193326Sedpublic: 2708198092Srdivacky 2709193326Sed QualType getResultType() const { return ResultType; } 2710221345Sdim 2711221345Sdim bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } 2712218893Sdim unsigned getRegParmType() const { return getExtInfo().getRegParm(); } 2713218893Sdim bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } 2714218893Sdim CallingConv getCallConv() const { return getExtInfo().getCC(); } 2715218893Sdim ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } 2716239462Sdim bool isConst() const { return getTypeQuals() & Qualifiers::Const; } 2717239462Sdim bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; } 2718239462Sdim bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; } 2719193326Sed 2720210299Sed /// \brief Determine the type of an expression that calls a function of 2721210299Sed /// this type. 2722234353Sdim QualType getCallResultType(ASTContext &Context) const { 2723210299Sed return getResultType().getNonLValueExprType(Context); 2724210299Sed } 2725210299Sed 2726226633Sdim static StringRef getNameForCallConv(CallingConv CC); 2727203955Srdivacky 2728193326Sed static bool classof(const Type *T) { 2729193326Sed return T->getTypeClass() == FunctionNoProto || 2730193326Sed T->getTypeClass() == FunctionProto; 2731193326Sed } 2732193326Sed}; 2733193326Sed 2734193326Sed/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has 2735193326Sed/// no information available about its arguments. 2736193326Sedclass FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { 2737218893Sdim FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) 2738234353Sdim : FunctionType(FunctionNoProto, Result, 0, RQ_None, Canonical, 2739224145Sdim /*Dependent=*/false, /*InstantiationDependent=*/false, 2740234353Sdim Result->isVariablyModifiedType(), 2741218893Sdim /*ContainsUnexpandedParameterPack=*/false, Info) {} 2742218893Sdim 2743193326Sed friend class ASTContext; // ASTContext creates these. 2744234353Sdim 2745193326Sedpublic: 2746193326Sed // No additional state past what FunctionType provides. 2747193326Sed 2748198092Srdivacky bool isSugared() const { return false; } 2749198092Srdivacky QualType desugar() const { return QualType(this, 0); } 2750198092Srdivacky 2751193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 2752206084Srdivacky Profile(ID, getResultType(), getExtInfo()); 2753193326Sed } 2754198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, 2755218893Sdim ExtInfo Info) { 2756218893Sdim Info.Profile(ID); 2757193326Sed ID.AddPointer(ResultType.getAsOpaquePtr()); 2758193326Sed } 2759198092Srdivacky 2760193326Sed static bool classof(const Type *T) { 2761193326Sed return T->getTypeClass() == FunctionNoProto; 2762193326Sed } 2763193326Sed}; 2764193326Sed 2765193326Sed/// FunctionProtoType - Represents a prototype with argument type info, e.g. 2766193326Sed/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no 2767193326Sed/// arguments, not as having a single void argument. Such a type can have an 2768193326Sed/// exception specification, but this specification is not part of the canonical 2769193326Sed/// type. 2770193326Sedclass FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { 2771218893Sdimpublic: 2772218893Sdim /// ExtProtoInfo - Extra information about a function prototype. 2773218893Sdim struct ExtProtoInfo { 2774218893Sdim ExtProtoInfo() : 2775234353Sdim Variadic(false), HasTrailingReturn(false), TypeQuals(0), 2776234353Sdim ExceptionSpecType(EST_None), RefQualifier(RQ_None), 2777234982Sdim NumExceptions(0), Exceptions(0), NoexceptExpr(0), 2778234982Sdim ExceptionSpecDecl(0), ExceptionSpecTemplate(0), 2779234982Sdim ConsumedArguments(0) {} 2780218893Sdim 2781218893Sdim FunctionType::ExtInfo ExtInfo; 2782234353Sdim bool Variadic : 1; 2783234353Sdim bool HasTrailingReturn : 1; 2784234353Sdim unsigned char TypeQuals; 2785221345Sdim ExceptionSpecificationType ExceptionSpecType; 2786218893Sdim RefQualifierKind RefQualifier; 2787218893Sdim unsigned NumExceptions; 2788218893Sdim const QualType *Exceptions; 2789221345Sdim Expr *NoexceptExpr; 2790234982Sdim FunctionDecl *ExceptionSpecDecl; 2791234982Sdim FunctionDecl *ExceptionSpecTemplate; 2792224145Sdim const bool *ConsumedArguments; 2793218893Sdim }; 2794218893Sdim 2795218893Sdimprivate: 2796218893Sdim /// \brief Determine whether there are any argument types that 2797218893Sdim /// contain an unexpanded parameter pack. 2798234353Sdim static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, 2799218893Sdim unsigned numArgs) { 2800193326Sed for (unsigned Idx = 0; Idx < numArgs; ++Idx) 2801218893Sdim if (ArgArray[Idx]->containsUnexpandedParameterPack()) 2802218893Sdim return true; 2803193326Sed 2804193326Sed return false; 2805193326Sed } 2806193326Sed 2807218893Sdim FunctionProtoType(QualType result, const QualType *args, unsigned numArgs, 2808218893Sdim QualType canonical, const ExtProtoInfo &epi); 2809193326Sed 2810193326Sed /// NumArgs - The number of arguments this function has, not counting '...'. 2811234353Sdim unsigned NumArgs : 17; 2812193326Sed 2813193326Sed /// NumExceptions - The number of types in the exception spec, if any. 2814221345Sdim unsigned NumExceptions : 9; 2815193326Sed 2816221345Sdim /// ExceptionSpecType - The type of exception specification this function has. 2817221345Sdim unsigned ExceptionSpecType : 3; 2818193326Sed 2819224145Sdim /// HasAnyConsumedArgs - Whether this function has any consumed arguments. 2820224145Sdim unsigned HasAnyConsumedArgs : 1; 2821224145Sdim 2822234353Sdim /// Variadic - Whether the function is variadic. 2823234353Sdim unsigned Variadic : 1; 2824234353Sdim 2825234353Sdim /// HasTrailingReturn - Whether this function has a trailing return type. 2826234353Sdim unsigned HasTrailingReturn : 1; 2827234353Sdim 2828234353Sdim // ArgInfo - There is an variable size array after the class in memory that 2829234353Sdim // holds the argument types. 2830234353Sdim 2831234353Sdim // Exceptions - There is another variable size array after ArgInfo that 2832234353Sdim // holds the exception types. 2833234353Sdim 2834234353Sdim // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing 2835234353Sdim // to the expression in the noexcept() specifier. 2836234353Sdim 2837234982Sdim // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may 2838234982Sdim // be a pair of FunctionDecl* pointing to the function which should be used to 2839234982Sdim // instantiate this function type's exception specification, and the function 2840234982Sdim // from which it should be instantiated. 2841234982Sdim 2842234353Sdim // ConsumedArgs - A variable size array, following Exceptions 2843234353Sdim // and of length NumArgs, holding flags indicating which arguments 2844234353Sdim // are consumed. This only appears if HasAnyConsumedArgs is true. 2845234353Sdim 2846193326Sed friend class ASTContext; // ASTContext creates these. 2847193326Sed 2848224145Sdim const bool *getConsumedArgsBuffer() const { 2849224145Sdim assert(hasAnyConsumedArgs()); 2850224145Sdim 2851224145Sdim // Find the end of the exceptions. 2852224145Sdim Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end()); 2853224145Sdim if (getExceptionSpecType() != EST_ComputedNoexcept) 2854224145Sdim eh_end += NumExceptions; 2855224145Sdim else 2856224145Sdim eh_end += 1; // NoexceptExpr 2857224145Sdim 2858224145Sdim return reinterpret_cast<const bool*>(eh_end); 2859224145Sdim } 2860224145Sdim 2861193326Sedpublic: 2862193326Sed unsigned getNumArgs() const { return NumArgs; } 2863193326Sed QualType getArgType(unsigned i) const { 2864193326Sed assert(i < NumArgs && "Invalid argument number!"); 2865193326Sed return arg_type_begin()[i]; 2866193326Sed } 2867193326Sed 2868218893Sdim ExtProtoInfo getExtProtoInfo() const { 2869218893Sdim ExtProtoInfo EPI; 2870218893Sdim EPI.ExtInfo = getExtInfo(); 2871218893Sdim EPI.Variadic = isVariadic(); 2872234353Sdim EPI.HasTrailingReturn = hasTrailingReturn(); 2873221345Sdim EPI.ExceptionSpecType = getExceptionSpecType(); 2874218893Sdim EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals()); 2875218893Sdim EPI.RefQualifier = getRefQualifier(); 2876221345Sdim if (EPI.ExceptionSpecType == EST_Dynamic) { 2877221345Sdim EPI.NumExceptions = NumExceptions; 2878221345Sdim EPI.Exceptions = exception_begin(); 2879221345Sdim } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 2880221345Sdim EPI.NoexceptExpr = getNoexceptExpr(); 2881234982Sdim } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { 2882234982Sdim EPI.ExceptionSpecDecl = getExceptionSpecDecl(); 2883234982Sdim EPI.ExceptionSpecTemplate = getExceptionSpecTemplate(); 2884239462Sdim } else if (EPI.ExceptionSpecType == EST_Unevaluated) { 2885239462Sdim EPI.ExceptionSpecDecl = getExceptionSpecDecl(); 2886221345Sdim } 2887224145Sdim if (hasAnyConsumedArgs()) 2888224145Sdim EPI.ConsumedArguments = getConsumedArgsBuffer(); 2889218893Sdim return EPI; 2890218893Sdim } 2891218893Sdim 2892221345Sdim /// \brief Get the kind of exception specification on this function. 2893221345Sdim ExceptionSpecificationType getExceptionSpecType() const { 2894221345Sdim return static_cast<ExceptionSpecificationType>(ExceptionSpecType); 2895221345Sdim } 2896221345Sdim /// \brief Return whether this function has any kind of exception spec. 2897221345Sdim bool hasExceptionSpec() const { 2898221345Sdim return getExceptionSpecType() != EST_None; 2899221345Sdim } 2900221345Sdim /// \brief Return whether this function has a dynamic (throw) exception spec. 2901221345Sdim bool hasDynamicExceptionSpec() const { 2902221345Sdim return isDynamicExceptionSpec(getExceptionSpecType()); 2903221345Sdim } 2904221345Sdim /// \brief Return whether this function has a noexcept exception spec. 2905221345Sdim bool hasNoexceptExceptionSpec() const { 2906221345Sdim return isNoexceptExceptionSpec(getExceptionSpecType()); 2907221345Sdim } 2908221345Sdim /// \brief Result type of getNoexceptSpec(). 2909221345Sdim enum NoexceptResult { 2910221345Sdim NR_NoNoexcept, ///< There is no noexcept specifier. 2911221345Sdim NR_BadNoexcept, ///< The noexcept specifier has a bad expression. 2912221345Sdim NR_Dependent, ///< The noexcept specifier is dependent. 2913221345Sdim NR_Throw, ///< The noexcept specifier evaluates to false. 2914221345Sdim NR_Nothrow ///< The noexcept specifier evaluates to true. 2915221345Sdim }; 2916221345Sdim /// \brief Get the meaning of the noexcept spec on this function, if any. 2917221345Sdim NoexceptResult getNoexceptSpec(ASTContext &Ctx) const; 2918193326Sed unsigned getNumExceptions() const { return NumExceptions; } 2919193326Sed QualType getExceptionType(unsigned i) const { 2920193326Sed assert(i < NumExceptions && "Invalid exception number!"); 2921193326Sed return exception_begin()[i]; 2922193326Sed } 2923221345Sdim Expr *getNoexceptExpr() const { 2924221345Sdim if (getExceptionSpecType() != EST_ComputedNoexcept) 2925221345Sdim return 0; 2926221345Sdim // NoexceptExpr sits where the arguments end. 2927221345Sdim return *reinterpret_cast<Expr *const *>(arg_type_end()); 2928193326Sed } 2929239462Sdim /// \brief If this function type has an exception specification which hasn't 2930239462Sdim /// been determined yet (either because it has not been evaluated or because 2931239462Sdim /// it has not been instantiated), this is the function whose exception 2932239462Sdim /// specification is represented by this type. 2933234982Sdim FunctionDecl *getExceptionSpecDecl() const { 2934239462Sdim if (getExceptionSpecType() != EST_Uninstantiated && 2935239462Sdim getExceptionSpecType() != EST_Unevaluated) 2936234982Sdim return 0; 2937234982Sdim return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0]; 2938234982Sdim } 2939234982Sdim /// \brief If this function type has an uninstantiated exception 2940234982Sdim /// specification, this is the function whose exception specification 2941234982Sdim /// should be instantiated to find the exception specification for 2942234982Sdim /// this type. 2943234982Sdim FunctionDecl *getExceptionSpecTemplate() const { 2944234982Sdim if (getExceptionSpecType() != EST_Uninstantiated) 2945234982Sdim return 0; 2946234982Sdim return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1]; 2947234982Sdim } 2948221345Sdim bool isNothrow(ASTContext &Ctx) const { 2949221345Sdim ExceptionSpecificationType EST = getExceptionSpecType(); 2950239462Sdim assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); 2951221345Sdim if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) 2952221345Sdim return true; 2953221345Sdim if (EST != EST_ComputedNoexcept) 2954221345Sdim return false; 2955221345Sdim return getNoexceptSpec(Ctx) == NR_Nothrow; 2956221345Sdim } 2957193326Sed 2958234353Sdim bool isVariadic() const { return Variadic; } 2959221345Sdim 2960218893Sdim /// \brief Determines whether this function prototype contains a 2961218893Sdim /// parameter pack at the end. 2962218893Sdim /// 2963218893Sdim /// A function template whose last parameter is a parameter pack can be 2964218893Sdim /// called with an arbitrary number of arguments, much like a variadic 2965234353Sdim /// function. 2966218893Sdim bool isTemplateVariadic() const; 2967234353Sdim 2968234353Sdim bool hasTrailingReturn() const { return HasTrailingReturn; } 2969234353Sdim 2970193326Sed unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); } 2971198092Srdivacky 2972234353Sdim 2973218893Sdim /// \brief Retrieve the ref-qualifier associated with this function type. 2974218893Sdim RefQualifierKind getRefQualifier() const { 2975218893Sdim return FunctionType::getRefQualifier(); 2976218893Sdim } 2977234353Sdim 2978193326Sed typedef const QualType *arg_type_iterator; 2979193326Sed arg_type_iterator arg_type_begin() const { 2980193326Sed return reinterpret_cast<const QualType *>(this+1); 2981193326Sed } 2982193326Sed arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; } 2983193326Sed 2984193326Sed typedef const QualType *exception_iterator; 2985193326Sed exception_iterator exception_begin() const { 2986193326Sed // exceptions begin where arguments end 2987193326Sed return arg_type_end(); 2988193326Sed } 2989193326Sed exception_iterator exception_end() const { 2990221345Sdim if (getExceptionSpecType() != EST_Dynamic) 2991221345Sdim return exception_begin(); 2992193326Sed return exception_begin() + NumExceptions; 2993193326Sed } 2994193326Sed 2995224145Sdim bool hasAnyConsumedArgs() const { 2996224145Sdim return HasAnyConsumedArgs; 2997224145Sdim } 2998224145Sdim bool isArgConsumed(unsigned I) const { 2999224145Sdim assert(I < getNumArgs() && "argument index out of range!"); 3000224145Sdim if (hasAnyConsumedArgs()) 3001224145Sdim return getConsumedArgsBuffer()[I]; 3002224145Sdim return false; 3003224145Sdim } 3004224145Sdim 3005198092Srdivacky bool isSugared() const { return false; } 3006198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3007198092Srdivacky 3008239462Sdim // FIXME: Remove the string version. 3009234353Sdim void printExceptionSpecification(std::string &S, 3010243830Sdim const PrintingPolicy &Policy) const; 3011239462Sdim void printExceptionSpecification(raw_ostream &OS, 3012243830Sdim const PrintingPolicy &Policy) const; 3013234353Sdim 3014193326Sed static bool classof(const Type *T) { 3015193326Sed return T->getTypeClass() == FunctionProto; 3016193326Sed } 3017193326Sed 3018221345Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); 3019193326Sed static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, 3020193326Sed arg_type_iterator ArgTys, unsigned NumArgs, 3021221345Sdim const ExtProtoInfo &EPI, const ASTContext &Context); 3022193326Sed}; 3023193326Sed 3024193326Sed 3025200583Srdivacky/// \brief Represents the dependent type named by a dependently-scoped 3026200583Srdivacky/// typename using declaration, e.g. 3027200583Srdivacky/// using typename Base<T>::foo; 3028200583Srdivacky/// Template instantiation turns these into the underlying type. 3029200583Srdivackyclass UnresolvedUsingType : public Type { 3030200583Srdivacky UnresolvedUsingTypenameDecl *Decl; 3031200583Srdivacky 3032203955Srdivacky UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) 3033234353Sdim : Type(UnresolvedUsing, QualType(), true, true, false, 3034218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3035203955Srdivacky Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {} 3036200583Srdivacky friend class ASTContext; // ASTContext creates these. 3037200583Srdivackypublic: 3038200583Srdivacky 3039200583Srdivacky UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } 3040200583Srdivacky 3041200583Srdivacky bool isSugared() const { return false; } 3042200583Srdivacky QualType desugar() const { return QualType(this, 0); } 3043200583Srdivacky 3044200583Srdivacky static bool classof(const Type *T) { 3045200583Srdivacky return T->getTypeClass() == UnresolvedUsing; 3046200583Srdivacky } 3047200583Srdivacky 3048200583Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3049200583Srdivacky return Profile(ID, Decl); 3050200583Srdivacky } 3051200583Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 3052200583Srdivacky UnresolvedUsingTypenameDecl *D) { 3053200583Srdivacky ID.AddPointer(D); 3054200583Srdivacky } 3055200583Srdivacky}; 3056200583Srdivacky 3057200583Srdivacky 3058193326Sedclass TypedefType : public Type { 3059221345Sdim TypedefNameDecl *Decl; 3060193326Sedprotected: 3061221345Sdim TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) 3062234353Sdim : Type(tc, can, can->isDependentType(), 3063224145Sdim can->isInstantiationDependentType(), 3064234353Sdim can->isVariablyModifiedType(), 3065218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3066221345Sdim Decl(const_cast<TypedefNameDecl*>(D)) { 3067193326Sed assert(!isa<TypedefType>(can) && "Invalid canonical type"); 3068193326Sed } 3069193326Sed friend class ASTContext; // ASTContext creates these. 3070193326Sedpublic: 3071198092Srdivacky 3072221345Sdim TypedefNameDecl *getDecl() const { return Decl; } 3073198092Srdivacky 3074198092Srdivacky bool isSugared() const { return true; } 3075198092Srdivacky QualType desugar() const; 3076198092Srdivacky 3077193326Sed static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } 3078193326Sed}; 3079193326Sed 3080193326Sed/// TypeOfExprType (GCC extension). 3081193326Sedclass TypeOfExprType : public Type { 3082193326Sed Expr *TOExpr; 3083198092Srdivacky 3084198092Srdivackyprotected: 3085198092Srdivacky TypeOfExprType(Expr *E, QualType can = QualType()); 3086193326Sed friend class ASTContext; // ASTContext creates these. 3087193326Sedpublic: 3088193326Sed Expr *getUnderlyingExpr() const { return TOExpr; } 3089193326Sed 3090198092Srdivacky /// \brief Remove a single level of sugar. 3091198092Srdivacky QualType desugar() const; 3092198092Srdivacky 3093198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3094224145Sdim bool isSugared() const; 3095198092Srdivacky 3096193326Sed static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } 3097193326Sed}; 3098193326Sed 3099203955Srdivacky/// \brief Internal representation of canonical, dependent 3100198092Srdivacky/// typeof(expr) types. 3101203955Srdivacky/// 3102203955Srdivacky/// This class is used internally by the ASTContext to manage 3103203955Srdivacky/// canonical, dependent types, only. Clients will only see instances 3104203955Srdivacky/// of this class via TypeOfExprType nodes. 3105198092Srdivackyclass DependentTypeOfExprType 3106198092Srdivacky : public TypeOfExprType, public llvm::FoldingSetNode { 3107218893Sdim const ASTContext &Context; 3108198092Srdivacky 3109198092Srdivackypublic: 3110218893Sdim DependentTypeOfExprType(const ASTContext &Context, Expr *E) 3111198092Srdivacky : TypeOfExprType(E), Context(Context) { } 3112198092Srdivacky 3113198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3114198092Srdivacky Profile(ID, Context, getUnderlyingExpr()); 3115198092Srdivacky } 3116198092Srdivacky 3117218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 3118198092Srdivacky Expr *E); 3119198092Srdivacky}; 3120198092Srdivacky 3121193326Sed/// TypeOfType (GCC extension). 3122193326Sedclass TypeOfType : public Type { 3123193326Sed QualType TOType; 3124198092Srdivacky TypeOfType(QualType T, QualType can) 3125234353Sdim : Type(TypeOf, can, T->isDependentType(), 3126224145Sdim T->isInstantiationDependentType(), 3127234353Sdim T->isVariablyModifiedType(), 3128234353Sdim T->containsUnexpandedParameterPack()), 3129218893Sdim TOType(T) { 3130193326Sed assert(!isa<TypedefType>(can) && "Invalid canonical type"); 3131193326Sed } 3132193326Sed friend class ASTContext; // ASTContext creates these. 3133193326Sedpublic: 3134193326Sed QualType getUnderlyingType() const { return TOType; } 3135193326Sed 3136198092Srdivacky /// \brief Remove a single level of sugar. 3137198092Srdivacky QualType desugar() const { return getUnderlyingType(); } 3138198092Srdivacky 3139198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3140198092Srdivacky bool isSugared() const { return true; } 3141198092Srdivacky 3142193326Sed static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } 3143193326Sed}; 3144193326Sed 3145195099Sed/// DecltypeType (C++0x) 3146195099Sedclass DecltypeType : public Type { 3147195099Sed Expr *E; 3148198092Srdivacky QualType UnderlyingType; 3149198092Srdivacky 3150198092Srdivackyprotected: 3151198092Srdivacky DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); 3152195099Sed friend class ASTContext; // ASTContext creates these. 3153195099Sedpublic: 3154195099Sed Expr *getUnderlyingExpr() const { return E; } 3155198092Srdivacky QualType getUnderlyingType() const { return UnderlyingType; } 3156198092Srdivacky 3157198092Srdivacky /// \brief Remove a single level of sugar. 3158224145Sdim QualType desugar() const; 3159198092Srdivacky 3160198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3161224145Sdim bool isSugared() const; 3162198092Srdivacky 3163195099Sed static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } 3164195099Sed}; 3165198092Srdivacky 3166203955Srdivacky/// \brief Internal representation of canonical, dependent 3167203955Srdivacky/// decltype(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 DecltypeType nodes. 3172198092Srdivackyclass DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { 3173218893Sdim const ASTContext &Context; 3174198092Srdivacky 3175198092Srdivackypublic: 3176218893Sdim DependentDecltypeType(const ASTContext &Context, Expr *E); 3177198092Srdivacky 3178198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3179198092Srdivacky Profile(ID, Context, getUnderlyingExpr()); 3180198092Srdivacky } 3181198092Srdivacky 3182218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 3183198092Srdivacky Expr *E); 3184198092Srdivacky}; 3185198092Srdivacky 3186223017Sdim/// \brief A unary type transform, which is a type constructed from another 3187223017Sdimclass UnaryTransformType : public Type { 3188223017Sdimpublic: 3189223017Sdim enum UTTKind { 3190223017Sdim EnumUnderlyingType 3191223017Sdim }; 3192223017Sdim 3193223017Sdimprivate: 3194223017Sdim /// The untransformed type. 3195223017Sdim QualType BaseType; 3196223017Sdim /// The transformed type if not dependent, otherwise the same as BaseType. 3197223017Sdim QualType UnderlyingType; 3198223017Sdim 3199223017Sdim UTTKind UKind; 3200223017Sdimprotected: 3201223017Sdim UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, 3202223017Sdim QualType CanonicalTy); 3203223017Sdim friend class ASTContext; 3204223017Sdimpublic: 3205223017Sdim bool isSugared() const { return !isDependentType(); } 3206223017Sdim QualType desugar() const { return UnderlyingType; } 3207223017Sdim 3208223017Sdim QualType getUnderlyingType() const { return UnderlyingType; } 3209223017Sdim QualType getBaseType() const { return BaseType; } 3210223017Sdim 3211223017Sdim UTTKind getUTTKind() const { return UKind; } 3212234353Sdim 3213223017Sdim static bool classof(const Type *T) { 3214223017Sdim return T->getTypeClass() == UnaryTransform; 3215223017Sdim } 3216223017Sdim}; 3217223017Sdim 3218193326Sedclass TagType : public Type { 3219212904Sdim /// Stores the TagDecl associated with this type. The decl may point to any 3220212904Sdim /// TagDecl that declares the entity. 3221212904Sdim TagDecl * decl; 3222193326Sed 3223234353Sdim friend class ASTReader; 3224234353Sdim 3225193326Sedprotected: 3226203955Srdivacky TagType(TypeClass TC, const TagDecl *D, QualType can); 3227193326Sed 3228198092Srdivackypublic: 3229212904Sdim TagDecl *getDecl() const; 3230198092Srdivacky 3231193326Sed /// @brief Determines whether this type is in the process of being 3232198092Srdivacky /// defined. 3233212904Sdim bool isBeingDefined() const; 3234193326Sed 3235198092Srdivacky static bool classof(const Type *T) { 3236193326Sed return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; 3237193326Sed } 3238193326Sed}; 3239193326Sed 3240193326Sed/// RecordType - This is a helper class that allows the use of isa/cast/dyncast 3241193326Sed/// to detect TagType objects of structs/unions/classes. 3242193326Sedclass RecordType : public TagType { 3243193326Sedprotected: 3244203955Srdivacky explicit RecordType(const RecordDecl *D) 3245203955Srdivacky : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3246193326Sed explicit RecordType(TypeClass TC, RecordDecl *D) 3247203955Srdivacky : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3248193326Sed friend class ASTContext; // ASTContext creates these. 3249193326Sedpublic: 3250198092Srdivacky 3251193326Sed RecordDecl *getDecl() const { 3252193326Sed return reinterpret_cast<RecordDecl*>(TagType::getDecl()); 3253193326Sed } 3254198092Srdivacky 3255198092Srdivacky // FIXME: This predicate is a helper to QualType/Type. It needs to 3256193326Sed // recursively check all fields for const-ness. If any field is declared 3257198092Srdivacky // const, it needs to return false. 3258193326Sed bool hasConstFields() const { return false; } 3259193326Sed 3260198092Srdivacky bool isSugared() const { return false; } 3261198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3262198092Srdivacky 3263234353Sdim static bool classof(const Type *T) { return T->getTypeClass() == Record; } 3264193326Sed}; 3265193326Sed 3266193326Sed/// EnumType - This is a helper class that allows the use of isa/cast/dyncast 3267193326Sed/// to detect TagType objects of enums. 3268193326Sedclass EnumType : public TagType { 3269203955Srdivacky explicit EnumType(const EnumDecl *D) 3270203955Srdivacky : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { } 3271193326Sed friend class ASTContext; // ASTContext creates these. 3272193326Sedpublic: 3273198092Srdivacky 3274193326Sed EnumDecl *getDecl() const { 3275193326Sed return reinterpret_cast<EnumDecl*>(TagType::getDecl()); 3276193326Sed } 3277198092Srdivacky 3278198092Srdivacky bool isSugared() const { return false; } 3279198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3280198092Srdivacky 3281234353Sdim static bool classof(const Type *T) { return T->getTypeClass() == Enum; } 3282193326Sed}; 3283193326Sed 3284218893Sdim/// AttributedType - An attributed type is a type to which a type 3285218893Sdim/// attribute has been applied. The "modified type" is the 3286218893Sdim/// fully-sugared type to which the attributed type was applied; 3287218893Sdim/// generally it is not canonically equivalent to the attributed type. 3288218893Sdim/// The "equivalent type" is the minimally-desugared type which the 3289218893Sdim/// type is canonically equivalent to. 3290218893Sdim/// 3291218893Sdim/// For example, in the following attributed type: 3292218893Sdim/// int32_t __attribute__((vector_size(16))) 3293218893Sdim/// - the modified type is the TypedefType for int32_t 3294218893Sdim/// - the equivalent type is VectorType(16, int32_t) 3295218893Sdim/// - the canonical type is VectorType(16, int) 3296218893Sdimclass AttributedType : public Type, public llvm::FoldingSetNode { 3297218893Sdimpublic: 3298218893Sdim // It is really silly to have yet another attribute-kind enum, but 3299218893Sdim // clang::attr::Kind doesn't currently cover the pure type attrs. 3300218893Sdim enum Kind { 3301218893Sdim // Expression operand. 3302218893Sdim attr_address_space, 3303218893Sdim attr_regparm, 3304218893Sdim attr_vector_size, 3305218893Sdim attr_neon_vector_type, 3306218893Sdim attr_neon_polyvector_type, 3307218893Sdim 3308218893Sdim FirstExprOperandKind = attr_address_space, 3309218893Sdim LastExprOperandKind = attr_neon_polyvector_type, 3310218893Sdim 3311218893Sdim // Enumerated operand (string or keyword). 3312218893Sdim attr_objc_gc, 3313224145Sdim attr_objc_ownership, 3314221345Sdim attr_pcs, 3315218893Sdim 3316218893Sdim FirstEnumOperandKind = attr_objc_gc, 3317221345Sdim LastEnumOperandKind = attr_pcs, 3318218893Sdim 3319218893Sdim // No operand. 3320218893Sdim attr_noreturn, 3321218893Sdim attr_cdecl, 3322218893Sdim attr_fastcall, 3323218893Sdim attr_stdcall, 3324218893Sdim attr_thiscall, 3325243830Sdim attr_pascal, 3326243830Sdim attr_pnaclcall 3327218893Sdim }; 3328218893Sdim 3329218893Sdimprivate: 3330218893Sdim QualType ModifiedType; 3331218893Sdim QualType EquivalentType; 3332218893Sdim 3333218893Sdim friend class ASTContext; // creates these 3334218893Sdim 3335218893Sdim AttributedType(QualType canon, Kind attrKind, 3336218893Sdim QualType modified, QualType equivalent) 3337218893Sdim : Type(Attributed, canon, canon->isDependentType(), 3338224145Sdim canon->isInstantiationDependentType(), 3339218893Sdim canon->isVariablyModifiedType(), 3340218893Sdim canon->containsUnexpandedParameterPack()), 3341218893Sdim ModifiedType(modified), EquivalentType(equivalent) { 3342218893Sdim AttributedTypeBits.AttrKind = attrKind; 3343218893Sdim } 3344218893Sdim 3345218893Sdimpublic: 3346218893Sdim Kind getAttrKind() const { 3347218893Sdim return static_cast<Kind>(AttributedTypeBits.AttrKind); 3348218893Sdim } 3349218893Sdim 3350218893Sdim QualType getModifiedType() const { return ModifiedType; } 3351218893Sdim QualType getEquivalentType() const { return EquivalentType; } 3352218893Sdim 3353218893Sdim bool isSugared() const { return true; } 3354218893Sdim QualType desugar() const { return getEquivalentType(); } 3355218893Sdim 3356218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 3357218893Sdim Profile(ID, getAttrKind(), ModifiedType, EquivalentType); 3358218893Sdim } 3359218893Sdim 3360218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, 3361218893Sdim QualType modified, QualType equivalent) { 3362218893Sdim ID.AddInteger(attrKind); 3363218893Sdim ID.AddPointer(modified.getAsOpaquePtr()); 3364218893Sdim ID.AddPointer(equivalent.getAsOpaquePtr()); 3365218893Sdim } 3366218893Sdim 3367218893Sdim static bool classof(const Type *T) { 3368218893Sdim return T->getTypeClass() == Attributed; 3369218893Sdim } 3370218893Sdim}; 3371218893Sdim 3372193326Sedclass TemplateTypeParmType : public Type, public llvm::FoldingSetNode { 3373221345Sdim // Helper data collector for canonical types. 3374221345Sdim struct CanonicalTTPTInfo { 3375221345Sdim unsigned Depth : 15; 3376221345Sdim unsigned ParameterPack : 1; 3377221345Sdim unsigned Index : 16; 3378221345Sdim }; 3379193326Sed 3380221345Sdim union { 3381221345Sdim // Info for the canonical type. 3382221345Sdim CanonicalTTPTInfo CanTTPTInfo; 3383221345Sdim // Info for the non-canonical type. 3384221345Sdim TemplateTypeParmDecl *TTPDecl; 3385221345Sdim }; 3386221345Sdim 3387221345Sdim /// Build a non-canonical type. 3388221345Sdim TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) 3389218893Sdim : Type(TemplateTypeParm, Canon, /*Dependent=*/true, 3390224145Sdim /*InstantiationDependent=*/true, 3391221345Sdim /*VariablyModified=*/false, 3392221345Sdim Canon->containsUnexpandedParameterPack()), 3393221345Sdim TTPDecl(TTPDecl) { } 3394193326Sed 3395221345Sdim /// Build the canonical type. 3396198092Srdivacky TemplateTypeParmType(unsigned D, unsigned I, bool PP) 3397234353Sdim : Type(TemplateTypeParm, QualType(this, 0), 3398224145Sdim /*Dependent=*/true, 3399224145Sdim /*InstantiationDependent=*/true, 3400221345Sdim /*VariablyModified=*/false, PP) { 3401221345Sdim CanTTPTInfo.Depth = D; 3402221345Sdim CanTTPTInfo.Index = I; 3403221345Sdim CanTTPTInfo.ParameterPack = PP; 3404221345Sdim } 3405193326Sed 3406193326Sed friend class ASTContext; // ASTContext creates these 3407193326Sed 3408221345Sdim const CanonicalTTPTInfo& getCanTTPTInfo() const { 3409221345Sdim QualType Can = getCanonicalTypeInternal(); 3410221345Sdim return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo; 3411221345Sdim } 3412221345Sdim 3413193326Sedpublic: 3414221345Sdim unsigned getDepth() const { return getCanTTPTInfo().Depth; } 3415221345Sdim unsigned getIndex() const { return getCanTTPTInfo().Index; } 3416221345Sdim bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; } 3417193326Sed 3418221345Sdim TemplateTypeParmDecl *getDecl() const { 3419221345Sdim return isCanonicalUnqualified() ? 0 : TTPDecl; 3420221345Sdim } 3421221345Sdim 3422221345Sdim IdentifierInfo *getIdentifier() const; 3423221345Sdim 3424198092Srdivacky bool isSugared() const { return false; } 3425198092Srdivacky QualType desugar() const { return QualType(this, 0); } 3426198092Srdivacky 3427193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 3428221345Sdim Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); 3429193326Sed } 3430193326Sed 3431198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, 3432198092Srdivacky unsigned Index, bool ParameterPack, 3433221345Sdim TemplateTypeParmDecl *TTPDecl) { 3434193326Sed ID.AddInteger(Depth); 3435193326Sed ID.AddInteger(Index); 3436194613Sed ID.AddBoolean(ParameterPack); 3437221345Sdim ID.AddPointer(TTPDecl); 3438193326Sed } 3439193326Sed 3440198092Srdivacky static bool classof(const Type *T) { 3441198092Srdivacky return T->getTypeClass() == TemplateTypeParm; 3442193326Sed } 3443193326Sed}; 3444193326Sed 3445198398Srdivacky/// \brief Represents the result of substituting a type for a template 3446198398Srdivacky/// type parameter. 3447198398Srdivacky/// 3448198398Srdivacky/// Within an instantiated template, all template type parameters have 3449198398Srdivacky/// been replaced with these. They are used solely to record that a 3450198398Srdivacky/// type was originally written as a template type parameter; 3451198398Srdivacky/// therefore they are never canonical. 3452198398Srdivackyclass SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { 3453198398Srdivacky // The original type parameter. 3454198398Srdivacky const TemplateTypeParmType *Replaced; 3455198398Srdivacky 3456198398Srdivacky SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) 3457218893Sdim : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), 3458224145Sdim Canon->isInstantiationDependentType(), 3459218893Sdim Canon->isVariablyModifiedType(), 3460218893Sdim Canon->containsUnexpandedParameterPack()), 3461198398Srdivacky Replaced(Param) { } 3462198398Srdivacky 3463198398Srdivacky friend class ASTContext; 3464198398Srdivacky 3465198398Srdivackypublic: 3466198398Srdivacky /// Gets the template parameter that was substituted for. 3467198398Srdivacky const TemplateTypeParmType *getReplacedParameter() const { 3468198398Srdivacky return Replaced; 3469198398Srdivacky } 3470198398Srdivacky 3471198398Srdivacky /// Gets the type that was substituted for the template 3472198398Srdivacky /// parameter. 3473198398Srdivacky QualType getReplacementType() const { 3474198398Srdivacky return getCanonicalTypeInternal(); 3475198398Srdivacky } 3476198398Srdivacky 3477198398Srdivacky bool isSugared() const { return true; } 3478198398Srdivacky QualType desugar() const { return getReplacementType(); } 3479198398Srdivacky 3480198398Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 3481198398Srdivacky Profile(ID, getReplacedParameter(), getReplacementType()); 3482198398Srdivacky } 3483198398Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 3484198398Srdivacky const TemplateTypeParmType *Replaced, 3485198398Srdivacky QualType Replacement) { 3486198398Srdivacky ID.AddPointer(Replaced); 3487198398Srdivacky ID.AddPointer(Replacement.getAsOpaquePtr()); 3488198398Srdivacky } 3489198398Srdivacky 3490198398Srdivacky static bool classof(const Type *T) { 3491198398Srdivacky return T->getTypeClass() == SubstTemplateTypeParm; 3492198398Srdivacky } 3493198398Srdivacky}; 3494198398Srdivacky 3495218893Sdim/// \brief Represents the result of substituting a set of types for a template 3496218893Sdim/// type parameter pack. 3497218893Sdim/// 3498218893Sdim/// When a pack expansion in the source code contains multiple parameter packs 3499218893Sdim/// and those parameter packs correspond to different levels of template 3500234353Sdim/// parameter lists, this type node is used to represent a template type 3501218893Sdim/// parameter pack from an outer level, which has already had its argument pack 3502218893Sdim/// substituted but that still lives within a pack expansion that itself 3503218893Sdim/// could not be instantiated. When actually performing a substitution into 3504218893Sdim/// that pack expansion (e.g., when all template parameters have corresponding 3505218893Sdim/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType 3506218893Sdim/// at the current pack substitution index. 3507218893Sdimclass SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { 3508218893Sdim /// \brief The original type parameter. 3509218893Sdim const TemplateTypeParmType *Replaced; 3510234353Sdim 3511218893Sdim /// \brief A pointer to the set of template arguments that this 3512218893Sdim /// parameter pack is instantiated with. 3513218893Sdim const TemplateArgument *Arguments; 3514234353Sdim 3515218893Sdim /// \brief The number of template arguments in \c Arguments. 3516218893Sdim unsigned NumArguments; 3517234353Sdim 3518234353Sdim SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, 3519218893Sdim QualType Canon, 3520218893Sdim const TemplateArgument &ArgPack); 3521234353Sdim 3522218893Sdim friend class ASTContext; 3523234353Sdim 3524218893Sdimpublic: 3525221345Sdim IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } 3526234353Sdim 3527218893Sdim /// Gets the template parameter that was substituted for. 3528218893Sdim const TemplateTypeParmType *getReplacedParameter() const { 3529218893Sdim return Replaced; 3530218893Sdim } 3531234353Sdim 3532218893Sdim bool isSugared() const { return false; } 3533218893Sdim QualType desugar() const { return QualType(this, 0); } 3534234353Sdim 3535218893Sdim TemplateArgument getArgumentPack() const; 3536234353Sdim 3537218893Sdim void Profile(llvm::FoldingSetNodeID &ID); 3538218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, 3539218893Sdim const TemplateTypeParmType *Replaced, 3540218893Sdim const TemplateArgument &ArgPack); 3541234353Sdim 3542218893Sdim static bool classof(const Type *T) { 3543218893Sdim return T->getTypeClass() == SubstTemplateTypeParmPack; 3544218893Sdim } 3545218893Sdim}; 3546218893Sdim 3547218893Sdim/// \brief Represents a C++0x auto type. 3548218893Sdim/// 3549218893Sdim/// These types are usually a placeholder for a deduced type. However, within 3550218893Sdim/// templates and before the initializer is attached, there is no deduced type 3551218893Sdim/// and an auto type is type-dependent and canonical. 3552218893Sdimclass AutoType : public Type, public llvm::FoldingSetNode { 3553218893Sdim AutoType(QualType DeducedType) 3554218893Sdim : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, 3555218893Sdim /*Dependent=*/DeducedType.isNull(), 3556224145Sdim /*InstantiationDependent=*/DeducedType.isNull(), 3557218893Sdim /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { 3558218893Sdim assert((DeducedType.isNull() || !DeducedType->isDependentType()) && 3559218893Sdim "deduced a dependent type for auto"); 3560218893Sdim } 3561218893Sdim 3562218893Sdim friend class ASTContext; // ASTContext creates these 3563218893Sdim 3564218893Sdimpublic: 3565218893Sdim bool isSugared() const { return isDeduced(); } 3566218893Sdim QualType desugar() const { return getCanonicalTypeInternal(); } 3567218893Sdim 3568218893Sdim QualType getDeducedType() const { 3569218893Sdim return isDeduced() ? getCanonicalTypeInternal() : QualType(); 3570218893Sdim } 3571218893Sdim bool isDeduced() const { 3572218893Sdim return !isDependentType(); 3573218893Sdim } 3574218893Sdim 3575218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 3576218893Sdim Profile(ID, getDeducedType()); 3577218893Sdim } 3578218893Sdim 3579218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, 3580218893Sdim QualType Deduced) { 3581218893Sdim ID.AddPointer(Deduced.getAsOpaquePtr()); 3582218893Sdim } 3583218893Sdim 3584218893Sdim static bool classof(const Type *T) { 3585218893Sdim return T->getTypeClass() == Auto; 3586218893Sdim } 3587218893Sdim}; 3588218893Sdim 3589224145Sdim/// \brief Represents a type template specialization; the template 3590224145Sdim/// must be a class template, a type alias template, or a template 3591224145Sdim/// template parameter. A template which cannot be resolved to one of 3592224145Sdim/// these, e.g. because it is written with a dependent scope 3593224145Sdim/// specifier, is instead represented as a 3594224145Sdim/// @c DependentTemplateSpecializationType. 3595193326Sed/// 3596224145Sdim/// A non-dependent template specialization type is always "sugar", 3597224145Sdim/// typically for a @c RecordType. For example, a class template 3598224145Sdim/// specialization type of @c vector<int> will refer to a tag type for 3599224145Sdim/// the instantiation @c std::vector<int, std::allocator<int>> 3600193326Sed/// 3601224145Sdim/// Template specializations are dependent if either the template or 3602224145Sdim/// any of the template arguments are dependent, in which case the 3603224145Sdim/// type may also be canonical. 3604223017Sdim/// 3605224145Sdim/// Instances of this type are allocated with a trailing array of 3606224145Sdim/// TemplateArguments, followed by a QualType representing the 3607224145Sdim/// non-canonical aliased type when the template is a type alias 3608224145Sdim/// template. 3609198092Srdivackyclass TemplateSpecializationType 3610193326Sed : public Type, public llvm::FoldingSetNode { 3611224145Sdim /// \brief The name of the template being specialized. This is 3612224145Sdim /// either a TemplateName::Template (in which case it is a 3613224145Sdim /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a 3614224145Sdim /// TypeAliasTemplateDecl*), a 3615224145Sdim /// TemplateName::SubstTemplateTemplateParmPack, or a 3616224145Sdim /// TemplateName::SubstTemplateTemplateParm (in which case the 3617224145Sdim /// replacement must, recursively, be one of these). 3618193326Sed TemplateName Template; 3619193326Sed 3620193326Sed /// \brief - The number of template arguments named in this class 3621193326Sed /// template specialization. 3622234353Sdim unsigned NumArgs : 31; 3623193326Sed 3624234353Sdim /// \brief Whether this template specialization type is a substituted 3625234353Sdim /// type alias. 3626234353Sdim bool TypeAlias : 1; 3627234353Sdim 3628210299Sed TemplateSpecializationType(TemplateName T, 3629193326Sed const TemplateArgument *Args, 3630223017Sdim unsigned NumArgs, QualType Canon, 3631223017Sdim QualType Aliased); 3632193326Sed 3633193326Sed friend class ASTContext; // ASTContext creates these 3634193326Sed 3635193326Sedpublic: 3636193326Sed /// \brief Determine whether any of the given template arguments are 3637193326Sed /// dependent. 3638193326Sed static bool anyDependentTemplateArguments(const TemplateArgument *Args, 3639224145Sdim unsigned NumArgs, 3640224145Sdim bool &InstantiationDependent); 3641193326Sed 3642198893Srdivacky static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, 3643224145Sdim unsigned NumArgs, 3644224145Sdim bool &InstantiationDependent); 3645198893Srdivacky 3646224145Sdim static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, 3647224145Sdim bool &InstantiationDependent); 3648199990Srdivacky 3649193326Sed /// \brief Print a template argument list, including the '<' and '>' 3650193326Sed /// enclosing the template arguments. 3651239462Sdim // FIXME: remove the string ones. 3652193326Sed static std::string PrintTemplateArgumentList(const TemplateArgument *Args, 3653193326Sed unsigned NumArgs, 3654218893Sdim const PrintingPolicy &Policy, 3655218893Sdim bool SkipBrackets = false); 3656193326Sed 3657198893Srdivacky static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args, 3658198893Srdivacky unsigned NumArgs, 3659198893Srdivacky const PrintingPolicy &Policy); 3660198893Srdivacky 3661199990Srdivacky static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &, 3662199990Srdivacky const PrintingPolicy &Policy); 3663199990Srdivacky 3664239462Sdim /// \brief Print a template argument list, including the '<' and '>' 3665239462Sdim /// enclosing the template arguments. 3666239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3667239462Sdim const TemplateArgument *Args, 3668239462Sdim unsigned NumArgs, 3669239462Sdim const PrintingPolicy &Policy, 3670239462Sdim bool SkipBrackets = false); 3671239462Sdim 3672239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3673239462Sdim const TemplateArgumentLoc *Args, 3674239462Sdim unsigned NumArgs, 3675239462Sdim const PrintingPolicy &Policy); 3676239462Sdim 3677239462Sdim static void PrintTemplateArgumentList(raw_ostream &OS, 3678239462Sdim const TemplateArgumentListInfo &, 3679239462Sdim const PrintingPolicy &Policy); 3680239462Sdim 3681207619Srdivacky /// True if this template specialization type matches a current 3682207619Srdivacky /// instantiation in the context in which it is found. 3683207619Srdivacky bool isCurrentInstantiation() const { 3684210299Sed return isa<InjectedClassNameType>(getCanonicalTypeInternal()); 3685207619Srdivacky } 3686207619Srdivacky 3687234353Sdim /// \brief Determine if this template specialization type is for a type alias 3688234353Sdim /// template that has been substituted. 3689234353Sdim /// 3690234353Sdim /// Nearly every template specialization type whose template is an alias 3691234353Sdim /// template will be substituted. However, this is not the case when 3692234353Sdim /// the specialization contains a pack expansion but the template alias 3693234353Sdim /// does not have a corresponding parameter pack, e.g., 3694234353Sdim /// 3695234353Sdim /// \code 3696234353Sdim /// template<typename T, typename U, typename V> struct S; 3697234353Sdim /// template<typename T, typename U> using A = S<T, int, U>; 3698234353Sdim /// template<typename... Ts> struct X { 3699234353Sdim /// typedef A<Ts...> type; // not a type alias 3700234353Sdim /// }; 3701234353Sdim /// \endcode 3702234353Sdim bool isTypeAlias() const { return TypeAlias; } 3703234353Sdim 3704223017Sdim /// Get the aliased type, if this is a specialization of a type alias 3705223017Sdim /// template. 3706223017Sdim QualType getAliasedType() const { 3707223017Sdim assert(isTypeAlias() && "not a type alias template specialization"); 3708223017Sdim return *reinterpret_cast<const QualType*>(end()); 3709223017Sdim } 3710223017Sdim 3711193326Sed typedef const TemplateArgument * iterator; 3712193326Sed 3713193326Sed iterator begin() const { return getArgs(); } 3714210299Sed iterator end() const; // defined inline in TemplateBase.h 3715193326Sed 3716193326Sed /// \brief Retrieve the name of the template that we are specializing. 3717193326Sed TemplateName getTemplateName() const { return Template; } 3718193326Sed 3719193326Sed /// \brief Retrieve the template arguments. 3720198092Srdivacky const TemplateArgument *getArgs() const { 3721193326Sed return reinterpret_cast<const TemplateArgument *>(this + 1); 3722193326Sed } 3723193326Sed 3724193326Sed /// \brief Retrieve the number of template arguments. 3725193326Sed unsigned getNumArgs() const { return NumArgs; } 3726193326Sed 3727193326Sed /// \brief Retrieve a specific template argument as a type. 3728239462Sdim /// \pre @c isArgType(Arg) 3729210299Sed const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h 3730193326Sed 3731207619Srdivacky bool isSugared() const { 3732223017Sdim return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); 3733207619Srdivacky } 3734198092Srdivacky QualType desugar() const { return getCanonicalTypeInternal(); } 3735198092Srdivacky 3736218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { 3737210299Sed Profile(ID, Template, getArgs(), NumArgs, Ctx); 3738223017Sdim if (isTypeAlias()) 3739223017Sdim getAliasedType().Profile(ID); 3740193326Sed } 3741193326Sed 3742193326Sed static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, 3743207619Srdivacky const TemplateArgument *Args, 3744207619Srdivacky unsigned NumArgs, 3745218893Sdim const ASTContext &Context); 3746193326Sed 3747198092Srdivacky static bool classof(const Type *T) { 3748198092Srdivacky return T->getTypeClass() == TemplateSpecialization; 3749193326Sed } 3750193326Sed}; 3751193326Sed 3752207619Srdivacky/// \brief The injected class name of a C++ class template or class 3753207619Srdivacky/// template partial specialization. Used to record that a type was 3754207619Srdivacky/// spelled with a bare identifier rather than as a template-id; the 3755207619Srdivacky/// equivalent for non-templated classes is just RecordType. 3756204962Srdivacky/// 3757207619Srdivacky/// Injected class name types are always dependent. Template 3758207619Srdivacky/// instantiation turns these into RecordTypes. 3759204962Srdivacky/// 3760207619Srdivacky/// Injected class name types are always canonical. This works 3761207619Srdivacky/// because it is impossible to compare an injected class name type 3762207619Srdivacky/// with the corresponding non-injected template type, for the same 3763207619Srdivacky/// reason that it is impossible to directly compare template 3764207619Srdivacky/// parameters from different dependent contexts: injected class name 3765207619Srdivacky/// types can only occur within the scope of a particular templated 3766207619Srdivacky/// declaration, and within that scope every template specialization 3767207619Srdivacky/// will canonicalize to the injected class name (when appropriate 3768207619Srdivacky/// according to the rules of the language). 3769204962Srdivackyclass InjectedClassNameType : public Type { 3770204962Srdivacky CXXRecordDecl *Decl; 3771204962Srdivacky 3772207619Srdivacky /// The template specialization which this type represents. 3773207619Srdivacky /// For example, in 3774207619Srdivacky /// template <class T> class A { ... }; 3775207619Srdivacky /// this is A<T>, whereas in 3776207619Srdivacky /// template <class X, class Y> class A<B<X,Y> > { ... }; 3777207619Srdivacky /// this is A<B<X,Y> >. 3778207619Srdivacky /// 3779207619Srdivacky /// It is always unqualified, always a template specialization type, 3780207619Srdivacky /// and always dependent. 3781207619Srdivacky QualType InjectedType; 3782204962Srdivacky 3783204962Srdivacky friend class ASTContext; // ASTContext creates these. 3784212904Sdim friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not 3785212904Sdim // currently suitable for AST reading, too much 3786210299Sed // interdependencies. 3787207619Srdivacky InjectedClassNameType(CXXRecordDecl *D, QualType TST) 3788218893Sdim : Type(InjectedClassName, QualType(), /*Dependent=*/true, 3789224145Sdim /*InstantiationDependent=*/true, 3790234353Sdim /*VariablyModified=*/false, 3791218893Sdim /*ContainsUnexpandedParameterPack=*/false), 3792207619Srdivacky Decl(D), InjectedType(TST) { 3793204962Srdivacky assert(isa<TemplateSpecializationType>(TST)); 3794204962Srdivacky assert(!TST.hasQualifiers()); 3795207619Srdivacky assert(TST->isDependentType()); 3796204962Srdivacky } 3797204962Srdivacky 3798204962Srdivackypublic: 3799207619Srdivacky QualType getInjectedSpecializationType() const { return InjectedType; } 3800207619Srdivacky const TemplateSpecializationType *getInjectedTST() const { 3801207619Srdivacky return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); 3802204962Srdivacky } 3803204962Srdivacky 3804212904Sdim CXXRecordDecl *getDecl() const; 3805204962Srdivacky 3806207619Srdivacky bool isSugared() const { return false; } 3807207619Srdivacky QualType desugar() const { return QualType(this, 0); } 3808204962Srdivacky 3809204962Srdivacky static bool classof(const Type *T) { 3810204962Srdivacky return T->getTypeClass() == InjectedClassName; 3811204962Srdivacky } 3812204962Srdivacky}; 3813204962Srdivacky 3814208600Srdivacky/// \brief The kind of a tag type. 3815208600Srdivackyenum TagTypeKind { 3816208600Srdivacky /// \brief The "struct" keyword. 3817208600Srdivacky TTK_Struct, 3818243830Sdim /// \brief The "__interface" keyword. 3819243830Sdim TTK_Interface, 3820208600Srdivacky /// \brief The "union" keyword. 3821208600Srdivacky TTK_Union, 3822208600Srdivacky /// \brief The "class" keyword. 3823208600Srdivacky TTK_Class, 3824208600Srdivacky /// \brief The "enum" keyword. 3825208600Srdivacky TTK_Enum 3826208600Srdivacky}; 3827208600Srdivacky 3828206084Srdivacky/// \brief The elaboration keyword that precedes a qualified type name or 3829206084Srdivacky/// introduces an elaborated-type-specifier. 3830206084Srdivackyenum ElaboratedTypeKeyword { 3831206084Srdivacky /// \brief The "struct" keyword introduces the elaborated-type-specifier. 3832206084Srdivacky ETK_Struct, 3833243830Sdim /// \brief The "__interface" keyword introduces the elaborated-type-specifier. 3834243830Sdim ETK_Interface, 3835206084Srdivacky /// \brief The "union" keyword introduces the elaborated-type-specifier. 3836206084Srdivacky ETK_Union, 3837208600Srdivacky /// \brief The "class" keyword introduces the elaborated-type-specifier. 3838208600Srdivacky ETK_Class, 3839206084Srdivacky /// \brief The "enum" keyword introduces the elaborated-type-specifier. 3840208600Srdivacky ETK_Enum, 3841208600Srdivacky /// \brief The "typename" keyword precedes the qualified type name, e.g., 3842208600Srdivacky /// \c typename T::type. 3843208600Srdivacky ETK_Typename, 3844208600Srdivacky /// \brief No keyword precedes the qualified type name. 3845208600Srdivacky ETK_None 3846206084Srdivacky}; 3847208600Srdivacky 3848208600Srdivacky/// A helper class for Type nodes having an ElaboratedTypeKeyword. 3849208600Srdivacky/// The keyword in stored in the free bits of the base class. 3850208600Srdivacky/// Also provides a few static helpers for converting and printing 3851208600Srdivacky/// elaborated type keyword and tag type kind enumerations. 3852208600Srdivackyclass TypeWithKeyword : public Type { 3853208600Srdivackyprotected: 3854208600Srdivacky TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, 3855234353Sdim QualType Canonical, bool Dependent, 3856234353Sdim bool InstantiationDependent, bool VariablyModified, 3857218893Sdim bool ContainsUnexpandedParameterPack) 3858234353Sdim : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, 3859218893Sdim ContainsUnexpandedParameterPack) { 3860218893Sdim TypeWithKeywordBits.Keyword = Keyword; 3861218893Sdim } 3862208600Srdivacky 3863208600Srdivackypublic: 3864208600Srdivacky ElaboratedTypeKeyword getKeyword() const { 3865218893Sdim return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); 3866208600Srdivacky } 3867208600Srdivacky 3868208600Srdivacky /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST) 3869208600Srdivacky /// into an elaborated type keyword. 3870208600Srdivacky static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); 3871208600Srdivacky 3872208600Srdivacky /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST) 3873208600Srdivacky /// into a tag type kind. It is an error to provide a type specifier 3874208600Srdivacky /// which *isn't* a tag kind here. 3875208600Srdivacky static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); 3876208600Srdivacky 3877208600Srdivacky /// getKeywordForTagDeclKind - Converts a TagTypeKind into an 3878208600Srdivacky /// elaborated type keyword. 3879208600Srdivacky static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); 3880208600Srdivacky 3881208600Srdivacky /// getTagTypeKindForKeyword - Converts an elaborated type keyword into 3882208600Srdivacky // a TagTypeKind. It is an error to provide an elaborated type keyword 3883208600Srdivacky /// which *isn't* a tag kind here. 3884208600Srdivacky static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); 3885208600Srdivacky 3886208600Srdivacky static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); 3887208600Srdivacky 3888208600Srdivacky static const char *getKeywordName(ElaboratedTypeKeyword Keyword); 3889208600Srdivacky 3890208600Srdivacky static const char *getTagTypeKindName(TagTypeKind Kind) { 3891208600Srdivacky return getKeywordName(getKeywordForTagTypeKind(Kind)); 3892208600Srdivacky } 3893208600Srdivacky 3894208600Srdivacky class CannotCastToThisType {}; 3895208600Srdivacky static CannotCastToThisType classof(const Type *); 3896208600Srdivacky}; 3897208600Srdivacky 3898208600Srdivacky/// \brief Represents a type that was referred to using an elaborated type 3899208600Srdivacky/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, 3900208600Srdivacky/// or both. 3901193326Sed/// 3902193326Sed/// This type is used to keep track of a type name as written in the 3903208600Srdivacky/// source code, including tag keywords and any nested-name-specifiers. 3904208600Srdivacky/// The type itself is always "sugar", used to express what was written 3905208600Srdivacky/// in the source code but containing no additional semantic information. 3906208600Srdivackyclass ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { 3907208600Srdivacky 3908193326Sed /// \brief The nested name specifier containing the qualifier. 3909193326Sed NestedNameSpecifier *NNS; 3910193326Sed 3911193326Sed /// \brief The type that this qualified name refers to. 3912193326Sed QualType NamedType; 3913193326Sed 3914208600Srdivacky ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 3915208600Srdivacky QualType NamedType, QualType CanonType) 3916208600Srdivacky : TypeWithKeyword(Keyword, Elaborated, CanonType, 3917218893Sdim NamedType->isDependentType(), 3918224145Sdim NamedType->isInstantiationDependentType(), 3919218893Sdim NamedType->isVariablyModifiedType(), 3920218893Sdim NamedType->containsUnexpandedParameterPack()), 3921208600Srdivacky NNS(NNS), NamedType(NamedType) { 3922208600Srdivacky assert(!(Keyword == ETK_None && NNS == 0) && 3923208600Srdivacky "ElaboratedType cannot have elaborated type keyword " 3924208600Srdivacky "and name qualifier both null."); 3925208600Srdivacky } 3926193326Sed 3927193326Sed friend class ASTContext; // ASTContext creates these 3928193326Sed 3929193326Sedpublic: 3930210299Sed ~ElaboratedType(); 3931208600Srdivacky 3932193326Sed /// \brief Retrieve the qualification on this type. 3933193326Sed NestedNameSpecifier *getQualifier() const { return NNS; } 3934193326Sed 3935193326Sed /// \brief Retrieve the type named by the qualified-id. 3936193326Sed QualType getNamedType() const { return NamedType; } 3937193326Sed 3938198092Srdivacky /// \brief Remove a single level of sugar. 3939198092Srdivacky QualType desugar() const { return getNamedType(); } 3940193326Sed 3941198092Srdivacky /// \brief Returns whether this type directly provides sugar. 3942198092Srdivacky bool isSugared() const { return true; } 3943198092Srdivacky 3944193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 3945208600Srdivacky Profile(ID, getKeyword(), NNS, NamedType); 3946193326Sed } 3947193326Sed 3948208600Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, 3949208600Srdivacky NestedNameSpecifier *NNS, QualType NamedType) { 3950208600Srdivacky ID.AddInteger(Keyword); 3951193326Sed ID.AddPointer(NNS); 3952193326Sed NamedType.Profile(ID); 3953193326Sed } 3954193326Sed 3955198092Srdivacky static bool classof(const Type *T) { 3956208600Srdivacky return T->getTypeClass() == Elaborated; 3957193326Sed } 3958193326Sed}; 3959193326Sed 3960206084Srdivacky/// \brief Represents a qualified type name for which the type name is 3961234353Sdim/// dependent. 3962193326Sed/// 3963234353Sdim/// DependentNameType represents a class of dependent types that involve a 3964234353Sdim/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent) 3965206084Srdivacky/// name of a type. The DependentNameType may start with a "typename" (for a 3966234353Sdim/// typename-specifier), "class", "struct", "union", or "enum" (for a 3967206084Srdivacky/// dependent elaborated-type-specifier), or nothing (in contexts where we 3968206084Srdivacky/// know that we must be referring to a type, e.g., in a base class specifier). 3969208600Srdivackyclass DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { 3970208600Srdivacky 3971193326Sed /// \brief The nested name specifier containing the qualifier. 3972193326Sed NestedNameSpecifier *NNS; 3973193326Sed 3974193326Sed /// \brief The type that this typename specifier refers to. 3975210299Sed const IdentifierInfo *Name; 3976193326Sed 3977234353Sdim DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 3978206084Srdivacky const IdentifierInfo *Name, QualType CanonType) 3979218893Sdim : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, 3980224145Sdim /*InstantiationDependent=*/true, 3981218893Sdim /*VariablyModified=*/false, 3982218893Sdim NNS->containsUnexpandedParameterPack()), 3983208600Srdivacky NNS(NNS), Name(Name) { 3984198092Srdivacky assert(NNS->isDependent() && 3985206084Srdivacky "DependentNameType requires a dependent nested-name-specifier"); 3986193326Sed } 3987193326Sed 3988193326Sed friend class ASTContext; // ASTContext creates these 3989193326Sed 3990193326Sedpublic: 3991193326Sed /// \brief Retrieve the qualification on this type. 3992193326Sed NestedNameSpecifier *getQualifier() const { return NNS; } 3993193326Sed 3994193326Sed /// \brief Retrieve the type named by the typename specifier as an 3995193326Sed /// identifier. 3996193326Sed /// 3997193326Sed /// This routine will return a non-NULL identifier pointer when the 3998193326Sed /// form of the original typename was terminated by an identifier, 3999193326Sed /// e.g., "typename T::type". 4000198092Srdivacky const IdentifierInfo *getIdentifier() const { 4001210299Sed return Name; 4002193326Sed } 4003193326Sed 4004198092Srdivacky bool isSugared() const { return false; } 4005198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4006198092Srdivacky 4007193326Sed void Profile(llvm::FoldingSetNodeID &ID) { 4008208600Srdivacky Profile(ID, getKeyword(), NNS, Name); 4009193326Sed } 4010193326Sed 4011206084Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, 4012210299Sed NestedNameSpecifier *NNS, const IdentifierInfo *Name) { 4013206084Srdivacky ID.AddInteger(Keyword); 4014193326Sed ID.AddPointer(NNS); 4015210299Sed ID.AddPointer(Name); 4016193326Sed } 4017193326Sed 4018198092Srdivacky static bool classof(const Type *T) { 4019206084Srdivacky return T->getTypeClass() == DependentName; 4020193326Sed } 4021193326Sed}; 4022193326Sed 4023210299Sed/// DependentTemplateSpecializationType - Represents a template 4024210299Sed/// specialization type whose template cannot be resolved, e.g. 4025210299Sed/// A<T>::template B<T> 4026210299Sedclass DependentTemplateSpecializationType : 4027210299Sed public TypeWithKeyword, public llvm::FoldingSetNode { 4028210299Sed 4029210299Sed /// \brief The nested name specifier containing the qualifier. 4030210299Sed NestedNameSpecifier *NNS; 4031210299Sed 4032210299Sed /// \brief The identifier of the template. 4033210299Sed const IdentifierInfo *Name; 4034210299Sed 4035210299Sed /// \brief - The number of template arguments named in this class 4036210299Sed /// template specialization. 4037210299Sed unsigned NumArgs; 4038210299Sed 4039210299Sed const TemplateArgument *getArgBuffer() const { 4040210299Sed return reinterpret_cast<const TemplateArgument*>(this+1); 4041210299Sed } 4042210299Sed TemplateArgument *getArgBuffer() { 4043210299Sed return reinterpret_cast<TemplateArgument*>(this+1); 4044210299Sed } 4045210299Sed 4046210299Sed DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, 4047210299Sed NestedNameSpecifier *NNS, 4048210299Sed const IdentifierInfo *Name, 4049210299Sed unsigned NumArgs, 4050210299Sed const TemplateArgument *Args, 4051210299Sed QualType Canon); 4052210299Sed 4053210299Sed friend class ASTContext; // ASTContext creates these 4054210299Sed 4055210299Sedpublic: 4056210299Sed NestedNameSpecifier *getQualifier() const { return NNS; } 4057210299Sed const IdentifierInfo *getIdentifier() const { return Name; } 4058210299Sed 4059210299Sed /// \brief Retrieve the template arguments. 4060210299Sed const TemplateArgument *getArgs() const { 4061210299Sed return getArgBuffer(); 4062210299Sed } 4063210299Sed 4064210299Sed /// \brief Retrieve the number of template arguments. 4065210299Sed unsigned getNumArgs() const { return NumArgs; } 4066210299Sed 4067210299Sed const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h 4068210299Sed 4069210299Sed typedef const TemplateArgument * iterator; 4070210299Sed iterator begin() const { return getArgs(); } 4071210299Sed iterator end() const; // inline in TemplateBase.h 4072210299Sed 4073210299Sed bool isSugared() const { return false; } 4074210299Sed QualType desugar() const { return QualType(this, 0); } 4075210299Sed 4076218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { 4077210299Sed Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs()); 4078210299Sed } 4079210299Sed 4080210299Sed static void Profile(llvm::FoldingSetNodeID &ID, 4081218893Sdim const ASTContext &Context, 4082210299Sed ElaboratedTypeKeyword Keyword, 4083210299Sed NestedNameSpecifier *Qualifier, 4084210299Sed const IdentifierInfo *Name, 4085210299Sed unsigned NumArgs, 4086210299Sed const TemplateArgument *Args); 4087210299Sed 4088210299Sed static bool classof(const Type *T) { 4089210299Sed return T->getTypeClass() == DependentTemplateSpecialization; 4090210299Sed } 4091210299Sed}; 4092210299Sed 4093218893Sdim/// \brief Represents a pack expansion of types. 4094218893Sdim/// 4095218893Sdim/// Pack expansions are part of C++0x variadic templates. A pack 4096218893Sdim/// expansion contains a pattern, which itself contains one or more 4097218893Sdim/// "unexpanded" parameter packs. When instantiated, a pack expansion 4098218893Sdim/// produces a series of types, each instantiated from the pattern of 4099218893Sdim/// the expansion, where the Ith instantiation of the pattern uses the 4100218893Sdim/// Ith arguments bound to each of the unexpanded parameter packs. The 4101218893Sdim/// pack expansion is considered to "expand" these unexpanded 4102218893Sdim/// parameter packs. 4103218893Sdim/// 4104218893Sdim/// \code 4105218893Sdim/// template<typename ...Types> struct tuple; 4106218893Sdim/// 4107234353Sdim/// template<typename ...Types> 4108218893Sdim/// struct tuple_of_references { 4109218893Sdim/// typedef tuple<Types&...> type; 4110218893Sdim/// }; 4111218893Sdim/// \endcode 4112218893Sdim/// 4113218893Sdim/// Here, the pack expansion \c Types&... is represented via a 4114218893Sdim/// PackExpansionType whose pattern is Types&. 4115218893Sdimclass PackExpansionType : public Type, public llvm::FoldingSetNode { 4116218893Sdim /// \brief The pattern of the pack expansion. 4117218893Sdim QualType Pattern; 4118218893Sdim 4119218893Sdim /// \brief The number of expansions that this pack expansion will 4120234353Sdim /// generate when substituted (+1), or indicates that 4121218893Sdim /// 4122234353Sdim /// This field will only have a non-zero value when some of the parameter 4123234353Sdim /// packs that occur within the pattern have been substituted but others have 4124218893Sdim /// not. 4125218893Sdim unsigned NumExpansions; 4126234353Sdim 4127218893Sdim PackExpansionType(QualType Pattern, QualType Canon, 4128218893Sdim llvm::Optional<unsigned> NumExpansions) 4129239462Sdim : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), 4130224145Sdim /*InstantiationDependent=*/true, 4131218893Sdim /*VariableModified=*/Pattern->isVariablyModifiedType(), 4132218893Sdim /*ContainsUnexpandedParameterPack=*/false), 4133234353Sdim Pattern(Pattern), 4134218893Sdim NumExpansions(NumExpansions? *NumExpansions + 1: 0) { } 4135218893Sdim 4136218893Sdim friend class ASTContext; // ASTContext creates these 4137234353Sdim 4138218893Sdimpublic: 4139218893Sdim /// \brief Retrieve the pattern of this pack expansion, which is the 4140218893Sdim /// type that will be repeatedly instantiated when instantiating the 4141218893Sdim /// pack expansion itself. 4142218893Sdim QualType getPattern() const { return Pattern; } 4143218893Sdim 4144218893Sdim /// \brief Retrieve the number of expansions that this pack expansion will 4145218893Sdim /// generate, if known. 4146218893Sdim llvm::Optional<unsigned> getNumExpansions() const { 4147218893Sdim if (NumExpansions) 4148218893Sdim return NumExpansions - 1; 4149234353Sdim 4150218893Sdim return llvm::Optional<unsigned>(); 4151218893Sdim } 4152234353Sdim 4153218893Sdim bool isSugared() const { return false; } 4154218893Sdim QualType desugar() const { return QualType(this, 0); } 4155218893Sdim 4156218893Sdim void Profile(llvm::FoldingSetNodeID &ID) { 4157218893Sdim Profile(ID, getPattern(), getNumExpansions()); 4158218893Sdim } 4159218893Sdim 4160218893Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, 4161218893Sdim llvm::Optional<unsigned> NumExpansions) { 4162218893Sdim ID.AddPointer(Pattern.getAsOpaquePtr()); 4163218893Sdim ID.AddBoolean(NumExpansions); 4164218893Sdim if (NumExpansions) 4165218893Sdim ID.AddInteger(*NumExpansions); 4166218893Sdim } 4167218893Sdim 4168218893Sdim static bool classof(const Type *T) { 4169218893Sdim return T->getTypeClass() == PackExpansion; 4170218893Sdim } 4171218893Sdim}; 4172218893Sdim 4173208600Srdivacky/// ObjCObjectType - Represents a class type in Objective C. 4174208600Srdivacky/// Every Objective C type is a combination of a base type and a 4175208600Srdivacky/// list of protocols. 4176208600Srdivacky/// 4177208600Srdivacky/// Given the following declarations: 4178239462Sdim/// \code 4179239462Sdim/// \@class C; 4180239462Sdim/// \@protocol P; 4181239462Sdim/// \endcode 4182208600Srdivacky/// 4183208600Srdivacky/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType 4184208600Srdivacky/// with base C and no protocols. 4185208600Srdivacky/// 4186208600Srdivacky/// 'C<P>' is an ObjCObjectType with base C and protocol list [P]. 4187208600Srdivacky/// 4188208600Srdivacky/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose 4189208600Srdivacky/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType 4190208600Srdivacky/// and no protocols. 4191208600Srdivacky/// 4192208600Srdivacky/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType 4193208600Srdivacky/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually 4194208600Srdivacky/// this should get its own sugar class to better represent the source. 4195208600Srdivackyclass ObjCObjectType : public Type { 4196218893Sdim // ObjCObjectType.NumProtocols - the number of protocols stored 4197218893Sdim // after the ObjCObjectPointerType node. 4198218893Sdim // 4199218893Sdim // These protocols are those written directly on the type. If 4200218893Sdim // protocol qualifiers ever become additive, the iterators will need 4201218893Sdim // to get kindof complicated. 4202218893Sdim // 4203218893Sdim // In the canonical object type, these are sorted alphabetically 4204218893Sdim // and uniqued. 4205198092Srdivacky 4206208600Srdivacky /// Either a BuiltinType or an InterfaceType or sugar for either. 4207208600Srdivacky QualType BaseType; 4208208600Srdivacky 4209208600Srdivacky ObjCProtocolDecl * const *getProtocolStorage() const { 4210208600Srdivacky return const_cast<ObjCObjectType*>(this)->getProtocolStorage(); 4211208600Srdivacky } 4212208600Srdivacky 4213208600Srdivacky ObjCProtocolDecl **getProtocolStorage(); 4214208600Srdivacky 4215208600Srdivackyprotected: 4216234353Sdim ObjCObjectType(QualType Canonical, QualType Base, 4217208600Srdivacky ObjCProtocolDecl * const *Protocols, unsigned NumProtocols); 4218208600Srdivacky 4219208600Srdivacky enum Nonce_ObjCInterface { Nonce_ObjCInterface }; 4220208600Srdivacky ObjCObjectType(enum Nonce_ObjCInterface) 4221224145Sdim : Type(ObjCInterface, QualType(), false, false, false, false), 4222218893Sdim BaseType(QualType(this_(), 0)) { 4223218893Sdim ObjCObjectTypeBits.NumProtocols = 0; 4224218893Sdim } 4225208600Srdivacky 4226198092Srdivackypublic: 4227208600Srdivacky /// getBaseType - Gets the base type of this object type. This is 4228208600Srdivacky /// always (possibly sugar for) one of: 4229208600Srdivacky /// - the 'id' builtin type (as opposed to the 'id' type visible to the 4230208600Srdivacky /// user, which is a typedef for an ObjCPointerType) 4231208600Srdivacky /// - the 'Class' builtin type (same caveat) 4232208600Srdivacky /// - an ObjCObjectType (currently always an ObjCInterfaceType) 4233208600Srdivacky QualType getBaseType() const { return BaseType; } 4234202879Srdivacky 4235208600Srdivacky bool isObjCId() const { 4236208600Srdivacky return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); 4237208600Srdivacky } 4238208600Srdivacky bool isObjCClass() const { 4239208600Srdivacky return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); 4240208600Srdivacky } 4241208600Srdivacky bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } 4242208600Srdivacky bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } 4243208600Srdivacky bool isObjCUnqualifiedIdOrClass() const { 4244208600Srdivacky if (!qual_empty()) return false; 4245208600Srdivacky if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) 4246208600Srdivacky return T->getKind() == BuiltinType::ObjCId || 4247208600Srdivacky T->getKind() == BuiltinType::ObjCClass; 4248208600Srdivacky return false; 4249208600Srdivacky } 4250208600Srdivacky bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } 4251208600Srdivacky bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } 4252198092Srdivacky 4253208600Srdivacky /// Gets the interface declaration for this object type, if the base type 4254208600Srdivacky /// really is an interface. 4255208600Srdivacky ObjCInterfaceDecl *getInterface() const; 4256208600Srdivacky 4257208600Srdivacky typedef ObjCProtocolDecl * const *qual_iterator; 4258208600Srdivacky 4259208600Srdivacky qual_iterator qual_begin() const { return getProtocolStorage(); } 4260208600Srdivacky qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } 4261208600Srdivacky 4262208600Srdivacky bool qual_empty() const { return getNumProtocols() == 0; } 4263208600Srdivacky 4264198092Srdivacky /// getNumProtocols - Return the number of qualifying protocols in this 4265198092Srdivacky /// interface type, or 0 if there are none. 4266218893Sdim unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; } 4267198092Srdivacky 4268208600Srdivacky /// \brief Fetch a protocol by index. 4269203955Srdivacky ObjCProtocolDecl *getProtocol(unsigned I) const { 4270203955Srdivacky assert(I < getNumProtocols() && "Out-of-range protocol access"); 4271203955Srdivacky return qual_begin()[I]; 4272203955Srdivacky } 4273234353Sdim 4274198092Srdivacky bool isSugared() const { return false; } 4275198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4276198092Srdivacky 4277208600Srdivacky static bool classof(const Type *T) { 4278208600Srdivacky return T->getTypeClass() == ObjCObject || 4279208600Srdivacky T->getTypeClass() == ObjCInterface; 4280208600Srdivacky } 4281208600Srdivacky}; 4282208600Srdivacky 4283208600Srdivacky/// ObjCObjectTypeImpl - A class providing a concrete implementation 4284208600Srdivacky/// of ObjCObjectType, so as to not increase the footprint of 4285208600Srdivacky/// ObjCInterfaceType. Code outside of ASTContext and the core type 4286208600Srdivacky/// system should not reference this type. 4287208600Srdivackyclass ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { 4288208600Srdivacky friend class ASTContext; 4289208600Srdivacky 4290208600Srdivacky // If anyone adds fields here, ObjCObjectType::getProtocolStorage() 4291208600Srdivacky // will need to be modified. 4292208600Srdivacky 4293234353Sdim ObjCObjectTypeImpl(QualType Canonical, QualType Base, 4294208600Srdivacky ObjCProtocolDecl * const *Protocols, 4295208600Srdivacky unsigned NumProtocols) 4296208600Srdivacky : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {} 4297208600Srdivacky 4298208600Srdivackypublic: 4299198092Srdivacky void Profile(llvm::FoldingSetNodeID &ID); 4300198092Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, 4301208600Srdivacky QualType Base, 4302234353Sdim ObjCProtocolDecl *const *protocols, 4303234353Sdim unsigned NumProtocols); 4304208600Srdivacky}; 4305198092Srdivacky 4306208600Srdivackyinline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { 4307208600Srdivacky return reinterpret_cast<ObjCProtocolDecl**>( 4308208600Srdivacky static_cast<ObjCObjectTypeImpl*>(this) + 1); 4309208600Srdivacky} 4310203955Srdivacky 4311208600Srdivacky/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for 4312208600Srdivacky/// object oriented design. They basically correspond to C++ classes. There 4313208600Srdivacky/// are two kinds of interface types, normal interfaces like "NSString" and 4314208600Srdivacky/// qualified interfaces, which are qualified with a protocol list like 4315208600Srdivacky/// "NSString<NSCopyable, NSAmazing>". 4316208600Srdivacky/// 4317208600Srdivacky/// ObjCInterfaceType guarantees the following properties when considered 4318208600Srdivacky/// as a subtype of its superclass, ObjCObjectType: 4319208600Srdivacky/// - There are no protocol qualifiers. To reinforce this, code which 4320208600Srdivacky/// tries to invoke the protocol methods via an ObjCInterfaceType will 4321208600Srdivacky/// fail to compile. 4322208600Srdivacky/// - It is its own base type. That is, if T is an ObjCInterfaceType*, 4323208600Srdivacky/// T->getBaseType() == QualType(T, 0). 4324208600Srdivackyclass ObjCInterfaceType : public ObjCObjectType { 4325234353Sdim mutable ObjCInterfaceDecl *Decl; 4326208600Srdivacky 4327208600Srdivacky ObjCInterfaceType(const ObjCInterfaceDecl *D) 4328208600Srdivacky : ObjCObjectType(Nonce_ObjCInterface), 4329208600Srdivacky Decl(const_cast<ObjCInterfaceDecl*>(D)) {} 4330208600Srdivacky friend class ASTContext; // ASTContext creates these. 4331234353Sdim friend class ASTReader; 4332234353Sdim friend class ObjCInterfaceDecl; 4333218893Sdim 4334208600Srdivackypublic: 4335208600Srdivacky /// getDecl - Get the declaration of this interface. 4336208600Srdivacky ObjCInterfaceDecl *getDecl() const { return Decl; } 4337208600Srdivacky 4338208600Srdivacky bool isSugared() const { return false; } 4339208600Srdivacky QualType desugar() const { return QualType(this, 0); } 4340208600Srdivacky 4341198092Srdivacky static bool classof(const Type *T) { 4342198092Srdivacky return T->getTypeClass() == ObjCInterface; 4343198092Srdivacky } 4344208600Srdivacky 4345208600Srdivacky // Nonsense to "hide" certain members of ObjCObjectType within this 4346208600Srdivacky // class. People asking for protocols on an ObjCInterfaceType are 4347208600Srdivacky // not going to get what they want: ObjCInterfaceTypes are 4348208600Srdivacky // guaranteed to have no protocols. 4349208600Srdivacky enum { 4350208600Srdivacky qual_iterator, 4351208600Srdivacky qual_begin, 4352208600Srdivacky qual_end, 4353208600Srdivacky getNumProtocols, 4354208600Srdivacky getProtocol 4355208600Srdivacky }; 4356198092Srdivacky}; 4357198092Srdivacky 4358208600Srdivackyinline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { 4359208600Srdivacky if (const ObjCInterfaceType *T = 4360208600Srdivacky getBaseType()->getAs<ObjCInterfaceType>()) 4361208600Srdivacky return T->getDecl(); 4362208600Srdivacky return 0; 4363208600Srdivacky} 4364208600Srdivacky 4365208600Srdivacky/// ObjCObjectPointerType - Used to represent a pointer to an 4366208600Srdivacky/// Objective C object. These are constructed from pointer 4367208600Srdivacky/// declarators when the pointee type is an ObjCObjectType (or sugar 4368208600Srdivacky/// for one). In addition, the 'id' and 'Class' types are typedefs 4369208600Srdivacky/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>' 4370208600Srdivacky/// are translated into these. 4371194613Sed/// 4372208600Srdivacky/// Pointers to pointers to Objective C objects are still PointerTypes; 4373208600Srdivacky/// only the first level of pointer gets it own type implementation. 4374194613Sedclass ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { 4375208600Srdivacky QualType PointeeType; 4376198092Srdivacky 4377208600Srdivacky ObjCObjectPointerType(QualType Canonical, QualType Pointee) 4378224145Sdim : Type(ObjCObjectPointer, Canonical, false, false, false, false), 4379208600Srdivacky PointeeType(Pointee) {} 4380194613Sed friend class ASTContext; // ASTContext creates these. 4381194613Sed 4382194613Sedpublic: 4383208600Srdivacky /// getPointeeType - Gets the type pointed to by this ObjC pointer. 4384208600Srdivacky /// The result will always be an ObjCObjectType or sugar thereof. 4385198092Srdivacky QualType getPointeeType() const { return PointeeType; } 4386198092Srdivacky 4387208600Srdivacky /// getObjCObjectType - Gets the type pointed to by this ObjC 4388208600Srdivacky /// pointer. This method always returns non-null. 4389208600Srdivacky /// 4390208600Srdivacky /// This method is equivalent to getPointeeType() except that 4391208600Srdivacky /// it discards any typedefs (or other sugar) between this 4392208600Srdivacky /// type and the "outermost" object type. So for: 4393239462Sdim /// \code 4394239462Sdim /// \@class A; \@protocol P; \@protocol Q; 4395208600Srdivacky /// typedef A<P> AP; 4396208600Srdivacky /// typedef A A1; 4397208600Srdivacky /// typedef A1<P> A1P; 4398208600Srdivacky /// typedef A1P<Q> A1PQ; 4399239462Sdim /// \endcode 4400208600Srdivacky /// For 'A*', getObjectType() will return 'A'. 4401208600Srdivacky /// For 'A<P>*', getObjectType() will return 'A<P>'. 4402208600Srdivacky /// For 'AP*', getObjectType() will return 'A<P>'. 4403208600Srdivacky /// For 'A1*', getObjectType() will return 'A'. 4404208600Srdivacky /// For 'A1<P>*', getObjectType() will return 'A1<P>'. 4405208600Srdivacky /// For 'A1P*', getObjectType() will return 'A1<P>'. 4406208600Srdivacky /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because 4407208600Srdivacky /// adding protocols to a protocol-qualified base discards the 4408208600Srdivacky /// old qualifiers (for now). But if it didn't, getObjectType() 4409208600Srdivacky /// would return 'A1P<Q>' (and we'd have to make iterating over 4410208600Srdivacky /// qualifiers more complicated). 4411208600Srdivacky const ObjCObjectType *getObjectType() const { 4412218893Sdim return PointeeType->castAs<ObjCObjectType>(); 4413208600Srdivacky } 4414208600Srdivacky 4415208600Srdivacky /// getInterfaceType - If this pointer points to an Objective C 4416239462Sdim /// \@interface type, gets the type for that interface. Any protocol 4417208600Srdivacky /// qualifiers on the interface are ignored. 4418208600Srdivacky /// 4419208600Srdivacky /// \return null if the base type for this pointer is 'id' or 'Class' 4420198092Srdivacky const ObjCInterfaceType *getInterfaceType() const { 4421208600Srdivacky return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>(); 4422198092Srdivacky } 4423208600Srdivacky 4424239462Sdim /// getInterfaceDecl - If this pointer points to an Objective \@interface 4425208600Srdivacky /// type, gets the declaration for that interface. 4426208600Srdivacky /// 4427208600Srdivacky /// \return null if the base type for this pointer is 'id' or 'Class' 4428198092Srdivacky ObjCInterfaceDecl *getInterfaceDecl() const { 4429208600Srdivacky return getObjectType()->getInterface(); 4430198092Srdivacky } 4431208600Srdivacky 4432208600Srdivacky /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if 4433208600Srdivacky /// its object type is the primitive 'id' type with no protocols. 4434198092Srdivacky bool isObjCIdType() const { 4435208600Srdivacky return getObjectType()->isObjCUnqualifiedId(); 4436198092Srdivacky } 4437208600Srdivacky 4438208600Srdivacky /// isObjCClassType - True if this is equivalent to the 'Class' type, 4439208600Srdivacky /// i.e. if its object tive is the primitive 'Class' type with no protocols. 4440198092Srdivacky bool isObjCClassType() const { 4441208600Srdivacky return getObjectType()->isObjCUnqualifiedClass(); 4442198092Srdivacky } 4443234353Sdim 4444208600Srdivacky /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some 4445208600Srdivacky /// non-empty set of protocols. 4446198092Srdivacky bool isObjCQualifiedIdType() const { 4447208600Srdivacky return getObjectType()->isObjCQualifiedId(); 4448198092Srdivacky } 4449208600Srdivacky 4450208600Srdivacky /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for 4451208600Srdivacky /// some non-empty set of protocols. 4452198092Srdivacky bool isObjCQualifiedClassType() const { 4453208600Srdivacky return getObjectType()->isObjCQualifiedClass(); 4454198092Srdivacky } 4455194613Sed 4456208600Srdivacky /// An iterator over the qualifiers on the object type. Provided 4457208600Srdivacky /// for convenience. This will always iterate over the full set of 4458208600Srdivacky /// protocols on a type, not just those provided directly. 4459208600Srdivacky typedef ObjCObjectType::qual_iterator qual_iterator; 4460208600Srdivacky 4461202879Srdivacky qual_iterator qual_begin() const { 4462208600Srdivacky return getObjectType()->qual_begin(); 4463202879Srdivacky } 4464208600Srdivacky qual_iterator qual_end() const { 4465208600Srdivacky return getObjectType()->qual_end(); 4466202879Srdivacky } 4467208600Srdivacky bool qual_empty() const { return getObjectType()->qual_empty(); } 4468194613Sed 4469208600Srdivacky /// getNumProtocols - Return the number of qualifying protocols on 4470208600Srdivacky /// the object type. 4471208600Srdivacky unsigned getNumProtocols() const { 4472208600Srdivacky return getObjectType()->getNumProtocols(); 4473208600Srdivacky } 4474194613Sed 4475208600Srdivacky /// \brief Retrieve a qualifying protocol by index on the object 4476208600Srdivacky /// type. 4477203955Srdivacky ObjCProtocolDecl *getProtocol(unsigned I) const { 4478208600Srdivacky return getObjectType()->getProtocol(I); 4479203955Srdivacky } 4480234353Sdim 4481198092Srdivacky bool isSugared() const { return false; } 4482198092Srdivacky QualType desugar() const { return QualType(this, 0); } 4483198092Srdivacky 4484208600Srdivacky void Profile(llvm::FoldingSetNodeID &ID) { 4485208600Srdivacky Profile(ID, getPointeeType()); 4486208600Srdivacky } 4487208600Srdivacky static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { 4488208600Srdivacky ID.AddPointer(T.getAsOpaquePtr()); 4489208600Srdivacky } 4490198092Srdivacky static bool classof(const Type *T) { 4491198092Srdivacky return T->getTypeClass() == ObjCObjectPointer; 4492194613Sed } 4493194613Sed}; 4494193326Sed 4495226633Sdimclass AtomicType : public Type, public llvm::FoldingSetNode { 4496226633Sdim QualType ValueType; 4497226633Sdim 4498226633Sdim AtomicType(QualType ValTy, QualType Canonical) 4499226633Sdim : Type(Atomic, Canonical, ValTy->isDependentType(), 4500226633Sdim ValTy->isInstantiationDependentType(), 4501226633Sdim ValTy->isVariablyModifiedType(), 4502226633Sdim ValTy->containsUnexpandedParameterPack()), 4503226633Sdim ValueType(ValTy) {} 4504226633Sdim friend class ASTContext; // ASTContext creates these. 4505226633Sdim 4506226633Sdim public: 4507226633Sdim /// getValueType - Gets the type contained by this atomic type, i.e. 4508226633Sdim /// the type returned by performing an atomic load of this atomic type. 4509226633Sdim QualType getValueType() const { return ValueType; } 4510226633Sdim 4511226633Sdim bool isSugared() const { return false; } 4512226633Sdim QualType desugar() const { return QualType(this, 0); } 4513226633Sdim 4514226633Sdim void Profile(llvm::FoldingSetNodeID &ID) { 4515226633Sdim Profile(ID, getValueType()); 4516226633Sdim } 4517226633Sdim static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { 4518226633Sdim ID.AddPointer(T.getAsOpaquePtr()); 4519226633Sdim } 4520226633Sdim static bool classof(const Type *T) { 4521226633Sdim return T->getTypeClass() == Atomic; 4522226633Sdim } 4523226633Sdim}; 4524226633Sdim 4525198092Srdivacky/// A qualifier set is used to build a set of qualifiers. 4526198092Srdivackyclass QualifierCollector : public Qualifiers { 4527198092Srdivackypublic: 4528218893Sdim QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {} 4529198092Srdivacky 4530198092Srdivacky /// Collect any qualifiers on the given type and return an 4531218893Sdim /// unqualified type. The qualifiers are assumed to be consistent 4532218893Sdim /// with those already in the type. 4533218893Sdim const Type *strip(QualType type) { 4534218893Sdim addFastQualifiers(type.getLocalFastQualifiers()); 4535218893Sdim if (!type.hasLocalNonFastQualifiers()) 4536218893Sdim return type.getTypePtrUnsafe(); 4537234353Sdim 4538218893Sdim const ExtQuals *extQuals = type.getExtQualsUnsafe(); 4539218893Sdim addConsistentQualifiers(extQuals->getQualifiers()); 4540218893Sdim return extQuals->getBaseType(); 4541198092Srdivacky } 4542198092Srdivacky 4543198092Srdivacky /// Apply the collected qualifiers to the given type. 4544218893Sdim QualType apply(const ASTContext &Context, QualType QT) const; 4545198092Srdivacky 4546198092Srdivacky /// Apply the collected qualifiers to the given type. 4547218893Sdim QualType apply(const ASTContext &Context, const Type* T) const; 4548198092Srdivacky}; 4549198092Srdivacky 4550198092Srdivacky 4551198092Srdivacky// Inline function definitions. 4552198092Srdivacky 4553234353Sdiminline SplitQualType SplitQualType::getSingleStepDesugaredType() const { 4554234353Sdim SplitQualType desugar = 4555234353Sdim Ty->getLocallyUnqualifiedSingleStepDesugaredType().split(); 4556234353Sdim desugar.Quals.addConsistentQualifiers(Quals); 4557234353Sdim return desugar; 4558234353Sdim} 4559234353Sdim 4560218893Sdiminline const Type *QualType::getTypePtr() const { 4561218893Sdim return getCommonPtr()->BaseType; 4562218893Sdim} 4563218893Sdim 4564218893Sdiminline const Type *QualType::getTypePtrOrNull() const { 4565218893Sdim return (isNull() ? 0 : getCommonPtr()->BaseType); 4566218893Sdim} 4567218893Sdim 4568218893Sdiminline SplitQualType QualType::split() const { 4569218893Sdim if (!hasLocalNonFastQualifiers()) 4570218893Sdim return SplitQualType(getTypePtrUnsafe(), 4571218893Sdim Qualifiers::fromFastMask(getLocalFastQualifiers())); 4572218893Sdim 4573218893Sdim const ExtQuals *eq = getExtQualsUnsafe(); 4574218893Sdim Qualifiers qs = eq->getQualifiers(); 4575218893Sdim qs.addFastQualifiers(getLocalFastQualifiers()); 4576218893Sdim return SplitQualType(eq->getBaseType(), qs); 4577218893Sdim} 4578218893Sdim 4579218893Sdiminline Qualifiers QualType::getLocalQualifiers() const { 4580218893Sdim Qualifiers Quals; 4581218893Sdim if (hasLocalNonFastQualifiers()) 4582218893Sdim Quals = getExtQualsUnsafe()->getQualifiers(); 4583218893Sdim Quals.addFastQualifiers(getLocalFastQualifiers()); 4584218893Sdim return Quals; 4585218893Sdim} 4586218893Sdim 4587218893Sdiminline Qualifiers QualType::getQualifiers() const { 4588218893Sdim Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers(); 4589218893Sdim quals.addFastQualifiers(getLocalFastQualifiers()); 4590218893Sdim return quals; 4591218893Sdim} 4592218893Sdim 4593218893Sdiminline unsigned QualType::getCVRQualifiers() const { 4594218893Sdim unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers(); 4595218893Sdim cvr |= getLocalCVRQualifiers(); 4596218893Sdim return cvr; 4597218893Sdim} 4598218893Sdim 4599218893Sdiminline QualType QualType::getCanonicalType() const { 4600218893Sdim QualType canon = getCommonPtr()->CanonicalType; 4601218893Sdim return canon.withFastQualifiers(getLocalFastQualifiers()); 4602218893Sdim} 4603218893Sdim 4604198398Srdivackyinline bool QualType::isCanonical() const { 4605218893Sdim return getTypePtr()->isCanonicalUnqualified(); 4606198398Srdivacky} 4607198398Srdivacky 4608198398Srdivackyinline bool QualType::isCanonicalAsParam() const { 4609218893Sdim if (!isCanonical()) return false; 4610199482Srdivacky if (hasLocalQualifiers()) return false; 4611234353Sdim 4612198398Srdivacky const Type *T = getTypePtr(); 4613218893Sdim if (T->isVariablyModifiedType() && T->hasSizedVLAType()) 4614218893Sdim return false; 4615218893Sdim 4616218893Sdim return !isa<FunctionType>(T) && !isa<ArrayType>(T); 4617198398Srdivacky} 4618198398Srdivacky 4619199482Srdivackyinline bool QualType::isConstQualified() const { 4620234353Sdim return isLocalConstQualified() || 4621218893Sdim getCommonPtr()->CanonicalType.isLocalConstQualified(); 4622199482Srdivacky} 4623199482Srdivacky 4624199482Srdivackyinline bool QualType::isRestrictQualified() const { 4625234353Sdim return isLocalRestrictQualified() || 4626218893Sdim getCommonPtr()->CanonicalType.isLocalRestrictQualified(); 4627199482Srdivacky} 4628199482Srdivacky 4629199482Srdivacky 4630199482Srdivackyinline bool QualType::isVolatileQualified() const { 4631234353Sdim return isLocalVolatileQualified() || 4632218893Sdim getCommonPtr()->CanonicalType.isLocalVolatileQualified(); 4633199482Srdivacky} 4634234353Sdim 4635199482Srdivackyinline bool QualType::hasQualifiers() const { 4636199482Srdivacky return hasLocalQualifiers() || 4637218893Sdim getCommonPtr()->CanonicalType.hasLocalQualifiers(); 4638199482Srdivacky} 4639201361Srdivacky 4640218893Sdiminline QualType QualType::getUnqualifiedType() const { 4641218893Sdim if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) 4642218893Sdim return QualType(getTypePtr(), 0); 4643218893Sdim 4644234353Sdim return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0); 4645201361Srdivacky} 4646201361Srdivacky 4647218893Sdiminline SplitQualType QualType::getSplitUnqualifiedType() const { 4648218893Sdim if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) 4649218893Sdim return split(); 4650218893Sdim 4651218893Sdim return getSplitUnqualifiedTypeImpl(*this); 4652193326Sed} 4653234353Sdim 4654218893Sdiminline void QualType::removeLocalConst() { 4655218893Sdim removeLocalFastQualifiers(Qualifiers::Const); 4656218893Sdim} 4657198092Srdivacky 4658218893Sdiminline void QualType::removeLocalRestrict() { 4659218893Sdim removeLocalFastQualifiers(Qualifiers::Restrict); 4660193326Sed} 4661193326Sed 4662218893Sdiminline void QualType::removeLocalVolatile() { 4663218893Sdim removeLocalFastQualifiers(Qualifiers::Volatile); 4664193326Sed} 4665193326Sed 4666218893Sdiminline void QualType::removeLocalCVRQualifiers(unsigned Mask) { 4667198092Srdivacky assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits"); 4668218893Sdim assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask); 4669193326Sed 4670198092Srdivacky // Fast path: we don't need to touch the slow qualifiers. 4671218893Sdim removeLocalFastQualifiers(Mask); 4672193326Sed} 4673193326Sed 4674193326Sed/// getAddressSpace - Return the address space of this type. 4675193326Sedinline unsigned QualType::getAddressSpace() const { 4676218893Sdim return getQualifiers().getAddressSpace(); 4677193326Sed} 4678193326Sed 4679193326Sed/// getObjCGCAttr - Return the gc attribute of this type. 4680198092Srdivackyinline Qualifiers::GC QualType::getObjCGCAttr() const { 4681218893Sdim return getQualifiers().getObjCGCAttr(); 4682193326Sed} 4683198092Srdivacky 4684206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { 4685206084Srdivacky if (const PointerType *PT = t.getAs<PointerType>()) { 4686198092Srdivacky if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>()) 4687206084Srdivacky return FT->getExtInfo(); 4688206084Srdivacky } else if (const FunctionType *FT = t.getAs<FunctionType>()) 4689206084Srdivacky return FT->getExtInfo(); 4690198092Srdivacky 4691206084Srdivacky return FunctionType::ExtInfo(); 4692198092Srdivacky} 4693198092Srdivacky 4694206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { 4695206084Srdivacky return getFunctionExtInfo(*t); 4696202879Srdivacky} 4697202879Srdivacky 4698193326Sed/// isMoreQualifiedThan - Determine whether this type is more 4699193326Sed/// qualified than the Other type. For example, "const volatile int" 4700193326Sed/// is more qualified than "const int", "volatile int", and 4701193326Sed/// "int". However, it is not more qualified than "const volatile 4702193326Sed/// int". 4703218893Sdiminline bool QualType::isMoreQualifiedThan(QualType other) const { 4704218893Sdim Qualifiers myQuals = getQualifiers(); 4705218893Sdim Qualifiers otherQuals = other.getQualifiers(); 4706218893Sdim return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals)); 4707193326Sed} 4708193326Sed 4709193326Sed/// isAtLeastAsQualifiedAs - Determine whether this type is at last 4710193326Sed/// as qualified as the Other type. For example, "const volatile 4711193326Sed/// int" is at least as qualified as "const int", "volatile int", 4712193326Sed/// "int", and "const volatile int". 4713218893Sdiminline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { 4714218893Sdim return getQualifiers().compatiblyIncludes(other.getQualifiers()); 4715193326Sed} 4716193326Sed 4717193326Sed/// getNonReferenceType - If Type is a reference type (e.g., const 4718193326Sed/// int&), returns the type that the reference refers to ("const 4719193326Sed/// int"). Otherwise, returns the type itself. This routine is used 4720193326Sed/// throughout Sema to implement C++ 5p6: 4721193326Sed/// 4722193326Sed/// If an expression initially has the type "reference to T" (8.3.2, 4723193326Sed/// 8.5.3), the type is adjusted to "T" prior to any further 4724193326Sed/// analysis, the expression designates the object or function 4725193326Sed/// denoted by the reference, and the expression is an lvalue. 4726193326Sedinline QualType QualType::getNonReferenceType() const { 4727198092Srdivacky if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>()) 4728193326Sed return RefType->getPointeeType(); 4729193326Sed else 4730193326Sed return *this; 4731193326Sed} 4732193326Sed 4733224145Sdiminline bool QualType::isCForbiddenLValueType() const { 4734224145Sdim return ((getTypePtr()->isVoidType() && !hasQualifiers()) || 4735224145Sdim getTypePtr()->isFunctionType()); 4736224145Sdim} 4737224145Sdim 4738221345Sdim/// \brief Tests whether the type is categorized as a fundamental type. 4739221345Sdim/// 4740221345Sdim/// \returns True for types specified in C++0x [basic.fundamental]. 4741221345Sdiminline bool Type::isFundamentalType() const { 4742221345Sdim return isVoidType() || 4743221345Sdim // FIXME: It's really annoying that we don't have an 4744221345Sdim // 'isArithmeticType()' which agrees with the standard definition. 4745221345Sdim (isArithmeticType() && !isEnumeralType()); 4746221345Sdim} 4747221345Sdim 4748221345Sdim/// \brief Tests whether the type is categorized as a compound type. 4749221345Sdim/// 4750221345Sdim/// \returns True for types specified in C++0x [basic.compound]. 4751221345Sdiminline bool Type::isCompoundType() const { 4752221345Sdim // C++0x [basic.compound]p1: 4753221345Sdim // Compound types can be constructed in the following ways: 4754221345Sdim // -- arrays of objects of a given type [...]; 4755221345Sdim return isArrayType() || 4756221345Sdim // -- functions, which have parameters of given types [...]; 4757221345Sdim isFunctionType() || 4758221345Sdim // -- pointers to void or objects or functions [...]; 4759221345Sdim isPointerType() || 4760221345Sdim // -- references to objects or functions of a given type. [...] 4761221345Sdim isReferenceType() || 4762221345Sdim // -- classes containing a sequence of objects of various types, [...]; 4763221345Sdim isRecordType() || 4764234353Sdim // -- unions, which are classes capable of containing objects of different 4765234353Sdim // types at different times; 4766221345Sdim isUnionType() || 4767221345Sdim // -- enumerations, which comprise a set of named constant values. [...]; 4768221345Sdim isEnumeralType() || 4769221345Sdim // -- pointers to non-static class members, [...]. 4770221345Sdim isMemberPointerType(); 4771221345Sdim} 4772221345Sdim 4773193326Sedinline bool Type::isFunctionType() const { 4774199482Srdivacky return isa<FunctionType>(CanonicalType); 4775193326Sed} 4776193326Sedinline bool Type::isPointerType() const { 4777199482Srdivacky return isa<PointerType>(CanonicalType); 4778193326Sed} 4779198092Srdivackyinline bool Type::isAnyPointerType() const { 4780198092Srdivacky return isPointerType() || isObjCObjectPointerType(); 4781198092Srdivacky} 4782193326Sedinline bool Type::isBlockPointerType() const { 4783199482Srdivacky return isa<BlockPointerType>(CanonicalType); 4784193326Sed} 4785193326Sedinline bool Type::isReferenceType() const { 4786199482Srdivacky return isa<ReferenceType>(CanonicalType); 4787193326Sed} 4788193326Sedinline bool Type::isLValueReferenceType() const { 4789199482Srdivacky return isa<LValueReferenceType>(CanonicalType); 4790193326Sed} 4791193326Sedinline bool Type::isRValueReferenceType() const { 4792199482Srdivacky return isa<RValueReferenceType>(CanonicalType); 4793193326Sed} 4794193326Sedinline bool Type::isFunctionPointerType() const { 4795218893Sdim if (const PointerType *T = getAs<PointerType>()) 4796193326Sed return T->getPointeeType()->isFunctionType(); 4797193326Sed else 4798193326Sed return false; 4799193326Sed} 4800193326Sedinline bool Type::isMemberPointerType() const { 4801199482Srdivacky return isa<MemberPointerType>(CanonicalType); 4802193326Sed} 4803193326Sedinline bool Type::isMemberFunctionPointerType() const { 4804198092Srdivacky if (const MemberPointerType* T = getAs<MemberPointerType>()) 4805212904Sdim return T->isMemberFunctionPointer(); 4806193326Sed else 4807193326Sed return false; 4808193326Sed} 4809212904Sdiminline bool Type::isMemberDataPointerType() const { 4810212904Sdim if (const MemberPointerType* T = getAs<MemberPointerType>()) 4811212904Sdim return T->isMemberDataPointer(); 4812212904Sdim else 4813212904Sdim return false; 4814212904Sdim} 4815193326Sedinline bool Type::isArrayType() const { 4816199482Srdivacky return isa<ArrayType>(CanonicalType); 4817193326Sed} 4818193326Sedinline bool Type::isConstantArrayType() const { 4819199482Srdivacky return isa<ConstantArrayType>(CanonicalType); 4820193326Sed} 4821193326Sedinline bool Type::isIncompleteArrayType() const { 4822199482Srdivacky return isa<IncompleteArrayType>(CanonicalType); 4823193326Sed} 4824193326Sedinline bool Type::isVariableArrayType() const { 4825199482Srdivacky return isa<VariableArrayType>(CanonicalType); 4826193326Sed} 4827193326Sedinline bool Type::isDependentSizedArrayType() const { 4828199482Srdivacky return isa<DependentSizedArrayType>(CanonicalType); 4829193326Sed} 4830218893Sdiminline bool Type::isBuiltinType() const { 4831218893Sdim return isa<BuiltinType>(CanonicalType); 4832218893Sdim} 4833193326Sedinline bool Type::isRecordType() const { 4834199482Srdivacky return isa<RecordType>(CanonicalType); 4835193326Sed} 4836218893Sdiminline bool Type::isEnumeralType() const { 4837218893Sdim return isa<EnumType>(CanonicalType); 4838218893Sdim} 4839193326Sedinline bool Type::isAnyComplexType() const { 4840199482Srdivacky return isa<ComplexType>(CanonicalType); 4841193326Sed} 4842193326Sedinline bool Type::isVectorType() const { 4843199482Srdivacky return isa<VectorType>(CanonicalType); 4844193326Sed} 4845193326Sedinline bool Type::isExtVectorType() const { 4846199482Srdivacky return isa<ExtVectorType>(CanonicalType); 4847193326Sed} 4848194613Sedinline bool Type::isObjCObjectPointerType() const { 4849199482Srdivacky return isa<ObjCObjectPointerType>(CanonicalType); 4850194613Sed} 4851208600Srdivackyinline bool Type::isObjCObjectType() const { 4852208600Srdivacky return isa<ObjCObjectType>(CanonicalType); 4853193326Sed} 4854212904Sdiminline bool Type::isObjCObjectOrInterfaceType() const { 4855234353Sdim return isa<ObjCInterfaceType>(CanonicalType) || 4856212904Sdim isa<ObjCObjectType>(CanonicalType); 4857212904Sdim} 4858226633Sdiminline bool Type::isAtomicType() const { 4859226633Sdim return isa<AtomicType>(CanonicalType); 4860226633Sdim} 4861212904Sdim 4862193326Sedinline bool Type::isObjCQualifiedIdType() const { 4863198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4864194613Sed return OPT->isObjCQualifiedIdType(); 4865194613Sed return false; 4866193326Sed} 4867198092Srdivackyinline bool Type::isObjCQualifiedClassType() const { 4868198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4869198092Srdivacky return OPT->isObjCQualifiedClassType(); 4870198092Srdivacky return false; 4871198092Srdivacky} 4872198092Srdivackyinline bool Type::isObjCIdType() const { 4873198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4874198092Srdivacky return OPT->isObjCIdType(); 4875198092Srdivacky return false; 4876198092Srdivacky} 4877198092Srdivackyinline bool Type::isObjCClassType() const { 4878198092Srdivacky if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) 4879198092Srdivacky return OPT->isObjCClassType(); 4880198092Srdivacky return false; 4881198092Srdivacky} 4882199990Srdivackyinline bool Type::isObjCSelType() const { 4883199990Srdivacky if (const PointerType *OPT = getAs<PointerType>()) 4884199990Srdivacky return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); 4885199990Srdivacky return false; 4886199990Srdivacky} 4887198092Srdivackyinline bool Type::isObjCBuiltinType() const { 4888199990Srdivacky return isObjCIdType() || isObjCClassType() || isObjCSelType(); 4889198092Srdivacky} 4890193326Sedinline bool Type::isTemplateTypeParmType() const { 4891199482Srdivacky return isa<TemplateTypeParmType>(CanonicalType); 4892193326Sed} 4893193326Sed 4894193326Sedinline bool Type::isSpecificBuiltinType(unsigned K) const { 4895198092Srdivacky if (const BuiltinType *BT = getAs<BuiltinType>()) 4896193326Sed if (BT->getKind() == (BuiltinType::Kind) K) 4897193326Sed return true; 4898193326Sed return false; 4899193326Sed} 4900193326Sed 4901218893Sdiminline bool Type::isPlaceholderType() const { 4902226633Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4903218893Sdim return BT->isPlaceholderType(); 4904218893Sdim return false; 4905218893Sdim} 4906218893Sdim 4907226633Sdiminline const BuiltinType *Type::getAsPlaceholderType() const { 4908226633Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4909226633Sdim if (BT->isPlaceholderType()) 4910226633Sdim return BT; 4911226633Sdim return 0; 4912226633Sdim} 4913226633Sdim 4914221345Sdiminline bool Type::isSpecificPlaceholderType(unsigned K) const { 4915234353Sdim assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)); 4916221345Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4917221345Sdim return (BT->getKind() == (BuiltinType::Kind) K); 4918221345Sdim return false; 4919221345Sdim} 4920221345Sdim 4921234353Sdiminline bool Type::isNonOverloadPlaceholderType() const { 4922234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) 4923234353Sdim return BT->isNonOverloadPlaceholderType(); 4924234353Sdim return false; 4925234353Sdim} 4926234353Sdim 4927234353Sdiminline bool Type::isVoidType() const { 4928234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4929234353Sdim return BT->getKind() == BuiltinType::Void; 4930234353Sdim return false; 4931234353Sdim} 4932234353Sdim 4933234353Sdiminline bool Type::isHalfType() const { 4934234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4935234353Sdim return BT->getKind() == BuiltinType::Half; 4936234353Sdim // FIXME: Should we allow complex __fp16? Probably not. 4937234353Sdim return false; 4938234353Sdim} 4939234353Sdim 4940234353Sdiminline bool Type::isNullPtrType() const { 4941234353Sdim if (const BuiltinType *BT = getAs<BuiltinType>()) 4942234353Sdim return BT->getKind() == BuiltinType::NullPtr; 4943234353Sdim return false; 4944234353Sdim} 4945234353Sdim 4946234353Sdimextern bool IsEnumDeclComplete(EnumDecl *); 4947234353Sdimextern bool IsEnumDeclScoped(EnumDecl *); 4948234353Sdim 4949234353Sdiminline bool Type::isIntegerType() const { 4950234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4951234353Sdim return BT->getKind() >= BuiltinType::Bool && 4952234353Sdim BT->getKind() <= BuiltinType::Int128; 4953234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { 4954234353Sdim // Incomplete enum types are not treated as integer types. 4955234353Sdim // FIXME: In C++, enum types are never integer types. 4956234353Sdim return IsEnumDeclComplete(ET->getDecl()) && 4957234353Sdim !IsEnumDeclScoped(ET->getDecl()); 4958234353Sdim } 4959234353Sdim return false; 4960234353Sdim} 4961234353Sdim 4962234353Sdiminline bool Type::isScalarType() const { 4963234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4964234353Sdim return BT->getKind() > BuiltinType::Void && 4965234353Sdim BT->getKind() <= BuiltinType::NullPtr; 4966234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) 4967234353Sdim // Enums are scalar types, but only if they are defined. Incomplete enums 4968234353Sdim // are not treated as scalar types. 4969234353Sdim return IsEnumDeclComplete(ET->getDecl()); 4970234353Sdim return isa<PointerType>(CanonicalType) || 4971234353Sdim isa<BlockPointerType>(CanonicalType) || 4972234353Sdim isa<MemberPointerType>(CanonicalType) || 4973234353Sdim isa<ComplexType>(CanonicalType) || 4974234353Sdim isa<ObjCObjectPointerType>(CanonicalType); 4975234353Sdim} 4976234353Sdim 4977234353Sdiminline bool Type::isIntegralOrEnumerationType() const { 4978234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4979234353Sdim return BT->getKind() >= BuiltinType::Bool && 4980234353Sdim BT->getKind() <= BuiltinType::Int128; 4981234353Sdim 4982234353Sdim // Check for a complete enum type; incomplete enum types are not properly an 4983234353Sdim // enumeration type in the sense required here. 4984234353Sdim if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) 4985234353Sdim return IsEnumDeclComplete(ET->getDecl()); 4986234353Sdim 4987234353Sdim return false; 4988234353Sdim} 4989234353Sdim 4990234353Sdiminline bool Type::isBooleanType() const { 4991234353Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) 4992234353Sdim return BT->getKind() == BuiltinType::Bool; 4993234353Sdim return false; 4994234353Sdim} 4995234353Sdim 4996193326Sed/// \brief Determines whether this is a type for which one can define 4997193326Sed/// an overloaded operator. 4998193326Sedinline bool Type::isOverloadableType() const { 4999193326Sed return isDependentType() || isRecordType() || isEnumeralType(); 5000193326Sed} 5001193326Sed 5002224145Sdim/// \brief Determines whether this type can decay to a pointer type. 5003224145Sdiminline bool Type::canDecayToPointerType() const { 5004224145Sdim return isFunctionType() || isArrayType(); 5005224145Sdim} 5006224145Sdim 5007193326Sedinline bool Type::hasPointerRepresentation() const { 5008193326Sed return (isPointerType() || isReferenceType() || isBlockPointerType() || 5009208600Srdivacky isObjCObjectPointerType() || isNullPtrType()); 5010193326Sed} 5011193326Sed 5012193326Sedinline bool Type::hasObjCPointerRepresentation() const { 5013208600Srdivacky return isObjCObjectPointerType(); 5014193326Sed} 5015193326Sed 5016218893Sdiminline const Type *Type::getBaseElementTypeUnsafe() const { 5017218893Sdim const Type *type = this; 5018218893Sdim while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) 5019218893Sdim type = arrayType->getElementType().getTypePtr(); 5020218893Sdim return type; 5021218893Sdim} 5022218893Sdim 5023193326Sed/// Insertion operator for diagnostics. This allows sending QualType's into a 5024193326Sed/// diagnostic with <<. 5025193326Sedinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 5026193326Sed QualType T) { 5027193326Sed DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), 5028226633Sdim DiagnosticsEngine::ak_qualtype); 5029193326Sed return DB; 5030193326Sed} 5031193326Sed 5032206084Srdivacky/// Insertion operator for partial diagnostics. This allows sending QualType's 5033206084Srdivacky/// into a diagnostic with <<. 5034206084Srdivackyinline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 5035206084Srdivacky QualType T) { 5036206084Srdivacky PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), 5037226633Sdim DiagnosticsEngine::ak_qualtype); 5038206084Srdivacky return PD; 5039206084Srdivacky} 5040206084Srdivacky 5041199482Srdivacky// Helper class template that is used by Type::getAs to ensure that one does 5042199482Srdivacky// not try to look through a qualified type to get to an array type. 5043199482Srdivackytemplate<typename T, 5044199482Srdivacky bool isArrayType = (llvm::is_same<T, ArrayType>::value || 5045199482Srdivacky llvm::is_base_of<ArrayType, T>::value)> 5046199482Srdivackystruct ArrayType_cannot_be_used_with_getAs { }; 5047234353Sdim 5048199482Srdivackytemplate<typename T> 5049199482Srdivackystruct ArrayType_cannot_be_used_with_getAs<T, true>; 5050234353Sdim 5051239462Sdim// Member-template getAs<specific type>'. 5052198092Srdivackytemplate <typename T> const T *Type::getAs() const { 5053199482Srdivacky ArrayType_cannot_be_used_with_getAs<T> at; 5054199482Srdivacky (void)at; 5055234353Sdim 5056198092Srdivacky // If this is directly a T type, return it. 5057198092Srdivacky if (const T *Ty = dyn_cast<T>(this)) 5058198092Srdivacky return Ty; 5059198092Srdivacky 5060198092Srdivacky // If the canonical form of this type isn't the right kind, reject it. 5061198092Srdivacky if (!isa<T>(CanonicalType)) 5062198092Srdivacky return 0; 5063198092Srdivacky 5064198092Srdivacky // If this is a typedef for the type, strip the typedef off without 5065198092Srdivacky // losing all typedef information. 5066198092Srdivacky return cast<T>(getUnqualifiedDesugaredType()); 5067198092Srdivacky} 5068198092Srdivacky 5069218893Sdiminline const ArrayType *Type::getAsArrayTypeUnsafe() const { 5070218893Sdim // If this is directly an array type, return it. 5071218893Sdim if (const ArrayType *arr = dyn_cast<ArrayType>(this)) 5072218893Sdim return arr; 5073218893Sdim 5074218893Sdim // If the canonical form of this type isn't the right kind, reject it. 5075218893Sdim if (!isa<ArrayType>(CanonicalType)) 5076218893Sdim return 0; 5077218893Sdim 5078218893Sdim // If this is a typedef for the type, strip the typedef off without 5079218893Sdim // losing all typedef information. 5080218893Sdim return cast<ArrayType>(getUnqualifiedDesugaredType()); 5081218893Sdim} 5082218893Sdim 5083218893Sdimtemplate <typename T> const T *Type::castAs() const { 5084218893Sdim ArrayType_cannot_be_used_with_getAs<T> at; 5085218893Sdim (void) at; 5086218893Sdim 5087218893Sdim assert(isa<T>(CanonicalType)); 5088218893Sdim if (const T *ty = dyn_cast<T>(this)) return ty; 5089218893Sdim return cast<T>(getUnqualifiedDesugaredType()); 5090218893Sdim} 5091218893Sdim 5092218893Sdiminline const ArrayType *Type::castAsArrayTypeUnsafe() const { 5093218893Sdim assert(isa<ArrayType>(CanonicalType)); 5094218893Sdim if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr; 5095218893Sdim return cast<ArrayType>(getUnqualifiedDesugaredType()); 5096218893Sdim} 5097218893Sdim 5098193326Sed} // end namespace clang 5099193326Sed 5100193326Sed#endif 5101