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