1193326Sed//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file defines the Type interface and subclasses.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#ifndef LLVM_CLANG_AST_TYPE_H
15193326Sed#define LLVM_CLANG_AST_TYPE_H
16193326Sed
17249423Sdim#include "clang/AST/NestedNameSpecifier.h"
18249423Sdim#include "clang/AST/TemplateName.h"
19193326Sed#include "clang/Basic/Diagnostic.h"
20221345Sdim#include "clang/Basic/ExceptionSpecificationType.h"
21193326Sed#include "clang/Basic/IdentifierTable.h"
22249423Sdim#include "clang/Basic/LLVM.h"
23203955Srdivacky#include "clang/Basic/Linkage.h"
24206084Srdivacky#include "clang/Basic/PartialDiagnostic.h"
25249423Sdim#include "clang/Basic/Specifiers.h"
26218893Sdim#include "clang/Basic/Visibility.h"
27193326Sed#include "llvm/ADT/APSInt.h"
28193326Sed#include "llvm/ADT/FoldingSet.h"
29218893Sdim#include "llvm/ADT/Optional.h"
30193326Sed#include "llvm/ADT/PointerIntPair.h"
31193326Sed#include "llvm/ADT/PointerUnion.h"
32239462Sdim#include "llvm/ADT/Twine.h"
33249423Sdim#include "llvm/Support/ErrorHandling.h"
34249423Sdim#include "llvm/Support/type_traits.h"
35193326Sed
36198092Srdivackynamespace clang {
37198092Srdivacky  enum {
38218893Sdim    TypeAlignmentInBits = 4,
39198092Srdivacky    TypeAlignment = 1 << TypeAlignmentInBits
40198092Srdivacky  };
41200583Srdivacky  class Type;
42200583Srdivacky  class ExtQuals;
43200583Srdivacky  class QualType;
44198092Srdivacky}
45193326Sed
46193326Sednamespace llvm {
47193326Sed  template <typename T>
48193326Sed  class PointerLikeTypeTraits;
49193326Sed  template<>
50193326Sed  class PointerLikeTypeTraits< ::clang::Type*> {
51193326Sed  public:
52193326Sed    static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
53193326Sed    static inline ::clang::Type *getFromVoidPointer(void *P) {
54193326Sed      return static_cast< ::clang::Type*>(P);
55193326Sed    }
56198092Srdivacky    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
57193326Sed  };
58198092Srdivacky  template<>
59198092Srdivacky  class PointerLikeTypeTraits< ::clang::ExtQuals*> {
60198092Srdivacky  public:
61198092Srdivacky    static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
62198092Srdivacky    static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
63198092Srdivacky      return static_cast< ::clang::ExtQuals*>(P);
64198092Srdivacky    }
65198092Srdivacky    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
66198092Srdivacky  };
67200583Srdivacky
68200583Srdivacky  template <>
69200583Srdivacky  struct isPodLike<clang::QualType> { static const bool value = true; };
70193326Sed}
71193326Sed
72193326Sednamespace clang {
73193326Sed  class ASTContext;
74221345Sdim  class TypedefNameDecl;
75193326Sed  class TemplateDecl;
76193326Sed  class TemplateTypeParmDecl;
77193326Sed  class NonTypeTemplateParmDecl;
78193326Sed  class TemplateTemplateParmDecl;
79193326Sed  class TagDecl;
80193326Sed  class RecordDecl;
81193326Sed  class CXXRecordDecl;
82193326Sed  class EnumDecl;
83193326Sed  class FieldDecl;
84234982Sdim  class FunctionDecl;
85193326Sed  class ObjCInterfaceDecl;
86193326Sed  class ObjCProtocolDecl;
87193326Sed  class ObjCMethodDecl;
88200583Srdivacky  class UnresolvedUsingTypenameDecl;
89193326Sed  class Expr;
90193326Sed  class Stmt;
91193326Sed  class SourceLocation;
92193326Sed  class StmtIteratorBase;
93193326Sed  class TemplateArgument;
94198893Srdivacky  class TemplateArgumentLoc;
95199990Srdivacky  class TemplateArgumentListInfo;
96208600Srdivacky  class ElaboratedType;
97218893Sdim  class ExtQuals;
98218893Sdim  class ExtQualsTypeCommonBase;
99198092Srdivacky  struct PrintingPolicy;
100193326Sed
101234353Sdim  template <typename> class CanQual;
102204643Srdivacky  typedef CanQual<Type> CanQualType;
103204643Srdivacky
104193326Sed  // Provide forward declarations for all of the *Type classes
105193326Sed#define TYPE(Class, Base) class Class##Type;
106193326Sed#include "clang/AST/TypeNodes.def"
107193326Sed
108198092Srdivacky/// Qualifiers - The collection of all-type qualifiers we support.
109198092Srdivacky/// Clang supports five independent qualifiers:
110198092Srdivacky/// * C99: const, volatile, and restrict
111198092Srdivacky/// * Embedded C (TR18037): address spaces
112198092Srdivacky/// * Objective C: the GC attributes (none, weak, or strong)
113198092Srdivackyclass Qualifiers {
114193326Sedpublic:
115198092Srdivacky  enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
116193326Sed    Const    = 0x1,
117193326Sed    Restrict = 0x2,
118193326Sed    Volatile = 0x4,
119198092Srdivacky    CVRMask = Const | Volatile | Restrict
120193326Sed  };
121198092Srdivacky
122198092Srdivacky  enum GC {
123193326Sed    GCNone = 0,
124193326Sed    Weak,
125193326Sed    Strong
126193326Sed  };
127198092Srdivacky
128224145Sdim  enum ObjCLifetime {
129224145Sdim    /// There is no lifetime qualification on this type.
130224145Sdim    OCL_None,
131224145Sdim
132224145Sdim    /// This object can be modified without requiring retains or
133224145Sdim    /// releases.
134224145Sdim    OCL_ExplicitNone,
135224145Sdim
136224145Sdim    /// Assigning into this object requires the old value to be
137224145Sdim    /// released and the new value to be retained.  The timing of the
138224145Sdim    /// release of the old value is inexact: it may be moved to
139224145Sdim    /// immediately after the last known point where the value is
140224145Sdim    /// live.
141224145Sdim    OCL_Strong,
142224145Sdim
143224145Sdim    /// Reading or writing from this object requires a barrier call.
144224145Sdim    OCL_Weak,
145224145Sdim
146224145Sdim    /// Assigning into this object requires a lifetime extension.
147224145Sdim    OCL_Autoreleasing
148224145Sdim  };
149224145Sdim
150198092Srdivacky  enum {
151198092Srdivacky    /// The maximum supported address space number.
152198092Srdivacky    /// 24 bits should be enough for anyone.
153198092Srdivacky    MaxAddressSpace = 0xffffffu,
154198092Srdivacky
155198092Srdivacky    /// The width of the "fast" qualifier mask.
156218893Sdim    FastWidth = 3,
157198092Srdivacky
158198092Srdivacky    /// The fast qualifier mask.
159198092Srdivacky    FastMask = (1 << FastWidth) - 1
160198092Srdivacky  };
161198092Srdivacky
162198092Srdivacky  Qualifiers() : Mask(0) {}
163198092Srdivacky
164243830Sdim  /// \brief Returns the common set of qualifiers while removing them from
165243830Sdim  /// the given sets.
166243830Sdim  static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
167243830Sdim    // If both are only CVR-qualified, bit operations are sufficient.
168243830Sdim    if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
169243830Sdim      Qualifiers Q;
170243830Sdim      Q.Mask = L.Mask & R.Mask;
171243830Sdim      L.Mask &= ~Q.Mask;
172243830Sdim      R.Mask &= ~Q.Mask;
173243830Sdim      return Q;
174243830Sdim    }
175243830Sdim
176243830Sdim    Qualifiers Q;
177243830Sdim    unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
178243830Sdim    Q.addCVRQualifiers(CommonCRV);
179243830Sdim    L.removeCVRQualifiers(CommonCRV);
180243830Sdim    R.removeCVRQualifiers(CommonCRV);
181243830Sdim
182243830Sdim    if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
183243830Sdim      Q.setObjCGCAttr(L.getObjCGCAttr());
184243830Sdim      L.removeObjCGCAttr();
185243830Sdim      R.removeObjCGCAttr();
186243830Sdim    }
187243830Sdim
188243830Sdim    if (L.getObjCLifetime() == R.getObjCLifetime()) {
189243830Sdim      Q.setObjCLifetime(L.getObjCLifetime());
190243830Sdim      L.removeObjCLifetime();
191243830Sdim      R.removeObjCLifetime();
192243830Sdim    }
193243830Sdim
194243830Sdim    if (L.getAddressSpace() == R.getAddressSpace()) {
195243830Sdim      Q.setAddressSpace(L.getAddressSpace());
196243830Sdim      L.removeAddressSpace();
197243830Sdim      R.removeAddressSpace();
198243830Sdim    }
199243830Sdim    return Q;
200243830Sdim  }
201243830Sdim
202198092Srdivacky  static Qualifiers fromFastMask(unsigned Mask) {
203198092Srdivacky    Qualifiers Qs;
204198092Srdivacky    Qs.addFastQualifiers(Mask);
205198092Srdivacky    return Qs;
206198092Srdivacky  }
207198092Srdivacky
208198092Srdivacky  static Qualifiers fromCVRMask(unsigned CVR) {
209198092Srdivacky    Qualifiers Qs;
210198092Srdivacky    Qs.addCVRQualifiers(CVR);
211198092Srdivacky    return Qs;
212198092Srdivacky  }
213198092Srdivacky
214198092Srdivacky  // Deserialize qualifiers from an opaque representation.
215198092Srdivacky  static Qualifiers fromOpaqueValue(unsigned opaque) {
216198092Srdivacky    Qualifiers Qs;
217198092Srdivacky    Qs.Mask = opaque;
218198092Srdivacky    return Qs;
219198092Srdivacky  }
220198092Srdivacky
221198092Srdivacky  // Serialize these qualifiers into an opaque representation.
222198092Srdivacky  unsigned getAsOpaqueValue() const {
223198092Srdivacky    return Mask;
224198092Srdivacky  }
225198092Srdivacky
226198092Srdivacky  bool hasConst() const { return Mask & Const; }
227198092Srdivacky  void setConst(bool flag) {
228198092Srdivacky    Mask = (Mask & ~Const) | (flag ? Const : 0);
229198092Srdivacky  }
230198092Srdivacky  void removeConst() { Mask &= ~Const; }
231198092Srdivacky  void addConst() { Mask |= Const; }
232198092Srdivacky
233198092Srdivacky  bool hasVolatile() const { return Mask & Volatile; }
234198092Srdivacky  void setVolatile(bool flag) {
235198092Srdivacky    Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
236198092Srdivacky  }
237198092Srdivacky  void removeVolatile() { Mask &= ~Volatile; }
238198092Srdivacky  void addVolatile() { Mask |= Volatile; }
239198092Srdivacky
240198092Srdivacky  bool hasRestrict() const { return Mask & Restrict; }
241198092Srdivacky  void setRestrict(bool flag) {
242198092Srdivacky    Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
243198092Srdivacky  }
244198092Srdivacky  void removeRestrict() { Mask &= ~Restrict; }
245198092Srdivacky  void addRestrict() { Mask |= Restrict; }
246198092Srdivacky
247198092Srdivacky  bool hasCVRQualifiers() const { return getCVRQualifiers(); }
248198092Srdivacky  unsigned getCVRQualifiers() const { return Mask & CVRMask; }
249198092Srdivacky  void setCVRQualifiers(unsigned mask) {
250198092Srdivacky    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
251198092Srdivacky    Mask = (Mask & ~CVRMask) | mask;
252198092Srdivacky  }
253198092Srdivacky  void removeCVRQualifiers(unsigned mask) {
254198092Srdivacky    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
255198092Srdivacky    Mask &= ~mask;
256198092Srdivacky  }
257198092Srdivacky  void removeCVRQualifiers() {
258198092Srdivacky    removeCVRQualifiers(CVRMask);
259198092Srdivacky  }
260198092Srdivacky  void addCVRQualifiers(unsigned mask) {
261198092Srdivacky    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
262198092Srdivacky    Mask |= mask;
263198092Srdivacky  }
264198092Srdivacky
265198092Srdivacky  bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
266198092Srdivacky  GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
267198092Srdivacky  void setObjCGCAttr(GC type) {
268198092Srdivacky    Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
269198092Srdivacky  }
270198092Srdivacky  void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
271198092Srdivacky  void addObjCGCAttr(GC type) {
272198092Srdivacky    assert(type);
273198092Srdivacky    setObjCGCAttr(type);
274198092Srdivacky  }
275221345Sdim  Qualifiers withoutObjCGCAttr() const {
276221345Sdim    Qualifiers qs = *this;
277221345Sdim    qs.removeObjCGCAttr();
278221345Sdim    return qs;
279221345Sdim  }
280234353Sdim  Qualifiers withoutObjCLifetime() const {
281224145Sdim    Qualifiers qs = *this;
282224145Sdim    qs.removeObjCLifetime();
283224145Sdim    return qs;
284224145Sdim  }
285198092Srdivacky
286224145Sdim  bool hasObjCLifetime() const { return Mask & LifetimeMask; }
287224145Sdim  ObjCLifetime getObjCLifetime() const {
288224145Sdim    return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
289224145Sdim  }
290224145Sdim  void setObjCLifetime(ObjCLifetime type) {
291224145Sdim    Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
292224145Sdim  }
293224145Sdim  void removeObjCLifetime() { setObjCLifetime(OCL_None); }
294224145Sdim  void addObjCLifetime(ObjCLifetime type) {
295224145Sdim    assert(type);
296234353Sdim    assert(!hasObjCLifetime());
297234353Sdim    Mask |= (type << LifetimeShift);
298224145Sdim  }
299224145Sdim
300224145Sdim  /// True if the lifetime is neither None or ExplicitNone.
301224145Sdim  bool hasNonTrivialObjCLifetime() const {
302224145Sdim    ObjCLifetime lifetime = getObjCLifetime();
303224145Sdim    return (lifetime > OCL_ExplicitNone);
304224145Sdim  }
305224145Sdim
306224145Sdim  /// True if the lifetime is either strong or weak.
307224145Sdim  bool hasStrongOrWeakObjCLifetime() const {
308224145Sdim    ObjCLifetime lifetime = getObjCLifetime();
309224145Sdim    return (lifetime == OCL_Strong || lifetime == OCL_Weak);
310224145Sdim  }
311234353Sdim
312198092Srdivacky  bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
313198092Srdivacky  unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
314198092Srdivacky  void setAddressSpace(unsigned space) {
315198092Srdivacky    assert(space <= MaxAddressSpace);
316198092Srdivacky    Mask = (Mask & ~AddressSpaceMask)
317198092Srdivacky         | (((uint32_t) space) << AddressSpaceShift);
318198092Srdivacky  }
319198092Srdivacky  void removeAddressSpace() { setAddressSpace(0); }
320198092Srdivacky  void addAddressSpace(unsigned space) {
321198092Srdivacky    assert(space);
322198092Srdivacky    setAddressSpace(space);
323198092Srdivacky  }
324198092Srdivacky
325198092Srdivacky  // Fast qualifiers are those that can be allocated directly
326198092Srdivacky  // on a QualType object.
327198092Srdivacky  bool hasFastQualifiers() const { return getFastQualifiers(); }
328198092Srdivacky  unsigned getFastQualifiers() const { return Mask & FastMask; }
329198092Srdivacky  void setFastQualifiers(unsigned mask) {
330198092Srdivacky    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
331198092Srdivacky    Mask = (Mask & ~FastMask) | mask;
332198092Srdivacky  }
333198092Srdivacky  void removeFastQualifiers(unsigned mask) {
334198092Srdivacky    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
335198092Srdivacky    Mask &= ~mask;
336198092Srdivacky  }
337198092Srdivacky  void removeFastQualifiers() {
338198092Srdivacky    removeFastQualifiers(FastMask);
339198092Srdivacky  }
340198092Srdivacky  void addFastQualifiers(unsigned mask) {
341198092Srdivacky    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
342198092Srdivacky    Mask |= mask;
343198092Srdivacky  }
344198092Srdivacky
345198092Srdivacky  /// hasNonFastQualifiers - Return true if the set contains any
346198092Srdivacky  /// qualifiers which require an ExtQuals node to be allocated.
347198092Srdivacky  bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
348198092Srdivacky  Qualifiers getNonFastQualifiers() const {
349198092Srdivacky    Qualifiers Quals = *this;
350198092Srdivacky    Quals.setFastQualifiers(0);
351198092Srdivacky    return Quals;
352198092Srdivacky  }
353198092Srdivacky
354198092Srdivacky  /// hasQualifiers - Return true if the set contains any qualifiers.
355198092Srdivacky  bool hasQualifiers() const { return Mask; }
356198092Srdivacky  bool empty() const { return !Mask; }
357198092Srdivacky
358198092Srdivacky  /// \brief Add the qualifiers from the given set to this set.
359198092Srdivacky  void addQualifiers(Qualifiers Q) {
360198092Srdivacky    // If the other set doesn't have any non-boolean qualifiers, just
361198092Srdivacky    // bit-or it in.
362198092Srdivacky    if (!(Q.Mask & ~CVRMask))
363198092Srdivacky      Mask |= Q.Mask;
364198092Srdivacky    else {
365198092Srdivacky      Mask |= (Q.Mask & CVRMask);
366198092Srdivacky      if (Q.hasAddressSpace())
367198092Srdivacky        addAddressSpace(Q.getAddressSpace());
368198092Srdivacky      if (Q.hasObjCGCAttr())
369198092Srdivacky        addObjCGCAttr(Q.getObjCGCAttr());
370224145Sdim      if (Q.hasObjCLifetime())
371224145Sdim        addObjCLifetime(Q.getObjCLifetime());
372198092Srdivacky    }
373198092Srdivacky  }
374198092Srdivacky
375243830Sdim  /// \brief Remove the qualifiers from the given set from this set.
376243830Sdim  void removeQualifiers(Qualifiers Q) {
377243830Sdim    // If the other set doesn't have any non-boolean qualifiers, just
378243830Sdim    // bit-and the inverse in.
379243830Sdim    if (!(Q.Mask & ~CVRMask))
380243830Sdim      Mask &= ~Q.Mask;
381243830Sdim    else {
382243830Sdim      Mask &= ~(Q.Mask & CVRMask);
383243830Sdim      if (getObjCGCAttr() == Q.getObjCGCAttr())
384243830Sdim        removeObjCGCAttr();
385243830Sdim      if (getObjCLifetime() == Q.getObjCLifetime())
386243830Sdim        removeObjCLifetime();
387243830Sdim      if (getAddressSpace() == Q.getAddressSpace())
388243830Sdim        removeAddressSpace();
389243830Sdim    }
390243830Sdim  }
391243830Sdim
392218893Sdim  /// \brief Add the qualifiers from the given set to this set, given that
393218893Sdim  /// they don't conflict.
394218893Sdim  void addConsistentQualifiers(Qualifiers qs) {
395218893Sdim    assert(getAddressSpace() == qs.getAddressSpace() ||
396218893Sdim           !hasAddressSpace() || !qs.hasAddressSpace());
397218893Sdim    assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
398218893Sdim           !hasObjCGCAttr() || !qs.hasObjCGCAttr());
399224145Sdim    assert(getObjCLifetime() == qs.getObjCLifetime() ||
400224145Sdim           !hasObjCLifetime() || !qs.hasObjCLifetime());
401218893Sdim    Mask |= qs.Mask;
402218893Sdim  }
403218893Sdim
404218893Sdim  /// \brief Determines if these qualifiers compatibly include another set.
405218893Sdim  /// Generally this answers the question of whether an object with the other
406218893Sdim  /// qualifiers can be safely used as an object with these qualifiers.
407218893Sdim  bool compatiblyIncludes(Qualifiers other) const {
408234353Sdim    return
409223017Sdim      // Address spaces must match exactly.
410223017Sdim      getAddressSpace() == other.getAddressSpace() &&
411223017Sdim      // ObjC GC qualifiers can match, be added, or be removed, but can't be
412223017Sdim      // changed.
413223017Sdim      (getObjCGCAttr() == other.getObjCGCAttr() ||
414223017Sdim       !hasObjCGCAttr() || !other.hasObjCGCAttr()) &&
415224145Sdim      // ObjC lifetime qualifiers must match exactly.
416224145Sdim      getObjCLifetime() == other.getObjCLifetime() &&
417223017Sdim      // CVR qualifiers may subset.
418223017Sdim      (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
419218893Sdim  }
420218893Sdim
421224145Sdim  /// \brief Determines if these qualifiers compatibly include another set of
422224145Sdim  /// qualifiers from the narrow perspective of Objective-C ARC lifetime.
423224145Sdim  ///
424224145Sdim  /// One set of Objective-C lifetime qualifiers compatibly includes the other
425234353Sdim  /// if the lifetime qualifiers match, or if both are non-__weak and the
426224145Sdim  /// including set also contains the 'const' qualifier.
427224145Sdim  bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
428224145Sdim    if (getObjCLifetime() == other.getObjCLifetime())
429224145Sdim      return true;
430234353Sdim
431224145Sdim    if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
432224145Sdim      return false;
433234353Sdim
434224145Sdim    return hasConst();
435224145Sdim  }
436234353Sdim
437221345Sdim  /// \brief Determine whether this set of qualifiers is a strict superset of
438221345Sdim  /// another set of qualifiers, not considering qualifier compatibility.
439221345Sdim  bool isStrictSupersetOf(Qualifiers Other) const;
440234353Sdim
441198092Srdivacky  bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
442198092Srdivacky  bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
443198092Srdivacky
444263508Sdim  LLVM_EXPLICIT operator bool() const { return hasQualifiers(); }
445198092Srdivacky
446198092Srdivacky  Qualifiers &operator+=(Qualifiers R) {
447198092Srdivacky    addQualifiers(R);
448198092Srdivacky    return *this;
449198092Srdivacky  }
450198092Srdivacky
451198092Srdivacky  // Union two qualifier sets.  If an enumerated qualifier appears
452198092Srdivacky  // in both sets, use the one from the right.
453198092Srdivacky  friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
454198092Srdivacky    L += R;
455198092Srdivacky    return L;
456198092Srdivacky  }
457234353Sdim
458212904Sdim  Qualifiers &operator-=(Qualifiers R) {
459243830Sdim    removeQualifiers(R);
460212904Sdim    return *this;
461212904Sdim  }
462198092Srdivacky
463212904Sdim  /// \brief Compute the difference between two qualifier sets.
464212904Sdim  friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
465212904Sdim    L -= R;
466212904Sdim    return L;
467212904Sdim  }
468234353Sdim
469198092Srdivacky  std::string getAsString() const;
470239462Sdim  std::string getAsString(const PrintingPolicy &Policy) const;
471198092Srdivacky
472239462Sdim  bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
473239462Sdim  void print(raw_ostream &OS, const PrintingPolicy &Policy,
474239462Sdim             bool appendSpaceIfNonEmpty = false) const;
475239462Sdim
476198092Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) const {
477198092Srdivacky    ID.AddInteger(Mask);
478198092Srdivacky  }
479198092Srdivacky
480198092Srdivackyprivate:
481198092Srdivacky
482224145Sdim  // bits:     |0 1 2|3 .. 4|5  ..  7|8   ...   31|
483224145Sdim  //           |C R V|GCAttr|Lifetime|AddressSpace|
484198092Srdivacky  uint32_t Mask;
485198092Srdivacky
486198092Srdivacky  static const uint32_t GCAttrMask = 0x18;
487198092Srdivacky  static const uint32_t GCAttrShift = 3;
488224145Sdim  static const uint32_t LifetimeMask = 0xE0;
489224145Sdim  static const uint32_t LifetimeShift = 5;
490224145Sdim  static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
491224145Sdim  static const uint32_t AddressSpaceShift = 8;
492198092Srdivacky};
493198092Srdivacky
494234353Sdim/// A std::pair-like structure for storing a qualified type split
495234353Sdim/// into its local qualifiers and its locally-unqualified type.
496234353Sdimstruct SplitQualType {
497234353Sdim  /// The locally-unqualified type.
498234353Sdim  const Type *Ty;
499202879Srdivacky
500234353Sdim  /// The local qualifiers.
501234353Sdim  Qualifiers Quals;
502234353Sdim
503234353Sdim  SplitQualType() : Ty(0), Quals() {}
504234353Sdim  SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
505234353Sdim
506234353Sdim  SplitQualType getSingleStepDesugaredType() const; // end of this file
507234353Sdim
508234353Sdim  // Make llvm::tie work.
509234353Sdim  operator std::pair<const Type *,Qualifiers>() const {
510234353Sdim    return std::pair<const Type *,Qualifiers>(Ty, Quals);
511234353Sdim  }
512234353Sdim
513234353Sdim  friend bool operator==(SplitQualType a, SplitQualType b) {
514234353Sdim    return a.Ty == b.Ty && a.Quals == b.Quals;
515234353Sdim  }
516234353Sdim  friend bool operator!=(SplitQualType a, SplitQualType b) {
517234353Sdim    return a.Ty != b.Ty || a.Quals != b.Quals;
518234353Sdim  }
519234353Sdim};
520234353Sdim
521198092Srdivacky/// QualType - For efficiency, we don't store CV-qualified types as nodes on
522198092Srdivacky/// their own: instead each reference to a type stores the qualifiers.  This
523198092Srdivacky/// greatly reduces the number of nodes we need to allocate for types (for
524198092Srdivacky/// example we only need one for 'int', 'const int', 'volatile int',
525198092Srdivacky/// 'const volatile int', etc).
526198092Srdivacky///
527198092Srdivacky/// As an added efficiency bonus, instead of making this a pair, we
528198092Srdivacky/// just store the two bits we care about in the low bits of the
529198092Srdivacky/// pointer.  To handle the packing/unpacking, we make QualType be a
530198092Srdivacky/// simple wrapper class that acts like a smart pointer.  A third bit
531198092Srdivacky/// indicates whether there are extended qualifiers present, in which
532198092Srdivacky/// case the pointer points to a special structure.
533198092Srdivackyclass QualType {
534198092Srdivacky  // Thankfully, these are efficiently composable.
535198092Srdivacky  llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
536198092Srdivacky                       Qualifiers::FastWidth> Value;
537198092Srdivacky
538198092Srdivacky  const ExtQuals *getExtQualsUnsafe() const {
539198092Srdivacky    return Value.getPointer().get<const ExtQuals*>();
540198092Srdivacky  }
541198092Srdivacky
542198092Srdivacky  const Type *getTypePtrUnsafe() const {
543198092Srdivacky    return Value.getPointer().get<const Type*>();
544198092Srdivacky  }
545198092Srdivacky
546218893Sdim  const ExtQualsTypeCommonBase *getCommonPtr() const {
547218893Sdim    assert(!isNull() && "Cannot retrieve a NULL type pointer");
548218893Sdim    uintptr_t CommonPtrVal
549218893Sdim      = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
550218893Sdim    CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
551218893Sdim    return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
552218893Sdim  }
553218893Sdim
554198092Srdivacky  friend class QualifierCollector;
555198092Srdivackypublic:
556193326Sed  QualType() {}
557198092Srdivacky
558193326Sed  QualType(const Type *Ptr, unsigned Quals)
559198092Srdivacky    : Value(Ptr, Quals) {}
560198092Srdivacky  QualType(const ExtQuals *Ptr, unsigned Quals)
561198092Srdivacky    : Value(Ptr, Quals) {}
562193326Sed
563199482Srdivacky  unsigned getLocalFastQualifiers() const { return Value.getInt(); }
564199482Srdivacky  void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
565198092Srdivacky
566198092Srdivacky  /// Retrieves a pointer to the underlying (unqualified) type.
567218893Sdim  ///
568218893Sdim  /// This function requires that the type not be NULL. If the type might be
569218893Sdim  /// NULL, use the (slightly less efficient) \c getTypePtrOrNull().
570218893Sdim  const Type *getTypePtr() const;
571234353Sdim
572218893Sdim  const Type *getTypePtrOrNull() const;
573198092Srdivacky
574226633Sdim  /// Retrieves a pointer to the name of the base type.
575226633Sdim  const IdentifierInfo *getBaseTypeIdentifier() const;
576226633Sdim
577218893Sdim  /// Divides a QualType into its unqualified type and a set of local
578218893Sdim  /// qualifiers.
579218893Sdim  SplitQualType split() const;
580218893Sdim
581193326Sed  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
582218893Sdim  static QualType getFromOpaquePtr(const void *Ptr) {
583193326Sed    QualType T;
584218893Sdim    T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
585193326Sed    return T;
586193326Sed  }
587198092Srdivacky
588218893Sdim  const Type &operator*() const {
589193326Sed    return *getTypePtr();
590193326Sed  }
591193326Sed
592218893Sdim  const Type *operator->() const {
593193326Sed    return getTypePtr();
594193326Sed  }
595198092Srdivacky
596198398Srdivacky  bool isCanonical() const;
597198398Srdivacky  bool isCanonicalAsParam() const;
598198398Srdivacky
599193326Sed  /// isNull - Return true if this QualType doesn't point to a type yet.
600193326Sed  bool isNull() const {
601198092Srdivacky    return Value.getPointer().isNull();
602193326Sed  }
603193326Sed
604234353Sdim  /// \brief Determine whether this particular QualType instance has the
605199482Srdivacky  /// "const" qualifier set, without looking through typedefs that may have
606199482Srdivacky  /// added "const" at a different level.
607199482Srdivacky  bool isLocalConstQualified() const {
608199482Srdivacky    return (getLocalFastQualifiers() & Qualifiers::Const);
609193326Sed  }
610234353Sdim
611199482Srdivacky  /// \brief Determine whether this type is const-qualified.
612199482Srdivacky  bool isConstQualified() const;
613234353Sdim
614234353Sdim  /// \brief Determine whether this particular QualType instance has the
615199482Srdivacky  /// "restrict" qualifier set, without looking through typedefs that may have
616199482Srdivacky  /// added "restrict" at a different level.
617199482Srdivacky  bool isLocalRestrictQualified() const {
618199482Srdivacky    return (getLocalFastQualifiers() & Qualifiers::Restrict);
619198092Srdivacky  }
620234353Sdim
621199482Srdivacky  /// \brief Determine whether this type is restrict-qualified.
622199482Srdivacky  bool isRestrictQualified() const;
623234353Sdim
624234353Sdim  /// \brief Determine whether this particular QualType instance has the
625199482Srdivacky  /// "volatile" qualifier set, without looking through typedefs that may have
626199482Srdivacky  /// added "volatile" at a different level.
627199482Srdivacky  bool isLocalVolatileQualified() const {
628218893Sdim    return (getLocalFastQualifiers() & Qualifiers::Volatile);
629193326Sed  }
630198092Srdivacky
631199482Srdivacky  /// \brief Determine whether this type is volatile-qualified.
632199482Srdivacky  bool isVolatileQualified() const;
633234353Sdim
634199482Srdivacky  /// \brief Determine whether this particular QualType instance has any
635234353Sdim  /// qualifiers, without looking through any typedefs that might add
636199482Srdivacky  /// qualifiers at a different level.
637199482Srdivacky  bool hasLocalQualifiers() const {
638199482Srdivacky    return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
639193326Sed  }
640193326Sed
641199482Srdivacky  /// \brief Determine whether this type has any qualifiers.
642199482Srdivacky  bool hasQualifiers() const;
643234353Sdim
644199482Srdivacky  /// \brief Determine whether this particular QualType instance has any
645199482Srdivacky  /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
646199482Srdivacky  /// instance.
647199482Srdivacky  bool hasLocalNonFastQualifiers() const {
648199482Srdivacky    return Value.getPointer().is<const ExtQuals*>();
649198092Srdivacky  }
650193326Sed
651199482Srdivacky  /// \brief Retrieve the set of qualifiers local to this particular QualType
652199482Srdivacky  /// instance, not including any qualifiers acquired through typedefs or
653199482Srdivacky  /// other sugar.
654218893Sdim  Qualifiers getLocalQualifiers() const;
655193326Sed
656199482Srdivacky  /// \brief Retrieve the set of qualifiers applied to this type.
657199482Srdivacky  Qualifiers getQualifiers() const;
658234353Sdim
659234353Sdim  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
660199482Srdivacky  /// local to this particular QualType instance, not including any qualifiers
661199482Srdivacky  /// acquired through typedefs or other sugar.
662199482Srdivacky  unsigned getLocalCVRQualifiers() const {
663218893Sdim    return getLocalFastQualifiers();
664193326Sed  }
665198092Srdivacky
666234353Sdim  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
667199482Srdivacky  /// applied to this type.
668199482Srdivacky  unsigned getCVRQualifiers() const;
669201361Srdivacky
670198092Srdivacky  bool isConstant(ASTContext& Ctx) const {
671198092Srdivacky    return QualType::isConstant(*this, Ctx);
672193326Sed  }
673193326Sed
674224145Sdim  /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
675224145Sdim  bool isPODType(ASTContext &Context) const;
676224145Sdim
677239462Sdim  /// isCXX98PODType() - Return true if this is a POD type according to the
678239462Sdim  /// rules of the C++98 standard, regardless of the current compilation's
679239462Sdim  /// language.
680239462Sdim  bool isCXX98PODType(ASTContext &Context) const;
681239462Sdim
682224145Sdim  /// isCXX11PODType() - Return true if this is a POD type according to the
683224145Sdim  /// more relaxed rules of the C++11 standard, regardless of the current
684224145Sdim  /// compilation's language.
685224145Sdim  /// (C++0x [basic.types]p9)
686224145Sdim  bool isCXX11PODType(ASTContext &Context) const;
687234353Sdim
688224145Sdim  /// isTrivialType - Return true if this is a trivial type
689224145Sdim  /// (C++0x [basic.types]p9)
690234353Sdim  bool isTrivialType(ASTContext &Context) const;
691224145Sdim
692224145Sdim  /// isTriviallyCopyableType - Return true if this is a trivially
693224145Sdim  /// copyable type (C++0x [basic.types]p9)
694224145Sdim  bool isTriviallyCopyableType(ASTContext &Context) const;
695224145Sdim
696198092Srdivacky  // Don't promise in the API that anything besides 'const' can be
697198092Srdivacky  // easily added.
698198092Srdivacky
699234353Sdim  /// addConst - add the specified type qualifier to this QualType.
700198092Srdivacky  void addConst() {
701198092Srdivacky    addFastQualifiers(Qualifiers::Const);
702198092Srdivacky  }
703198092Srdivacky  QualType withConst() const {
704198092Srdivacky    return withFastQualifiers(Qualifiers::Const);
705198092Srdivacky  }
706198092Srdivacky
707234353Sdim  /// addVolatile - add the specified type qualifier to this QualType.
708223017Sdim  void addVolatile() {
709223017Sdim    addFastQualifiers(Qualifiers::Volatile);
710223017Sdim  }
711223017Sdim  QualType withVolatile() const {
712223017Sdim    return withFastQualifiers(Qualifiers::Volatile);
713223017Sdim  }
714234353Sdim
715234353Sdim  /// Add the restrict qualifier to this QualType.
716234353Sdim  void addRestrict() {
717234353Sdim    addFastQualifiers(Qualifiers::Restrict);
718234353Sdim  }
719234353Sdim  QualType withRestrict() const {
720234353Sdim    return withFastQualifiers(Qualifiers::Restrict);
721234353Sdim  }
722223017Sdim
723224145Sdim  QualType withCVRQualifiers(unsigned CVR) const {
724224145Sdim    return withFastQualifiers(CVR);
725224145Sdim  }
726224145Sdim
727198092Srdivacky  void addFastQualifiers(unsigned TQs) {
728198092Srdivacky    assert(!(TQs & ~Qualifiers::FastMask)
729198092Srdivacky           && "non-fast qualifier bits set in mask!");
730198092Srdivacky    Value.setInt(Value.getInt() | TQs);
731198092Srdivacky  }
732198092Srdivacky
733218893Sdim  void removeLocalConst();
734218893Sdim  void removeLocalVolatile();
735218893Sdim  void removeLocalRestrict();
736218893Sdim  void removeLocalCVRQualifiers(unsigned Mask);
737198092Srdivacky
738218893Sdim  void removeLocalFastQualifiers() { Value.setInt(0); }
739218893Sdim  void removeLocalFastQualifiers(unsigned Mask) {
740198092Srdivacky    assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
741198092Srdivacky    Value.setInt(Value.getInt() & ~Mask);
742198092Srdivacky  }
743198092Srdivacky
744198092Srdivacky  // Creates a type with the given qualifiers in addition to any
745198092Srdivacky  // qualifiers already on this type.
746198092Srdivacky  QualType withFastQualifiers(unsigned TQs) const {
747198092Srdivacky    QualType T = *this;
748198092Srdivacky    T.addFastQualifiers(TQs);
749198092Srdivacky    return T;
750198092Srdivacky  }
751198092Srdivacky
752198092Srdivacky  // Creates a type with exactly the given fast qualifiers, removing
753198092Srdivacky  // any existing fast qualifiers.
754218893Sdim  QualType withExactLocalFastQualifiers(unsigned TQs) const {
755218893Sdim    return withoutLocalFastQualifiers().withFastQualifiers(TQs);
756198092Srdivacky  }
757198092Srdivacky
758198092Srdivacky  // Removes fast qualifiers, but leaves any extended qualifiers in place.
759218893Sdim  QualType withoutLocalFastQualifiers() const {
760198092Srdivacky    QualType T = *this;
761218893Sdim    T.removeLocalFastQualifiers();
762198092Srdivacky    return T;
763198092Srdivacky  }
764198092Srdivacky
765218893Sdim  QualType getCanonicalType() const;
766218893Sdim
767199482Srdivacky  /// \brief Return this type with all of the instance-specific qualifiers
768199482Srdivacky  /// removed, but without removing any qualifiers that may have been applied
769199482Srdivacky  /// through typedefs.
770199482Srdivacky  QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
771198092Srdivacky
772218893Sdim  /// \brief Retrieve the unqualified variant of the given type,
773218893Sdim  /// removing as little sugar as possible.
774218893Sdim  ///
775218893Sdim  /// This routine looks through various kinds of sugar to find the
776218893Sdim  /// least-desugared type that is unqualified. For example, given:
777218893Sdim  ///
778218893Sdim  /// \code
779218893Sdim  /// typedef int Integer;
780218893Sdim  /// typedef const Integer CInteger;
781218893Sdim  /// typedef CInteger DifferenceType;
782218893Sdim  /// \endcode
783218893Sdim  ///
784218893Sdim  /// Executing \c getUnqualifiedType() on the type \c DifferenceType will
785218893Sdim  /// desugar until we hit the type \c Integer, which has no qualifiers on it.
786218893Sdim  ///
787249423Sdim  /// The resulting type might still be qualified if it's sugar for an array
788249423Sdim  /// type.  To strip qualifiers even from within a sugared array type, use
789218893Sdim  /// ASTContext::getUnqualifiedArrayType.
790218893Sdim  inline QualType getUnqualifiedType() const;
791218893Sdim
792218893Sdim  /// getSplitUnqualifiedType - Retrieve the unqualified variant of the
793218893Sdim  /// given type, removing as little sugar as possible.
794218893Sdim  ///
795218893Sdim  /// Like getUnqualifiedType(), but also returns the set of
796218893Sdim  /// qualifiers that were built up.
797218893Sdim  ///
798249423Sdim  /// The resulting type might still be qualified if it's sugar for an array
799249423Sdim  /// type.  To strip qualifiers even from within a sugared array type, use
800218893Sdim  /// ASTContext::getUnqualifiedArrayType.
801218893Sdim  inline SplitQualType getSplitUnqualifiedType() const;
802234353Sdim
803221345Sdim  /// \brief Determine whether this type is more qualified than the other
804221345Sdim  /// given type, requiring exact equality for non-CVR qualifiers.
805193326Sed  bool isMoreQualifiedThan(QualType Other) const;
806221345Sdim
807221345Sdim  /// \brief Determine whether this type is at least as qualified as the other
808221345Sdim  /// given type, requiring exact equality for non-CVR qualifiers.
809193326Sed  bool isAtLeastAsQualifiedAs(QualType Other) const;
810234353Sdim
811193326Sed  QualType getNonReferenceType() const;
812198092Srdivacky
813210299Sed  /// \brief Determine the type of a (typically non-lvalue) expression with the
814210299Sed  /// specified result type.
815234353Sdim  ///
816210299Sed  /// This routine should be used for expressions for which the return type is
817210299Sed  /// explicitly specified (e.g., in a cast or call) and isn't necessarily
818234353Sdim  /// an lvalue. It removes a top-level reference (since there are no
819210299Sed  /// expressions of reference type) and deletes top-level cvr-qualifiers
820210299Sed  /// from non-class types (in C++) or all types (in C).
821263508Sdim  QualType getNonLValueExprType(const ASTContext &Context) const;
822234353Sdim
823193326Sed  /// getDesugaredType - Return the specified type with any "sugar" removed from
824193326Sed  /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
825193326Sed  /// the type is already concrete, it returns it unmodified.  This is similar
826193326Sed  /// to getting the canonical type, but it doesn't remove *all* typedefs.  For
827193326Sed  /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
828193326Sed  /// concrete.
829198092Srdivacky  ///
830198092Srdivacky  /// Qualifiers are left in place.
831218893Sdim  QualType getDesugaredType(const ASTContext &Context) const {
832218893Sdim    return getDesugaredType(*this, Context);
833198092Srdivacky  }
834193326Sed
835218893Sdim  SplitQualType getSplitDesugaredType() const {
836218893Sdim    return getSplitDesugaredType(*this);
837218893Sdim  }
838218893Sdim
839224145Sdim  /// \brief Return the specified type with one level of "sugar" removed from
840234353Sdim  /// the type.
841224145Sdim  ///
842224145Sdim  /// This routine takes off the first typedef, typeof, etc. If the outer level
843224145Sdim  /// of the type is already concrete, it returns it unmodified.
844234353Sdim  QualType getSingleStepDesugaredType(const ASTContext &Context) const {
845234353Sdim    return getSingleStepDesugaredTypeImpl(*this, Context);
846234353Sdim  }
847234353Sdim
848218893Sdim  /// IgnoreParens - Returns the specified type after dropping any
849218893Sdim  /// outer-level parentheses.
850218893Sdim  QualType IgnoreParens() const {
851218893Sdim    if (isa<ParenType>(*this))
852218893Sdim      return QualType::IgnoreParens(*this);
853218893Sdim    return *this;
854218893Sdim  }
855218893Sdim
856193326Sed  /// operator==/!= - Indicate whether the specified types and qualifiers are
857193326Sed  /// identical.
858198092Srdivacky  friend bool operator==(const QualType &LHS, const QualType &RHS) {
859198092Srdivacky    return LHS.Value == RHS.Value;
860193326Sed  }
861198092Srdivacky  friend bool operator!=(const QualType &LHS, const QualType &RHS) {
862198092Srdivacky    return LHS.Value != RHS.Value;
863193326Sed  }
864218893Sdim  std::string getAsString() const {
865218893Sdim    return getAsString(split());
866218893Sdim  }
867218893Sdim  static std::string getAsString(SplitQualType split) {
868234353Sdim    return getAsString(split.Ty, split.Quals);
869218893Sdim  }
870218893Sdim  static std::string getAsString(const Type *ty, Qualifiers qs);
871193326Sed
872239462Sdim  std::string getAsString(const PrintingPolicy &Policy) const;
873239462Sdim
874239462Sdim  void print(raw_ostream &OS, const PrintingPolicy &Policy,
875239462Sdim             const Twine &PlaceHolder = Twine()) const {
876239462Sdim    print(split(), OS, Policy, PlaceHolder);
877193326Sed  }
878239462Sdim  static void print(SplitQualType split, raw_ostream &OS,
879239462Sdim                    const PrintingPolicy &policy, const Twine &PlaceHolder) {
880239462Sdim    return print(split.Ty, split.Quals, OS, policy, PlaceHolder);
881239462Sdim  }
882239462Sdim  static void print(const Type *ty, Qualifiers qs,
883239462Sdim                    raw_ostream &OS, const PrintingPolicy &policy,
884239462Sdim                    const Twine &PlaceHolder);
885239462Sdim
886195341Sed  void getAsStringInternal(std::string &Str,
887218893Sdim                           const PrintingPolicy &Policy) const {
888218893Sdim    return getAsStringInternal(split(), Str, Policy);
889218893Sdim  }
890218893Sdim  static void getAsStringInternal(SplitQualType split, std::string &out,
891218893Sdim                                  const PrintingPolicy &policy) {
892234353Sdim    return getAsStringInternal(split.Ty, split.Quals, out, policy);
893218893Sdim  }
894218893Sdim  static void getAsStringInternal(const Type *ty, Qualifiers qs,
895218893Sdim                                  std::string &out,
896218893Sdim                                  const PrintingPolicy &policy);
897198092Srdivacky
898239462Sdim  class StreamedQualTypeHelper {
899239462Sdim    const QualType &T;
900239462Sdim    const PrintingPolicy &Policy;
901239462Sdim    const Twine &PlaceHolder;
902239462Sdim  public:
903239462Sdim    StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
904239462Sdim                           const Twine &PlaceHolder)
905239462Sdim      : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { }
906239462Sdim
907239462Sdim    friend raw_ostream &operator<<(raw_ostream &OS,
908239462Sdim                                   const StreamedQualTypeHelper &SQT) {
909239462Sdim      SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder);
910239462Sdim      return OS;
911239462Sdim    }
912239462Sdim  };
913239462Sdim
914239462Sdim  StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
915239462Sdim                                const Twine &PlaceHolder = Twine()) const {
916239462Sdim    return StreamedQualTypeHelper(*this, Policy, PlaceHolder);
917239462Sdim  }
918239462Sdim
919193326Sed  void dump(const char *s) const;
920193326Sed  void dump() const;
921198092Srdivacky
922193326Sed  void Profile(llvm::FoldingSetNodeID &ID) const {
923193326Sed    ID.AddPointer(getAsOpaquePtr());
924193326Sed  }
925193326Sed
926193326Sed  /// getAddressSpace - Return the address space of this type.
927193326Sed  inline unsigned getAddressSpace() const;
928198092Srdivacky
929224145Sdim  /// getObjCGCAttr - Returns gc attribute of this type.
930198092Srdivacky  inline Qualifiers::GC getObjCGCAttr() const;
931193326Sed
932193326Sed  /// isObjCGCWeak true when Type is objc's weak.
933193326Sed  bool isObjCGCWeak() const {
934198092Srdivacky    return getObjCGCAttr() == Qualifiers::Weak;
935193326Sed  }
936193326Sed
937193326Sed  /// isObjCGCStrong true when Type is objc's strong.
938193326Sed  bool isObjCGCStrong() const {
939198092Srdivacky    return getObjCGCAttr() == Qualifiers::Strong;
940193326Sed  }
941198092Srdivacky
942224145Sdim  /// getObjCLifetime - Returns lifetime attribute of this type.
943224145Sdim  Qualifiers::ObjCLifetime getObjCLifetime() const {
944224145Sdim    return getQualifiers().getObjCLifetime();
945224145Sdim  }
946224145Sdim
947224145Sdim  bool hasNonTrivialObjCLifetime() const {
948224145Sdim    return getQualifiers().hasNonTrivialObjCLifetime();
949224145Sdim  }
950224145Sdim
951224145Sdim  bool hasStrongOrWeakObjCLifetime() const {
952224145Sdim    return getQualifiers().hasStrongOrWeakObjCLifetime();
953224145Sdim  }
954224145Sdim
955218893Sdim  enum DestructionKind {
956218893Sdim    DK_none,
957224145Sdim    DK_cxx_destructor,
958224145Sdim    DK_objc_strong_lifetime,
959224145Sdim    DK_objc_weak_lifetime
960218893Sdim  };
961218893Sdim
962218893Sdim  /// isDestructedType - nonzero if objects of this type require
963218893Sdim  /// non-trivial work to clean up after.  Non-zero because it's
964218893Sdim  /// conceivable that qualifiers (objc_gc(weak)?) could make
965218893Sdim  /// something require destruction.
966218893Sdim  DestructionKind isDestructedType() const {
967218893Sdim    return isDestructedTypeImpl(*this);
968218893Sdim  }
969218893Sdim
970234353Sdim  /// \brief Determine whether expressions of the given type are forbidden
971224145Sdim  /// from being lvalues in C.
972224145Sdim  ///
973224145Sdim  /// The expression types that are forbidden to be lvalues are:
974224145Sdim  ///   - 'void', but not qualified void
975224145Sdim  ///   - function types
976224145Sdim  ///
977224145Sdim  /// The exact rule here is C99 6.3.2.1:
978224145Sdim  ///   An lvalue is an expression with an object type or an incomplete
979224145Sdim  ///   type other than void.
980224145Sdim  bool isCForbiddenLValueType() const;
981224145Sdim
982198092Srdivackyprivate:
983198092Srdivacky  // These methods are implemented in a separate translation unit;
984198092Srdivacky  // "static"-ize them to avoid creating temporary QualTypes in the
985198092Srdivacky  // caller.
986198092Srdivacky  static bool isConstant(QualType T, ASTContext& Ctx);
987218893Sdim  static QualType getDesugaredType(QualType T, const ASTContext &Context);
988218893Sdim  static SplitQualType getSplitDesugaredType(QualType T);
989218893Sdim  static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
990234353Sdim  static QualType getSingleStepDesugaredTypeImpl(QualType type,
991234353Sdim                                                 const ASTContext &C);
992218893Sdim  static QualType IgnoreParens(QualType T);
993218893Sdim  static DestructionKind isDestructedTypeImpl(QualType type);
994193326Sed};
995193326Sed
996193326Sed} // end clang.
997193326Sed
998193326Sednamespace llvm {
999193326Sed/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
1000193326Sed/// to a specific Type class.
1001249423Sdimtemplate<> struct simplify_type< ::clang::QualType> {
1002218893Sdim  typedef const ::clang::Type *SimpleType;
1003249423Sdim  static SimpleType getSimplifiedValue(::clang::QualType Val) {
1004193326Sed    return Val.getTypePtr();
1005193326Sed  }
1006193326Sed};
1007198092Srdivacky
1008193326Sed// Teach SmallPtrSet that QualType is "basically a pointer".
1009193326Sedtemplate<>
1010193326Sedclass PointerLikeTypeTraits<clang::QualType> {
1011193326Sedpublic:
1012193326Sed  static inline void *getAsVoidPointer(clang::QualType P) {
1013193326Sed    return P.getAsOpaquePtr();
1014193326Sed  }
1015193326Sed  static inline clang::QualType getFromVoidPointer(void *P) {
1016193326Sed    return clang::QualType::getFromOpaquePtr(P);
1017193326Sed  }
1018198092Srdivacky  // Various qualifiers go in low bits.
1019193326Sed  enum { NumLowBitsAvailable = 0 };
1020193326Sed};
1021198092Srdivacky
1022193326Sed} // end namespace llvm
1023193326Sed
1024193326Sednamespace clang {
1025193326Sed
1026234353Sdim/// \brief Base class that is common to both the \c ExtQuals and \c Type
1027218893Sdim/// classes, which allows \c QualType to access the common fields between the
1028218893Sdim/// two.
1029218893Sdim///
1030218893Sdimclass ExtQualsTypeCommonBase {
1031218893Sdim  ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
1032218893Sdim    : BaseType(baseType), CanonicalType(canon) {}
1033218893Sdim
1034218893Sdim  /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or
1035218893Sdim  /// a self-referential pointer (for \c Type).
1036218893Sdim  ///
1037234353Sdim  /// This pointer allows an efficient mapping from a QualType to its
1038218893Sdim  /// underlying type pointer.
1039218893Sdim  const Type *const BaseType;
1040218893Sdim
1041218893Sdim  /// \brief The canonical type of this type.  A QualType.
1042218893Sdim  QualType CanonicalType;
1043218893Sdim
1044218893Sdim  friend class QualType;
1045218893Sdim  friend class Type;
1046218893Sdim  friend class ExtQuals;
1047218893Sdim};
1048234353Sdim
1049218893Sdim/// ExtQuals - We can encode up to four bits in the low bits of a
1050218893Sdim/// type pointer, but there are many more type qualifiers that we want
1051218893Sdim/// to be able to apply to an arbitrary type.  Therefore we have this
1052218893Sdim/// struct, intended to be heap-allocated and used by QualType to
1053218893Sdim/// store qualifiers.
1054218893Sdim///
1055234353Sdim/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers
1056218893Sdim/// in three low bits on the QualType pointer; a fourth bit records whether
1057218893Sdim/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
1058218893Sdim/// Objective-C GC attributes) are much more rare.
1059218893Sdimclass ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
1060218893Sdim  // NOTE: changing the fast qualifiers should be straightforward as
1061218893Sdim  // long as you don't make 'const' non-fast.
1062218893Sdim  // 1. Qualifiers:
1063218893Sdim  //    a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
1064218893Sdim  //       Fast qualifiers must occupy the low-order bits.
1065218893Sdim  //    b) Update Qualifiers::FastWidth and FastMask.
1066218893Sdim  // 2. QualType:
1067218893Sdim  //    a) Update is{Volatile,Restrict}Qualified(), defined inline.
1068218893Sdim  //    b) Update remove{Volatile,Restrict}, defined near the end of
1069218893Sdim  //       this header.
1070218893Sdim  // 3. ASTContext:
1071218893Sdim  //    a) Update get{Volatile,Restrict}Type.
1072218893Sdim
1073218893Sdim  /// Quals - the immutable set of qualifiers applied by this
1074218893Sdim  /// node;  always contains extended qualifiers.
1075218893Sdim  Qualifiers Quals;
1076218893Sdim
1077218893Sdim  ExtQuals *this_() { return this; }
1078218893Sdim
1079218893Sdimpublic:
1080234353Sdim  ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
1081218893Sdim    : ExtQualsTypeCommonBase(baseType,
1082218893Sdim                             canon.isNull() ? QualType(this_(), 0) : canon),
1083218893Sdim      Quals(quals)
1084218893Sdim  {
1085218893Sdim    assert(Quals.hasNonFastQualifiers()
1086218893Sdim           && "ExtQuals created with no fast qualifiers");
1087218893Sdim    assert(!Quals.hasFastQualifiers()
1088218893Sdim           && "ExtQuals created with fast qualifiers");
1089218893Sdim  }
1090218893Sdim
1091218893Sdim  Qualifiers getQualifiers() const { return Quals; }
1092218893Sdim
1093218893Sdim  bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
1094218893Sdim  Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
1095218893Sdim
1096224145Sdim  bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
1097224145Sdim  Qualifiers::ObjCLifetime getObjCLifetime() const {
1098224145Sdim    return Quals.getObjCLifetime();
1099224145Sdim  }
1100224145Sdim
1101218893Sdim  bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
1102218893Sdim  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
1103218893Sdim
1104218893Sdim  const Type *getBaseType() const { return BaseType; }
1105218893Sdim
1106218893Sdimpublic:
1107218893Sdim  void Profile(llvm::FoldingSetNodeID &ID) const {
1108218893Sdim    Profile(ID, getBaseType(), Quals);
1109218893Sdim  }
1110218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID,
1111218893Sdim                      const Type *BaseType,
1112218893Sdim                      Qualifiers Quals) {
1113218893Sdim    assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
1114218893Sdim    ID.AddPointer(BaseType);
1115218893Sdim    Quals.Profile(ID);
1116218893Sdim  }
1117218893Sdim};
1118218893Sdim
1119234353Sdim/// \brief The kind of C++0x ref-qualifier associated with a function type,
1120234353Sdim/// which determines whether a member function's "this" object can be an
1121218893Sdim/// lvalue, rvalue, or neither.
1122218893Sdimenum RefQualifierKind {
1123218893Sdim  /// \brief No ref-qualifier was provided.
1124218893Sdim  RQ_None = 0,
1125218893Sdim  /// \brief An lvalue ref-qualifier was provided (\c &).
1126218893Sdim  RQ_LValue,
1127218893Sdim  /// \brief An rvalue ref-qualifier was provided (\c &&).
1128218893Sdim  RQ_RValue
1129218893Sdim};
1130234353Sdim
1131193326Sed/// Type - This is the base class of the type hierarchy.  A central concept
1132193326Sed/// with types is that each type always has a canonical type.  A canonical type
1133193326Sed/// is the type with any typedef names stripped out of it or the types it
1134193326Sed/// references.  For example, consider:
1135193326Sed///
1136193326Sed///  typedef int  foo;
1137193326Sed///  typedef foo* bar;
1138193326Sed///    'int *'    'foo *'    'bar'
1139193326Sed///
1140193326Sed/// There will be a Type object created for 'int'.  Since int is canonical, its
1141193326Sed/// canonicaltype pointer points to itself.  There is also a Type for 'foo' (a
1142193326Sed/// TypedefType).  Its CanonicalType pointer points to the 'int' Type.  Next
1143193326Sed/// there is a PointerType that represents 'int*', which, like 'int', is
1144193326Sed/// canonical.  Finally, there is a PointerType type for 'foo*' whose canonical
1145193326Sed/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
1146193326Sed/// is also 'int*'.
1147193326Sed///
1148193326Sed/// Non-canonical types are useful for emitting diagnostics, without losing
1149193326Sed/// information about typedefs being used.  Canonical types are useful for type
1150193326Sed/// comparisons (they allow by-pointer equality tests) and useful for reasoning
1151193326Sed/// about whether something has a particular form (e.g. is a function type),
1152193326Sed/// because they implicitly, recursively, strip all typedefs out of a type.
1153193326Sed///
1154193326Sed/// Types, once created, are immutable.
1155193326Sed///
1156218893Sdimclass Type : public ExtQualsTypeCommonBase {
1157193326Sedpublic:
1158193326Sed  enum TypeClass {
1159193326Sed#define TYPE(Class, Base) Class,
1160203955Srdivacky#define LAST_TYPE(Class) TypeLast = Class,
1161193326Sed#define ABSTRACT_TYPE(Class, Base)
1162193326Sed#include "clang/AST/TypeNodes.def"
1163193326Sed    TagFirst = Record, TagLast = Enum
1164193326Sed  };
1165198092Srdivacky
1166193326Sedprivate:
1167243830Sdim  Type(const Type &) LLVM_DELETED_FUNCTION;
1168243830Sdim  void operator=(const Type &) LLVM_DELETED_FUNCTION;
1169208600Srdivacky
1170218893Sdim  /// Bitfields required by the Type class.
1171218893Sdim  class TypeBitfields {
1172218893Sdim    friend class Type;
1173218893Sdim    template <class T> friend class TypePropertyCache;
1174193326Sed
1175218893Sdim    /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
1176218893Sdim    unsigned TC : 8;
1177203955Srdivacky
1178218893Sdim    /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
1179218893Sdim    unsigned Dependent : 1;
1180234353Sdim
1181234353Sdim    /// \brief Whether this type somehow involves a template parameter, even
1182224145Sdim    /// if the resolution of the type does not depend on a template parameter.
1183224145Sdim    unsigned InstantiationDependent : 1;
1184234353Sdim
1185218893Sdim    /// \brief Whether this type is a variably-modified type (C99 6.7.5).
1186218893Sdim    unsigned VariablyModified : 1;
1187218893Sdim
1188218893Sdim    /// \brief Whether this type contains an unexpanded parameter pack
1189218893Sdim    /// (for C++0x variadic templates).
1190218893Sdim    unsigned ContainsUnexpandedParameterPack : 1;
1191234353Sdim
1192249423Sdim    /// \brief True if the cache (i.e. the bitfields here starting with
1193249423Sdim    /// 'Cache') is valid.
1194249423Sdim    mutable unsigned CacheValid : 1;
1195234353Sdim
1196218893Sdim    /// \brief Linkage of this type.
1197263508Sdim    mutable unsigned CachedLinkage : 3;
1198210299Sed
1199234353Sdim    /// \brief Whether this type involves and local or unnamed types.
1200218893Sdim    mutable unsigned CachedLocalOrUnnamed : 1;
1201234353Sdim
1202218893Sdim    /// \brief FromAST - Whether this type comes from an AST file.
1203218893Sdim    mutable unsigned FromAST : 1;
1204210299Sed
1205218893Sdim    bool isCacheValid() const {
1206249423Sdim      return CacheValid;
1207218893Sdim    }
1208218893Sdim    Linkage getLinkage() const {
1209218893Sdim      assert(isCacheValid() && "getting linkage from invalid cache");
1210218893Sdim      return static_cast<Linkage>(CachedLinkage);
1211218893Sdim    }
1212218893Sdim    bool hasLocalOrUnnamedType() const {
1213218893Sdim      assert(isCacheValid() && "getting linkage from invalid cache");
1214218893Sdim      return CachedLocalOrUnnamed;
1215218893Sdim    }
1216218893Sdim  };
1217263508Sdim  enum { NumTypeBits = 18 };
1218218893Sdim
1219218893Sdimprotected:
1220218893Sdim  // These classes allow subclasses to somewhat cleanly pack bitfields
1221218893Sdim  // into Type.
1222218893Sdim
1223218893Sdim  class ArrayTypeBitfields {
1224218893Sdim    friend class ArrayType;
1225218893Sdim
1226218893Sdim    unsigned : NumTypeBits;
1227218893Sdim
1228218893Sdim    /// IndexTypeQuals - CVR qualifiers from declarations like
1229218893Sdim    /// 'int X[static restrict 4]'. For function parameters only.
1230218893Sdim    unsigned IndexTypeQuals : 3;
1231218893Sdim
1232218893Sdim    /// SizeModifier - storage class qualifiers from declarations like
1233218893Sdim    /// 'int X[static restrict 4]'. For function parameters only.
1234218893Sdim    /// Actually an ArrayType::ArraySizeModifier.
1235218893Sdim    unsigned SizeModifier : 3;
1236218893Sdim  };
1237218893Sdim
1238218893Sdim  class BuiltinTypeBitfields {
1239218893Sdim    friend class BuiltinType;
1240218893Sdim
1241218893Sdim    unsigned : NumTypeBits;
1242218893Sdim
1243218893Sdim    /// The kind (BuiltinType::Kind) of builtin type this is.
1244218893Sdim    unsigned Kind : 8;
1245218893Sdim  };
1246218893Sdim
1247218893Sdim  class FunctionTypeBitfields {
1248218893Sdim    friend class FunctionType;
1249218893Sdim
1250218893Sdim    unsigned : NumTypeBits;
1251218893Sdim
1252218893Sdim    /// Extra information which affects how the function is called, like
1253218893Sdim    /// regparm and the calling convention.
1254243830Sdim    unsigned ExtInfo : 9;
1255218893Sdim
1256218893Sdim    /// TypeQuals - Used only by FunctionProtoType, put here to pack with the
1257218893Sdim    /// other bitfields.
1258218893Sdim    /// The qualifiers are part of FunctionProtoType because...
1259218893Sdim    ///
1260218893Sdim    /// C++ 8.3.5p4: The return type, the parameter type list and the
1261218893Sdim    /// cv-qualifier-seq, [...], are part of the function type.
1262218893Sdim    unsigned TypeQuals : 3;
1263218893Sdim  };
1264218893Sdim
1265218893Sdim  class ObjCObjectTypeBitfields {
1266218893Sdim    friend class ObjCObjectType;
1267218893Sdim
1268218893Sdim    unsigned : NumTypeBits;
1269218893Sdim
1270218893Sdim    /// NumProtocols - The number of protocols stored directly on this
1271218893Sdim    /// object type.
1272218893Sdim    unsigned NumProtocols : 32 - NumTypeBits;
1273218893Sdim  };
1274218893Sdim
1275218893Sdim  class ReferenceTypeBitfields {
1276218893Sdim    friend class ReferenceType;
1277218893Sdim
1278218893Sdim    unsigned : NumTypeBits;
1279218893Sdim
1280218893Sdim    /// True if the type was originally spelled with an lvalue sigil.
1281218893Sdim    /// This is never true of rvalue references but can also be false
1282218893Sdim    /// on lvalue references because of C++0x [dcl.typedef]p9,
1283218893Sdim    /// as follows:
1284218893Sdim    ///
1285218893Sdim    ///   typedef int &ref;    // lvalue, spelled lvalue
1286218893Sdim    ///   typedef int &&rvref; // rvalue
1287218893Sdim    ///   ref &a;              // lvalue, inner ref, spelled lvalue
1288218893Sdim    ///   ref &&a;             // lvalue, inner ref
1289218893Sdim    ///   rvref &a;            // lvalue, inner ref, spelled lvalue
1290218893Sdim    ///   rvref &&a;           // rvalue, inner ref
1291218893Sdim    unsigned SpelledAsLValue : 1;
1292218893Sdim
1293218893Sdim    /// True if the inner type is a reference type.  This only happens
1294218893Sdim    /// in non-canonical forms.
1295218893Sdim    unsigned InnerRef : 1;
1296218893Sdim  };
1297218893Sdim
1298218893Sdim  class TypeWithKeywordBitfields {
1299218893Sdim    friend class TypeWithKeyword;
1300218893Sdim
1301218893Sdim    unsigned : NumTypeBits;
1302218893Sdim
1303218893Sdim    /// An ElaboratedTypeKeyword.  8 bits for efficient access.
1304218893Sdim    unsigned Keyword : 8;
1305218893Sdim  };
1306218893Sdim
1307218893Sdim  class VectorTypeBitfields {
1308218893Sdim    friend class VectorType;
1309218893Sdim
1310218893Sdim    unsigned : NumTypeBits;
1311218893Sdim
1312218893Sdim    /// VecKind - The kind of vector, either a generic vector type or some
1313218893Sdim    /// target-specific vector type such as for AltiVec or Neon.
1314218893Sdim    unsigned VecKind : 3;
1315218893Sdim
1316218893Sdim    /// NumElements - The number of elements in the vector.
1317218893Sdim    unsigned NumElements : 29 - NumTypeBits;
1318263508Sdim
1319263508Sdim    enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
1320218893Sdim  };
1321218893Sdim
1322218893Sdim  class AttributedTypeBitfields {
1323218893Sdim    friend class AttributedType;
1324218893Sdim
1325218893Sdim    unsigned : NumTypeBits;
1326218893Sdim
1327218893Sdim    /// AttrKind - an AttributedType::Kind
1328218893Sdim    unsigned AttrKind : 32 - NumTypeBits;
1329218893Sdim  };
1330218893Sdim
1331251662Sdim  class AutoTypeBitfields {
1332251662Sdim    friend class AutoType;
1333251662Sdim
1334251662Sdim    unsigned : NumTypeBits;
1335251662Sdim
1336251662Sdim    /// Was this placeholder type spelled as 'decltype(auto)'?
1337251662Sdim    unsigned IsDecltypeAuto : 1;
1338251662Sdim  };
1339251662Sdim
1340218893Sdim  union {
1341218893Sdim    TypeBitfields TypeBits;
1342218893Sdim    ArrayTypeBitfields ArrayTypeBits;
1343218893Sdim    AttributedTypeBitfields AttributedTypeBits;
1344251662Sdim    AutoTypeBitfields AutoTypeBits;
1345218893Sdim    BuiltinTypeBitfields BuiltinTypeBits;
1346218893Sdim    FunctionTypeBitfields FunctionTypeBits;
1347218893Sdim    ObjCObjectTypeBitfields ObjCObjectTypeBits;
1348218893Sdim    ReferenceTypeBitfields ReferenceTypeBits;
1349218893Sdim    TypeWithKeywordBitfields TypeWithKeywordBits;
1350218893Sdim    VectorTypeBitfields VectorTypeBits;
1351218893Sdim  };
1352218893Sdim
1353218893Sdimprivate:
1354212904Sdim  /// \brief Set whether this type comes from an AST file.
1355234353Sdim  void setFromAST(bool V = true) const {
1356218893Sdim    TypeBits.FromAST = V;
1357210299Sed  }
1358210299Sed
1359218893Sdim  template <class T> friend class TypePropertyCache;
1360218893Sdim
1361208600Srdivackyprotected:
1362193326Sed  // silence VC++ warning C4355: 'this' : used in base member initializer list
1363193326Sed  Type *this_() { return this; }
1364234353Sdim  Type(TypeClass tc, QualType canon, bool Dependent,
1365224145Sdim       bool InstantiationDependent, bool VariablyModified,
1366218893Sdim       bool ContainsUnexpandedParameterPack)
1367218893Sdim    : ExtQualsTypeCommonBase(this,
1368218893Sdim                             canon.isNull() ? QualType(this_(), 0) : canon) {
1369218893Sdim    TypeBits.TC = tc;
1370218893Sdim    TypeBits.Dependent = Dependent;
1371224145Sdim    TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
1372218893Sdim    TypeBits.VariablyModified = VariablyModified;
1373218893Sdim    TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
1374249423Sdim    TypeBits.CacheValid = false;
1375218893Sdim    TypeBits.CachedLocalOrUnnamed = false;
1376218893Sdim    TypeBits.CachedLinkage = NoLinkage;
1377218893Sdim    TypeBits.FromAST = false;
1378218893Sdim  }
1379193326Sed  friend class ASTContext;
1380198092Srdivacky
1381234353Sdim  void setDependent(bool D = true) {
1382234353Sdim    TypeBits.Dependent = D;
1383224145Sdim    if (D)
1384224145Sdim      TypeBits.InstantiationDependent = true;
1385224145Sdim  }
1386234353Sdim  void setInstantiationDependent(bool D = true) {
1387224145Sdim    TypeBits.InstantiationDependent = D; }
1388234353Sdim  void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
1389224145Sdim  }
1390218893Sdim  void setContainsUnexpandedParameterPack(bool PP = true) {
1391218893Sdim    TypeBits.ContainsUnexpandedParameterPack = PP;
1392218893Sdim  }
1393218893Sdim
1394193326Sedpublic:
1395218893Sdim  TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
1396198092Srdivacky
1397212904Sdim  /// \brief Whether this type comes from an AST file.
1398218893Sdim  bool isFromAST() const { return TypeBits.FromAST; }
1399210299Sed
1400218893Sdim  /// \brief Whether this type is or contains an unexpanded parameter
1401218893Sdim  /// pack, used to support C++0x variadic templates.
1402218893Sdim  ///
1403218893Sdim  /// A type that contains a parameter pack shall be expanded by the
1404218893Sdim  /// ellipsis operator at some point. For example, the typedef in the
1405218893Sdim  /// following example contains an unexpanded parameter pack 'T':
1406218893Sdim  ///
1407218893Sdim  /// \code
1408218893Sdim  /// template<typename ...T>
1409218893Sdim  /// struct X {
1410218893Sdim  ///   typedef T* pointer_types; // ill-formed; T is a parameter pack.
1411218893Sdim  /// };
1412218893Sdim  /// \endcode
1413218893Sdim  ///
1414234353Sdim  /// Note that this routine does not specify which
1415234353Sdim  bool containsUnexpandedParameterPack() const {
1416218893Sdim    return TypeBits.ContainsUnexpandedParameterPack;
1417218893Sdim  }
1418218893Sdim
1419218893Sdim  /// Determines if this type would be canonical if it had no further
1420218893Sdim  /// qualification.
1421198398Srdivacky  bool isCanonicalUnqualified() const {
1422218893Sdim    return CanonicalType == QualType(this, 0);
1423198398Srdivacky  }
1424193326Sed
1425234353Sdim  /// Pull a single level of sugar off of this locally-unqualified type.
1426234353Sdim  /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
1427234353Sdim  /// or QualType::getSingleStepDesugaredType(const ASTContext&).
1428234353Sdim  QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
1429234353Sdim
1430198092Srdivacky  /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
1431193326Sed  /// object types, function types, and incomplete types.
1432198092Srdivacky
1433193326Sed  /// isIncompleteType - Return true if this is an incomplete type.
1434193326Sed  /// A type that can describe objects, but which lacks information needed to
1435193326Sed  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
1436198092Srdivacky  /// routine will need to determine if the size is actually required.
1437234353Sdim  ///
1438234353Sdim  /// \brief Def If non-NULL, and the type refers to some kind of declaration
1439234353Sdim  /// that can be completed (such as a C struct, C++ class, or Objective-C
1440234353Sdim  /// class), will be set to the declaration.
1441234353Sdim  bool isIncompleteType(NamedDecl **Def = 0) const;
1442193326Sed
1443193326Sed  /// isIncompleteOrObjectType - Return true if this is an incomplete or object
1444193326Sed  /// type, in other words, not a function type.
1445193326Sed  bool isIncompleteOrObjectType() const {
1446193326Sed    return !isFunctionType();
1447193326Sed  }
1448234353Sdim
1449218893Sdim  /// \brief Determine whether this type is an object type.
1450218893Sdim  bool isObjectType() const {
1451218893Sdim    // C++ [basic.types]p8:
1452234353Sdim    //   An object type is a (possibly cv-qualified) type that is not a
1453218893Sdim    //   function type, not a reference type, and not a void type.
1454218893Sdim    return !isReferenceType() && !isFunctionType() && !isVoidType();
1455218893Sdim  }
1456193326Sed
1457200583Srdivacky  /// isLiteralType - Return true if this is a literal type
1458251662Sdim  /// (C++11 [basic.types]p10)
1459263508Sdim  bool isLiteralType(const ASTContext &Ctx) const;
1460200583Srdivacky
1461221345Sdim  /// \brief Test if this type is a standard-layout type.
1462221345Sdim  /// (C++0x [basic.type]p9)
1463221345Sdim  bool isStandardLayoutType() const;
1464221345Sdim
1465193326Sed  /// Helper methods to distinguish type categories. All type predicates
1466193326Sed  /// operate on the canonical type, ignoring typedefs and qualifiers.
1467193326Sed
1468210299Sed  /// isBuiltinType - returns true if the type is a builtin type.
1469210299Sed  bool isBuiltinType() const;
1470210299Sed
1471193326Sed  /// isSpecificBuiltinType - Test for a particular builtin type.
1472193326Sed  bool isSpecificBuiltinType(unsigned K) const;
1473198092Srdivacky
1474218893Sdim  /// isPlaceholderType - Test for a type which does not represent an
1475218893Sdim  /// actual type-system type but is instead used as a placeholder for
1476218893Sdim  /// various convenient purposes within Clang.  All such types are
1477218893Sdim  /// BuiltinTypes.
1478218893Sdim  bool isPlaceholderType() const;
1479226633Sdim  const BuiltinType *getAsPlaceholderType() const;
1480218893Sdim
1481221345Sdim  /// isSpecificPlaceholderType - Test for a specific placeholder type.
1482221345Sdim  bool isSpecificPlaceholderType(unsigned K) const;
1483221345Sdim
1484234353Sdim  /// isNonOverloadPlaceholderType - Test for a placeholder type
1485234353Sdim  /// other than Overload;  see BuiltinType::isNonOverloadPlaceholderType.
1486234353Sdim  bool isNonOverloadPlaceholderType() const;
1487234353Sdim
1488193326Sed  /// isIntegerType() does *not* include complex integers (a GCC extension).
1489193326Sed  /// isComplexIntegerType() can be used to test for complex integers.
1490193326Sed  bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
1491193326Sed  bool isEnumeralType() const;
1492193326Sed  bool isBooleanType() const;
1493193326Sed  bool isCharType() const;
1494193326Sed  bool isWideCharType() const;
1495226633Sdim  bool isChar16Type() const;
1496226633Sdim  bool isChar32Type() const;
1497200583Srdivacky  bool isAnyCharacterType() const;
1498210299Sed  bool isIntegralType(ASTContext &Ctx) const;
1499234353Sdim
1500210299Sed  /// \brief Determine whether this type is an integral or enumeration type.
1501210299Sed  bool isIntegralOrEnumerationType() const;
1502218893Sdim  /// \brief Determine whether this type is an integral or unscoped enumeration
1503218893Sdim  /// type.
1504218893Sdim  bool isIntegralOrUnscopedEnumerationType() const;
1505234353Sdim
1506193326Sed  /// Floating point categories.
1507193326Sed  bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
1508193326Sed  /// isComplexType() does *not* include complex integers (a GCC extension).
1509193326Sed  /// isComplexIntegerType() can be used to test for complex integers.
1510193326Sed  bool isComplexType() const;      // C99 6.2.5p11 (complex)
1511193326Sed  bool isAnyComplexType() const;   // C99 6.2.5p11 (complex) + Complex Int.
1512193326Sed  bool isFloatingType() const;     // C99 6.2.5p11 (real floating + complex)
1513226633Sdim  bool isHalfType() const;         // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half)
1514193326Sed  bool isRealType() const;         // C99 6.2.5p17 (real floating + integer)
1515193326Sed  bool isArithmeticType() const;   // C99 6.2.5p18 (integer + floating)
1516193326Sed  bool isVoidType() const;         // C99 6.2.5p19
1517193326Sed  bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
1518193326Sed  bool isAggregateType() const;
1519221345Sdim  bool isFundamentalType() const;
1520221345Sdim  bool isCompoundType() const;
1521198092Srdivacky
1522193326Sed  // Type Predicates: Check to see if this type is structurally the specified
1523193326Sed  // type, ignoring typedefs and qualifiers.
1524193326Sed  bool isFunctionType() const;
1525198092Srdivacky  bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
1526198092Srdivacky  bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
1527193326Sed  bool isPointerType() const;
1528198092Srdivacky  bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
1529193326Sed  bool isBlockPointerType() const;
1530195341Sed  bool isVoidPointerType() const;
1531193326Sed  bool isReferenceType() const;
1532193326Sed  bool isLValueReferenceType() const;
1533193326Sed  bool isRValueReferenceType() const;
1534193326Sed  bool isFunctionPointerType() const;
1535193326Sed  bool isMemberPointerType() const;
1536193326Sed  bool isMemberFunctionPointerType() const;
1537212904Sdim  bool isMemberDataPointerType() const;
1538193326Sed  bool isArrayType() const;
1539193326Sed  bool isConstantArrayType() const;
1540193326Sed  bool isIncompleteArrayType() const;
1541193326Sed  bool isVariableArrayType() const;
1542193326Sed  bool isDependentSizedArrayType() const;
1543193326Sed  bool isRecordType() const;
1544198092Srdivacky  bool isClassType() const;
1545198092Srdivacky  bool isStructureType() const;
1546243830Sdim  bool isInterfaceType() const;
1547207619Srdivacky  bool isStructureOrClassType() const;
1548193326Sed  bool isUnionType() const;
1549193326Sed  bool isComplexIntegerType() const;            // GCC _Complex integer type.
1550193326Sed  bool isVectorType() const;                    // GCC vector type.
1551193326Sed  bool isExtVectorType() const;                 // Extended vector type.
1552224145Sdim  bool isObjCObjectPointerType() const;         // pointer to ObjC object
1553224145Sdim  bool isObjCRetainableType() const;            // ObjC object or block pointer
1554224145Sdim  bool isObjCLifetimeType() const;              // (array of)* retainable type
1555224145Sdim  bool isObjCIndirectLifetimeType() const;      // (pointer to)* lifetime type
1556224145Sdim  bool isObjCNSObjectType() const;              // __attribute__((NSObject))
1557198092Srdivacky  // FIXME: change this to 'raw' interface type, so we can used 'interface' type
1558198092Srdivacky  // for the common case.
1559208600Srdivacky  bool isObjCObjectType() const;                // NSString or typeof(*(id)0)
1560193326Sed  bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
1561193326Sed  bool isObjCQualifiedIdType() const;           // id<foo>
1562198092Srdivacky  bool isObjCQualifiedClassType() const;        // Class<foo>
1563212904Sdim  bool isObjCObjectOrInterfaceType() const;
1564198092Srdivacky  bool isObjCIdType() const;                    // id
1565198092Srdivacky  bool isObjCClassType() const;                 // Class
1566199990Srdivacky  bool isObjCSelType() const;                 // Class
1567198092Srdivacky  bool isObjCBuiltinType() const;               // 'id' or 'Class'
1568224145Sdim  bool isObjCARCBridgableType() const;
1569224145Sdim  bool isCARCBridgableType() const;
1570193326Sed  bool isTemplateTypeParmType() const;          // C++ template type parameter
1571193326Sed  bool isNullPtrType() const;                   // C++0x nullptr_t
1572234353Sdim  bool isAtomicType() const;                    // C11 _Atomic()
1573193326Sed
1574249423Sdim  bool isImage1dT() const;                      // OpenCL image1d_t
1575249423Sdim  bool isImage1dArrayT() const;                 // OpenCL image1d_array_t
1576249423Sdim  bool isImage1dBufferT() const;                // OpenCL image1d_buffer_t
1577249423Sdim  bool isImage2dT() const;                      // OpenCL image2d_t
1578249423Sdim  bool isImage2dArrayT() const;                 // OpenCL image2d_array_t
1579249423Sdim  bool isImage3dT() const;                      // OpenCL image3d_t
1580249423Sdim
1581249423Sdim  bool isImageType() const;                     // Any OpenCL image type
1582249423Sdim
1583249423Sdim  bool isSamplerT() const;                      // OpenCL sampler_t
1584249423Sdim  bool isEventT() const;                        // OpenCL event_t
1585249423Sdim
1586249423Sdim  bool isOpenCLSpecificType() const;            // Any OpenCL specific type
1587249423Sdim
1588224145Sdim  /// Determines if this type, which must satisfy
1589224145Sdim  /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
1590224145Sdim  /// than implicitly __strong.
1591224145Sdim  bool isObjCARCImplicitlyUnretainedType() const;
1592224145Sdim
1593224145Sdim  /// Return the implicit lifetime for this type, which must not be dependent.
1594224145Sdim  Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
1595224145Sdim
1596218893Sdim  enum ScalarTypeKind {
1597226633Sdim    STK_CPointer,
1598226633Sdim    STK_BlockPointer,
1599226633Sdim    STK_ObjCObjectPointer,
1600218893Sdim    STK_MemberPointer,
1601218893Sdim    STK_Bool,
1602218893Sdim    STK_Integral,
1603218893Sdim    STK_Floating,
1604218893Sdim    STK_IntegralComplex,
1605218893Sdim    STK_FloatingComplex
1606218893Sdim  };
1607218893Sdim  /// getScalarTypeKind - Given that this is a scalar type, classify it.
1608218893Sdim  ScalarTypeKind getScalarTypeKind() const;
1609218893Sdim
1610193326Sed  /// isDependentType - Whether this type is a dependent type, meaning
1611198092Srdivacky  /// that its definition somehow depends on a template parameter
1612193326Sed  /// (C++ [temp.dep.type]).
1613218893Sdim  bool isDependentType() const { return TypeBits.Dependent; }
1614234353Sdim
1615224145Sdim  /// \brief Determine whether this type is an instantiation-dependent type,
1616224145Sdim  /// meaning that the type involves a template parameter (even if the
1617224145Sdim  /// definition does not actually depend on the type substituted for that
1618224145Sdim  /// template parameter).
1619234353Sdim  bool isInstantiationDependentType() const {
1620234353Sdim    return TypeBits.InstantiationDependent;
1621224145Sdim  }
1622234353Sdim
1623251662Sdim  /// \brief Determine whether this type is an undeduced type, meaning that
1624251662Sdim  /// it somehow involves a C++11 'auto' type which has not yet been deduced.
1625251662Sdim  bool isUndeducedType() const;
1626251662Sdim
1627218893Sdim  /// \brief Whether this type is a variably-modified type (C99 6.7.5).
1628218893Sdim  bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
1629218893Sdim
1630218893Sdim  /// \brief Whether this type involves a variable-length array type
1631218893Sdim  /// with a definite size.
1632218893Sdim  bool hasSizedVLAType() const;
1633234353Sdim
1634218893Sdim  /// \brief Whether this type is or contains a local or unnamed type.
1635218893Sdim  bool hasUnnamedOrLocalType() const;
1636234353Sdim
1637193326Sed  bool isOverloadableType() const;
1638193326Sed
1639206084Srdivacky  /// \brief Determine wither this type is a C++ elaborated-type-specifier.
1640206084Srdivacky  bool isElaboratedTypeSpecifier() const;
1641224145Sdim
1642224145Sdim  bool canDecayToPointerType() const;
1643234353Sdim
1644193326Sed  /// hasPointerRepresentation - Whether this type is represented
1645193326Sed  /// natively as a pointer; this includes pointers, references, block
1646193326Sed  /// pointers, and Objective-C interface, qualified id, and qualified
1647193326Sed  /// interface types, as well as nullptr_t.
1648193326Sed  bool hasPointerRepresentation() const;
1649193326Sed
1650193326Sed  /// hasObjCPointerRepresentation - Whether this type can represent
1651193326Sed  /// an objective pointer type for the purpose of GC'ability
1652198092Srdivacky  bool hasObjCPointerRepresentation() const;
1653193326Sed
1654212904Sdim  /// \brief Determine whether this type has an integer representation
1655212904Sdim  /// of some sort, e.g., it is an integer type or a vector.
1656212904Sdim  bool hasIntegerRepresentation() const;
1657212904Sdim
1658212904Sdim  /// \brief Determine whether this type has an signed integer representation
1659212904Sdim  /// of some sort, e.g., it is an signed integer type or a vector.
1660212904Sdim  bool hasSignedIntegerRepresentation() const;
1661212904Sdim
1662212904Sdim  /// \brief Determine whether this type has an unsigned integer representation
1663212904Sdim  /// of some sort, e.g., it is an unsigned integer type or a vector.
1664212904Sdim  bool hasUnsignedIntegerRepresentation() const;
1665212904Sdim
1666210299Sed  /// \brief Determine whether this type has a floating-point representation
1667210299Sed  /// of some sort, e.g., it is a floating-point type or a vector thereof.
1668210299Sed  bool hasFloatingRepresentation() const;
1669212904Sdim
1670193326Sed  // Type Checking Functions: Check to see if this type is structurally the
1671193326Sed  // specified type, ignoring typedefs and qualifiers, and return a pointer to
1672193326Sed  // the best type we can.
1673193326Sed  const RecordType *getAsStructureType() const;
1674193326Sed  /// NOTE: getAs*ArrayType are methods on ASTContext.
1675193326Sed  const RecordType *getAsUnionType() const;
1676193326Sed  const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
1677198092Srdivacky  // The following is a convenience method that returns an ObjCObjectPointerType
1678198092Srdivacky  // for object declared using an interface.
1679198092Srdivacky  const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
1680194613Sed  const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
1681221345Sdim  const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
1682208600Srdivacky  const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
1683193326Sed
1684207619Srdivacky  /// \brief Retrieves the CXXRecordDecl that this type refers to, either
1685234353Sdim  /// because the type is a RecordType or because it is the injected-class-name
1686207619Srdivacky  /// type of a class template or class template partial specialization.
1687207619Srdivacky  CXXRecordDecl *getAsCXXRecordDecl() const;
1688218893Sdim
1689243830Sdim  /// If this is a pointer or reference to a RecordType, return the
1690243830Sdim  /// CXXRecordDecl that that type refers to.
1691243830Sdim  ///
1692243830Sdim  /// If this is not a pointer or reference, or the type being pointed to does
1693243830Sdim  /// not refer to a CXXRecordDecl, returns NULL.
1694243830Sdim  const CXXRecordDecl *getPointeeCXXRecordDecl() const;
1695243830Sdim
1696218893Sdim  /// \brief Get the AutoType whose type will be deduced for a variable with
1697218893Sdim  /// an initializer of this type. This looks through declarators like pointer
1698218893Sdim  /// types, but not through decltype or typedefs.
1699218893Sdim  AutoType *getContainedAutoType() const;
1700234353Sdim
1701218893Sdim  /// Member-template getAs<specific type>'.  Look through sugar for
1702239462Sdim  /// an instance of \<specific type>.   This scheme will eventually
1703218893Sdim  /// replace the specific getAsXXXX methods above.
1704218893Sdim  ///
1705218893Sdim  /// There are some specializations of this member template listed
1706218893Sdim  /// immediately following this class.
1707198092Srdivacky  template <typename T> const T *getAs() const;
1708198092Srdivacky
1709218893Sdim  /// A variant of getAs<> for array types which silently discards
1710218893Sdim  /// qualifiers from the outermost type.
1711218893Sdim  const ArrayType *getAsArrayTypeUnsafe() const;
1712218893Sdim
1713218893Sdim  /// Member-template castAs<specific type>.  Look through sugar for
1714239462Sdim  /// the underlying instance of \<specific type>.
1715218893Sdim  ///
1716218893Sdim  /// This method has the same relationship to getAs<T> as cast<T> has
1717218893Sdim  /// to dyn_cast<T>; which is to say, the underlying type *must*
1718218893Sdim  /// have the intended type, and this method will never return null.
1719218893Sdim  template <typename T> const T *castAs() const;
1720218893Sdim
1721218893Sdim  /// A variant of castAs<> for array type which silently discards
1722218893Sdim  /// qualifiers from the outermost type.
1723218893Sdim  const ArrayType *castAsArrayTypeUnsafe() const;
1724218893Sdim
1725218893Sdim  /// getBaseElementTypeUnsafe - Get the base element type of this
1726218893Sdim  /// type, potentially discarding type qualifiers.  This method
1727218893Sdim  /// should never be used when type qualifiers are meaningful.
1728218893Sdim  const Type *getBaseElementTypeUnsafe() const;
1729218893Sdim
1730193326Sed  /// getArrayElementTypeNoTypeQual - If this is an array type, return the
1731193326Sed  /// element type of the array, potentially with type qualifiers missing.
1732193326Sed  /// This method should never be used when type qualifiers are meaningful.
1733193326Sed  const Type *getArrayElementTypeNoTypeQual() const;
1734198092Srdivacky
1735198092Srdivacky  /// getPointeeType - If this is a pointer, ObjC object pointer, or block
1736198092Srdivacky  /// pointer, this returns the respective pointee.
1737198092Srdivacky  QualType getPointeeType() const;
1738198092Srdivacky
1739198092Srdivacky  /// getUnqualifiedDesugaredType() - Return the specified type with
1740198092Srdivacky  /// any "sugar" removed from the type, removing any typedefs,
1741198092Srdivacky  /// typeofs, etc., as well as any qualifiers.
1742198092Srdivacky  const Type *getUnqualifiedDesugaredType() const;
1743198092Srdivacky
1744193326Sed  /// More type predicates useful for type checking/promotion
1745193326Sed  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
1746193326Sed
1747193326Sed  /// isSignedIntegerType - Return true if this is an integer type that is
1748193326Sed  /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
1749223017Sdim  /// or an enum decl which has a signed representation.
1750193326Sed  bool isSignedIntegerType() const;
1751193326Sed
1752193326Sed  /// isUnsignedIntegerType - Return true if this is an integer type that is
1753234353Sdim  /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool],
1754223017Sdim  /// or an enum decl which has an unsigned representation.
1755193326Sed  bool isUnsignedIntegerType() const;
1756193326Sed
1757234353Sdim  /// Determines whether this is an integer type that is signed or an
1758223017Sdim  /// enumeration types whose underlying type is a signed integer type.
1759223017Sdim  bool isSignedIntegerOrEnumerationType() const;
1760234353Sdim
1761234353Sdim  /// Determines whether this is an integer type that is unsigned or an
1762223017Sdim  /// enumeration types whose underlying type is a unsigned integer type.
1763223017Sdim  bool isUnsignedIntegerOrEnumerationType() const;
1764223017Sdim
1765193326Sed  /// isConstantSizeType - Return true if this is not a variable sized type,
1766193326Sed  /// according to the rules of C99 6.7.5p3.  It is not legal to call this on
1767193326Sed  /// incomplete types.
1768193326Sed  bool isConstantSizeType() const;
1769193326Sed
1770193326Sed  /// isSpecifierType - Returns true if this type can be represented by some
1771193326Sed  /// set of type specifiers.
1772193326Sed  bool isSpecifierType() const;
1773193326Sed
1774208600Srdivacky  /// \brief Determine the linkage of this type.
1775208600Srdivacky  Linkage getLinkage() const;
1776218893Sdim
1777218893Sdim  /// \brief Determine the visibility of this type.
1778249423Sdim  Visibility getVisibility() const {
1779249423Sdim    return getLinkageAndVisibility().getVisibility();
1780249423Sdim  }
1781218893Sdim
1782234353Sdim  /// \brief Return true if the visibility was explicitly set is the code.
1783249423Sdim  bool isVisibilityExplicit() const {
1784249423Sdim    return getLinkageAndVisibility().isVisibilityExplicit();
1785249423Sdim  }
1786234353Sdim
1787218893Sdim  /// \brief Determine the linkage and visibility of this type.
1788249423Sdim  LinkageInfo getLinkageAndVisibility() const;
1789234353Sdim
1790249423Sdim  /// \brief True if the computed linkage is valid. Used for consistency
1791249423Sdim  /// checking. Should always return true.
1792249423Sdim  bool isLinkageValid() const;
1793234353Sdim
1794198092Srdivacky  const char *getTypeClassName() const;
1795198092Srdivacky
1796204643Srdivacky  QualType getCanonicalTypeInternal() const {
1797204643Srdivacky    return CanonicalType;
1798204643Srdivacky  }
1799204643Srdivacky  CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
1800234353Sdim  LLVM_ATTRIBUTE_USED void dump() const;
1801224145Sdim
1802212904Sdim  friend class ASTReader;
1803212904Sdim  friend class ASTWriter;
1804193326Sed};
1805193326Sed
1806239462Sdim/// \brief This will check for a TypedefType by removing any existing sugar
1807239462Sdim/// until it reaches a TypedefType or a non-sugared type.
1808239462Sdimtemplate <> const TypedefType *Type::getAs() const;
1809193326Sed
1810243830Sdim/// \brief This will check for a TemplateSpecializationType by removing any
1811243830Sdim/// existing sugar until it reaches a TemplateSpecializationType or a
1812243830Sdim/// non-sugared type.
1813243830Sdimtemplate <> const TemplateSpecializationType *Type::getAs() const;
1814243830Sdim
1815263508Sdim/// \brief This will check for an AttributedType by removing any existing sugar
1816263508Sdim/// until it reaches an AttributedType or a non-sugared type.
1817263508Sdimtemplate <> const AttributedType *Type::getAs() const;
1818263508Sdim
1819198092Srdivacky// We can do canonical leaf types faster, because we don't have to
1820198092Srdivacky// worry about preserving child type decoration.
1821198092Srdivacky#define TYPE(Class, Base)
1822198092Srdivacky#define LEAF_TYPE(Class) \
1823198092Srdivackytemplate <> inline const Class##Type *Type::getAs() const { \
1824198092Srdivacky  return dyn_cast<Class##Type>(CanonicalType); \
1825218893Sdim} \
1826218893Sdimtemplate <> inline const Class##Type *Type::castAs() const { \
1827218893Sdim  return cast<Class##Type>(CanonicalType); \
1828198092Srdivacky}
1829198092Srdivacky#include "clang/AST/TypeNodes.def"
1830193326Sed
1831193326Sed
1832193326Sed/// BuiltinType - This class is used for builtin types like 'int'.  Builtin
1833193326Sed/// types are always canonical and have a literal name field.
1834193326Sedclass BuiltinType : public Type {
1835193326Sedpublic:
1836193326Sed  enum Kind {
1837234353Sdim#define BUILTIN_TYPE(Id, SingletonId) Id,
1838234353Sdim#define LAST_BUILTIN_TYPE(Id) LastKind = Id
1839234353Sdim#include "clang/AST/BuiltinTypes.def"
1840193326Sed  };
1841218893Sdim
1842193326Sedpublic:
1843198092Srdivacky  BuiltinType(Kind K)
1844218893Sdim    : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
1845224145Sdim           /*InstantiationDependent=*/(K == Dependent),
1846218893Sdim           /*VariablyModified=*/false,
1847218893Sdim           /*Unexpanded paramter pack=*/false) {
1848218893Sdim    BuiltinTypeBits.Kind = K;
1849218893Sdim  }
1850198092Srdivacky
1851218893Sdim  Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
1852239462Sdim  StringRef getName(const PrintingPolicy &Policy) const;
1853239462Sdim  const char *getNameAsCString(const PrintingPolicy &Policy) const {
1854239462Sdim    // The StringRef is null-terminated.
1855239462Sdim    StringRef str = getName(Policy);
1856239462Sdim    assert(!str.empty() && str.data()[str.size()] == '\0');
1857239462Sdim    return str.data();
1858239462Sdim  }
1859198092Srdivacky
1860198092Srdivacky  bool isSugared() const { return false; }
1861198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
1862198092Srdivacky
1863199482Srdivacky  bool isInteger() const {
1864218893Sdim    return getKind() >= Bool && getKind() <= Int128;
1865199482Srdivacky  }
1866198092Srdivacky
1867199482Srdivacky  bool isSignedInteger() const {
1868218893Sdim    return getKind() >= Char_S && getKind() <= Int128;
1869199482Srdivacky  }
1870199482Srdivacky
1871199482Srdivacky  bool isUnsignedInteger() const {
1872218893Sdim    return getKind() >= Bool && getKind() <= UInt128;
1873199482Srdivacky  }
1874199482Srdivacky
1875199482Srdivacky  bool isFloatingPoint() const {
1876226633Sdim    return getKind() >= Half && getKind() <= LongDouble;
1877199482Srdivacky  }
1878199482Srdivacky
1879234353Sdim  /// Determines whether the given kind corresponds to a placeholder type.
1880234353Sdim  static bool isPlaceholderTypeKind(Kind K) {
1881234353Sdim    return K >= Overload;
1882234353Sdim  }
1883234353Sdim
1884221345Sdim  /// Determines whether this type is a placeholder type, i.e. a type
1885221345Sdim  /// which cannot appear in arbitrary positions in a fully-formed
1886221345Sdim  /// expression.
1887218893Sdim  bool isPlaceholderType() const {
1888234353Sdim    return isPlaceholderTypeKind(getKind());
1889218893Sdim  }
1890218893Sdim
1891234353Sdim  /// Determines whether this type is a placeholder type other than
1892234353Sdim  /// Overload.  Most placeholder types require only syntactic
1893234353Sdim  /// information about their context in order to be resolved (e.g.
1894234353Sdim  /// whether it is a call expression), which means they can (and
1895234353Sdim  /// should) be resolved in an earlier "phase" of analysis.
1896234353Sdim  /// Overload expressions sometimes pick up further information
1897234353Sdim  /// from their context, like whether the context expects a
1898234353Sdim  /// specific function-pointer type, and so frequently need
1899234353Sdim  /// special treatment.
1900234353Sdim  bool isNonOverloadPlaceholderType() const {
1901234353Sdim    return getKind() > Overload;
1902234353Sdim  }
1903234353Sdim
1904193326Sed  static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
1905193326Sed};
1906193326Sed
1907193326Sed/// ComplexType - C99 6.2.5p11 - Complex values.  This supports the C99 complex
1908193326Sed/// types (_Complex float etc) as well as the GCC integer complex extensions.
1909193326Sed///
1910193326Sedclass ComplexType : public Type, public llvm::FoldingSetNode {
1911193326Sed  QualType ElementType;
1912193326Sed  ComplexType(QualType Element, QualType CanonicalPtr) :
1913218893Sdim    Type(Complex, CanonicalPtr, Element->isDependentType(),
1914224145Sdim         Element->isInstantiationDependentType(),
1915218893Sdim         Element->isVariablyModifiedType(),
1916218893Sdim         Element->containsUnexpandedParameterPack()),
1917193326Sed    ElementType(Element) {
1918193326Sed  }
1919193326Sed  friend class ASTContext;  // ASTContext creates these.
1920208600Srdivacky
1921193326Sedpublic:
1922193326Sed  QualType getElementType() const { return ElementType; }
1923198092Srdivacky
1924198092Srdivacky  bool isSugared() const { return false; }
1925198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
1926198092Srdivacky
1927193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
1928193326Sed    Profile(ID, getElementType());
1929193326Sed  }
1930193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
1931193326Sed    ID.AddPointer(Element.getAsOpaquePtr());
1932193326Sed  }
1933198092Srdivacky
1934193326Sed  static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
1935193326Sed};
1936193326Sed
1937218893Sdim/// ParenType - Sugar for parentheses used when specifying types.
1938218893Sdim///
1939218893Sdimclass ParenType : public Type, public llvm::FoldingSetNode {
1940218893Sdim  QualType Inner;
1941218893Sdim
1942218893Sdim  ParenType(QualType InnerType, QualType CanonType) :
1943218893Sdim    Type(Paren, CanonType, InnerType->isDependentType(),
1944224145Sdim         InnerType->isInstantiationDependentType(),
1945218893Sdim         InnerType->isVariablyModifiedType(),
1946218893Sdim         InnerType->containsUnexpandedParameterPack()),
1947218893Sdim    Inner(InnerType) {
1948218893Sdim  }
1949218893Sdim  friend class ASTContext;  // ASTContext creates these.
1950218893Sdim
1951218893Sdimpublic:
1952218893Sdim
1953218893Sdim  QualType getInnerType() const { return Inner; }
1954218893Sdim
1955218893Sdim  bool isSugared() const { return true; }
1956218893Sdim  QualType desugar() const { return getInnerType(); }
1957218893Sdim
1958218893Sdim  void Profile(llvm::FoldingSetNodeID &ID) {
1959218893Sdim    Profile(ID, getInnerType());
1960218893Sdim  }
1961218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
1962218893Sdim    Inner.Profile(ID);
1963218893Sdim  }
1964218893Sdim
1965218893Sdim  static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
1966218893Sdim};
1967218893Sdim
1968193326Sed/// PointerType - C99 6.7.5.1 - Pointer Declarators.
1969193326Sed///
1970193326Sedclass PointerType : public Type, public llvm::FoldingSetNode {
1971193326Sed  QualType PointeeType;
1972193326Sed
1973193326Sed  PointerType(QualType Pointee, QualType CanonicalPtr) :
1974218893Sdim    Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
1975224145Sdim         Pointee->isInstantiationDependentType(),
1976218893Sdim         Pointee->isVariablyModifiedType(),
1977234353Sdim         Pointee->containsUnexpandedParameterPack()),
1978218893Sdim    PointeeType(Pointee) {
1979193326Sed  }
1980193326Sed  friend class ASTContext;  // ASTContext creates these.
1981208600Srdivacky
1982193326Sedpublic:
1983198092Srdivacky
1984193326Sed  QualType getPointeeType() const { return PointeeType; }
1985193326Sed
1986198092Srdivacky  bool isSugared() const { return false; }
1987198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
1988198092Srdivacky
1989193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
1990193326Sed    Profile(ID, getPointeeType());
1991193326Sed  }
1992193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
1993193326Sed    ID.AddPointer(Pointee.getAsOpaquePtr());
1994193326Sed  }
1995198092Srdivacky
1996193326Sed  static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
1997193326Sed};
1998193326Sed
1999263508Sdim/// \brief Represents a pointer type decayed from an array or function type.
2000263508Sdimclass DecayedType : public Type, public llvm::FoldingSetNode {
2001263508Sdim  QualType OriginalType;
2002263508Sdim  QualType DecayedPointer;
2003263508Sdim
2004263508Sdim  DecayedType(QualType OriginalType, QualType DecayedPointer,
2005263508Sdim              QualType CanonicalPtr)
2006263508Sdim      : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(),
2007263508Sdim             OriginalType->isInstantiationDependentType(),
2008263508Sdim             OriginalType->isVariablyModifiedType(),
2009263508Sdim             OriginalType->containsUnexpandedParameterPack()),
2010263508Sdim        OriginalType(OriginalType), DecayedPointer(DecayedPointer) {
2011263508Sdim    assert(isa<PointerType>(DecayedPointer));
2012263508Sdim  }
2013263508Sdim
2014263508Sdim  friend class ASTContext;  // ASTContext creates these.
2015263508Sdim
2016263508Sdimpublic:
2017263508Sdim  QualType getDecayedType() const { return DecayedPointer; }
2018263508Sdim  QualType getOriginalType() const { return OriginalType; }
2019263508Sdim
2020263508Sdim  QualType getPointeeType() const {
2021263508Sdim    return cast<PointerType>(DecayedPointer)->getPointeeType();
2022263508Sdim  }
2023263508Sdim
2024263508Sdim  bool isSugared() const { return true; }
2025263508Sdim  QualType desugar() const { return DecayedPointer; }
2026263508Sdim
2027263508Sdim  void Profile(llvm::FoldingSetNodeID &ID) {
2028263508Sdim    Profile(ID, OriginalType);
2029263508Sdim  }
2030263508Sdim  static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) {
2031263508Sdim    ID.AddPointer(OriginalType.getAsOpaquePtr());
2032263508Sdim  }
2033263508Sdim
2034263508Sdim  static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
2035263508Sdim};
2036263508Sdim
2037193326Sed/// BlockPointerType - pointer to a block type.
2038193326Sed/// This type is to represent types syntactically represented as
2039193326Sed/// "void (^)(int)", etc. Pointee is required to always be a function type.
2040193326Sed///
2041193326Sedclass BlockPointerType : public Type, public llvm::FoldingSetNode {
2042193326Sed  QualType PointeeType;  // Block is some kind of pointer type
2043193326Sed  BlockPointerType(QualType Pointee, QualType CanonicalCls) :
2044218893Sdim    Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
2045224145Sdim         Pointee->isInstantiationDependentType(),
2046218893Sdim         Pointee->isVariablyModifiedType(),
2047218893Sdim         Pointee->containsUnexpandedParameterPack()),
2048193326Sed    PointeeType(Pointee) {
2049193326Sed  }
2050193326Sed  friend class ASTContext;  // ASTContext creates these.
2051234353Sdim
2052193326Sedpublic:
2053198092Srdivacky
2054193326Sed  // Get the pointee type. Pointee is required to always be a function type.
2055193326Sed  QualType getPointeeType() const { return PointeeType; }
2056193326Sed
2057198092Srdivacky  bool isSugared() const { return false; }
2058198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2059198092Srdivacky
2060193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2061193326Sed      Profile(ID, getPointeeType());
2062193326Sed  }
2063193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
2064193326Sed      ID.AddPointer(Pointee.getAsOpaquePtr());
2065193326Sed  }
2066198092Srdivacky
2067198092Srdivacky  static bool classof(const Type *T) {
2068198092Srdivacky    return T->getTypeClass() == BlockPointer;
2069193326Sed  }
2070193326Sed};
2071193326Sed
2072193326Sed/// ReferenceType - Base for LValueReferenceType and RValueReferenceType
2073193326Sed///
2074193326Sedclass ReferenceType : public Type, public llvm::FoldingSetNode {
2075193326Sed  QualType PointeeType;
2076193326Sed
2077193326Sedprotected:
2078198398Srdivacky  ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
2079198398Srdivacky                bool SpelledAsLValue) :
2080218893Sdim    Type(tc, CanonicalRef, Referencee->isDependentType(),
2081224145Sdim         Referencee->isInstantiationDependentType(),
2082218893Sdim         Referencee->isVariablyModifiedType(),
2083234353Sdim         Referencee->containsUnexpandedParameterPack()),
2084234353Sdim    PointeeType(Referencee)
2085218893Sdim  {
2086218893Sdim    ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
2087218893Sdim    ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
2088193326Sed  }
2089234353Sdim
2090193326Sedpublic:
2091218893Sdim  bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
2092218893Sdim  bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
2093234353Sdim
2094198398Srdivacky  QualType getPointeeTypeAsWritten() const { return PointeeType; }
2095198398Srdivacky  QualType getPointeeType() const {
2096198398Srdivacky    // FIXME: this might strip inner qualifiers; okay?
2097198398Srdivacky    const ReferenceType *T = this;
2098218893Sdim    while (T->isInnerRef())
2099218893Sdim      T = T->PointeeType->castAs<ReferenceType>();
2100198398Srdivacky    return T->PointeeType;
2101198398Srdivacky  }
2102198398Srdivacky
2103193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2104218893Sdim    Profile(ID, PointeeType, isSpelledAsLValue());
2105193326Sed  }
2106198398Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID,
2107198398Srdivacky                      QualType Referencee,
2108198398Srdivacky                      bool SpelledAsLValue) {
2109193326Sed    ID.AddPointer(Referencee.getAsOpaquePtr());
2110198398Srdivacky    ID.AddBoolean(SpelledAsLValue);
2111193326Sed  }
2112193326Sed
2113193326Sed  static bool classof(const Type *T) {
2114193326Sed    return T->getTypeClass() == LValueReference ||
2115193326Sed           T->getTypeClass() == RValueReference;
2116193326Sed  }
2117193326Sed};
2118193326Sed
2119193326Sed/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
2120193326Sed///
2121193326Sedclass LValueReferenceType : public ReferenceType {
2122198398Srdivacky  LValueReferenceType(QualType Referencee, QualType CanonicalRef,
2123198398Srdivacky                      bool SpelledAsLValue) :
2124198398Srdivacky    ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
2125198398Srdivacky  {}
2126193326Sed  friend class ASTContext; // ASTContext creates these
2127193326Sedpublic:
2128198092Srdivacky  bool isSugared() const { return false; }
2129198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2130198092Srdivacky
2131193326Sed  static bool classof(const Type *T) {
2132193326Sed    return T->getTypeClass() == LValueReference;
2133193326Sed  }
2134193326Sed};
2135193326Sed
2136193326Sed/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference
2137193326Sed///
2138193326Sedclass RValueReferenceType : public ReferenceType {
2139193326Sed  RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
2140198398Srdivacky    ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
2141193326Sed  }
2142193326Sed  friend class ASTContext; // ASTContext creates these
2143193326Sedpublic:
2144198092Srdivacky  bool isSugared() const { return false; }
2145198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2146198092Srdivacky
2147193326Sed  static bool classof(const Type *T) {
2148193326Sed    return T->getTypeClass() == RValueReference;
2149193326Sed  }
2150193326Sed};
2151193326Sed
2152193326Sed/// MemberPointerType - C++ 8.3.3 - Pointers to members
2153193326Sed///
2154193326Sedclass MemberPointerType : public Type, public llvm::FoldingSetNode {
2155193326Sed  QualType PointeeType;
2156193326Sed  /// The class of which the pointee is a member. Must ultimately be a
2157193326Sed  /// RecordType, but could be a typedef or a template parameter too.
2158193326Sed  const Type *Class;
2159193326Sed
2160193326Sed  MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
2161193326Sed    Type(MemberPointer, CanonicalPtr,
2162218893Sdim         Cls->isDependentType() || Pointee->isDependentType(),
2163234353Sdim         (Cls->isInstantiationDependentType() ||
2164224145Sdim          Pointee->isInstantiationDependentType()),
2165218893Sdim         Pointee->isVariablyModifiedType(),
2166234353Sdim         (Cls->containsUnexpandedParameterPack() ||
2167218893Sdim          Pointee->containsUnexpandedParameterPack())),
2168193326Sed    PointeeType(Pointee), Class(Cls) {
2169193326Sed  }
2170193326Sed  friend class ASTContext; // ASTContext creates these.
2171234353Sdim
2172193326Sedpublic:
2173193326Sed  QualType getPointeeType() const { return PointeeType; }
2174193326Sed
2175212904Sdim  /// Returns true if the member type (i.e. the pointee type) is a
2176212904Sdim  /// function type rather than a data-member type.
2177212904Sdim  bool isMemberFunctionPointer() const {
2178212904Sdim    return PointeeType->isFunctionProtoType();
2179212904Sdim  }
2180212904Sdim
2181212904Sdim  /// Returns true if the member type (i.e. the pointee type) is a
2182212904Sdim  /// data type rather than a function type.
2183212904Sdim  bool isMemberDataPointer() const {
2184212904Sdim    return !PointeeType->isFunctionProtoType();
2185212904Sdim  }
2186212904Sdim
2187193326Sed  const Type *getClass() const { return Class; }
2188193326Sed
2189198092Srdivacky  bool isSugared() const { return false; }
2190198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2191198092Srdivacky
2192193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2193193326Sed    Profile(ID, getPointeeType(), getClass());
2194193326Sed  }
2195193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
2196193326Sed                      const Type *Class) {
2197193326Sed    ID.AddPointer(Pointee.getAsOpaquePtr());
2198193326Sed    ID.AddPointer(Class);
2199193326Sed  }
2200193326Sed
2201193326Sed  static bool classof(const Type *T) {
2202193326Sed    return T->getTypeClass() == MemberPointer;
2203193326Sed  }
2204193326Sed};
2205193326Sed
2206193326Sed/// ArrayType - C99 6.7.5.2 - Array Declarators.
2207193326Sed///
2208193326Sedclass ArrayType : public Type, public llvm::FoldingSetNode {
2209193326Sedpublic:
2210193326Sed  /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
2211193326Sed  /// an array with a static size (e.g. int X[static 4]), or an array
2212193326Sed  /// with a star size (e.g. int X[*]).
2213193326Sed  /// 'static' is only allowed on function parameters.
2214193326Sed  enum ArraySizeModifier {
2215193326Sed    Normal, Static, Star
2216193326Sed  };
2217193326Sedprivate:
2218193326Sed  /// ElementType - The element type of the array.
2219193326Sed  QualType ElementType;
2220198092Srdivacky
2221193326Sedprotected:
2222193326Sed  // C++ [temp.dep.type]p1:
2223193326Sed  //   A type is dependent if it is...
2224193326Sed  //     - an array type constructed from any dependent type or whose
2225193326Sed  //       size is specified by a constant expression that is
2226193326Sed  //       value-dependent,
2227193326Sed  ArrayType(TypeClass tc, QualType et, QualType can,
2228218893Sdim            ArraySizeModifier sm, unsigned tq,
2229218893Sdim            bool ContainsUnexpandedParameterPack)
2230218893Sdim    : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
2231224145Sdim           et->isInstantiationDependentType() || tc == DependentSizedArray,
2232218893Sdim           (tc == VariableArray || et->isVariablyModifiedType()),
2233218893Sdim           ContainsUnexpandedParameterPack),
2234218893Sdim      ElementType(et) {
2235218893Sdim    ArrayTypeBits.IndexTypeQuals = tq;
2236218893Sdim    ArrayTypeBits.SizeModifier = sm;
2237218893Sdim  }
2238193326Sed
2239193326Sed  friend class ASTContext;  // ASTContext creates these.
2240208600Srdivacky
2241193326Sedpublic:
2242193326Sed  QualType getElementType() const { return ElementType; }
2243193326Sed  ArraySizeModifier getSizeModifier() const {
2244218893Sdim    return ArraySizeModifier(ArrayTypeBits.SizeModifier);
2245193326Sed  }
2246198092Srdivacky  Qualifiers getIndexTypeQualifiers() const {
2247218893Sdim    return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
2248198092Srdivacky  }
2249218893Sdim  unsigned getIndexTypeCVRQualifiers() const {
2250218893Sdim    return ArrayTypeBits.IndexTypeQuals;
2251218893Sdim  }
2252198092Srdivacky
2253193326Sed  static bool classof(const Type *T) {
2254193326Sed    return T->getTypeClass() == ConstantArray ||
2255193326Sed           T->getTypeClass() == VariableArray ||
2256193326Sed           T->getTypeClass() == IncompleteArray ||
2257193326Sed           T->getTypeClass() == DependentSizedArray;
2258193326Sed  }
2259193326Sed};
2260193326Sed
2261198092Srdivacky/// ConstantArrayType - This class represents the canonical version of
2262198092Srdivacky/// C arrays with a specified constant size.  For example, the canonical
2263198092Srdivacky/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element
2264198092Srdivacky/// type is 'int' and the size is 404.
2265193326Sedclass ConstantArrayType : public ArrayType {
2266193326Sed  llvm::APInt Size; // Allows us to unique the type.
2267198092Srdivacky
2268193326Sed  ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
2269193326Sed                    ArraySizeModifier sm, unsigned tq)
2270218893Sdim    : ArrayType(ConstantArray, et, can, sm, tq,
2271218893Sdim                et->containsUnexpandedParameterPack()),
2272198092Srdivacky      Size(size) {}
2273198092Srdivackyprotected:
2274198092Srdivacky  ConstantArrayType(TypeClass tc, QualType et, QualType can,
2275198092Srdivacky                    const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
2276234353Sdim    : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()),
2277218893Sdim      Size(size) {}
2278193326Sed  friend class ASTContext;  // ASTContext creates these.
2279193326Sedpublic:
2280193326Sed  const llvm::APInt &getSize() const { return Size; }
2281198092Srdivacky  bool isSugared() const { return false; }
2282198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2283198092Srdivacky
2284234353Sdim
2285212904Sdim  /// \brief Determine the number of bits required to address a member of
2286212904Sdim  // an array with the given element type and number of elements.
2287212904Sdim  static unsigned getNumAddressingBits(ASTContext &Context,
2288212904Sdim                                       QualType ElementType,
2289212904Sdim                                       const llvm::APInt &NumElements);
2290234353Sdim
2291212904Sdim  /// \brief Determine the maximum number of active bits that an array's size
2292212904Sdim  /// can require, which limits the maximum size of the array.
2293212904Sdim  static unsigned getMaxSizeBits(ASTContext &Context);
2294234353Sdim
2295193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2296198092Srdivacky    Profile(ID, getElementType(), getSize(),
2297198092Srdivacky            getSizeModifier(), getIndexTypeCVRQualifiers());
2298193326Sed  }
2299193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
2300193326Sed                      const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
2301193326Sed                      unsigned TypeQuals) {
2302193326Sed    ID.AddPointer(ET.getAsOpaquePtr());
2303193326Sed    ID.AddInteger(ArraySize.getZExtValue());
2304193326Sed    ID.AddInteger(SizeMod);
2305193326Sed    ID.AddInteger(TypeQuals);
2306193326Sed  }
2307198092Srdivacky  static bool classof(const Type *T) {
2308198398Srdivacky    return T->getTypeClass() == ConstantArray;
2309193326Sed  }
2310193326Sed};
2311193326Sed
2312193326Sed/// IncompleteArrayType - This class represents C arrays with an unspecified
2313193326Sed/// size.  For example 'int A[]' has an IncompleteArrayType where the element
2314193326Sed/// type is 'int' and the size is unspecified.
2315193326Sedclass IncompleteArrayType : public ArrayType {
2316198092Srdivacky
2317193326Sed  IncompleteArrayType(QualType et, QualType can,
2318198092Srdivacky                      ArraySizeModifier sm, unsigned tq)
2319234353Sdim    : ArrayType(IncompleteArray, et, can, sm, tq,
2320218893Sdim                et->containsUnexpandedParameterPack()) {}
2321193326Sed  friend class ASTContext;  // ASTContext creates these.
2322193326Sedpublic:
2323198092Srdivacky  bool isSugared() const { return false; }
2324198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2325193326Sed
2326198092Srdivacky  static bool classof(const Type *T) {
2327198092Srdivacky    return T->getTypeClass() == IncompleteArray;
2328193326Sed  }
2329198092Srdivacky
2330193326Sed  friend class StmtIteratorBase;
2331198092Srdivacky
2332193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2333198092Srdivacky    Profile(ID, getElementType(), getSizeModifier(),
2334198092Srdivacky            getIndexTypeCVRQualifiers());
2335193326Sed  }
2336198092Srdivacky
2337193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
2338193326Sed                      ArraySizeModifier SizeMod, unsigned TypeQuals) {
2339193326Sed    ID.AddPointer(ET.getAsOpaquePtr());
2340193326Sed    ID.AddInteger(SizeMod);
2341193326Sed    ID.AddInteger(TypeQuals);
2342193326Sed  }
2343193326Sed};
2344193326Sed
2345193326Sed/// VariableArrayType - This class represents C arrays with a specified size
2346193326Sed/// which is not an integer-constant-expression.  For example, 'int s[x+foo()]'.
2347193326Sed/// Since the size expression is an arbitrary expression, we store it as such.
2348193326Sed///
2349193326Sed/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
2350193326Sed/// should not be: two lexically equivalent variable array types could mean
2351193326Sed/// different things, for example, these variables do not have the same type
2352193326Sed/// dynamically:
2353193326Sed///
2354193326Sed/// void foo(int x) {
2355193326Sed///   int Y[x];
2356193326Sed///   ++x;
2357193326Sed///   int Z[x];
2358193326Sed/// }
2359193326Sed///
2360193326Sedclass VariableArrayType : public ArrayType {
2361198092Srdivacky  /// SizeExpr - An assignment expression. VLA's are only permitted within
2362198092Srdivacky  /// a function block.
2363193326Sed  Stmt *SizeExpr;
2364198092Srdivacky  /// Brackets - The left and right array brackets.
2365198092Srdivacky  SourceRange Brackets;
2366198092Srdivacky
2367193326Sed  VariableArrayType(QualType et, QualType can, Expr *e,
2368198092Srdivacky                    ArraySizeModifier sm, unsigned tq,
2369198092Srdivacky                    SourceRange brackets)
2370234353Sdim    : ArrayType(VariableArray, et, can, sm, tq,
2371218893Sdim                et->containsUnexpandedParameterPack()),
2372198092Srdivacky      SizeExpr((Stmt*) e), Brackets(brackets) {}
2373193326Sed  friend class ASTContext;  // ASTContext creates these.
2374193326Sed
2375193326Sedpublic:
2376198092Srdivacky  Expr *getSizeExpr() const {
2377193326Sed    // We use C-style casts instead of cast<> here because we do not wish
2378193326Sed    // to have a dependency of Type.h on Stmt.h/Expr.h.
2379193326Sed    return (Expr*) SizeExpr;
2380193326Sed  }
2381198092Srdivacky  SourceRange getBracketsRange() const { return Brackets; }
2382198092Srdivacky  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
2383198092Srdivacky  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
2384198092Srdivacky
2385198092Srdivacky  bool isSugared() const { return false; }
2386198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2387198092Srdivacky
2388198092Srdivacky  static bool classof(const Type *T) {
2389198092Srdivacky    return T->getTypeClass() == VariableArray;
2390193326Sed  }
2391198092Srdivacky
2392193326Sed  friend class StmtIteratorBase;
2393198092Srdivacky
2394193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2395226633Sdim    llvm_unreachable("Cannot unique VariableArrayTypes.");
2396193326Sed  }
2397193326Sed};
2398193326Sed
2399193326Sed/// DependentSizedArrayType - This type represents an array type in
2400193326Sed/// C++ whose size is a value-dependent expression. For example:
2401199990Srdivacky///
2402199990Srdivacky/// \code
2403198092Srdivacky/// template<typename T, int Size>
2404193326Sed/// class array {
2405193326Sed///   T data[Size];
2406193326Sed/// };
2407199990Srdivacky/// \endcode
2408199990Srdivacky///
2409193326Sed/// For these types, we won't actually know what the array bound is
2410193326Sed/// until template instantiation occurs, at which point this will
2411193326Sed/// become either a ConstantArrayType or a VariableArrayType.
2412193326Sedclass DependentSizedArrayType : public ArrayType {
2413218893Sdim  const ASTContext &Context;
2414198092Srdivacky
2415199990Srdivacky  /// \brief An assignment expression that will instantiate to the
2416193326Sed  /// size of the array.
2417199990Srdivacky  ///
2418199990Srdivacky  /// The expression itself might be NULL, in which case the array
2419199990Srdivacky  /// type will have its size deduced from an initializer.
2420193326Sed  Stmt *SizeExpr;
2421199990Srdivacky
2422198092Srdivacky  /// Brackets - The left and right array brackets.
2423198092Srdivacky  SourceRange Brackets;
2424198092Srdivacky
2425218893Sdim  DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
2426198092Srdivacky                          Expr *e, ArraySizeModifier sm, unsigned tq,
2427218893Sdim                          SourceRange brackets);
2428218893Sdim
2429193326Sed  friend class ASTContext;  // ASTContext creates these.
2430193326Sed
2431193326Sedpublic:
2432198092Srdivacky  Expr *getSizeExpr() const {
2433193326Sed    // We use C-style casts instead of cast<> here because we do not wish
2434193326Sed    // to have a dependency of Type.h on Stmt.h/Expr.h.
2435193326Sed    return (Expr*) SizeExpr;
2436193326Sed  }
2437198092Srdivacky  SourceRange getBracketsRange() const { return Brackets; }
2438198092Srdivacky  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
2439198092Srdivacky  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
2440198092Srdivacky
2441198092Srdivacky  bool isSugared() const { return false; }
2442198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2443198092Srdivacky
2444198092Srdivacky  static bool classof(const Type *T) {
2445198092Srdivacky    return T->getTypeClass() == DependentSizedArray;
2446193326Sed  }
2447198092Srdivacky
2448193326Sed  friend class StmtIteratorBase;
2449198092Srdivacky
2450198092Srdivacky
2451193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2452198092Srdivacky    Profile(ID, Context, getElementType(),
2453198092Srdivacky            getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
2454193326Sed  }
2455198092Srdivacky
2456218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2457198092Srdivacky                      QualType ET, ArraySizeModifier SizeMod,
2458198092Srdivacky                      unsigned TypeQuals, Expr *E);
2459193326Sed};
2460193326Sed
2461194613Sed/// DependentSizedExtVectorType - This type represent an extended vector type
2462194613Sed/// where either the type or size is dependent. For example:
2463194613Sed/// @code
2464194613Sed/// template<typename T, int Size>
2465194613Sed/// class vector {
2466194613Sed///   typedef T __attribute__((ext_vector_type(Size))) type;
2467194613Sed/// }
2468194613Sed/// @endcode
2469198092Srdivackyclass DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
2470218893Sdim  const ASTContext &Context;
2471194613Sed  Expr *SizeExpr;
2472194613Sed  /// ElementType - The element type of the array.
2473194613Sed  QualType ElementType;
2474194613Sed  SourceLocation loc;
2475198092Srdivacky
2476218893Sdim  DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
2477218893Sdim                              QualType can, Expr *SizeExpr, SourceLocation loc);
2478218893Sdim
2479194613Sed  friend class ASTContext;
2480194613Sed
2481194613Sedpublic:
2482198092Srdivacky  Expr *getSizeExpr() const { return SizeExpr; }
2483194613Sed  QualType getElementType() const { return ElementType; }
2484194613Sed  SourceLocation getAttributeLoc() const { return loc; }
2485194613Sed
2486198092Srdivacky  bool isSugared() const { return false; }
2487198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2488198092Srdivacky
2489198092Srdivacky  static bool classof(const Type *T) {
2490198092Srdivacky    return T->getTypeClass() == DependentSizedExtVector;
2491194613Sed  }
2492198092Srdivacky
2493198092Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) {
2494198092Srdivacky    Profile(ID, Context, getElementType(), getSizeExpr());
2495198092Srdivacky  }
2496198092Srdivacky
2497218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2498198092Srdivacky                      QualType ElementType, Expr *SizeExpr);
2499194613Sed};
2500194613Sed
2501198092Srdivacky
2502193326Sed/// VectorType - GCC generic vector type. This type is created using
2503198092Srdivacky/// __attribute__((vector_size(n)), where "n" specifies the vector size in
2504203955Srdivacky/// bytes; or from an Altivec __vector or vector declaration.
2505203955Srdivacky/// Since the constructor takes the number of vector elements, the
2506193326Sed/// client is responsible for converting the size into the number of elements.
2507193326Sedclass VectorType : public Type, public llvm::FoldingSetNode {
2508210299Sedpublic:
2509218893Sdim  enum VectorKind {
2510218893Sdim    GenericVector,  // not a target-specific vector type
2511218893Sdim    AltiVecVector,  // is AltiVec vector
2512218893Sdim    AltiVecPixel,   // is AltiVec 'vector Pixel'
2513218893Sdim    AltiVecBool,    // is AltiVec 'vector bool ...'
2514218893Sdim    NeonVector,     // is ARM Neon vector
2515218893Sdim    NeonPolyVector  // is ARM Neon polynomial vector
2516210299Sed  };
2517193326Sedprotected:
2518193326Sed  /// ElementType - The element type of the vector.
2519193326Sed  QualType ElementType;
2520198092Srdivacky
2521203955Srdivacky  VectorType(QualType vecType, unsigned nElements, QualType canonType,
2522218893Sdim             VectorKind vecKind);
2523234353Sdim
2524198092Srdivacky  VectorType(TypeClass tc, QualType vecType, unsigned nElements,
2525218893Sdim             QualType canonType, VectorKind vecKind);
2526218893Sdim
2527193326Sed  friend class ASTContext;  // ASTContext creates these.
2528234353Sdim
2529193326Sedpublic:
2530198092Srdivacky
2531193326Sed  QualType getElementType() const { return ElementType; }
2532218893Sdim  unsigned getNumElements() const { return VectorTypeBits.NumElements; }
2533263508Sdim  static bool isVectorSizeTooLarge(unsigned NumElements) {
2534263508Sdim    return NumElements > VectorTypeBitfields::MaxNumElements;
2535263508Sdim  }
2536193326Sed
2537198092Srdivacky  bool isSugared() const { return false; }
2538198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2539198092Srdivacky
2540218893Sdim  VectorKind getVectorKind() const {
2541218893Sdim    return VectorKind(VectorTypeBits.VecKind);
2542218893Sdim  }
2543210299Sed
2544193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2545218893Sdim    Profile(ID, getElementType(), getNumElements(),
2546218893Sdim            getTypeClass(), getVectorKind());
2547193326Sed  }
2548198092Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
2549203955Srdivacky                      unsigned NumElements, TypeClass TypeClass,
2550218893Sdim                      VectorKind VecKind) {
2551193326Sed    ID.AddPointer(ElementType.getAsOpaquePtr());
2552193326Sed    ID.AddInteger(NumElements);
2553193326Sed    ID.AddInteger(TypeClass);
2554218893Sdim    ID.AddInteger(VecKind);
2555193326Sed  }
2556203955Srdivacky
2557198092Srdivacky  static bool classof(const Type *T) {
2558198092Srdivacky    return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
2559193326Sed  }
2560193326Sed};
2561193326Sed
2562193326Sed/// ExtVectorType - Extended vector type. This type is created using
2563193326Sed/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
2564193326Sed/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
2565193326Sed/// class enables syntactic extensions, like Vector Components for accessing
2566193326Sed/// points, colors, and textures (modeled after OpenGL Shading Language).
2567193326Sedclass ExtVectorType : public VectorType {
2568193326Sed  ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
2569218893Sdim    VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
2570193326Sed  friend class ASTContext;  // ASTContext creates these.
2571193326Sedpublic:
2572193326Sed  static int getPointAccessorIdx(char c) {
2573193326Sed    switch (c) {
2574193326Sed    default: return -1;
2575193326Sed    case 'x': return 0;
2576193326Sed    case 'y': return 1;
2577193326Sed    case 'z': return 2;
2578193326Sed    case 'w': return 3;
2579193326Sed    }
2580193326Sed  }
2581193326Sed  static int getNumericAccessorIdx(char c) {
2582193326Sed    switch (c) {
2583193326Sed      default: return -1;
2584193326Sed      case '0': return 0;
2585193326Sed      case '1': return 1;
2586193326Sed      case '2': return 2;
2587193326Sed      case '3': return 3;
2588193326Sed      case '4': return 4;
2589193326Sed      case '5': return 5;
2590193326Sed      case '6': return 6;
2591193326Sed      case '7': return 7;
2592193326Sed      case '8': return 8;
2593193326Sed      case '9': return 9;
2594195099Sed      case 'A':
2595193326Sed      case 'a': return 10;
2596195099Sed      case 'B':
2597193326Sed      case 'b': return 11;
2598195099Sed      case 'C':
2599193326Sed      case 'c': return 12;
2600195099Sed      case 'D':
2601193326Sed      case 'd': return 13;
2602195099Sed      case 'E':
2603193326Sed      case 'e': return 14;
2604195099Sed      case 'F':
2605193326Sed      case 'f': return 15;
2606193326Sed    }
2607193326Sed  }
2608198092Srdivacky
2609193326Sed  static int getAccessorIdx(char c) {
2610193326Sed    if (int idx = getPointAccessorIdx(c)+1) return idx-1;
2611193326Sed    return getNumericAccessorIdx(c);
2612193326Sed  }
2613198092Srdivacky
2614193326Sed  bool isAccessorWithinNumElements(char c) const {
2615193326Sed    if (int idx = getAccessorIdx(c)+1)
2616218893Sdim      return unsigned(idx-1) < getNumElements();
2617193326Sed    return false;
2618193326Sed  }
2619198092Srdivacky  bool isSugared() const { return false; }
2620198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2621198092Srdivacky
2622198092Srdivacky  static bool classof(const Type *T) {
2623198092Srdivacky    return T->getTypeClass() == ExtVector;
2624193326Sed  }
2625193326Sed};
2626193326Sed
2627193326Sed/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
2628193326Sed/// class of FunctionNoProtoType and FunctionProtoType.
2629193326Sed///
2630193326Sedclass FunctionType : public Type {
2631193326Sed  // The type returned by the function.
2632193326Sed  QualType ResultType;
2633206084Srdivacky
2634206084Srdivacky public:
2635218893Sdim  /// ExtInfo - A class which abstracts out some details necessary for
2636218893Sdim  /// making a call.
2637218893Sdim  ///
2638218893Sdim  /// It is not actually used directly for storing this information in
2639218893Sdim  /// a FunctionType, although FunctionType does currently use the
2640218893Sdim  /// same bit-pattern.
2641218893Sdim  ///
2642218893Sdim  // If you add a field (say Foo), other than the obvious places (both,
2643218893Sdim  // constructors, compile failures), what you need to update is
2644218893Sdim  // * Operator==
2645206084Srdivacky  // * getFoo
2646206084Srdivacky  // * withFoo
2647206084Srdivacky  // * functionType. Add Foo, getFoo.
2648206084Srdivacky  // * ASTContext::getFooType
2649206084Srdivacky  // * ASTContext::mergeFunctionTypes
2650206084Srdivacky  // * FunctionNoProtoType::Profile
2651206084Srdivacky  // * FunctionProtoType::Profile
2652206084Srdivacky  // * TypePrinter::PrintFunctionProto
2653212904Sdim  // * AST read and write
2654206084Srdivacky  // * Codegen
2655218893Sdim  class ExtInfo {
2656243830Sdim    // Feel free to rearrange or add bits, but if you go over 9,
2657218893Sdim    // you'll need to adjust both the Bits field below and
2658218893Sdim    // Type::FunctionTypeBitfields.
2659206084Srdivacky
2660224145Sdim    //   |  CC  |noreturn|produces|regparm|
2661243830Sdim    //   |0 .. 3|   4    |    5   | 6 .. 8|
2662224145Sdim    //
2663224145Sdim    // regparm is either 0 (no regparm attribute) or the regparm value+1.
2664243830Sdim    enum { CallConvMask = 0xF };
2665243830Sdim    enum { NoReturnMask = 0x10 };
2666243830Sdim    enum { ProducesResultMask = 0x20 };
2667224145Sdim    enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
2668243830Sdim           RegParmOffset = 6 }; // Assumed to be the last field
2669218893Sdim
2670224145Sdim    uint16_t Bits;
2671218893Sdim
2672224145Sdim    ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
2673218893Sdim
2674218893Sdim    friend class FunctionType;
2675218893Sdim
2676206084Srdivacky   public:
2677206084Srdivacky    // Constructor with no defaults. Use this when you know that you
2678212904Sdim    // have all the elements (when reading an AST file for example).
2679224145Sdim    ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
2680224145Sdim            bool producesResult) {
2681224145Sdim      assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
2682218893Sdim      Bits = ((unsigned) cc) |
2683218893Sdim             (noReturn ? NoReturnMask : 0) |
2684224145Sdim             (producesResult ? ProducesResultMask : 0) |
2685224145Sdim             (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
2686218893Sdim    }
2687206084Srdivacky
2688206084Srdivacky    // Constructor with all defaults. Use when for example creating a
2689206084Srdivacky    // function know to use defaults.
2690263508Sdim    ExtInfo() : Bits(CC_C) { }
2691206084Srdivacky
2692263508Sdim    // Constructor with just the calling convention, which is an important part
2693263508Sdim    // of the canonical type.
2694263508Sdim    ExtInfo(CallingConv CC) : Bits(CC) { }
2695263508Sdim
2696218893Sdim    bool getNoReturn() const { return Bits & NoReturnMask; }
2697224145Sdim    bool getProducesResult() const { return Bits & ProducesResultMask; }
2698224145Sdim    bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
2699234353Sdim    unsigned getRegParm() const {
2700224145Sdim      unsigned RegParm = Bits >> RegParmOffset;
2701224145Sdim      if (RegParm > 0)
2702224145Sdim        --RegParm;
2703224145Sdim      return RegParm;
2704224145Sdim    }
2705218893Sdim    CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
2706206084Srdivacky
2707218893Sdim    bool operator==(ExtInfo Other) const {
2708218893Sdim      return Bits == Other.Bits;
2709206084Srdivacky    }
2710218893Sdim    bool operator!=(ExtInfo Other) const {
2711218893Sdim      return Bits != Other.Bits;
2712206084Srdivacky    }
2713206084Srdivacky
2714206084Srdivacky    // Note that we don't have setters. That is by design, use
2715206084Srdivacky    // the following with methods instead of mutating these objects.
2716206084Srdivacky
2717206084Srdivacky    ExtInfo withNoReturn(bool noReturn) const {
2718218893Sdim      if (noReturn)
2719218893Sdim        return ExtInfo(Bits | NoReturnMask);
2720218893Sdim      else
2721218893Sdim        return ExtInfo(Bits & ~NoReturnMask);
2722206084Srdivacky    }
2723206084Srdivacky
2724224145Sdim    ExtInfo withProducesResult(bool producesResult) const {
2725224145Sdim      if (producesResult)
2726224145Sdim        return ExtInfo(Bits | ProducesResultMask);
2727224145Sdim      else
2728224145Sdim        return ExtInfo(Bits & ~ProducesResultMask);
2729224145Sdim    }
2730224145Sdim
2731206084Srdivacky    ExtInfo withRegParm(unsigned RegParm) const {
2732224145Sdim      assert(RegParm < 7 && "Invalid regparm value");
2733224145Sdim      return ExtInfo((Bits & ~RegParmMask) |
2734224145Sdim                     ((RegParm + 1) << RegParmOffset));
2735206084Srdivacky    }
2736206084Srdivacky
2737206084Srdivacky    ExtInfo withCallingConv(CallingConv cc) const {
2738218893Sdim      return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc);
2739206084Srdivacky    }
2740206084Srdivacky
2741218893Sdim    void Profile(llvm::FoldingSetNodeID &ID) const {
2742218893Sdim      ID.AddInteger(Bits);
2743218893Sdim    }
2744206084Srdivacky  };
2745206084Srdivacky
2746193326Sedprotected:
2747234353Sdim  FunctionType(TypeClass tc, QualType res,
2748249423Sdim               unsigned typeQuals, QualType Canonical, bool Dependent,
2749224145Sdim               bool InstantiationDependent,
2750234353Sdim               bool VariablyModified, bool ContainsUnexpandedParameterPack,
2751218893Sdim               ExtInfo Info)
2752234353Sdim    : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
2753234353Sdim           ContainsUnexpandedParameterPack),
2754218893Sdim      ResultType(res) {
2755218893Sdim    FunctionTypeBits.ExtInfo = Info.Bits;
2756218893Sdim    FunctionTypeBits.TypeQuals = typeQuals;
2757218893Sdim  }
2758218893Sdim  unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
2759234353Sdim
2760193326Sedpublic:
2761198092Srdivacky
2762193326Sed  QualType getResultType() const { return ResultType; }
2763221345Sdim
2764221345Sdim  bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
2765218893Sdim  unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
2766249423Sdim  /// \brief Determine whether this function type includes the GNU noreturn
2767249423Sdim  /// attribute. The C++11 [[noreturn]] attribute does not affect the function
2768249423Sdim  /// type.
2769218893Sdim  bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
2770218893Sdim  CallingConv getCallConv() const { return getExtInfo().getCC(); }
2771218893Sdim  ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
2772239462Sdim  bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
2773239462Sdim  bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; }
2774239462Sdim  bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; }
2775193326Sed
2776210299Sed  /// \brief Determine the type of an expression that calls a function of
2777210299Sed  /// this type.
2778234353Sdim  QualType getCallResultType(ASTContext &Context) const {
2779210299Sed    return getResultType().getNonLValueExprType(Context);
2780210299Sed  }
2781210299Sed
2782226633Sdim  static StringRef getNameForCallConv(CallingConv CC);
2783203955Srdivacky
2784193326Sed  static bool classof(const Type *T) {
2785193326Sed    return T->getTypeClass() == FunctionNoProto ||
2786193326Sed           T->getTypeClass() == FunctionProto;
2787193326Sed  }
2788193326Sed};
2789193326Sed
2790193326Sed/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
2791193326Sed/// no information available about its arguments.
2792193326Sedclass FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
2793218893Sdim  FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
2794249423Sdim    : FunctionType(FunctionNoProto, Result, 0, Canonical,
2795224145Sdim                   /*Dependent=*/false, /*InstantiationDependent=*/false,
2796234353Sdim                   Result->isVariablyModifiedType(),
2797218893Sdim                   /*ContainsUnexpandedParameterPack=*/false, Info) {}
2798218893Sdim
2799193326Sed  friend class ASTContext;  // ASTContext creates these.
2800234353Sdim
2801193326Sedpublic:
2802193326Sed  // No additional state past what FunctionType provides.
2803193326Sed
2804198092Srdivacky  bool isSugared() const { return false; }
2805198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
2806198092Srdivacky
2807193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
2808206084Srdivacky    Profile(ID, getResultType(), getExtInfo());
2809193326Sed  }
2810198092Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
2811218893Sdim                      ExtInfo Info) {
2812218893Sdim    Info.Profile(ID);
2813193326Sed    ID.AddPointer(ResultType.getAsOpaquePtr());
2814193326Sed  }
2815198092Srdivacky
2816193326Sed  static bool classof(const Type *T) {
2817193326Sed    return T->getTypeClass() == FunctionNoProto;
2818193326Sed  }
2819193326Sed};
2820193326Sed
2821193326Sed/// FunctionProtoType - Represents a prototype with argument type info, e.g.
2822193326Sed/// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
2823193326Sed/// arguments, not as having a single void argument. Such a type can have an
2824193326Sed/// exception specification, but this specification is not part of the canonical
2825193326Sed/// type.
2826193326Sedclass FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
2827218893Sdimpublic:
2828218893Sdim  /// ExtProtoInfo - Extra information about a function prototype.
2829218893Sdim  struct ExtProtoInfo {
2830218893Sdim    ExtProtoInfo() :
2831234353Sdim      Variadic(false), HasTrailingReturn(false), TypeQuals(0),
2832234353Sdim      ExceptionSpecType(EST_None), RefQualifier(RQ_None),
2833234982Sdim      NumExceptions(0), Exceptions(0), NoexceptExpr(0),
2834234982Sdim      ExceptionSpecDecl(0), ExceptionSpecTemplate(0),
2835234982Sdim      ConsumedArguments(0) {}
2836218893Sdim
2837263508Sdim    ExtProtoInfo(CallingConv CC)
2838263508Sdim        : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
2839263508Sdim          ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
2840263508Sdim          Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0),
2841263508Sdim          ExceptionSpecTemplate(0), ConsumedArguments(0) {}
2842263508Sdim
2843218893Sdim    FunctionType::ExtInfo ExtInfo;
2844234353Sdim    bool Variadic : 1;
2845234353Sdim    bool HasTrailingReturn : 1;
2846234353Sdim    unsigned char TypeQuals;
2847221345Sdim    ExceptionSpecificationType ExceptionSpecType;
2848218893Sdim    RefQualifierKind RefQualifier;
2849218893Sdim    unsigned NumExceptions;
2850218893Sdim    const QualType *Exceptions;
2851221345Sdim    Expr *NoexceptExpr;
2852234982Sdim    FunctionDecl *ExceptionSpecDecl;
2853234982Sdim    FunctionDecl *ExceptionSpecTemplate;
2854224145Sdim    const bool *ConsumedArguments;
2855218893Sdim  };
2856218893Sdim
2857218893Sdimprivate:
2858218893Sdim  /// \brief Determine whether there are any argument types that
2859218893Sdim  /// contain an unexpanded parameter pack.
2860234353Sdim  static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
2861218893Sdim                                                 unsigned numArgs) {
2862193326Sed    for (unsigned Idx = 0; Idx < numArgs; ++Idx)
2863218893Sdim      if (ArgArray[Idx]->containsUnexpandedParameterPack())
2864218893Sdim        return true;
2865193326Sed
2866193326Sed    return false;
2867193326Sed  }
2868193326Sed
2869249423Sdim  FunctionProtoType(QualType result, ArrayRef<QualType> args,
2870218893Sdim                    QualType canonical, const ExtProtoInfo &epi);
2871193326Sed
2872193326Sed  /// NumArgs - The number of arguments this function has, not counting '...'.
2873249423Sdim  unsigned NumArgs : 15;
2874193326Sed
2875193326Sed  /// NumExceptions - The number of types in the exception spec, if any.
2876221345Sdim  unsigned NumExceptions : 9;
2877193326Sed
2878221345Sdim  /// ExceptionSpecType - The type of exception specification this function has.
2879221345Sdim  unsigned ExceptionSpecType : 3;
2880193326Sed
2881224145Sdim  /// HasAnyConsumedArgs - Whether this function has any consumed arguments.
2882224145Sdim  unsigned HasAnyConsumedArgs : 1;
2883224145Sdim
2884234353Sdim  /// Variadic - Whether the function is variadic.
2885234353Sdim  unsigned Variadic : 1;
2886234353Sdim
2887234353Sdim  /// HasTrailingReturn - Whether this function has a trailing return type.
2888234353Sdim  unsigned HasTrailingReturn : 1;
2889234353Sdim
2890249423Sdim  /// \brief The ref-qualifier associated with a \c FunctionProtoType.
2891249423Sdim  ///
2892249423Sdim  /// This is a value of type \c RefQualifierKind.
2893249423Sdim  unsigned RefQualifier : 2;
2894249423Sdim
2895234353Sdim  // ArgInfo - There is an variable size array after the class in memory that
2896234353Sdim  // holds the argument types.
2897234353Sdim
2898234353Sdim  // Exceptions - There is another variable size array after ArgInfo that
2899234353Sdim  // holds the exception types.
2900234353Sdim
2901234353Sdim  // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
2902234353Sdim  // to the expression in the noexcept() specifier.
2903234353Sdim
2904234982Sdim  // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may
2905234982Sdim  // be a pair of FunctionDecl* pointing to the function which should be used to
2906234982Sdim  // instantiate this function type's exception specification, and the function
2907234982Sdim  // from which it should be instantiated.
2908234982Sdim
2909234353Sdim  // ConsumedArgs - A variable size array, following Exceptions
2910234353Sdim  // and of length NumArgs, holding flags indicating which arguments
2911234353Sdim  // are consumed.  This only appears if HasAnyConsumedArgs is true.
2912234353Sdim
2913193326Sed  friend class ASTContext;  // ASTContext creates these.
2914193326Sed
2915224145Sdim  const bool *getConsumedArgsBuffer() const {
2916224145Sdim    assert(hasAnyConsumedArgs());
2917224145Sdim
2918224145Sdim    // Find the end of the exceptions.
2919224145Sdim    Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end());
2920224145Sdim    if (getExceptionSpecType() != EST_ComputedNoexcept)
2921224145Sdim      eh_end += NumExceptions;
2922224145Sdim    else
2923224145Sdim      eh_end += 1; // NoexceptExpr
2924224145Sdim
2925224145Sdim    return reinterpret_cast<const bool*>(eh_end);
2926224145Sdim  }
2927224145Sdim
2928193326Sedpublic:
2929193326Sed  unsigned getNumArgs() const { return NumArgs; }
2930193326Sed  QualType getArgType(unsigned i) const {
2931193326Sed    assert(i < NumArgs && "Invalid argument number!");
2932193326Sed    return arg_type_begin()[i];
2933193326Sed  }
2934249423Sdim  ArrayRef<QualType> getArgTypes() const {
2935249423Sdim    return ArrayRef<QualType>(arg_type_begin(), arg_type_end());
2936249423Sdim  }
2937193326Sed
2938218893Sdim  ExtProtoInfo getExtProtoInfo() const {
2939218893Sdim    ExtProtoInfo EPI;
2940218893Sdim    EPI.ExtInfo = getExtInfo();
2941218893Sdim    EPI.Variadic = isVariadic();
2942234353Sdim    EPI.HasTrailingReturn = hasTrailingReturn();
2943221345Sdim    EPI.ExceptionSpecType = getExceptionSpecType();
2944218893Sdim    EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
2945218893Sdim    EPI.RefQualifier = getRefQualifier();
2946221345Sdim    if (EPI.ExceptionSpecType == EST_Dynamic) {
2947221345Sdim      EPI.NumExceptions = NumExceptions;
2948221345Sdim      EPI.Exceptions = exception_begin();
2949221345Sdim    } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
2950221345Sdim      EPI.NoexceptExpr = getNoexceptExpr();
2951234982Sdim    } else if (EPI.ExceptionSpecType == EST_Uninstantiated) {
2952234982Sdim      EPI.ExceptionSpecDecl = getExceptionSpecDecl();
2953234982Sdim      EPI.ExceptionSpecTemplate = getExceptionSpecTemplate();
2954239462Sdim    } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
2955239462Sdim      EPI.ExceptionSpecDecl = getExceptionSpecDecl();
2956221345Sdim    }
2957224145Sdim    if (hasAnyConsumedArgs())
2958224145Sdim      EPI.ConsumedArguments = getConsumedArgsBuffer();
2959218893Sdim    return EPI;
2960218893Sdim  }
2961218893Sdim
2962221345Sdim  /// \brief Get the kind of exception specification on this function.
2963221345Sdim  ExceptionSpecificationType getExceptionSpecType() const {
2964221345Sdim    return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
2965221345Sdim  }
2966221345Sdim  /// \brief Return whether this function has any kind of exception spec.
2967221345Sdim  bool hasExceptionSpec() const {
2968221345Sdim    return getExceptionSpecType() != EST_None;
2969221345Sdim  }
2970221345Sdim  /// \brief Return whether this function has a dynamic (throw) exception spec.
2971221345Sdim  bool hasDynamicExceptionSpec() const {
2972221345Sdim    return isDynamicExceptionSpec(getExceptionSpecType());
2973221345Sdim  }
2974221345Sdim  /// \brief Return whether this function has a noexcept exception spec.
2975221345Sdim  bool hasNoexceptExceptionSpec() const {
2976221345Sdim    return isNoexceptExceptionSpec(getExceptionSpecType());
2977221345Sdim  }
2978221345Sdim  /// \brief Result type of getNoexceptSpec().
2979221345Sdim  enum NoexceptResult {
2980221345Sdim    NR_NoNoexcept,  ///< There is no noexcept specifier.
2981221345Sdim    NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
2982221345Sdim    NR_Dependent,   ///< The noexcept specifier is dependent.
2983221345Sdim    NR_Throw,       ///< The noexcept specifier evaluates to false.
2984221345Sdim    NR_Nothrow      ///< The noexcept specifier evaluates to true.
2985221345Sdim  };
2986221345Sdim  /// \brief Get the meaning of the noexcept spec on this function, if any.
2987263508Sdim  NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const;
2988193326Sed  unsigned getNumExceptions() const { return NumExceptions; }
2989193326Sed  QualType getExceptionType(unsigned i) const {
2990193326Sed    assert(i < NumExceptions && "Invalid exception number!");
2991193326Sed    return exception_begin()[i];
2992193326Sed  }
2993221345Sdim  Expr *getNoexceptExpr() const {
2994221345Sdim    if (getExceptionSpecType() != EST_ComputedNoexcept)
2995221345Sdim      return 0;
2996221345Sdim    // NoexceptExpr sits where the arguments end.
2997221345Sdim    return *reinterpret_cast<Expr *const *>(arg_type_end());
2998193326Sed  }
2999239462Sdim  /// \brief If this function type has an exception specification which hasn't
3000239462Sdim  /// been determined yet (either because it has not been evaluated or because
3001239462Sdim  /// it has not been instantiated), this is the function whose exception
3002239462Sdim  /// specification is represented by this type.
3003234982Sdim  FunctionDecl *getExceptionSpecDecl() const {
3004239462Sdim    if (getExceptionSpecType() != EST_Uninstantiated &&
3005239462Sdim        getExceptionSpecType() != EST_Unevaluated)
3006234982Sdim      return 0;
3007234982Sdim    return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0];
3008234982Sdim  }
3009234982Sdim  /// \brief If this function type has an uninstantiated exception
3010234982Sdim  /// specification, this is the function whose exception specification
3011234982Sdim  /// should be instantiated to find the exception specification for
3012234982Sdim  /// this type.
3013234982Sdim  FunctionDecl *getExceptionSpecTemplate() const {
3014234982Sdim    if (getExceptionSpecType() != EST_Uninstantiated)
3015234982Sdim      return 0;
3016234982Sdim    return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1];
3017234982Sdim  }
3018263508Sdim  bool isNothrow(const ASTContext &Ctx) const {
3019221345Sdim    ExceptionSpecificationType EST = getExceptionSpecType();
3020239462Sdim    assert(EST != EST_Unevaluated && EST != EST_Uninstantiated);
3021221345Sdim    if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
3022221345Sdim      return true;
3023221345Sdim    if (EST != EST_ComputedNoexcept)
3024221345Sdim      return false;
3025221345Sdim    return getNoexceptSpec(Ctx) == NR_Nothrow;
3026221345Sdim  }
3027193326Sed
3028234353Sdim  bool isVariadic() const { return Variadic; }
3029221345Sdim
3030218893Sdim  /// \brief Determines whether this function prototype contains a
3031218893Sdim  /// parameter pack at the end.
3032218893Sdim  ///
3033218893Sdim  /// A function template whose last parameter is a parameter pack can be
3034218893Sdim  /// called with an arbitrary number of arguments, much like a variadic
3035234353Sdim  /// function.
3036218893Sdim  bool isTemplateVariadic() const;
3037234353Sdim
3038234353Sdim  bool hasTrailingReturn() const { return HasTrailingReturn; }
3039234353Sdim
3040193326Sed  unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
3041198092Srdivacky
3042234353Sdim
3043218893Sdim  /// \brief Retrieve the ref-qualifier associated with this function type.
3044218893Sdim  RefQualifierKind getRefQualifier() const {
3045249423Sdim    return static_cast<RefQualifierKind>(RefQualifier);
3046218893Sdim  }
3047234353Sdim
3048193326Sed  typedef const QualType *arg_type_iterator;
3049193326Sed  arg_type_iterator arg_type_begin() const {
3050193326Sed    return reinterpret_cast<const QualType *>(this+1);
3051193326Sed  }
3052193326Sed  arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
3053193326Sed
3054193326Sed  typedef const QualType *exception_iterator;
3055193326Sed  exception_iterator exception_begin() const {
3056193326Sed    // exceptions begin where arguments end
3057193326Sed    return arg_type_end();
3058193326Sed  }
3059193326Sed  exception_iterator exception_end() const {
3060221345Sdim    if (getExceptionSpecType() != EST_Dynamic)
3061221345Sdim      return exception_begin();
3062193326Sed    return exception_begin() + NumExceptions;
3063193326Sed  }
3064193326Sed
3065224145Sdim  bool hasAnyConsumedArgs() const {
3066224145Sdim    return HasAnyConsumedArgs;
3067224145Sdim  }
3068224145Sdim  bool isArgConsumed(unsigned I) const {
3069224145Sdim    assert(I < getNumArgs() && "argument index out of range!");
3070224145Sdim    if (hasAnyConsumedArgs())
3071224145Sdim      return getConsumedArgsBuffer()[I];
3072224145Sdim    return false;
3073224145Sdim  }
3074224145Sdim
3075198092Srdivacky  bool isSugared() const { return false; }
3076198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
3077198092Srdivacky
3078239462Sdim  void printExceptionSpecification(raw_ostream &OS,
3079243830Sdim                                   const PrintingPolicy &Policy) const;
3080234353Sdim
3081193326Sed  static bool classof(const Type *T) {
3082193326Sed    return T->getTypeClass() == FunctionProto;
3083193326Sed  }
3084193326Sed
3085221345Sdim  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
3086193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
3087193326Sed                      arg_type_iterator ArgTys, unsigned NumArgs,
3088221345Sdim                      const ExtProtoInfo &EPI, const ASTContext &Context);
3089193326Sed};
3090193326Sed
3091193326Sed
3092200583Srdivacky/// \brief Represents the dependent type named by a dependently-scoped
3093200583Srdivacky/// typename using declaration, e.g.
3094200583Srdivacky///   using typename Base<T>::foo;
3095200583Srdivacky/// Template instantiation turns these into the underlying type.
3096200583Srdivackyclass UnresolvedUsingType : public Type {
3097200583Srdivacky  UnresolvedUsingTypenameDecl *Decl;
3098200583Srdivacky
3099203955Srdivacky  UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
3100234353Sdim    : Type(UnresolvedUsing, QualType(), true, true, false,
3101218893Sdim           /*ContainsUnexpandedParameterPack=*/false),
3102203955Srdivacky      Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
3103200583Srdivacky  friend class ASTContext; // ASTContext creates these.
3104200583Srdivackypublic:
3105200583Srdivacky
3106200583Srdivacky  UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
3107200583Srdivacky
3108200583Srdivacky  bool isSugared() const { return false; }
3109200583Srdivacky  QualType desugar() const { return QualType(this, 0); }
3110200583Srdivacky
3111200583Srdivacky  static bool classof(const Type *T) {
3112200583Srdivacky    return T->getTypeClass() == UnresolvedUsing;
3113200583Srdivacky  }
3114200583Srdivacky
3115200583Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) {
3116200583Srdivacky    return Profile(ID, Decl);
3117200583Srdivacky  }
3118200583Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID,
3119200583Srdivacky                      UnresolvedUsingTypenameDecl *D) {
3120200583Srdivacky    ID.AddPointer(D);
3121200583Srdivacky  }
3122200583Srdivacky};
3123200583Srdivacky
3124200583Srdivacky
3125193326Sedclass TypedefType : public Type {
3126221345Sdim  TypedefNameDecl *Decl;
3127193326Sedprotected:
3128221345Sdim  TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
3129234353Sdim    : Type(tc, can, can->isDependentType(),
3130224145Sdim           can->isInstantiationDependentType(),
3131234353Sdim           can->isVariablyModifiedType(),
3132218893Sdim           /*ContainsUnexpandedParameterPack=*/false),
3133221345Sdim      Decl(const_cast<TypedefNameDecl*>(D)) {
3134193326Sed    assert(!isa<TypedefType>(can) && "Invalid canonical type");
3135193326Sed  }
3136193326Sed  friend class ASTContext;  // ASTContext creates these.
3137193326Sedpublic:
3138198092Srdivacky
3139221345Sdim  TypedefNameDecl *getDecl() const { return Decl; }
3140198092Srdivacky
3141198092Srdivacky  bool isSugared() const { return true; }
3142198092Srdivacky  QualType desugar() const;
3143198092Srdivacky
3144193326Sed  static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
3145193326Sed};
3146193326Sed
3147193326Sed/// TypeOfExprType (GCC extension).
3148193326Sedclass TypeOfExprType : public Type {
3149193326Sed  Expr *TOExpr;
3150198092Srdivacky
3151198092Srdivackyprotected:
3152198092Srdivacky  TypeOfExprType(Expr *E, QualType can = QualType());
3153193326Sed  friend class ASTContext;  // ASTContext creates these.
3154193326Sedpublic:
3155193326Sed  Expr *getUnderlyingExpr() const { return TOExpr; }
3156193326Sed
3157198092Srdivacky  /// \brief Remove a single level of sugar.
3158198092Srdivacky  QualType desugar() const;
3159198092Srdivacky
3160198092Srdivacky  /// \brief Returns whether this type directly provides sugar.
3161224145Sdim  bool isSugared() const;
3162198092Srdivacky
3163193326Sed  static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
3164193326Sed};
3165193326Sed
3166203955Srdivacky/// \brief Internal representation of canonical, dependent
3167198092Srdivacky/// typeof(expr) types.
3168203955Srdivacky///
3169203955Srdivacky/// This class is used internally by the ASTContext to manage
3170203955Srdivacky/// canonical, dependent types, only. Clients will only see instances
3171203955Srdivacky/// of this class via TypeOfExprType nodes.
3172198092Srdivackyclass DependentTypeOfExprType
3173198092Srdivacky  : public TypeOfExprType, public llvm::FoldingSetNode {
3174218893Sdim  const ASTContext &Context;
3175198092Srdivacky
3176198092Srdivackypublic:
3177218893Sdim  DependentTypeOfExprType(const ASTContext &Context, Expr *E)
3178198092Srdivacky    : TypeOfExprType(E), Context(Context) { }
3179198092Srdivacky
3180198092Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) {
3181198092Srdivacky    Profile(ID, Context, getUnderlyingExpr());
3182198092Srdivacky  }
3183198092Srdivacky
3184218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3185198092Srdivacky                      Expr *E);
3186198092Srdivacky};
3187198092Srdivacky
3188193326Sed/// TypeOfType (GCC extension).
3189193326Sedclass TypeOfType : public Type {
3190193326Sed  QualType TOType;
3191198092Srdivacky  TypeOfType(QualType T, QualType can)
3192234353Sdim    : Type(TypeOf, can, T->isDependentType(),
3193224145Sdim           T->isInstantiationDependentType(),
3194234353Sdim           T->isVariablyModifiedType(),
3195234353Sdim           T->containsUnexpandedParameterPack()),
3196218893Sdim      TOType(T) {
3197193326Sed    assert(!isa<TypedefType>(can) && "Invalid canonical type");
3198193326Sed  }
3199193326Sed  friend class ASTContext;  // ASTContext creates these.
3200193326Sedpublic:
3201193326Sed  QualType getUnderlyingType() const { return TOType; }
3202193326Sed
3203198092Srdivacky  /// \brief Remove a single level of sugar.
3204198092Srdivacky  QualType desugar() const { return getUnderlyingType(); }
3205198092Srdivacky
3206198092Srdivacky  /// \brief Returns whether this type directly provides sugar.
3207198092Srdivacky  bool isSugared() const { return true; }
3208198092Srdivacky
3209193326Sed  static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
3210193326Sed};
3211193326Sed
3212195099Sed/// DecltypeType (C++0x)
3213195099Sedclass DecltypeType : public Type {
3214195099Sed  Expr *E;
3215198092Srdivacky  QualType UnderlyingType;
3216198092Srdivacky
3217198092Srdivackyprotected:
3218198092Srdivacky  DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
3219195099Sed  friend class ASTContext;  // ASTContext creates these.
3220195099Sedpublic:
3221195099Sed  Expr *getUnderlyingExpr() const { return E; }
3222198092Srdivacky  QualType getUnderlyingType() const { return UnderlyingType; }
3223198092Srdivacky
3224198092Srdivacky  /// \brief Remove a single level of sugar.
3225224145Sdim  QualType desugar() const;
3226198092Srdivacky
3227198092Srdivacky  /// \brief Returns whether this type directly provides sugar.
3228224145Sdim  bool isSugared() const;
3229198092Srdivacky
3230195099Sed  static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
3231195099Sed};
3232198092Srdivacky
3233203955Srdivacky/// \brief Internal representation of canonical, dependent
3234203955Srdivacky/// decltype(expr) types.
3235203955Srdivacky///
3236203955Srdivacky/// This class is used internally by the ASTContext to manage
3237203955Srdivacky/// canonical, dependent types, only. Clients will only see instances
3238203955Srdivacky/// of this class via DecltypeType nodes.
3239198092Srdivackyclass DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
3240218893Sdim  const ASTContext &Context;
3241198092Srdivacky
3242198092Srdivackypublic:
3243218893Sdim  DependentDecltypeType(const ASTContext &Context, Expr *E);
3244198092Srdivacky
3245198092Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) {
3246198092Srdivacky    Profile(ID, Context, getUnderlyingExpr());
3247198092Srdivacky  }
3248198092Srdivacky
3249218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3250198092Srdivacky                      Expr *E);
3251198092Srdivacky};
3252198092Srdivacky
3253223017Sdim/// \brief A unary type transform, which is a type constructed from another
3254223017Sdimclass UnaryTransformType : public Type {
3255223017Sdimpublic:
3256223017Sdim  enum UTTKind {
3257223017Sdim    EnumUnderlyingType
3258223017Sdim  };
3259223017Sdim
3260223017Sdimprivate:
3261223017Sdim  /// The untransformed type.
3262223017Sdim  QualType BaseType;
3263223017Sdim  /// The transformed type if not dependent, otherwise the same as BaseType.
3264223017Sdim  QualType UnderlyingType;
3265223017Sdim
3266223017Sdim  UTTKind UKind;
3267223017Sdimprotected:
3268223017Sdim  UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
3269223017Sdim                     QualType CanonicalTy);
3270223017Sdim  friend class ASTContext;
3271223017Sdimpublic:
3272223017Sdim  bool isSugared() const { return !isDependentType(); }
3273223017Sdim  QualType desugar() const { return UnderlyingType; }
3274223017Sdim
3275223017Sdim  QualType getUnderlyingType() const { return UnderlyingType; }
3276223017Sdim  QualType getBaseType() const { return BaseType; }
3277223017Sdim
3278223017Sdim  UTTKind getUTTKind() const { return UKind; }
3279234353Sdim
3280223017Sdim  static bool classof(const Type *T) {
3281223017Sdim    return T->getTypeClass() == UnaryTransform;
3282223017Sdim  }
3283223017Sdim};
3284223017Sdim
3285193326Sedclass TagType : public Type {
3286212904Sdim  /// Stores the TagDecl associated with this type. The decl may point to any
3287212904Sdim  /// TagDecl that declares the entity.
3288212904Sdim  TagDecl * decl;
3289193326Sed
3290234353Sdim  friend class ASTReader;
3291234353Sdim
3292193326Sedprotected:
3293203955Srdivacky  TagType(TypeClass TC, const TagDecl *D, QualType can);
3294193326Sed
3295198092Srdivackypublic:
3296212904Sdim  TagDecl *getDecl() const;
3297198092Srdivacky
3298193326Sed  /// @brief Determines whether this type is in the process of being
3299198092Srdivacky  /// defined.
3300212904Sdim  bool isBeingDefined() const;
3301193326Sed
3302198092Srdivacky  static bool classof(const Type *T) {
3303193326Sed    return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
3304193326Sed  }
3305193326Sed};
3306193326Sed
3307193326Sed/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
3308193326Sed/// to detect TagType objects of structs/unions/classes.
3309193326Sedclass RecordType : public TagType {
3310193326Sedprotected:
3311203955Srdivacky  explicit RecordType(const RecordDecl *D)
3312203955Srdivacky    : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
3313193326Sed  explicit RecordType(TypeClass TC, RecordDecl *D)
3314203955Srdivacky    : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
3315193326Sed  friend class ASTContext;   // ASTContext creates these.
3316193326Sedpublic:
3317198092Srdivacky
3318193326Sed  RecordDecl *getDecl() const {
3319193326Sed    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
3320193326Sed  }
3321198092Srdivacky
3322198092Srdivacky  // FIXME: This predicate is a helper to QualType/Type. It needs to
3323193326Sed  // recursively check all fields for const-ness. If any field is declared
3324198092Srdivacky  // const, it needs to return false.
3325193326Sed  bool hasConstFields() const { return false; }
3326193326Sed
3327198092Srdivacky  bool isSugared() const { return false; }
3328198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
3329198092Srdivacky
3330234353Sdim  static bool classof(const Type *T) { return T->getTypeClass() == Record; }
3331193326Sed};
3332193326Sed
3333193326Sed/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
3334193326Sed/// to detect TagType objects of enums.
3335193326Sedclass EnumType : public TagType {
3336203955Srdivacky  explicit EnumType(const EnumDecl *D)
3337203955Srdivacky    : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
3338193326Sed  friend class ASTContext;   // ASTContext creates these.
3339193326Sedpublic:
3340198092Srdivacky
3341193326Sed  EnumDecl *getDecl() const {
3342193326Sed    return reinterpret_cast<EnumDecl*>(TagType::getDecl());
3343193326Sed  }
3344198092Srdivacky
3345198092Srdivacky  bool isSugared() const { return false; }
3346198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
3347198092Srdivacky
3348234353Sdim  static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
3349193326Sed};
3350193326Sed
3351218893Sdim/// AttributedType - An attributed type is a type to which a type
3352218893Sdim/// attribute has been applied.  The "modified type" is the
3353218893Sdim/// fully-sugared type to which the attributed type was applied;
3354218893Sdim/// generally it is not canonically equivalent to the attributed type.
3355218893Sdim/// The "equivalent type" is the minimally-desugared type which the
3356218893Sdim/// type is canonically equivalent to.
3357218893Sdim///
3358218893Sdim/// For example, in the following attributed type:
3359218893Sdim///     int32_t __attribute__((vector_size(16)))
3360218893Sdim///   - the modified type is the TypedefType for int32_t
3361218893Sdim///   - the equivalent type is VectorType(16, int32_t)
3362218893Sdim///   - the canonical type is VectorType(16, int)
3363218893Sdimclass AttributedType : public Type, public llvm::FoldingSetNode {
3364218893Sdimpublic:
3365218893Sdim  // It is really silly to have yet another attribute-kind enum, but
3366218893Sdim  // clang::attr::Kind doesn't currently cover the pure type attrs.
3367218893Sdim  enum Kind {
3368218893Sdim    // Expression operand.
3369218893Sdim    attr_address_space,
3370218893Sdim    attr_regparm,
3371218893Sdim    attr_vector_size,
3372218893Sdim    attr_neon_vector_type,
3373218893Sdim    attr_neon_polyvector_type,
3374218893Sdim
3375218893Sdim    FirstExprOperandKind = attr_address_space,
3376218893Sdim    LastExprOperandKind = attr_neon_polyvector_type,
3377218893Sdim
3378218893Sdim    // Enumerated operand (string or keyword).
3379218893Sdim    attr_objc_gc,
3380224145Sdim    attr_objc_ownership,
3381221345Sdim    attr_pcs,
3382263508Sdim    attr_pcs_vfp,
3383218893Sdim
3384218893Sdim    FirstEnumOperandKind = attr_objc_gc,
3385263508Sdim    LastEnumOperandKind = attr_pcs_vfp,
3386218893Sdim
3387218893Sdim    // No operand.
3388218893Sdim    attr_noreturn,
3389218893Sdim    attr_cdecl,
3390218893Sdim    attr_fastcall,
3391218893Sdim    attr_stdcall,
3392218893Sdim    attr_thiscall,
3393243830Sdim    attr_pascal,
3394249423Sdim    attr_pnaclcall,
3395256030Sdim    attr_inteloclbicc,
3396256030Sdim    attr_ms_abi,
3397263508Sdim    attr_sysv_abi,
3398263508Sdim    attr_ptr32,
3399263508Sdim    attr_ptr64,
3400263508Sdim    attr_sptr,
3401263508Sdim    attr_uptr
3402218893Sdim  };
3403218893Sdim
3404218893Sdimprivate:
3405218893Sdim  QualType ModifiedType;
3406218893Sdim  QualType EquivalentType;
3407218893Sdim
3408218893Sdim  friend class ASTContext; // creates these
3409218893Sdim
3410218893Sdim  AttributedType(QualType canon, Kind attrKind,
3411218893Sdim                 QualType modified, QualType equivalent)
3412218893Sdim    : Type(Attributed, canon, canon->isDependentType(),
3413224145Sdim           canon->isInstantiationDependentType(),
3414218893Sdim           canon->isVariablyModifiedType(),
3415218893Sdim           canon->containsUnexpandedParameterPack()),
3416218893Sdim      ModifiedType(modified), EquivalentType(equivalent) {
3417218893Sdim    AttributedTypeBits.AttrKind = attrKind;
3418218893Sdim  }
3419218893Sdim
3420218893Sdimpublic:
3421218893Sdim  Kind getAttrKind() const {
3422218893Sdim    return static_cast<Kind>(AttributedTypeBits.AttrKind);
3423218893Sdim  }
3424218893Sdim
3425218893Sdim  QualType getModifiedType() const { return ModifiedType; }
3426218893Sdim  QualType getEquivalentType() const { return EquivalentType; }
3427218893Sdim
3428218893Sdim  bool isSugared() const { return true; }
3429218893Sdim  QualType desugar() const { return getEquivalentType(); }
3430218893Sdim
3431263508Sdim  bool isMSTypeSpec() const;
3432263508Sdim
3433263508Sdim  bool isCallingConv() const;
3434263508Sdim
3435218893Sdim  void Profile(llvm::FoldingSetNodeID &ID) {
3436218893Sdim    Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
3437218893Sdim  }
3438218893Sdim
3439218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
3440218893Sdim                      QualType modified, QualType equivalent) {
3441218893Sdim    ID.AddInteger(attrKind);
3442218893Sdim    ID.AddPointer(modified.getAsOpaquePtr());
3443218893Sdim    ID.AddPointer(equivalent.getAsOpaquePtr());
3444218893Sdim  }
3445218893Sdim
3446218893Sdim  static bool classof(const Type *T) {
3447218893Sdim    return T->getTypeClass() == Attributed;
3448218893Sdim  }
3449218893Sdim};
3450218893Sdim
3451193326Sedclass TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
3452221345Sdim  // Helper data collector for canonical types.
3453221345Sdim  struct CanonicalTTPTInfo {
3454221345Sdim    unsigned Depth : 15;
3455221345Sdim    unsigned ParameterPack : 1;
3456221345Sdim    unsigned Index : 16;
3457221345Sdim  };
3458193326Sed
3459221345Sdim  union {
3460221345Sdim    // Info for the canonical type.
3461221345Sdim    CanonicalTTPTInfo CanTTPTInfo;
3462221345Sdim    // Info for the non-canonical type.
3463221345Sdim    TemplateTypeParmDecl *TTPDecl;
3464221345Sdim  };
3465221345Sdim
3466221345Sdim  /// Build a non-canonical type.
3467221345Sdim  TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
3468218893Sdim    : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
3469224145Sdim           /*InstantiationDependent=*/true,
3470221345Sdim           /*VariablyModified=*/false,
3471221345Sdim           Canon->containsUnexpandedParameterPack()),
3472221345Sdim      TTPDecl(TTPDecl) { }
3473193326Sed
3474221345Sdim  /// Build the canonical type.
3475198092Srdivacky  TemplateTypeParmType(unsigned D, unsigned I, bool PP)
3476234353Sdim    : Type(TemplateTypeParm, QualType(this, 0),
3477224145Sdim           /*Dependent=*/true,
3478224145Sdim           /*InstantiationDependent=*/true,
3479221345Sdim           /*VariablyModified=*/false, PP) {
3480221345Sdim    CanTTPTInfo.Depth = D;
3481221345Sdim    CanTTPTInfo.Index = I;
3482221345Sdim    CanTTPTInfo.ParameterPack = PP;
3483221345Sdim  }
3484193326Sed
3485193326Sed  friend class ASTContext;  // ASTContext creates these
3486193326Sed
3487221345Sdim  const CanonicalTTPTInfo& getCanTTPTInfo() const {
3488221345Sdim    QualType Can = getCanonicalTypeInternal();
3489221345Sdim    return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
3490221345Sdim  }
3491221345Sdim
3492193326Sedpublic:
3493221345Sdim  unsigned getDepth() const { return getCanTTPTInfo().Depth; }
3494221345Sdim  unsigned getIndex() const { return getCanTTPTInfo().Index; }
3495221345Sdim  bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
3496193326Sed
3497221345Sdim  TemplateTypeParmDecl *getDecl() const {
3498221345Sdim    return isCanonicalUnqualified() ? 0 : TTPDecl;
3499221345Sdim  }
3500221345Sdim
3501221345Sdim  IdentifierInfo *getIdentifier() const;
3502221345Sdim
3503198092Srdivacky  bool isSugared() const { return false; }
3504198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
3505198092Srdivacky
3506193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
3507221345Sdim    Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
3508193326Sed  }
3509193326Sed
3510198092Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
3511198092Srdivacky                      unsigned Index, bool ParameterPack,
3512221345Sdim                      TemplateTypeParmDecl *TTPDecl) {
3513193326Sed    ID.AddInteger(Depth);
3514193326Sed    ID.AddInteger(Index);
3515194613Sed    ID.AddBoolean(ParameterPack);
3516221345Sdim    ID.AddPointer(TTPDecl);
3517193326Sed  }
3518193326Sed
3519198092Srdivacky  static bool classof(const Type *T) {
3520198092Srdivacky    return T->getTypeClass() == TemplateTypeParm;
3521193326Sed  }
3522193326Sed};
3523193326Sed
3524198398Srdivacky/// \brief Represents the result of substituting a type for a template
3525198398Srdivacky/// type parameter.
3526198398Srdivacky///
3527198398Srdivacky/// Within an instantiated template, all template type parameters have
3528198398Srdivacky/// been replaced with these.  They are used solely to record that a
3529198398Srdivacky/// type was originally written as a template type parameter;
3530198398Srdivacky/// therefore they are never canonical.
3531198398Srdivackyclass SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
3532198398Srdivacky  // The original type parameter.
3533198398Srdivacky  const TemplateTypeParmType *Replaced;
3534198398Srdivacky
3535198398Srdivacky  SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
3536218893Sdim    : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
3537224145Sdim           Canon->isInstantiationDependentType(),
3538218893Sdim           Canon->isVariablyModifiedType(),
3539218893Sdim           Canon->containsUnexpandedParameterPack()),
3540198398Srdivacky      Replaced(Param) { }
3541198398Srdivacky
3542198398Srdivacky  friend class ASTContext;
3543198398Srdivacky
3544198398Srdivackypublic:
3545198398Srdivacky  /// Gets the template parameter that was substituted for.
3546198398Srdivacky  const TemplateTypeParmType *getReplacedParameter() const {
3547198398Srdivacky    return Replaced;
3548198398Srdivacky  }
3549198398Srdivacky
3550198398Srdivacky  /// Gets the type that was substituted for the template
3551198398Srdivacky  /// parameter.
3552198398Srdivacky  QualType getReplacementType() const {
3553198398Srdivacky    return getCanonicalTypeInternal();
3554198398Srdivacky  }
3555198398Srdivacky
3556198398Srdivacky  bool isSugared() const { return true; }
3557198398Srdivacky  QualType desugar() const { return getReplacementType(); }
3558198398Srdivacky
3559198398Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) {
3560198398Srdivacky    Profile(ID, getReplacedParameter(), getReplacementType());
3561198398Srdivacky  }
3562198398Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID,
3563198398Srdivacky                      const TemplateTypeParmType *Replaced,
3564198398Srdivacky                      QualType Replacement) {
3565198398Srdivacky    ID.AddPointer(Replaced);
3566198398Srdivacky    ID.AddPointer(Replacement.getAsOpaquePtr());
3567198398Srdivacky  }
3568198398Srdivacky
3569198398Srdivacky  static bool classof(const Type *T) {
3570198398Srdivacky    return T->getTypeClass() == SubstTemplateTypeParm;
3571198398Srdivacky  }
3572198398Srdivacky};
3573198398Srdivacky
3574218893Sdim/// \brief Represents the result of substituting a set of types for a template
3575218893Sdim/// type parameter pack.
3576218893Sdim///
3577218893Sdim/// When a pack expansion in the source code contains multiple parameter packs
3578218893Sdim/// and those parameter packs correspond to different levels of template
3579234353Sdim/// parameter lists, this type node is used to represent a template type
3580218893Sdim/// parameter pack from an outer level, which has already had its argument pack
3581218893Sdim/// substituted but that still lives within a pack expansion that itself
3582218893Sdim/// could not be instantiated. When actually performing a substitution into
3583218893Sdim/// that pack expansion (e.g., when all template parameters have corresponding
3584218893Sdim/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
3585218893Sdim/// at the current pack substitution index.
3586218893Sdimclass SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
3587218893Sdim  /// \brief The original type parameter.
3588218893Sdim  const TemplateTypeParmType *Replaced;
3589234353Sdim
3590218893Sdim  /// \brief A pointer to the set of template arguments that this
3591218893Sdim  /// parameter pack is instantiated with.
3592218893Sdim  const TemplateArgument *Arguments;
3593234353Sdim
3594218893Sdim  /// \brief The number of template arguments in \c Arguments.
3595218893Sdim  unsigned NumArguments;
3596234353Sdim
3597234353Sdim  SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
3598218893Sdim                                QualType Canon,
3599218893Sdim                                const TemplateArgument &ArgPack);
3600234353Sdim
3601218893Sdim  friend class ASTContext;
3602234353Sdim
3603218893Sdimpublic:
3604221345Sdim  IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
3605234353Sdim
3606218893Sdim  /// Gets the template parameter that was substituted for.
3607218893Sdim  const TemplateTypeParmType *getReplacedParameter() const {
3608218893Sdim    return Replaced;
3609218893Sdim  }
3610234353Sdim
3611218893Sdim  bool isSugared() const { return false; }
3612218893Sdim  QualType desugar() const { return QualType(this, 0); }
3613234353Sdim
3614218893Sdim  TemplateArgument getArgumentPack() const;
3615234353Sdim
3616218893Sdim  void Profile(llvm::FoldingSetNodeID &ID);
3617218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID,
3618218893Sdim                      const TemplateTypeParmType *Replaced,
3619218893Sdim                      const TemplateArgument &ArgPack);
3620234353Sdim
3621218893Sdim  static bool classof(const Type *T) {
3622218893Sdim    return T->getTypeClass() == SubstTemplateTypeParmPack;
3623218893Sdim  }
3624218893Sdim};
3625218893Sdim
3626251662Sdim/// \brief Represents a C++11 auto or C++1y decltype(auto) type.
3627218893Sdim///
3628251662Sdim/// These types are usually a placeholder for a deduced type. However, before
3629251662Sdim/// the initializer is attached, or if the initializer is type-dependent, there
3630251662Sdim/// is no deduced type and an auto type is canonical. In the latter case, it is
3631251662Sdim/// also a dependent type.
3632218893Sdimclass AutoType : public Type, public llvm::FoldingSetNode {
3633263508Sdim  AutoType(QualType DeducedType, bool IsDecltypeAuto,
3634263508Sdim           bool IsDependent)
3635218893Sdim    : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
3636251662Sdim           /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
3637263508Sdim           /*VariablyModified=*/false,
3638263508Sdim           /*ContainsParameterPack=*/DeducedType.isNull()
3639263508Sdim               ? false : DeducedType->containsUnexpandedParameterPack()) {
3640251662Sdim    assert((DeducedType.isNull() || !IsDependent) &&
3641251662Sdim           "auto deduced to dependent type");
3642251662Sdim    AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto;
3643218893Sdim  }
3644218893Sdim
3645218893Sdim  friend class ASTContext;  // ASTContext creates these
3646218893Sdim
3647218893Sdimpublic:
3648251662Sdim  bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; }
3649251662Sdim
3650251662Sdim  bool isSugared() const { return !isCanonicalUnqualified(); }
3651218893Sdim  QualType desugar() const { return getCanonicalTypeInternal(); }
3652218893Sdim
3653251662Sdim  /// \brief Get the type deduced for this auto type, or null if it's either
3654251662Sdim  /// not been deduced or was deduced to a dependent type.
3655218893Sdim  QualType getDeducedType() const {
3656251662Sdim    return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
3657218893Sdim  }
3658218893Sdim  bool isDeduced() const {
3659251662Sdim    return !isCanonicalUnqualified() || isDependentType();
3660218893Sdim  }
3661218893Sdim
3662218893Sdim  void Profile(llvm::FoldingSetNodeID &ID) {
3663263508Sdim    Profile(ID, getDeducedType(), isDecltypeAuto(),
3664263508Sdim		    isDependentType());
3665218893Sdim  }
3666218893Sdim
3667251662Sdim  static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
3668251662Sdim                      bool IsDecltypeAuto, bool IsDependent) {
3669218893Sdim    ID.AddPointer(Deduced.getAsOpaquePtr());
3670251662Sdim    ID.AddBoolean(IsDecltypeAuto);
3671251662Sdim    ID.AddBoolean(IsDependent);
3672218893Sdim  }
3673218893Sdim
3674218893Sdim  static bool classof(const Type *T) {
3675218893Sdim    return T->getTypeClass() == Auto;
3676218893Sdim  }
3677218893Sdim};
3678218893Sdim
3679224145Sdim/// \brief Represents a type template specialization; the template
3680224145Sdim/// must be a class template, a type alias template, or a template
3681224145Sdim/// template parameter.  A template which cannot be resolved to one of
3682224145Sdim/// these, e.g. because it is written with a dependent scope
3683224145Sdim/// specifier, is instead represented as a
3684224145Sdim/// @c DependentTemplateSpecializationType.
3685193326Sed///
3686224145Sdim/// A non-dependent template specialization type is always "sugar",
3687224145Sdim/// typically for a @c RecordType.  For example, a class template
3688224145Sdim/// specialization type of @c vector<int> will refer to a tag type for
3689224145Sdim/// the instantiation @c std::vector<int, std::allocator<int>>
3690193326Sed///
3691224145Sdim/// Template specializations are dependent if either the template or
3692224145Sdim/// any of the template arguments are dependent, in which case the
3693224145Sdim/// type may also be canonical.
3694223017Sdim///
3695224145Sdim/// Instances of this type are allocated with a trailing array of
3696224145Sdim/// TemplateArguments, followed by a QualType representing the
3697224145Sdim/// non-canonical aliased type when the template is a type alias
3698224145Sdim/// template.
3699198092Srdivackyclass TemplateSpecializationType
3700193326Sed  : public Type, public llvm::FoldingSetNode {
3701224145Sdim  /// \brief The name of the template being specialized.  This is
3702224145Sdim  /// either a TemplateName::Template (in which case it is a
3703224145Sdim  /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
3704224145Sdim  /// TypeAliasTemplateDecl*), a
3705224145Sdim  /// TemplateName::SubstTemplateTemplateParmPack, or a
3706224145Sdim  /// TemplateName::SubstTemplateTemplateParm (in which case the
3707224145Sdim  /// replacement must, recursively, be one of these).
3708193326Sed  TemplateName Template;
3709193326Sed
3710193326Sed  /// \brief - The number of template arguments named in this class
3711193326Sed  /// template specialization.
3712234353Sdim  unsigned NumArgs : 31;
3713193326Sed
3714234353Sdim  /// \brief Whether this template specialization type is a substituted
3715234353Sdim  /// type alias.
3716234353Sdim  bool TypeAlias : 1;
3717234353Sdim
3718210299Sed  TemplateSpecializationType(TemplateName T,
3719193326Sed                             const TemplateArgument *Args,
3720223017Sdim                             unsigned NumArgs, QualType Canon,
3721223017Sdim                             QualType Aliased);
3722193326Sed
3723193326Sed  friend class ASTContext;  // ASTContext creates these
3724193326Sed
3725193326Sedpublic:
3726193326Sed  /// \brief Determine whether any of the given template arguments are
3727193326Sed  /// dependent.
3728198893Srdivacky  static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
3729224145Sdim                                            unsigned NumArgs,
3730224145Sdim                                            bool &InstantiationDependent);
3731198893Srdivacky
3732224145Sdim  static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
3733224145Sdim                                            bool &InstantiationDependent);
3734199990Srdivacky
3735193326Sed  /// \brief Print a template argument list, including the '<' and '>'
3736193326Sed  /// enclosing the template arguments.
3737239462Sdim  static void PrintTemplateArgumentList(raw_ostream &OS,
3738239462Sdim                                        const TemplateArgument *Args,
3739239462Sdim                                        unsigned NumArgs,
3740239462Sdim                                        const PrintingPolicy &Policy,
3741239462Sdim                                        bool SkipBrackets = false);
3742239462Sdim
3743239462Sdim  static void PrintTemplateArgumentList(raw_ostream &OS,
3744239462Sdim                                        const TemplateArgumentLoc *Args,
3745239462Sdim                                        unsigned NumArgs,
3746239462Sdim                                        const PrintingPolicy &Policy);
3747239462Sdim
3748239462Sdim  static void PrintTemplateArgumentList(raw_ostream &OS,
3749239462Sdim                                        const TemplateArgumentListInfo &,
3750239462Sdim                                        const PrintingPolicy &Policy);
3751239462Sdim
3752207619Srdivacky  /// True if this template specialization type matches a current
3753207619Srdivacky  /// instantiation in the context in which it is found.
3754207619Srdivacky  bool isCurrentInstantiation() const {
3755210299Sed    return isa<InjectedClassNameType>(getCanonicalTypeInternal());
3756207619Srdivacky  }
3757207619Srdivacky
3758234353Sdim  /// \brief Determine if this template specialization type is for a type alias
3759234353Sdim  /// template that has been substituted.
3760234353Sdim  ///
3761234353Sdim  /// Nearly every template specialization type whose template is an alias
3762234353Sdim  /// template will be substituted. However, this is not the case when
3763234353Sdim  /// the specialization contains a pack expansion but the template alias
3764234353Sdim  /// does not have a corresponding parameter pack, e.g.,
3765234353Sdim  ///
3766234353Sdim  /// \code
3767234353Sdim  /// template<typename T, typename U, typename V> struct S;
3768234353Sdim  /// template<typename T, typename U> using A = S<T, int, U>;
3769234353Sdim  /// template<typename... Ts> struct X {
3770234353Sdim  ///   typedef A<Ts...> type; // not a type alias
3771234353Sdim  /// };
3772234353Sdim  /// \endcode
3773234353Sdim  bool isTypeAlias() const { return TypeAlias; }
3774234353Sdim
3775223017Sdim  /// Get the aliased type, if this is a specialization of a type alias
3776223017Sdim  /// template.
3777223017Sdim  QualType getAliasedType() const {
3778223017Sdim    assert(isTypeAlias() && "not a type alias template specialization");
3779223017Sdim    return *reinterpret_cast<const QualType*>(end());
3780223017Sdim  }
3781223017Sdim
3782193326Sed  typedef const TemplateArgument * iterator;
3783193326Sed
3784193326Sed  iterator begin() const { return getArgs(); }
3785210299Sed  iterator end() const; // defined inline in TemplateBase.h
3786193326Sed
3787193326Sed  /// \brief Retrieve the name of the template that we are specializing.
3788193326Sed  TemplateName getTemplateName() const { return Template; }
3789193326Sed
3790193326Sed  /// \brief Retrieve the template arguments.
3791198092Srdivacky  const TemplateArgument *getArgs() const {
3792193326Sed    return reinterpret_cast<const TemplateArgument *>(this + 1);
3793193326Sed  }
3794193326Sed
3795193326Sed  /// \brief Retrieve the number of template arguments.
3796193326Sed  unsigned getNumArgs() const { return NumArgs; }
3797193326Sed
3798193326Sed  /// \brief Retrieve a specific template argument as a type.
3799239462Sdim  /// \pre @c isArgType(Arg)
3800210299Sed  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
3801193326Sed
3802207619Srdivacky  bool isSugared() const {
3803223017Sdim    return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
3804207619Srdivacky  }
3805198092Srdivacky  QualType desugar() const { return getCanonicalTypeInternal(); }
3806198092Srdivacky
3807218893Sdim  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
3808210299Sed    Profile(ID, Template, getArgs(), NumArgs, Ctx);
3809223017Sdim    if (isTypeAlias())
3810223017Sdim      getAliasedType().Profile(ID);
3811193326Sed  }
3812193326Sed
3813193326Sed  static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
3814207619Srdivacky                      const TemplateArgument *Args,
3815207619Srdivacky                      unsigned NumArgs,
3816218893Sdim                      const ASTContext &Context);
3817193326Sed
3818198092Srdivacky  static bool classof(const Type *T) {
3819198092Srdivacky    return T->getTypeClass() == TemplateSpecialization;
3820193326Sed  }
3821193326Sed};
3822193326Sed
3823207619Srdivacky/// \brief The injected class name of a C++ class template or class
3824207619Srdivacky/// template partial specialization.  Used to record that a type was
3825207619Srdivacky/// spelled with a bare identifier rather than as a template-id; the
3826207619Srdivacky/// equivalent for non-templated classes is just RecordType.
3827204962Srdivacky///
3828207619Srdivacky/// Injected class name types are always dependent.  Template
3829207619Srdivacky/// instantiation turns these into RecordTypes.
3830204962Srdivacky///
3831207619Srdivacky/// Injected class name types are always canonical.  This works
3832207619Srdivacky/// because it is impossible to compare an injected class name type
3833207619Srdivacky/// with the corresponding non-injected template type, for the same
3834207619Srdivacky/// reason that it is impossible to directly compare template
3835207619Srdivacky/// parameters from different dependent contexts: injected class name
3836207619Srdivacky/// types can only occur within the scope of a particular templated
3837207619Srdivacky/// declaration, and within that scope every template specialization
3838207619Srdivacky/// will canonicalize to the injected class name (when appropriate
3839207619Srdivacky/// according to the rules of the language).
3840204962Srdivackyclass InjectedClassNameType : public Type {
3841204962Srdivacky  CXXRecordDecl *Decl;
3842204962Srdivacky
3843207619Srdivacky  /// The template specialization which this type represents.
3844207619Srdivacky  /// For example, in
3845207619Srdivacky  ///   template <class T> class A { ... };
3846207619Srdivacky  /// this is A<T>, whereas in
3847207619Srdivacky  ///   template <class X, class Y> class A<B<X,Y> > { ... };
3848207619Srdivacky  /// this is A<B<X,Y> >.
3849207619Srdivacky  ///
3850207619Srdivacky  /// It is always unqualified, always a template specialization type,
3851207619Srdivacky  /// and always dependent.
3852207619Srdivacky  QualType InjectedType;
3853204962Srdivacky
3854204962Srdivacky  friend class ASTContext; // ASTContext creates these.
3855212904Sdim  friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
3856212904Sdim                          // currently suitable for AST reading, too much
3857210299Sed                          // interdependencies.
3858207619Srdivacky  InjectedClassNameType(CXXRecordDecl *D, QualType TST)
3859218893Sdim    : Type(InjectedClassName, QualType(), /*Dependent=*/true,
3860224145Sdim           /*InstantiationDependent=*/true,
3861234353Sdim           /*VariablyModified=*/false,
3862218893Sdim           /*ContainsUnexpandedParameterPack=*/false),
3863207619Srdivacky      Decl(D), InjectedType(TST) {
3864204962Srdivacky    assert(isa<TemplateSpecializationType>(TST));
3865204962Srdivacky    assert(!TST.hasQualifiers());
3866207619Srdivacky    assert(TST->isDependentType());
3867204962Srdivacky  }
3868204962Srdivacky
3869204962Srdivackypublic:
3870207619Srdivacky  QualType getInjectedSpecializationType() const { return InjectedType; }
3871207619Srdivacky  const TemplateSpecializationType *getInjectedTST() const {
3872207619Srdivacky    return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
3873204962Srdivacky  }
3874204962Srdivacky
3875212904Sdim  CXXRecordDecl *getDecl() const;
3876204962Srdivacky
3877207619Srdivacky  bool isSugared() const { return false; }
3878207619Srdivacky  QualType desugar() const { return QualType(this, 0); }
3879204962Srdivacky
3880204962Srdivacky  static bool classof(const Type *T) {
3881204962Srdivacky    return T->getTypeClass() == InjectedClassName;
3882204962Srdivacky  }
3883204962Srdivacky};
3884204962Srdivacky
3885208600Srdivacky/// \brief The kind of a tag type.
3886208600Srdivackyenum TagTypeKind {
3887208600Srdivacky  /// \brief The "struct" keyword.
3888208600Srdivacky  TTK_Struct,
3889243830Sdim  /// \brief The "__interface" keyword.
3890243830Sdim  TTK_Interface,
3891208600Srdivacky  /// \brief The "union" keyword.
3892208600Srdivacky  TTK_Union,
3893208600Srdivacky  /// \brief The "class" keyword.
3894208600Srdivacky  TTK_Class,
3895208600Srdivacky  /// \brief The "enum" keyword.
3896208600Srdivacky  TTK_Enum
3897208600Srdivacky};
3898208600Srdivacky
3899206084Srdivacky/// \brief The elaboration keyword that precedes a qualified type name or
3900206084Srdivacky/// introduces an elaborated-type-specifier.
3901206084Srdivackyenum ElaboratedTypeKeyword {
3902206084Srdivacky  /// \brief The "struct" keyword introduces the elaborated-type-specifier.
3903206084Srdivacky  ETK_Struct,
3904243830Sdim  /// \brief The "__interface" keyword introduces the elaborated-type-specifier.
3905243830Sdim  ETK_Interface,
3906206084Srdivacky  /// \brief The "union" keyword introduces the elaborated-type-specifier.
3907206084Srdivacky  ETK_Union,
3908208600Srdivacky  /// \brief The "class" keyword introduces the elaborated-type-specifier.
3909208600Srdivacky  ETK_Class,
3910206084Srdivacky  /// \brief The "enum" keyword introduces the elaborated-type-specifier.
3911208600Srdivacky  ETK_Enum,
3912208600Srdivacky  /// \brief The "typename" keyword precedes the qualified type name, e.g.,
3913208600Srdivacky  /// \c typename T::type.
3914208600Srdivacky  ETK_Typename,
3915208600Srdivacky  /// \brief No keyword precedes the qualified type name.
3916208600Srdivacky  ETK_None
3917206084Srdivacky};
3918208600Srdivacky
3919208600Srdivacky/// A helper class for Type nodes having an ElaboratedTypeKeyword.
3920208600Srdivacky/// The keyword in stored in the free bits of the base class.
3921208600Srdivacky/// Also provides a few static helpers for converting and printing
3922208600Srdivacky/// elaborated type keyword and tag type kind enumerations.
3923208600Srdivackyclass TypeWithKeyword : public Type {
3924208600Srdivackyprotected:
3925208600Srdivacky  TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
3926234353Sdim                  QualType Canonical, bool Dependent,
3927234353Sdim                  bool InstantiationDependent, bool VariablyModified,
3928218893Sdim                  bool ContainsUnexpandedParameterPack)
3929234353Sdim  : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
3930218893Sdim         ContainsUnexpandedParameterPack) {
3931218893Sdim    TypeWithKeywordBits.Keyword = Keyword;
3932218893Sdim  }
3933208600Srdivacky
3934208600Srdivackypublic:
3935208600Srdivacky  ElaboratedTypeKeyword getKeyword() const {
3936218893Sdim    return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
3937208600Srdivacky  }
3938208600Srdivacky
3939208600Srdivacky  /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
3940208600Srdivacky  /// into an elaborated type keyword.
3941208600Srdivacky  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
3942208600Srdivacky
3943208600Srdivacky  /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
3944208600Srdivacky  /// into a tag type kind.  It is an error to provide a type specifier
3945208600Srdivacky  /// which *isn't* a tag kind here.
3946208600Srdivacky  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
3947208600Srdivacky
3948208600Srdivacky  /// getKeywordForTagDeclKind - Converts a TagTypeKind into an
3949208600Srdivacky  /// elaborated type keyword.
3950208600Srdivacky  static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
3951208600Srdivacky
3952208600Srdivacky  /// getTagTypeKindForKeyword - Converts an elaborated type keyword into
3953208600Srdivacky  // a TagTypeKind. It is an error to provide an elaborated type keyword
3954208600Srdivacky  /// which *isn't* a tag kind here.
3955208600Srdivacky  static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
3956208600Srdivacky
3957208600Srdivacky  static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
3958208600Srdivacky
3959208600Srdivacky  static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
3960208600Srdivacky
3961208600Srdivacky  static const char *getTagTypeKindName(TagTypeKind Kind) {
3962208600Srdivacky    return getKeywordName(getKeywordForTagTypeKind(Kind));
3963208600Srdivacky  }
3964208600Srdivacky
3965208600Srdivacky  class CannotCastToThisType {};
3966208600Srdivacky  static CannotCastToThisType classof(const Type *);
3967208600Srdivacky};
3968208600Srdivacky
3969208600Srdivacky/// \brief Represents a type that was referred to using an elaborated type
3970208600Srdivacky/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
3971208600Srdivacky/// or both.
3972193326Sed///
3973193326Sed/// This type is used to keep track of a type name as written in the
3974208600Srdivacky/// source code, including tag keywords and any nested-name-specifiers.
3975208600Srdivacky/// The type itself is always "sugar", used to express what was written
3976208600Srdivacky/// in the source code but containing no additional semantic information.
3977208600Srdivackyclass ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
3978208600Srdivacky
3979193326Sed  /// \brief The nested name specifier containing the qualifier.
3980193326Sed  NestedNameSpecifier *NNS;
3981193326Sed
3982193326Sed  /// \brief The type that this qualified name refers to.
3983193326Sed  QualType NamedType;
3984193326Sed
3985208600Srdivacky  ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
3986208600Srdivacky                 QualType NamedType, QualType CanonType)
3987208600Srdivacky    : TypeWithKeyword(Keyword, Elaborated, CanonType,
3988218893Sdim                      NamedType->isDependentType(),
3989224145Sdim                      NamedType->isInstantiationDependentType(),
3990218893Sdim                      NamedType->isVariablyModifiedType(),
3991218893Sdim                      NamedType->containsUnexpandedParameterPack()),
3992208600Srdivacky      NNS(NNS), NamedType(NamedType) {
3993208600Srdivacky    assert(!(Keyword == ETK_None && NNS == 0) &&
3994208600Srdivacky           "ElaboratedType cannot have elaborated type keyword "
3995208600Srdivacky           "and name qualifier both null.");
3996208600Srdivacky  }
3997193326Sed
3998193326Sed  friend class ASTContext;  // ASTContext creates these
3999193326Sed
4000193326Sedpublic:
4001210299Sed  ~ElaboratedType();
4002208600Srdivacky
4003193326Sed  /// \brief Retrieve the qualification on this type.
4004193326Sed  NestedNameSpecifier *getQualifier() const { return NNS; }
4005193326Sed
4006193326Sed  /// \brief Retrieve the type named by the qualified-id.
4007193326Sed  QualType getNamedType() const { return NamedType; }
4008193326Sed
4009198092Srdivacky  /// \brief Remove a single level of sugar.
4010198092Srdivacky  QualType desugar() const { return getNamedType(); }
4011193326Sed
4012198092Srdivacky  /// \brief Returns whether this type directly provides sugar.
4013198092Srdivacky  bool isSugared() const { return true; }
4014198092Srdivacky
4015193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
4016208600Srdivacky    Profile(ID, getKeyword(), NNS, NamedType);
4017193326Sed  }
4018193326Sed
4019208600Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
4020208600Srdivacky                      NestedNameSpecifier *NNS, QualType NamedType) {
4021208600Srdivacky    ID.AddInteger(Keyword);
4022193326Sed    ID.AddPointer(NNS);
4023193326Sed    NamedType.Profile(ID);
4024193326Sed  }
4025193326Sed
4026198092Srdivacky  static bool classof(const Type *T) {
4027208600Srdivacky    return T->getTypeClass() == Elaborated;
4028193326Sed  }
4029193326Sed};
4030193326Sed
4031206084Srdivacky/// \brief Represents a qualified type name for which the type name is
4032234353Sdim/// dependent.
4033193326Sed///
4034234353Sdim/// DependentNameType represents a class of dependent types that involve a
4035234353Sdim/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent)
4036206084Srdivacky/// name of a type. The DependentNameType may start with a "typename" (for a
4037234353Sdim/// typename-specifier), "class", "struct", "union", or "enum" (for a
4038206084Srdivacky/// dependent elaborated-type-specifier), or nothing (in contexts where we
4039206084Srdivacky/// know that we must be referring to a type, e.g., in a base class specifier).
4040208600Srdivackyclass DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
4041208600Srdivacky
4042193326Sed  /// \brief The nested name specifier containing the qualifier.
4043193326Sed  NestedNameSpecifier *NNS;
4044193326Sed
4045193326Sed  /// \brief The type that this typename specifier refers to.
4046210299Sed  const IdentifierInfo *Name;
4047193326Sed
4048234353Sdim  DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
4049206084Srdivacky                    const IdentifierInfo *Name, QualType CanonType)
4050218893Sdim    : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
4051224145Sdim                      /*InstantiationDependent=*/true,
4052218893Sdim                      /*VariablyModified=*/false,
4053218893Sdim                      NNS->containsUnexpandedParameterPack()),
4054208600Srdivacky      NNS(NNS), Name(Name) {
4055198092Srdivacky    assert(NNS->isDependent() &&
4056206084Srdivacky           "DependentNameType requires a dependent nested-name-specifier");
4057193326Sed  }
4058193326Sed
4059193326Sed  friend class ASTContext;  // ASTContext creates these
4060193326Sed
4061193326Sedpublic:
4062193326Sed  /// \brief Retrieve the qualification on this type.
4063193326Sed  NestedNameSpecifier *getQualifier() const { return NNS; }
4064193326Sed
4065193326Sed  /// \brief Retrieve the type named by the typename specifier as an
4066193326Sed  /// identifier.
4067193326Sed  ///
4068193326Sed  /// This routine will return a non-NULL identifier pointer when the
4069193326Sed  /// form of the original typename was terminated by an identifier,
4070193326Sed  /// e.g., "typename T::type".
4071198092Srdivacky  const IdentifierInfo *getIdentifier() const {
4072210299Sed    return Name;
4073193326Sed  }
4074193326Sed
4075198092Srdivacky  bool isSugared() const { return false; }
4076198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
4077198092Srdivacky
4078193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
4079208600Srdivacky    Profile(ID, getKeyword(), NNS, Name);
4080193326Sed  }
4081193326Sed
4082206084Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
4083210299Sed                      NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
4084206084Srdivacky    ID.AddInteger(Keyword);
4085193326Sed    ID.AddPointer(NNS);
4086210299Sed    ID.AddPointer(Name);
4087193326Sed  }
4088193326Sed
4089198092Srdivacky  static bool classof(const Type *T) {
4090206084Srdivacky    return T->getTypeClass() == DependentName;
4091193326Sed  }
4092193326Sed};
4093193326Sed
4094210299Sed/// DependentTemplateSpecializationType - Represents a template
4095210299Sed/// specialization type whose template cannot be resolved, e.g.
4096210299Sed///   A<T>::template B<T>
4097210299Sedclass DependentTemplateSpecializationType :
4098210299Sed  public TypeWithKeyword, public llvm::FoldingSetNode {
4099210299Sed
4100210299Sed  /// \brief The nested name specifier containing the qualifier.
4101210299Sed  NestedNameSpecifier *NNS;
4102210299Sed
4103210299Sed  /// \brief The identifier of the template.
4104210299Sed  const IdentifierInfo *Name;
4105210299Sed
4106210299Sed  /// \brief - The number of template arguments named in this class
4107210299Sed  /// template specialization.
4108210299Sed  unsigned NumArgs;
4109210299Sed
4110210299Sed  const TemplateArgument *getArgBuffer() const {
4111210299Sed    return reinterpret_cast<const TemplateArgument*>(this+1);
4112210299Sed  }
4113210299Sed  TemplateArgument *getArgBuffer() {
4114210299Sed    return reinterpret_cast<TemplateArgument*>(this+1);
4115210299Sed  }
4116210299Sed
4117210299Sed  DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
4118210299Sed                                      NestedNameSpecifier *NNS,
4119210299Sed                                      const IdentifierInfo *Name,
4120210299Sed                                      unsigned NumArgs,
4121210299Sed                                      const TemplateArgument *Args,
4122210299Sed                                      QualType Canon);
4123210299Sed
4124210299Sed  friend class ASTContext;  // ASTContext creates these
4125210299Sed
4126210299Sedpublic:
4127210299Sed  NestedNameSpecifier *getQualifier() const { return NNS; }
4128210299Sed  const IdentifierInfo *getIdentifier() const { return Name; }
4129210299Sed
4130210299Sed  /// \brief Retrieve the template arguments.
4131210299Sed  const TemplateArgument *getArgs() const {
4132210299Sed    return getArgBuffer();
4133210299Sed  }
4134210299Sed
4135210299Sed  /// \brief Retrieve the number of template arguments.
4136210299Sed  unsigned getNumArgs() const { return NumArgs; }
4137210299Sed
4138210299Sed  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
4139210299Sed
4140210299Sed  typedef const TemplateArgument * iterator;
4141210299Sed  iterator begin() const { return getArgs(); }
4142210299Sed  iterator end() const; // inline in TemplateBase.h
4143210299Sed
4144210299Sed  bool isSugared() const { return false; }
4145210299Sed  QualType desugar() const { return QualType(this, 0); }
4146210299Sed
4147218893Sdim  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
4148210299Sed    Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
4149210299Sed  }
4150210299Sed
4151210299Sed  static void Profile(llvm::FoldingSetNodeID &ID,
4152218893Sdim                      const ASTContext &Context,
4153210299Sed                      ElaboratedTypeKeyword Keyword,
4154210299Sed                      NestedNameSpecifier *Qualifier,
4155210299Sed                      const IdentifierInfo *Name,
4156210299Sed                      unsigned NumArgs,
4157210299Sed                      const TemplateArgument *Args);
4158210299Sed
4159210299Sed  static bool classof(const Type *T) {
4160210299Sed    return T->getTypeClass() == DependentTemplateSpecialization;
4161210299Sed  }
4162210299Sed};
4163210299Sed
4164218893Sdim/// \brief Represents a pack expansion of types.
4165218893Sdim///
4166218893Sdim/// Pack expansions are part of C++0x variadic templates. A pack
4167218893Sdim/// expansion contains a pattern, which itself contains one or more
4168218893Sdim/// "unexpanded" parameter packs. When instantiated, a pack expansion
4169218893Sdim/// produces a series of types, each instantiated from the pattern of
4170218893Sdim/// the expansion, where the Ith instantiation of the pattern uses the
4171218893Sdim/// Ith arguments bound to each of the unexpanded parameter packs. The
4172218893Sdim/// pack expansion is considered to "expand" these unexpanded
4173218893Sdim/// parameter packs.
4174218893Sdim///
4175218893Sdim/// \code
4176218893Sdim/// template<typename ...Types> struct tuple;
4177218893Sdim///
4178234353Sdim/// template<typename ...Types>
4179218893Sdim/// struct tuple_of_references {
4180218893Sdim///   typedef tuple<Types&...> type;
4181218893Sdim/// };
4182218893Sdim/// \endcode
4183218893Sdim///
4184218893Sdim/// Here, the pack expansion \c Types&... is represented via a
4185218893Sdim/// PackExpansionType whose pattern is Types&.
4186218893Sdimclass PackExpansionType : public Type, public llvm::FoldingSetNode {
4187218893Sdim  /// \brief The pattern of the pack expansion.
4188218893Sdim  QualType Pattern;
4189218893Sdim
4190218893Sdim  /// \brief The number of expansions that this pack expansion will
4191234353Sdim  /// generate when substituted (+1), or indicates that
4192218893Sdim  ///
4193234353Sdim  /// This field will only have a non-zero value when some of the parameter
4194234353Sdim  /// packs that occur within the pattern have been substituted but others have
4195218893Sdim  /// not.
4196218893Sdim  unsigned NumExpansions;
4197234353Sdim
4198218893Sdim  PackExpansionType(QualType Pattern, QualType Canon,
4199249423Sdim                    Optional<unsigned> NumExpansions)
4200239462Sdim    : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
4201224145Sdim           /*InstantiationDependent=*/true,
4202218893Sdim           /*VariableModified=*/Pattern->isVariablyModifiedType(),
4203218893Sdim           /*ContainsUnexpandedParameterPack=*/false),
4204234353Sdim      Pattern(Pattern),
4205218893Sdim      NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
4206218893Sdim
4207218893Sdim  friend class ASTContext;  // ASTContext creates these
4208234353Sdim
4209218893Sdimpublic:
4210218893Sdim  /// \brief Retrieve the pattern of this pack expansion, which is the
4211218893Sdim  /// type that will be repeatedly instantiated when instantiating the
4212218893Sdim  /// pack expansion itself.
4213218893Sdim  QualType getPattern() const { return Pattern; }
4214218893Sdim
4215218893Sdim  /// \brief Retrieve the number of expansions that this pack expansion will
4216218893Sdim  /// generate, if known.
4217249423Sdim  Optional<unsigned> getNumExpansions() const {
4218218893Sdim    if (NumExpansions)
4219218893Sdim      return NumExpansions - 1;
4220234353Sdim
4221249423Sdim    return None;
4222218893Sdim  }
4223234353Sdim
4224263508Sdim  bool isSugared() const { return !Pattern->isDependentType(); }
4225263508Sdim  QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); }
4226218893Sdim
4227218893Sdim  void Profile(llvm::FoldingSetNodeID &ID) {
4228218893Sdim    Profile(ID, getPattern(), getNumExpansions());
4229218893Sdim  }
4230218893Sdim
4231218893Sdim  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
4232249423Sdim                      Optional<unsigned> NumExpansions) {
4233218893Sdim    ID.AddPointer(Pattern.getAsOpaquePtr());
4234249423Sdim    ID.AddBoolean(NumExpansions.hasValue());
4235218893Sdim    if (NumExpansions)
4236218893Sdim      ID.AddInteger(*NumExpansions);
4237218893Sdim  }
4238218893Sdim
4239218893Sdim  static bool classof(const Type *T) {
4240218893Sdim    return T->getTypeClass() == PackExpansion;
4241218893Sdim  }
4242218893Sdim};
4243218893Sdim
4244208600Srdivacky/// ObjCObjectType - Represents a class type in Objective C.
4245208600Srdivacky/// Every Objective C type is a combination of a base type and a
4246208600Srdivacky/// list of protocols.
4247208600Srdivacky///
4248208600Srdivacky/// Given the following declarations:
4249239462Sdim/// \code
4250239462Sdim///   \@class C;
4251239462Sdim///   \@protocol P;
4252239462Sdim/// \endcode
4253208600Srdivacky///
4254208600Srdivacky/// 'C' is an ObjCInterfaceType C.  It is sugar for an ObjCObjectType
4255208600Srdivacky/// with base C and no protocols.
4256208600Srdivacky///
4257208600Srdivacky/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].
4258208600Srdivacky///
4259263508Sdim/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose
4260208600Srdivacky/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
4261208600Srdivacky/// and no protocols.
4262208600Srdivacky///
4263263508Sdim/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
4264208600Srdivacky/// with base BuiltinType::ObjCIdType and protocol list [P].  Eventually
4265208600Srdivacky/// this should get its own sugar class to better represent the source.
4266208600Srdivackyclass ObjCObjectType : public Type {
4267218893Sdim  // ObjCObjectType.NumProtocols - the number of protocols stored
4268218893Sdim  // after the ObjCObjectPointerType node.
4269218893Sdim  //
4270218893Sdim  // These protocols are those written directly on the type.  If
4271218893Sdim  // protocol qualifiers ever become additive, the iterators will need
4272218893Sdim  // to get kindof complicated.
4273218893Sdim  //
4274218893Sdim  // In the canonical object type, these are sorted alphabetically
4275218893Sdim  // and uniqued.
4276198092Srdivacky
4277208600Srdivacky  /// Either a BuiltinType or an InterfaceType or sugar for either.
4278208600Srdivacky  QualType BaseType;
4279208600Srdivacky
4280208600Srdivacky  ObjCProtocolDecl * const *getProtocolStorage() const {
4281208600Srdivacky    return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
4282208600Srdivacky  }
4283208600Srdivacky
4284208600Srdivacky  ObjCProtocolDecl **getProtocolStorage();
4285208600Srdivacky
4286208600Srdivackyprotected:
4287234353Sdim  ObjCObjectType(QualType Canonical, QualType Base,
4288208600Srdivacky                 ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);
4289208600Srdivacky
4290208600Srdivacky  enum Nonce_ObjCInterface { Nonce_ObjCInterface };
4291208600Srdivacky  ObjCObjectType(enum Nonce_ObjCInterface)
4292224145Sdim        : Type(ObjCInterface, QualType(), false, false, false, false),
4293218893Sdim      BaseType(QualType(this_(), 0)) {
4294218893Sdim    ObjCObjectTypeBits.NumProtocols = 0;
4295218893Sdim  }
4296208600Srdivacky
4297198092Srdivackypublic:
4298208600Srdivacky  /// getBaseType - Gets the base type of this object type.  This is
4299208600Srdivacky  /// always (possibly sugar for) one of:
4300208600Srdivacky  ///  - the 'id' builtin type (as opposed to the 'id' type visible to the
4301263508Sdim  ///    user, which is a typedef for an ObjCObjectPointerType)
4302208600Srdivacky  ///  - the 'Class' builtin type (same caveat)
4303208600Srdivacky  ///  - an ObjCObjectType (currently always an ObjCInterfaceType)
4304208600Srdivacky  QualType getBaseType() const { return BaseType; }
4305202879Srdivacky
4306208600Srdivacky  bool isObjCId() const {
4307208600Srdivacky    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
4308208600Srdivacky  }
4309208600Srdivacky  bool isObjCClass() const {
4310208600Srdivacky    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
4311208600Srdivacky  }
4312208600Srdivacky  bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
4313208600Srdivacky  bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
4314208600Srdivacky  bool isObjCUnqualifiedIdOrClass() const {
4315208600Srdivacky    if (!qual_empty()) return false;
4316208600Srdivacky    if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
4317208600Srdivacky      return T->getKind() == BuiltinType::ObjCId ||
4318208600Srdivacky             T->getKind() == BuiltinType::ObjCClass;
4319208600Srdivacky    return false;
4320208600Srdivacky  }
4321208600Srdivacky  bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
4322208600Srdivacky  bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
4323198092Srdivacky
4324208600Srdivacky  /// Gets the interface declaration for this object type, if the base type
4325208600Srdivacky  /// really is an interface.
4326208600Srdivacky  ObjCInterfaceDecl *getInterface() const;
4327208600Srdivacky
4328208600Srdivacky  typedef ObjCProtocolDecl * const *qual_iterator;
4329208600Srdivacky
4330208600Srdivacky  qual_iterator qual_begin() const { return getProtocolStorage(); }
4331208600Srdivacky  qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
4332208600Srdivacky
4333208600Srdivacky  bool qual_empty() const { return getNumProtocols() == 0; }
4334208600Srdivacky
4335198092Srdivacky  /// getNumProtocols - Return the number of qualifying protocols in this
4336198092Srdivacky  /// interface type, or 0 if there are none.
4337218893Sdim  unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
4338198092Srdivacky
4339208600Srdivacky  /// \brief Fetch a protocol by index.
4340203955Srdivacky  ObjCProtocolDecl *getProtocol(unsigned I) const {
4341203955Srdivacky    assert(I < getNumProtocols() && "Out-of-range protocol access");
4342203955Srdivacky    return qual_begin()[I];
4343203955Srdivacky  }
4344234353Sdim
4345198092Srdivacky  bool isSugared() const { return false; }
4346198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
4347198092Srdivacky
4348208600Srdivacky  static bool classof(const Type *T) {
4349208600Srdivacky    return T->getTypeClass() == ObjCObject ||
4350208600Srdivacky           T->getTypeClass() == ObjCInterface;
4351208600Srdivacky  }
4352208600Srdivacky};
4353208600Srdivacky
4354208600Srdivacky/// ObjCObjectTypeImpl - A class providing a concrete implementation
4355208600Srdivacky/// of ObjCObjectType, so as to not increase the footprint of
4356208600Srdivacky/// ObjCInterfaceType.  Code outside of ASTContext and the core type
4357208600Srdivacky/// system should not reference this type.
4358208600Srdivackyclass ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
4359208600Srdivacky  friend class ASTContext;
4360208600Srdivacky
4361208600Srdivacky  // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
4362208600Srdivacky  // will need to be modified.
4363208600Srdivacky
4364234353Sdim  ObjCObjectTypeImpl(QualType Canonical, QualType Base,
4365208600Srdivacky                     ObjCProtocolDecl * const *Protocols,
4366208600Srdivacky                     unsigned NumProtocols)
4367208600Srdivacky    : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
4368208600Srdivacky
4369208600Srdivackypublic:
4370198092Srdivacky  void Profile(llvm::FoldingSetNodeID &ID);
4371198092Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID,
4372208600Srdivacky                      QualType Base,
4373234353Sdim                      ObjCProtocolDecl *const *protocols,
4374234353Sdim                      unsigned NumProtocols);
4375208600Srdivacky};
4376198092Srdivacky
4377208600Srdivackyinline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
4378208600Srdivacky  return reinterpret_cast<ObjCProtocolDecl**>(
4379208600Srdivacky            static_cast<ObjCObjectTypeImpl*>(this) + 1);
4380208600Srdivacky}
4381203955Srdivacky
4382208600Srdivacky/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
4383208600Srdivacky/// object oriented design.  They basically correspond to C++ classes.  There
4384208600Srdivacky/// are two kinds of interface types, normal interfaces like "NSString" and
4385208600Srdivacky/// qualified interfaces, which are qualified with a protocol list like
4386208600Srdivacky/// "NSString<NSCopyable, NSAmazing>".
4387208600Srdivacky///
4388208600Srdivacky/// ObjCInterfaceType guarantees the following properties when considered
4389208600Srdivacky/// as a subtype of its superclass, ObjCObjectType:
4390208600Srdivacky///   - There are no protocol qualifiers.  To reinforce this, code which
4391208600Srdivacky///     tries to invoke the protocol methods via an ObjCInterfaceType will
4392208600Srdivacky///     fail to compile.
4393208600Srdivacky///   - It is its own base type.  That is, if T is an ObjCInterfaceType*,
4394208600Srdivacky///     T->getBaseType() == QualType(T, 0).
4395208600Srdivackyclass ObjCInterfaceType : public ObjCObjectType {
4396234353Sdim  mutable ObjCInterfaceDecl *Decl;
4397208600Srdivacky
4398208600Srdivacky  ObjCInterfaceType(const ObjCInterfaceDecl *D)
4399208600Srdivacky    : ObjCObjectType(Nonce_ObjCInterface),
4400208600Srdivacky      Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
4401208600Srdivacky  friend class ASTContext;  // ASTContext creates these.
4402234353Sdim  friend class ASTReader;
4403234353Sdim  friend class ObjCInterfaceDecl;
4404218893Sdim
4405208600Srdivackypublic:
4406208600Srdivacky  /// getDecl - Get the declaration of this interface.
4407208600Srdivacky  ObjCInterfaceDecl *getDecl() const { return Decl; }
4408208600Srdivacky
4409208600Srdivacky  bool isSugared() const { return false; }
4410208600Srdivacky  QualType desugar() const { return QualType(this, 0); }
4411208600Srdivacky
4412198092Srdivacky  static bool classof(const Type *T) {
4413198092Srdivacky    return T->getTypeClass() == ObjCInterface;
4414198092Srdivacky  }
4415208600Srdivacky
4416208600Srdivacky  // Nonsense to "hide" certain members of ObjCObjectType within this
4417208600Srdivacky  // class.  People asking for protocols on an ObjCInterfaceType are
4418208600Srdivacky  // not going to get what they want: ObjCInterfaceTypes are
4419208600Srdivacky  // guaranteed to have no protocols.
4420208600Srdivacky  enum {
4421208600Srdivacky    qual_iterator,
4422208600Srdivacky    qual_begin,
4423208600Srdivacky    qual_end,
4424208600Srdivacky    getNumProtocols,
4425208600Srdivacky    getProtocol
4426208600Srdivacky  };
4427198092Srdivacky};
4428198092Srdivacky
4429208600Srdivackyinline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
4430208600Srdivacky  if (const ObjCInterfaceType *T =
4431208600Srdivacky        getBaseType()->getAs<ObjCInterfaceType>())
4432208600Srdivacky    return T->getDecl();
4433208600Srdivacky  return 0;
4434208600Srdivacky}
4435208600Srdivacky
4436208600Srdivacky/// ObjCObjectPointerType - Used to represent a pointer to an
4437208600Srdivacky/// Objective C object.  These are constructed from pointer
4438208600Srdivacky/// declarators when the pointee type is an ObjCObjectType (or sugar
4439208600Srdivacky/// for one).  In addition, the 'id' and 'Class' types are typedefs
4440208600Srdivacky/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>'
4441208600Srdivacky/// are translated into these.
4442194613Sed///
4443208600Srdivacky/// Pointers to pointers to Objective C objects are still PointerTypes;
4444208600Srdivacky/// only the first level of pointer gets it own type implementation.
4445194613Sedclass ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
4446208600Srdivacky  QualType PointeeType;
4447198092Srdivacky
4448208600Srdivacky  ObjCObjectPointerType(QualType Canonical, QualType Pointee)
4449224145Sdim    : Type(ObjCObjectPointer, Canonical, false, false, false, false),
4450208600Srdivacky      PointeeType(Pointee) {}
4451194613Sed  friend class ASTContext;  // ASTContext creates these.
4452194613Sed
4453194613Sedpublic:
4454208600Srdivacky  /// getPointeeType - Gets the type pointed to by this ObjC pointer.
4455208600Srdivacky  /// The result will always be an ObjCObjectType or sugar thereof.
4456198092Srdivacky  QualType getPointeeType() const { return PointeeType; }
4457198092Srdivacky
4458208600Srdivacky  /// getObjCObjectType - Gets the type pointed to by this ObjC
4459208600Srdivacky  /// pointer.  This method always returns non-null.
4460208600Srdivacky  ///
4461208600Srdivacky  /// This method is equivalent to getPointeeType() except that
4462208600Srdivacky  /// it discards any typedefs (or other sugar) between this
4463208600Srdivacky  /// type and the "outermost" object type.  So for:
4464239462Sdim  /// \code
4465239462Sdim  ///   \@class A; \@protocol P; \@protocol Q;
4466208600Srdivacky  ///   typedef A<P> AP;
4467208600Srdivacky  ///   typedef A A1;
4468208600Srdivacky  ///   typedef A1<P> A1P;
4469208600Srdivacky  ///   typedef A1P<Q> A1PQ;
4470239462Sdim  /// \endcode
4471208600Srdivacky  /// For 'A*', getObjectType() will return 'A'.
4472208600Srdivacky  /// For 'A<P>*', getObjectType() will return 'A<P>'.
4473208600Srdivacky  /// For 'AP*', getObjectType() will return 'A<P>'.
4474208600Srdivacky  /// For 'A1*', getObjectType() will return 'A'.
4475208600Srdivacky  /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
4476208600Srdivacky  /// For 'A1P*', getObjectType() will return 'A1<P>'.
4477208600Srdivacky  /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
4478208600Srdivacky  ///   adding protocols to a protocol-qualified base discards the
4479208600Srdivacky  ///   old qualifiers (for now).  But if it didn't, getObjectType()
4480208600Srdivacky  ///   would return 'A1P<Q>' (and we'd have to make iterating over
4481208600Srdivacky  ///   qualifiers more complicated).
4482208600Srdivacky  const ObjCObjectType *getObjectType() const {
4483218893Sdim    return PointeeType->castAs<ObjCObjectType>();
4484208600Srdivacky  }
4485208600Srdivacky
4486208600Srdivacky  /// getInterfaceType - If this pointer points to an Objective C
4487239462Sdim  /// \@interface type, gets the type for that interface.  Any protocol
4488208600Srdivacky  /// qualifiers on the interface are ignored.
4489208600Srdivacky  ///
4490208600Srdivacky  /// \return null if the base type for this pointer is 'id' or 'Class'
4491198092Srdivacky  const ObjCInterfaceType *getInterfaceType() const {
4492208600Srdivacky    return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>();
4493198092Srdivacky  }
4494208600Srdivacky
4495239462Sdim  /// getInterfaceDecl - If this pointer points to an Objective \@interface
4496208600Srdivacky  /// type, gets the declaration for that interface.
4497208600Srdivacky  ///
4498208600Srdivacky  /// \return null if the base type for this pointer is 'id' or 'Class'
4499198092Srdivacky  ObjCInterfaceDecl *getInterfaceDecl() const {
4500208600Srdivacky    return getObjectType()->getInterface();
4501198092Srdivacky  }
4502208600Srdivacky
4503208600Srdivacky  /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if
4504208600Srdivacky  /// its object type is the primitive 'id' type with no protocols.
4505198092Srdivacky  bool isObjCIdType() const {
4506208600Srdivacky    return getObjectType()->isObjCUnqualifiedId();
4507198092Srdivacky  }
4508208600Srdivacky
4509208600Srdivacky  /// isObjCClassType - True if this is equivalent to the 'Class' type,
4510208600Srdivacky  /// i.e. if its object tive is the primitive 'Class' type with no protocols.
4511198092Srdivacky  bool isObjCClassType() const {
4512208600Srdivacky    return getObjectType()->isObjCUnqualifiedClass();
4513198092Srdivacky  }
4514234353Sdim
4515208600Srdivacky  /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some
4516208600Srdivacky  /// non-empty set of protocols.
4517198092Srdivacky  bool isObjCQualifiedIdType() const {
4518208600Srdivacky    return getObjectType()->isObjCQualifiedId();
4519198092Srdivacky  }
4520208600Srdivacky
4521208600Srdivacky  /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for
4522208600Srdivacky  /// some non-empty set of protocols.
4523198092Srdivacky  bool isObjCQualifiedClassType() const {
4524208600Srdivacky    return getObjectType()->isObjCQualifiedClass();
4525198092Srdivacky  }
4526194613Sed
4527208600Srdivacky  /// An iterator over the qualifiers on the object type.  Provided
4528208600Srdivacky  /// for convenience.  This will always iterate over the full set of
4529208600Srdivacky  /// protocols on a type, not just those provided directly.
4530208600Srdivacky  typedef ObjCObjectType::qual_iterator qual_iterator;
4531208600Srdivacky
4532202879Srdivacky  qual_iterator qual_begin() const {
4533208600Srdivacky    return getObjectType()->qual_begin();
4534202879Srdivacky  }
4535208600Srdivacky  qual_iterator qual_end() const {
4536208600Srdivacky    return getObjectType()->qual_end();
4537202879Srdivacky  }
4538208600Srdivacky  bool qual_empty() const { return getObjectType()->qual_empty(); }
4539194613Sed
4540208600Srdivacky  /// getNumProtocols - Return the number of qualifying protocols on
4541208600Srdivacky  /// the object type.
4542208600Srdivacky  unsigned getNumProtocols() const {
4543208600Srdivacky    return getObjectType()->getNumProtocols();
4544208600Srdivacky  }
4545194613Sed
4546208600Srdivacky  /// \brief Retrieve a qualifying protocol by index on the object
4547208600Srdivacky  /// type.
4548203955Srdivacky  ObjCProtocolDecl *getProtocol(unsigned I) const {
4549208600Srdivacky    return getObjectType()->getProtocol(I);
4550203955Srdivacky  }
4551234353Sdim
4552198092Srdivacky  bool isSugared() const { return false; }
4553198092Srdivacky  QualType desugar() const { return QualType(this, 0); }
4554198092Srdivacky
4555208600Srdivacky  void Profile(llvm::FoldingSetNodeID &ID) {
4556208600Srdivacky    Profile(ID, getPointeeType());
4557208600Srdivacky  }
4558208600Srdivacky  static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
4559208600Srdivacky    ID.AddPointer(T.getAsOpaquePtr());
4560208600Srdivacky  }
4561198092Srdivacky  static bool classof(const Type *T) {
4562198092Srdivacky    return T->getTypeClass() == ObjCObjectPointer;
4563194613Sed  }
4564194613Sed};
4565193326Sed
4566226633Sdimclass AtomicType : public Type, public llvm::FoldingSetNode {
4567226633Sdim  QualType ValueType;
4568226633Sdim
4569226633Sdim  AtomicType(QualType ValTy, QualType Canonical)
4570226633Sdim    : Type(Atomic, Canonical, ValTy->isDependentType(),
4571226633Sdim           ValTy->isInstantiationDependentType(),
4572226633Sdim           ValTy->isVariablyModifiedType(),
4573226633Sdim           ValTy->containsUnexpandedParameterPack()),
4574226633Sdim      ValueType(ValTy) {}
4575226633Sdim  friend class ASTContext;  // ASTContext creates these.
4576226633Sdim
4577226633Sdim  public:
4578226633Sdim  /// getValueType - Gets the type contained by this atomic type, i.e.
4579226633Sdim  /// the type returned by performing an atomic load of this atomic type.
4580226633Sdim  QualType getValueType() const { return ValueType; }
4581226633Sdim
4582226633Sdim  bool isSugared() const { return false; }
4583226633Sdim  QualType desugar() const { return QualType(this, 0); }
4584226633Sdim
4585226633Sdim  void Profile(llvm::FoldingSetNodeID &ID) {
4586226633Sdim    Profile(ID, getValueType());
4587226633Sdim  }
4588226633Sdim  static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
4589226633Sdim    ID.AddPointer(T.getAsOpaquePtr());
4590226633Sdim  }
4591226633Sdim  static bool classof(const Type *T) {
4592226633Sdim    return T->getTypeClass() == Atomic;
4593226633Sdim  }
4594226633Sdim};
4595226633Sdim
4596198092Srdivacky/// A qualifier set is used to build a set of qualifiers.
4597198092Srdivackyclass QualifierCollector : public Qualifiers {
4598198092Srdivackypublic:
4599218893Sdim  QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {}
4600198092Srdivacky
4601198092Srdivacky  /// Collect any qualifiers on the given type and return an
4602218893Sdim  /// unqualified type.  The qualifiers are assumed to be consistent
4603218893Sdim  /// with those already in the type.
4604218893Sdim  const Type *strip(QualType type) {
4605218893Sdim    addFastQualifiers(type.getLocalFastQualifiers());
4606218893Sdim    if (!type.hasLocalNonFastQualifiers())
4607218893Sdim      return type.getTypePtrUnsafe();
4608234353Sdim
4609218893Sdim    const ExtQuals *extQuals = type.getExtQualsUnsafe();
4610218893Sdim    addConsistentQualifiers(extQuals->getQualifiers());
4611218893Sdim    return extQuals->getBaseType();
4612198092Srdivacky  }
4613198092Srdivacky
4614198092Srdivacky  /// Apply the collected qualifiers to the given type.
4615218893Sdim  QualType apply(const ASTContext &Context, QualType QT) const;
4616198092Srdivacky
4617198092Srdivacky  /// Apply the collected qualifiers to the given type.
4618218893Sdim  QualType apply(const ASTContext &Context, const Type* T) const;
4619198092Srdivacky};
4620198092Srdivacky
4621198092Srdivacky
4622198092Srdivacky// Inline function definitions.
4623198092Srdivacky
4624234353Sdiminline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
4625234353Sdim  SplitQualType desugar =
4626234353Sdim    Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
4627234353Sdim  desugar.Quals.addConsistentQualifiers(Quals);
4628234353Sdim  return desugar;
4629234353Sdim}
4630234353Sdim
4631218893Sdiminline const Type *QualType::getTypePtr() const {
4632218893Sdim  return getCommonPtr()->BaseType;
4633218893Sdim}
4634218893Sdim
4635218893Sdiminline const Type *QualType::getTypePtrOrNull() const {
4636218893Sdim  return (isNull() ? 0 : getCommonPtr()->BaseType);
4637218893Sdim}
4638218893Sdim
4639218893Sdiminline SplitQualType QualType::split() const {
4640218893Sdim  if (!hasLocalNonFastQualifiers())
4641218893Sdim    return SplitQualType(getTypePtrUnsafe(),
4642218893Sdim                         Qualifiers::fromFastMask(getLocalFastQualifiers()));
4643218893Sdim
4644218893Sdim  const ExtQuals *eq = getExtQualsUnsafe();
4645218893Sdim  Qualifiers qs = eq->getQualifiers();
4646218893Sdim  qs.addFastQualifiers(getLocalFastQualifiers());
4647218893Sdim  return SplitQualType(eq->getBaseType(), qs);
4648218893Sdim}
4649218893Sdim
4650218893Sdiminline Qualifiers QualType::getLocalQualifiers() const {
4651218893Sdim  Qualifiers Quals;
4652218893Sdim  if (hasLocalNonFastQualifiers())
4653218893Sdim    Quals = getExtQualsUnsafe()->getQualifiers();
4654218893Sdim  Quals.addFastQualifiers(getLocalFastQualifiers());
4655218893Sdim  return Quals;
4656218893Sdim}
4657218893Sdim
4658218893Sdiminline Qualifiers QualType::getQualifiers() const {
4659218893Sdim  Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers();
4660218893Sdim  quals.addFastQualifiers(getLocalFastQualifiers());
4661218893Sdim  return quals;
4662218893Sdim}
4663218893Sdim
4664218893Sdiminline unsigned QualType::getCVRQualifiers() const {
4665218893Sdim  unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers();
4666218893Sdim  cvr |= getLocalCVRQualifiers();
4667218893Sdim  return cvr;
4668218893Sdim}
4669218893Sdim
4670218893Sdiminline QualType QualType::getCanonicalType() const {
4671218893Sdim  QualType canon = getCommonPtr()->CanonicalType;
4672218893Sdim  return canon.withFastQualifiers(getLocalFastQualifiers());
4673218893Sdim}
4674218893Sdim
4675198398Srdivackyinline bool QualType::isCanonical() const {
4676218893Sdim  return getTypePtr()->isCanonicalUnqualified();
4677198398Srdivacky}
4678198398Srdivacky
4679198398Srdivackyinline bool QualType::isCanonicalAsParam() const {
4680218893Sdim  if (!isCanonical()) return false;
4681199482Srdivacky  if (hasLocalQualifiers()) return false;
4682234353Sdim
4683198398Srdivacky  const Type *T = getTypePtr();
4684218893Sdim  if (T->isVariablyModifiedType() && T->hasSizedVLAType())
4685218893Sdim    return false;
4686218893Sdim
4687218893Sdim  return !isa<FunctionType>(T) && !isa<ArrayType>(T);
4688198398Srdivacky}
4689198398Srdivacky
4690199482Srdivackyinline bool QualType::isConstQualified() const {
4691234353Sdim  return isLocalConstQualified() ||
4692218893Sdim         getCommonPtr()->CanonicalType.isLocalConstQualified();
4693199482Srdivacky}
4694199482Srdivacky
4695199482Srdivackyinline bool QualType::isRestrictQualified() const {
4696234353Sdim  return isLocalRestrictQualified() ||
4697218893Sdim         getCommonPtr()->CanonicalType.isLocalRestrictQualified();
4698199482Srdivacky}
4699199482Srdivacky
4700199482Srdivacky
4701199482Srdivackyinline bool QualType::isVolatileQualified() const {
4702234353Sdim  return isLocalVolatileQualified() ||
4703218893Sdim         getCommonPtr()->CanonicalType.isLocalVolatileQualified();
4704199482Srdivacky}
4705234353Sdim
4706199482Srdivackyinline bool QualType::hasQualifiers() const {
4707199482Srdivacky  return hasLocalQualifiers() ||
4708218893Sdim         getCommonPtr()->CanonicalType.hasLocalQualifiers();
4709199482Srdivacky}
4710201361Srdivacky
4711218893Sdiminline QualType QualType::getUnqualifiedType() const {
4712218893Sdim  if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
4713218893Sdim    return QualType(getTypePtr(), 0);
4714218893Sdim
4715234353Sdim  return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
4716201361Srdivacky}
4717251662Sdim
4718218893Sdiminline SplitQualType QualType::getSplitUnqualifiedType() const {
4719218893Sdim  if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
4720218893Sdim    return split();
4721218893Sdim
4722218893Sdim  return getSplitUnqualifiedTypeImpl(*this);
4723193326Sed}
4724234353Sdim
4725218893Sdiminline void QualType::removeLocalConst() {
4726218893Sdim  removeLocalFastQualifiers(Qualifiers::Const);
4727218893Sdim}
4728198092Srdivacky
4729218893Sdiminline void QualType::removeLocalRestrict() {
4730218893Sdim  removeLocalFastQualifiers(Qualifiers::Restrict);
4731193326Sed}
4732193326Sed
4733218893Sdiminline void QualType::removeLocalVolatile() {
4734218893Sdim  removeLocalFastQualifiers(Qualifiers::Volatile);
4735193326Sed}
4736193326Sed
4737218893Sdiminline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
4738198092Srdivacky  assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
4739218893Sdim  assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask);
4740193326Sed
4741198092Srdivacky  // Fast path: we don't need to touch the slow qualifiers.
4742218893Sdim  removeLocalFastQualifiers(Mask);
4743193326Sed}
4744193326Sed
4745193326Sed/// getAddressSpace - Return the address space of this type.
4746193326Sedinline unsigned QualType::getAddressSpace() const {
4747218893Sdim  return getQualifiers().getAddressSpace();
4748193326Sed}
4749251662Sdim
4750193326Sed/// getObjCGCAttr - Return the gc attribute of this type.
4751198092Srdivackyinline Qualifiers::GC QualType::getObjCGCAttr() const {
4752218893Sdim  return getQualifiers().getObjCGCAttr();
4753193326Sed}
4754198092Srdivacky
4755206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
4756206084Srdivacky  if (const PointerType *PT = t.getAs<PointerType>()) {
4757198092Srdivacky    if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
4758206084Srdivacky      return FT->getExtInfo();
4759206084Srdivacky  } else if (const FunctionType *FT = t.getAs<FunctionType>())
4760206084Srdivacky    return FT->getExtInfo();
4761198092Srdivacky
4762206084Srdivacky  return FunctionType::ExtInfo();
4763198092Srdivacky}
4764198092Srdivacky
4765206084Srdivackyinline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
4766206084Srdivacky  return getFunctionExtInfo(*t);
4767202879Srdivacky}
4768202879Srdivacky
4769193326Sed/// isMoreQualifiedThan - Determine whether this type is more
4770193326Sed/// qualified than the Other type. For example, "const volatile int"
4771193326Sed/// is more qualified than "const int", "volatile int", and
4772193326Sed/// "int". However, it is not more qualified than "const volatile
4773193326Sed/// int".
4774218893Sdiminline bool QualType::isMoreQualifiedThan(QualType other) const {
4775218893Sdim  Qualifiers myQuals = getQualifiers();
4776218893Sdim  Qualifiers otherQuals = other.getQualifiers();
4777218893Sdim  return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals));
4778193326Sed}
4779193326Sed
4780193326Sed/// isAtLeastAsQualifiedAs - Determine whether this type is at last
4781193326Sed/// as qualified as the Other type. For example, "const volatile
4782193326Sed/// int" is at least as qualified as "const int", "volatile int",
4783193326Sed/// "int", and "const volatile int".
4784218893Sdiminline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
4785218893Sdim  return getQualifiers().compatiblyIncludes(other.getQualifiers());
4786193326Sed}
4787193326Sed
4788193326Sed/// getNonReferenceType - If Type is a reference type (e.g., const
4789193326Sed/// int&), returns the type that the reference refers to ("const
4790193326Sed/// int"). Otherwise, returns the type itself. This routine is used
4791193326Sed/// throughout Sema to implement C++ 5p6:
4792193326Sed///
4793193326Sed///   If an expression initially has the type "reference to T" (8.3.2,
4794193326Sed///   8.5.3), the type is adjusted to "T" prior to any further
4795193326Sed///   analysis, the expression designates the object or function
4796193326Sed///   denoted by the reference, and the expression is an lvalue.
4797193326Sedinline QualType QualType::getNonReferenceType() const {
4798198092Srdivacky  if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>())
4799193326Sed    return RefType->getPointeeType();
4800193326Sed  else
4801193326Sed    return *this;
4802193326Sed}
4803193326Sed
4804224145Sdiminline bool QualType::isCForbiddenLValueType() const {
4805224145Sdim  return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
4806224145Sdim          getTypePtr()->isFunctionType());
4807224145Sdim}
4808224145Sdim
4809221345Sdim/// \brief Tests whether the type is categorized as a fundamental type.
4810221345Sdim///
4811221345Sdim/// \returns True for types specified in C++0x [basic.fundamental].
4812221345Sdiminline bool Type::isFundamentalType() const {
4813221345Sdim  return isVoidType() ||
4814221345Sdim         // FIXME: It's really annoying that we don't have an
4815221345Sdim         // 'isArithmeticType()' which agrees with the standard definition.
4816221345Sdim         (isArithmeticType() && !isEnumeralType());
4817221345Sdim}
4818221345Sdim
4819221345Sdim/// \brief Tests whether the type is categorized as a compound type.
4820221345Sdim///
4821221345Sdim/// \returns True for types specified in C++0x [basic.compound].
4822221345Sdiminline bool Type::isCompoundType() const {
4823221345Sdim  // C++0x [basic.compound]p1:
4824221345Sdim  //   Compound types can be constructed in the following ways:
4825221345Sdim  //    -- arrays of objects of a given type [...];
4826221345Sdim  return isArrayType() ||
4827221345Sdim  //    -- functions, which have parameters of given types [...];
4828221345Sdim         isFunctionType() ||
4829221345Sdim  //    -- pointers to void or objects or functions [...];
4830221345Sdim         isPointerType() ||
4831221345Sdim  //    -- references to objects or functions of a given type. [...]
4832221345Sdim         isReferenceType() ||
4833221345Sdim  //    -- classes containing a sequence of objects of various types, [...];
4834221345Sdim         isRecordType() ||
4835234353Sdim  //    -- unions, which are classes capable of containing objects of different
4836234353Sdim  //               types at different times;
4837221345Sdim         isUnionType() ||
4838221345Sdim  //    -- enumerations, which comprise a set of named constant values. [...];
4839221345Sdim         isEnumeralType() ||
4840221345Sdim  //    -- pointers to non-static class members, [...].
4841221345Sdim         isMemberPointerType();
4842221345Sdim}
4843221345Sdim
4844193326Sedinline bool Type::isFunctionType() const {
4845199482Srdivacky  return isa<FunctionType>(CanonicalType);
4846193326Sed}
4847193326Sedinline bool Type::isPointerType() const {
4848199482Srdivacky  return isa<PointerType>(CanonicalType);
4849193326Sed}
4850198092Srdivackyinline bool Type::isAnyPointerType() const {
4851198092Srdivacky  return isPointerType() || isObjCObjectPointerType();
4852198092Srdivacky}
4853193326Sedinline bool Type::isBlockPointerType() const {
4854199482Srdivacky  return isa<BlockPointerType>(CanonicalType);
4855193326Sed}
4856193326Sedinline bool Type::isReferenceType() const {
4857199482Srdivacky  return isa<ReferenceType>(CanonicalType);
4858193326Sed}
4859193326Sedinline bool Type::isLValueReferenceType() const {
4860199482Srdivacky  return isa<LValueReferenceType>(CanonicalType);
4861193326Sed}
4862193326Sedinline bool Type::isRValueReferenceType() const {
4863199482Srdivacky  return isa<RValueReferenceType>(CanonicalType);
4864193326Sed}
4865193326Sedinline bool Type::isFunctionPointerType() const {
4866218893Sdim  if (const PointerType *T = getAs<PointerType>())
4867193326Sed    return T->getPointeeType()->isFunctionType();
4868193326Sed  else
4869193326Sed    return false;
4870193326Sed}
4871193326Sedinline bool Type::isMemberPointerType() const {
4872199482Srdivacky  return isa<MemberPointerType>(CanonicalType);
4873193326Sed}
4874193326Sedinline bool Type::isMemberFunctionPointerType() const {
4875198092Srdivacky  if (const MemberPointerType* T = getAs<MemberPointerType>())
4876212904Sdim    return T->isMemberFunctionPointer();
4877193326Sed  else
4878193326Sed    return false;
4879193326Sed}
4880212904Sdiminline bool Type::isMemberDataPointerType() const {
4881212904Sdim  if (const MemberPointerType* T = getAs<MemberPointerType>())
4882212904Sdim    return T->isMemberDataPointer();
4883212904Sdim  else
4884212904Sdim    return false;
4885212904Sdim}
4886193326Sedinline bool Type::isArrayType() const {
4887199482Srdivacky  return isa<ArrayType>(CanonicalType);
4888193326Sed}
4889193326Sedinline bool Type::isConstantArrayType() const {
4890199482Srdivacky  return isa<ConstantArrayType>(CanonicalType);
4891193326Sed}
4892193326Sedinline bool Type::isIncompleteArrayType() const {
4893199482Srdivacky  return isa<IncompleteArrayType>(CanonicalType);
4894193326Sed}
4895193326Sedinline bool Type::isVariableArrayType() const {
4896199482Srdivacky  return isa<VariableArrayType>(CanonicalType);
4897193326Sed}
4898193326Sedinline bool Type::isDependentSizedArrayType() const {
4899199482Srdivacky  return isa<DependentSizedArrayType>(CanonicalType);
4900193326Sed}
4901218893Sdiminline bool Type::isBuiltinType() const {
4902218893Sdim  return isa<BuiltinType>(CanonicalType);
4903218893Sdim}
4904193326Sedinline bool Type::isRecordType() const {
4905199482Srdivacky  return isa<RecordType>(CanonicalType);
4906193326Sed}
4907218893Sdiminline bool Type::isEnumeralType() const {
4908218893Sdim  return isa<EnumType>(CanonicalType);
4909218893Sdim}
4910193326Sedinline bool Type::isAnyComplexType() const {
4911199482Srdivacky  return isa<ComplexType>(CanonicalType);
4912193326Sed}
4913193326Sedinline bool Type::isVectorType() const {
4914199482Srdivacky  return isa<VectorType>(CanonicalType);
4915193326Sed}
4916193326Sedinline bool Type::isExtVectorType() const {
4917199482Srdivacky  return isa<ExtVectorType>(CanonicalType);
4918193326Sed}
4919194613Sedinline bool Type::isObjCObjectPointerType() const {
4920199482Srdivacky  return isa<ObjCObjectPointerType>(CanonicalType);
4921194613Sed}
4922208600Srdivackyinline bool Type::isObjCObjectType() const {
4923208600Srdivacky  return isa<ObjCObjectType>(CanonicalType);
4924193326Sed}
4925212904Sdiminline bool Type::isObjCObjectOrInterfaceType() const {
4926234353Sdim  return isa<ObjCInterfaceType>(CanonicalType) ||
4927212904Sdim    isa<ObjCObjectType>(CanonicalType);
4928212904Sdim}
4929226633Sdiminline bool Type::isAtomicType() const {
4930226633Sdim  return isa<AtomicType>(CanonicalType);
4931226633Sdim}
4932212904Sdim
4933193326Sedinline bool Type::isObjCQualifiedIdType() const {
4934198092Srdivacky  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
4935194613Sed    return OPT->isObjCQualifiedIdType();
4936194613Sed  return false;
4937193326Sed}
4938198092Srdivackyinline bool Type::isObjCQualifiedClassType() const {
4939198092Srdivacky  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
4940198092Srdivacky    return OPT->isObjCQualifiedClassType();
4941198092Srdivacky  return false;
4942198092Srdivacky}
4943198092Srdivackyinline bool Type::isObjCIdType() const {
4944198092Srdivacky  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
4945198092Srdivacky    return OPT->isObjCIdType();
4946198092Srdivacky  return false;
4947198092Srdivacky}
4948198092Srdivackyinline bool Type::isObjCClassType() const {
4949198092Srdivacky  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
4950198092Srdivacky    return OPT->isObjCClassType();
4951198092Srdivacky  return false;
4952198092Srdivacky}
4953199990Srdivackyinline bool Type::isObjCSelType() const {
4954199990Srdivacky  if (const PointerType *OPT = getAs<PointerType>())
4955199990Srdivacky    return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
4956199990Srdivacky  return false;
4957199990Srdivacky}
4958198092Srdivackyinline bool Type::isObjCBuiltinType() const {
4959199990Srdivacky  return isObjCIdType() || isObjCClassType() || isObjCSelType();
4960198092Srdivacky}
4961249423Sdim
4962249423Sdiminline bool Type::isImage1dT() const {
4963249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLImage1d);
4964249423Sdim}
4965249423Sdim
4966249423Sdiminline bool Type::isImage1dArrayT() const {
4967249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLImage1dArray);
4968249423Sdim}
4969249423Sdim
4970249423Sdiminline bool Type::isImage1dBufferT() const {
4971249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer);
4972249423Sdim}
4973249423Sdim
4974249423Sdiminline bool Type::isImage2dT() const {
4975249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLImage2d);
4976249423Sdim}
4977249423Sdim
4978249423Sdiminline bool Type::isImage2dArrayT() const {
4979249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLImage2dArray);
4980249423Sdim}
4981249423Sdim
4982249423Sdiminline bool Type::isImage3dT() const {
4983249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLImage3d);
4984249423Sdim}
4985249423Sdim
4986249423Sdiminline bool Type::isSamplerT() const {
4987249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLSampler);
4988249423Sdim}
4989249423Sdim
4990249423Sdiminline bool Type::isEventT() const {
4991249423Sdim  return isSpecificBuiltinType(BuiltinType::OCLEvent);
4992249423Sdim}
4993249423Sdim
4994249423Sdiminline bool Type::isImageType() const {
4995249423Sdim  return isImage3dT() ||
4996249423Sdim         isImage2dT() || isImage2dArrayT() ||
4997249423Sdim         isImage1dT() || isImage1dArrayT() || isImage1dBufferT();
4998249423Sdim}
4999249423Sdim
5000249423Sdiminline bool Type::isOpenCLSpecificType() const {
5001249423Sdim  return isSamplerT() || isEventT() || isImageType();
5002249423Sdim}
5003249423Sdim
5004193326Sedinline bool Type::isTemplateTypeParmType() const {
5005199482Srdivacky  return isa<TemplateTypeParmType>(CanonicalType);
5006193326Sed}
5007193326Sed
5008193326Sedinline bool Type::isSpecificBuiltinType(unsigned K) const {
5009198092Srdivacky  if (const BuiltinType *BT = getAs<BuiltinType>())
5010193326Sed    if (BT->getKind() == (BuiltinType::Kind) K)
5011193326Sed      return true;
5012193326Sed  return false;
5013193326Sed}
5014193326Sed
5015218893Sdiminline bool Type::isPlaceholderType() const {
5016226633Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
5017218893Sdim    return BT->isPlaceholderType();
5018218893Sdim  return false;
5019218893Sdim}
5020218893Sdim
5021226633Sdiminline const BuiltinType *Type::getAsPlaceholderType() const {
5022226633Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
5023226633Sdim    if (BT->isPlaceholderType())
5024226633Sdim      return BT;
5025226633Sdim  return 0;
5026226633Sdim}
5027226633Sdim
5028221345Sdiminline bool Type::isSpecificPlaceholderType(unsigned K) const {
5029234353Sdim  assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
5030221345Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
5031221345Sdim    return (BT->getKind() == (BuiltinType::Kind) K);
5032221345Sdim  return false;
5033221345Sdim}
5034221345Sdim
5035234353Sdiminline bool Type::isNonOverloadPlaceholderType() const {
5036234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
5037234353Sdim    return BT->isNonOverloadPlaceholderType();
5038234353Sdim  return false;
5039234353Sdim}
5040234353Sdim
5041234353Sdiminline bool Type::isVoidType() const {
5042234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5043234353Sdim    return BT->getKind() == BuiltinType::Void;
5044234353Sdim  return false;
5045234353Sdim}
5046234353Sdim
5047234353Sdiminline bool Type::isHalfType() const {
5048234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5049234353Sdim    return BT->getKind() == BuiltinType::Half;
5050234353Sdim  // FIXME: Should we allow complex __fp16? Probably not.
5051234353Sdim  return false;
5052234353Sdim}
5053234353Sdim
5054234353Sdiminline bool Type::isNullPtrType() const {
5055234353Sdim  if (const BuiltinType *BT = getAs<BuiltinType>())
5056234353Sdim    return BT->getKind() == BuiltinType::NullPtr;
5057234353Sdim  return false;
5058234353Sdim}
5059234353Sdim
5060234353Sdimextern bool IsEnumDeclComplete(EnumDecl *);
5061234353Sdimextern bool IsEnumDeclScoped(EnumDecl *);
5062234353Sdim
5063234353Sdiminline bool Type::isIntegerType() const {
5064234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5065234353Sdim    return BT->getKind() >= BuiltinType::Bool &&
5066234353Sdim           BT->getKind() <= BuiltinType::Int128;
5067234353Sdim  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
5068234353Sdim    // Incomplete enum types are not treated as integer types.
5069234353Sdim    // FIXME: In C++, enum types are never integer types.
5070234353Sdim    return IsEnumDeclComplete(ET->getDecl()) &&
5071234353Sdim      !IsEnumDeclScoped(ET->getDecl());
5072234353Sdim  }
5073234353Sdim  return false;
5074234353Sdim}
5075234353Sdim
5076234353Sdiminline bool Type::isScalarType() const {
5077234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5078234353Sdim    return BT->getKind() > BuiltinType::Void &&
5079234353Sdim           BT->getKind() <= BuiltinType::NullPtr;
5080234353Sdim  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
5081234353Sdim    // Enums are scalar types, but only if they are defined.  Incomplete enums
5082234353Sdim    // are not treated as scalar types.
5083234353Sdim    return IsEnumDeclComplete(ET->getDecl());
5084234353Sdim  return isa<PointerType>(CanonicalType) ||
5085234353Sdim         isa<BlockPointerType>(CanonicalType) ||
5086234353Sdim         isa<MemberPointerType>(CanonicalType) ||
5087234353Sdim         isa<ComplexType>(CanonicalType) ||
5088234353Sdim         isa<ObjCObjectPointerType>(CanonicalType);
5089234353Sdim}
5090234353Sdim
5091234353Sdiminline bool Type::isIntegralOrEnumerationType() const {
5092234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5093234353Sdim    return BT->getKind() >= BuiltinType::Bool &&
5094234353Sdim           BT->getKind() <= BuiltinType::Int128;
5095234353Sdim
5096234353Sdim  // Check for a complete enum type; incomplete enum types are not properly an
5097234353Sdim  // enumeration type in the sense required here.
5098234353Sdim  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
5099234353Sdim    return IsEnumDeclComplete(ET->getDecl());
5100234353Sdim
5101234353Sdim  return false;
5102234353Sdim}
5103234353Sdim
5104234353Sdiminline bool Type::isBooleanType() const {
5105234353Sdim  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5106234353Sdim    return BT->getKind() == BuiltinType::Bool;
5107234353Sdim  return false;
5108234353Sdim}
5109234353Sdim
5110251662Sdiminline bool Type::isUndeducedType() const {
5111251662Sdim  const AutoType *AT = getContainedAutoType();
5112251662Sdim  return AT && !AT->isDeduced();
5113251662Sdim}
5114251662Sdim
5115193326Sed/// \brief Determines whether this is a type for which one can define
5116193326Sed/// an overloaded operator.
5117193326Sedinline bool Type::isOverloadableType() const {
5118193326Sed  return isDependentType() || isRecordType() || isEnumeralType();
5119193326Sed}
5120193326Sed
5121224145Sdim/// \brief Determines whether this type can decay to a pointer type.
5122224145Sdiminline bool Type::canDecayToPointerType() const {
5123224145Sdim  return isFunctionType() || isArrayType();
5124224145Sdim}
5125224145Sdim
5126193326Sedinline bool Type::hasPointerRepresentation() const {
5127193326Sed  return (isPointerType() || isReferenceType() || isBlockPointerType() ||
5128208600Srdivacky          isObjCObjectPointerType() || isNullPtrType());
5129193326Sed}
5130193326Sed
5131193326Sedinline bool Type::hasObjCPointerRepresentation() const {
5132208600Srdivacky  return isObjCObjectPointerType();
5133193326Sed}
5134193326Sed
5135218893Sdiminline const Type *Type::getBaseElementTypeUnsafe() const {
5136218893Sdim  const Type *type = this;
5137218893Sdim  while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe())
5138218893Sdim    type = arrayType->getElementType().getTypePtr();
5139218893Sdim  return type;
5140218893Sdim}
5141218893Sdim
5142193326Sed/// Insertion operator for diagnostics.  This allows sending QualType's into a
5143193326Sed/// diagnostic with <<.
5144193326Sedinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
5145193326Sed                                           QualType T) {
5146193326Sed  DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
5147226633Sdim                  DiagnosticsEngine::ak_qualtype);
5148193326Sed  return DB;
5149193326Sed}
5150193326Sed
5151206084Srdivacky/// Insertion operator for partial diagnostics.  This allows sending QualType's
5152206084Srdivacky/// into a diagnostic with <<.
5153206084Srdivackyinline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
5154206084Srdivacky                                           QualType T) {
5155206084Srdivacky  PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
5156226633Sdim                  DiagnosticsEngine::ak_qualtype);
5157206084Srdivacky  return PD;
5158206084Srdivacky}
5159206084Srdivacky
5160199482Srdivacky// Helper class template that is used by Type::getAs to ensure that one does
5161199482Srdivacky// not try to look through a qualified type to get to an array type.
5162199482Srdivackytemplate<typename T,
5163199482Srdivacky         bool isArrayType = (llvm::is_same<T, ArrayType>::value ||
5164199482Srdivacky                             llvm::is_base_of<ArrayType, T>::value)>
5165199482Srdivackystruct ArrayType_cannot_be_used_with_getAs { };
5166234353Sdim
5167199482Srdivackytemplate<typename T>
5168199482Srdivackystruct ArrayType_cannot_be_used_with_getAs<T, true>;
5169234353Sdim
5170239462Sdim// Member-template getAs<specific type>'.
5171198092Srdivackytemplate <typename T> const T *Type::getAs() const {
5172199482Srdivacky  ArrayType_cannot_be_used_with_getAs<T> at;
5173199482Srdivacky  (void)at;
5174234353Sdim
5175198092Srdivacky  // If this is directly a T type, return it.
5176198092Srdivacky  if (const T *Ty = dyn_cast<T>(this))
5177198092Srdivacky    return Ty;
5178198092Srdivacky
5179198092Srdivacky  // If the canonical form of this type isn't the right kind, reject it.
5180198092Srdivacky  if (!isa<T>(CanonicalType))
5181198092Srdivacky    return 0;
5182198092Srdivacky
5183198092Srdivacky  // If this is a typedef for the type, strip the typedef off without
5184198092Srdivacky  // losing all typedef information.
5185198092Srdivacky  return cast<T>(getUnqualifiedDesugaredType());
5186198092Srdivacky}
5187198092Srdivacky
5188218893Sdiminline const ArrayType *Type::getAsArrayTypeUnsafe() const {
5189218893Sdim  // If this is directly an array type, return it.
5190218893Sdim  if (const ArrayType *arr = dyn_cast<ArrayType>(this))
5191218893Sdim    return arr;
5192218893Sdim
5193218893Sdim  // If the canonical form of this type isn't the right kind, reject it.
5194218893Sdim  if (!isa<ArrayType>(CanonicalType))
5195218893Sdim    return 0;
5196218893Sdim
5197218893Sdim  // If this is a typedef for the type, strip the typedef off without
5198218893Sdim  // losing all typedef information.
5199218893Sdim  return cast<ArrayType>(getUnqualifiedDesugaredType());
5200218893Sdim}
5201218893Sdim
5202218893Sdimtemplate <typename T> const T *Type::castAs() const {
5203218893Sdim  ArrayType_cannot_be_used_with_getAs<T> at;
5204218893Sdim  (void) at;
5205218893Sdim
5206218893Sdim  assert(isa<T>(CanonicalType));
5207218893Sdim  if (const T *ty = dyn_cast<T>(this)) return ty;
5208218893Sdim  return cast<T>(getUnqualifiedDesugaredType());
5209218893Sdim}
5210218893Sdim
5211218893Sdiminline const ArrayType *Type::castAsArrayTypeUnsafe() const {
5212218893Sdim  assert(isa<ArrayType>(CanonicalType));
5213218893Sdim  if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr;
5214218893Sdim  return cast<ArrayType>(getUnqualifiedDesugaredType());
5215218893Sdim}
5216218893Sdim
5217193326Sed}  // end namespace clang
5218193326Sed
5219193326Sed#endif
5220