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