Type.cpp revision b197572cf1cd70a817a1f546478cb2cb9112c48e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Type.cpp - Type representation and manipulation ------------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file implements type-related functionality.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes#include "clang/AST/ASTContext.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/Type.h"
1649aa7ff1245abd03e6e998e01302df31e4c6f8f6Argyrios Kyrtzidis#include "clang/AST/DeclCXX.h"
17980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#include "clang/AST/DeclObjC.h"
18aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#include "clang/AST/DeclTemplate.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/Expr.h"
20d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor#include "clang/AST/PrettyPrinter.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringExtras.h"
22bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor#include "llvm/Support/raw_ostream.h"
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
254bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattnerbool QualType::isConstant(ASTContext &Ctx) const {
26b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes  if (isConstQualified())
27b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes    return true;
28b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes
29b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes  if (getTypePtr()->isArrayType())
30b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes    return Ctx.getAsArrayType(*this)->getElementType().isConstant(Ctx);
31b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes
32b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes  return false;
33b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes}
34b381aac9bae6d608c72267dd0ed08ec6369e94e4Nuno Lopes
35566c2ba743065ec090f5154d5c30cf593aa12a6eTed Kremenekvoid Type::Destroy(ASTContext& C) {
36566c2ba743065ec090f5154d5c30cf593aa12a6eTed Kremenek  this->~Type();
373e9704981d7691fdd44913bf1786e8d760d8a627Steve Naroff  C.Deallocate(this);
384b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek}
394b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek
407e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregorvoid ConstantArrayWithExprType::Destroy(ASTContext& C) {
417e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // FIXME: destruction of SizeExpr commented out due to resource contention.
427e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // SizeExpr->Destroy(C);
437e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // See FIXME in SemaDecl.cpp:1536: if we were able to either steal
447e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // or clone the SizeExpr there, then here we could freely delete it.
457e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // Since we do not know how to steal or clone, we keep a pointer to
467e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // a shared resource, but we cannot free it.
477e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  // (There probably is a trivial solution ... for people knowing clang!).
487e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  this->~ConstantArrayWithExprType();
497e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  C.Deallocate(this);
507e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor}
517e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor
524b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenekvoid VariableArrayType::Destroy(ASTContext& C) {
53f91f5c8a66ffd812f61819836529f8ad437f7e2bEli Friedman  if (SizeExpr)
54f91f5c8a66ffd812f61819836529f8ad437f7e2bEli Friedman    SizeExpr->Destroy(C);
55566c2ba743065ec090f5154d5c30cf593aa12a6eTed Kremenek  this->~VariableArrayType();
563e9704981d7691fdd44913bf1786e8d760d8a627Steve Naroff  C.Deallocate(this);
574b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek}
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
59898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorvoid DependentSizedArrayType::Destroy(ASTContext& C) {
60e7f38406a38f453e83000a1e52a5ec0aada66e51Argyrios Kyrtzidis  // FIXME: Resource contention like in ConstantArrayWithExprType ?
61e7f38406a38f453e83000a1e52a5ec0aada66e51Argyrios Kyrtzidis  // May crash, depending on platform or a particular build.
62e7f38406a38f453e83000a1e52a5ec0aada66e51Argyrios Kyrtzidis  // SizeExpr->Destroy(C);
63566c2ba743065ec090f5154d5c30cf593aa12a6eTed Kremenek  this->~DependentSizedArrayType();
643e9704981d7691fdd44913bf1786e8d760d8a627Steve Naroff  C.Deallocate(this);
65898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
66c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
679cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid DependentSizedExtVectorType::Destroy(ASTContext& C) {
68bd1099efde211cbb63fce3feee4ebcc6bac58781Douglas Gregor  // FIXME: Deallocate size expression, once we're cloning properly.
69bd1099efde211cbb63fce3feee4ebcc6bac58781Douglas Gregor//  if (SizeExpr)
70bd1099efde211cbb63fce3feee4ebcc6bac58781Douglas Gregor//    SizeExpr->Destroy(C);
719cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  this->~DependentSizedExtVectorType();
729cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  C.Deallocate(this);
739cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor}
749cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
75c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// getArrayElementTypeNoTypeQual - If this is an array type, return the
76c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// element type of the array, potentially with type qualifiers missing.
77c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// This method should never be used when type qualifiers are meaningful.
78c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattnerconst Type *Type::getArrayElementTypeNoTypeQual() const {
79c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // If this is directly an array type, return it.
80c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
81c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return ATy->getElementType().getTypePtr();
82c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
83c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
84c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (!isa<ArrayType>(CanonicalType)) {
85c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    // Look through type qualifiers
86c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    if (ArrayType *AT = dyn_cast<ArrayType>(CanonicalType.getUnqualifiedType()))
87c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner      return AT->getElementType().getTypePtr();
88c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return 0;
89c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  }
90c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
91c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // If this is a typedef for an array type, strip the typedef off without
92c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // losing all typedef information.
932fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ArrayType>(getDesugaredType())->getElementType().getTypePtr();
942fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner}
952fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner
962fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// getDesugaredType - Return the specified type with any "sugar" removed from
972fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// the type.  This takes off typedefs, typeof's etc.  If the outer level of
982fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// the type is already concrete, it returns it unmodified.  This is similar
992fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
1002fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
1012fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// concrete.
102969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor///
103969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// \param ForDisplay When true, the desugaring is provided for
104969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// display purposes only. In this case, we apply more heuristics to
105969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// decide whether it is worth providing a desugared form of the type
106969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// or not.
107969c689d893a248eca4f049f5b89f747e66e4bffDouglas GregorQualType QualType::getDesugaredType(bool ForDisplay) const {
108969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  return getTypePtr()->getDesugaredType(ForDisplay)
1092fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner     .getWithAdditionalQualifiers(getCVRQualifiers());
110c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
111c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
112c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// getDesugaredType - Return the specified type with any "sugar" removed from
113c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// type type.  This takes off typedefs, typeof's etc.  If the outer level of
114c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// the type is already concrete, it returns it unmodified.  This is similar
115c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
116c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// example, it return "T*" as "T*", (not as "int*"), because the pointer is
117c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// concrete.
118969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor///
119969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// \param ForDisplay When true, the desugaring is provided for
120969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// display purposes only. In this case, we apply more heuristics to
121969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// decide whether it is worth providing a desugared form of the type
122969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// or not.
123969c689d893a248eca4f049f5b89f747e66e4bffDouglas GregorQualType Type::getDesugaredType(bool ForDisplay) const {
124c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
1252fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return TDT->LookThroughTypedefs().getDesugaredType();
12672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  if (const TypeOfExprType *TOE = dyn_cast<TypeOfExprType>(this))
1272fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return TOE->getUnderlyingExpr()->getType().getDesugaredType();
128c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
1292fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return TOT->getUnderlyingType().getDesugaredType();
130563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  if (const DecltypeType *DTT = dyn_cast<DecltypeType>(this)) {
131563a03b1338d31c2462def43253a722bc885d384Anders Carlsson    if (!DTT->getUnderlyingType()->isDependentType())
132563a03b1338d31c2462def43253a722bc885d384Anders Carlsson      return DTT->getUnderlyingType().getDesugaredType();
133563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  }
1347532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  if (const TemplateSpecializationType *Spec
135c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor        = dyn_cast<TemplateSpecializationType>(this)) {
136969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor    if (ForDisplay)
137969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      return QualType(this, 0);
138969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor
139c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    QualType Canon = Spec->getCanonicalTypeInternal();
140c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (Canon->getAsTemplateSpecializationType())
141c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor      return QualType(this, 0);
142c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    return Canon->getDesugaredType();
143c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor  }
144969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  if (const QualifiedNameType *QualName  = dyn_cast<QualifiedNameType>(this)) {
145969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor    if (ForDisplay) {
146969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      // If desugaring the type that the qualified name is referring to
147969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      // produces something interesting, that's our desugared type.
148969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      QualType NamedType = QualName->getNamedType().getDesugaredType();
149969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      if (NamedType != QualName->getNamedType())
150969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor        return NamedType;
151969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor    } else
152969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      return QualName->getNamedType().getDesugaredType();
153969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  }
1545cdf82164dd7c2b2320d6735c63ace4331e0716dDouglas Gregor
155969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  return QualType(this, 0);
156c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
157c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// isVoidType - Helper method to determine if this is the 'void' type.
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isVoidType() const {
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() == BuiltinType::Void;
162f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
1634bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isVoidType();
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isObjectType() const {
168bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType) ||
169bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor      isa<IncompleteArrayType>(CanonicalType) || isVoidType())
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return false;
171f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
1724bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isObjectType();
173bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  return true;
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isDerivedType() const {
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (CanonicalType->getTypeClass()) {
178f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  case ExtQual:
179f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return cast<ExtQualType>(CanonicalType)->getBaseType()->isDerivedType();
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Pointer:
181fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  case VariableArray:
182fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  case ConstantArray:
1837e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  case ConstantArrayWithExpr:
1847e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  case ConstantArrayWithoutExpr:
185c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  case IncompleteArray:
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case FunctionProto:
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case FunctionNoProto:
1887c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  case LValueReference:
1897c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  case RValueReference:
19072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Record:
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return true;
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default:
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return false;
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
19799dc91422144483c20d1c7381bc9ac634b646b04Chris Lattnerbool Type::isClassType() const {
1986217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const RecordType *RT = getAs<RecordType>())
199f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner    return RT->getDecl()->isClass();
20099dc91422144483c20d1c7381bc9ac634b646b04Chris Lattner  return false;
20199dc91422144483c20d1c7381bc9ac634b646b04Chris Lattner}
202c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerbool Type::isStructureType() const {
2036217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const RecordType *RT = getAs<RecordType>())
204f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner    return RT->getDecl()->isStruct();
205c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  return false;
206c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner}
2077154a77e7c1f23418342d3b72836ab504aa7821eSteve Naroffbool Type::isVoidPointerType() const {
2086217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType *PT = getAs<PointerType>())
2097154a77e7c1f23418342d3b72836ab504aa7821eSteve Naroff    return PT->getPointeeType()->isVoidType();
2107154a77e7c1f23418342d3b72836ab504aa7821eSteve Naroff  return false;
2117154a77e7c1f23418342d3b72836ab504aa7821eSteve Naroff}
2127154a77e7c1f23418342d3b72836ab504aa7821eSteve Naroff
213c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerbool Type::isUnionType() const {
2146217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const RecordType *RT = getAs<RecordType>())
215f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner    return RT->getDecl()->isUnion();
216c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  return false;
217c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner}
218c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner
219c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattnerbool Type::isComplexType() const {
22002f62a9fedbc370fba081303399410a3afdde29fSteve Naroff  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
22102f62a9fedbc370fba081303399410a3afdde29fSteve Naroff    return CT->getElementType()->isFloatingType();
222f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
2234bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isComplexType();
22402f62a9fedbc370fba081303399410a3afdde29fSteve Naroff  return false;
225c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner}
226c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner
2274cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroffbool Type::isComplexIntegerType() const {
2284cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // Check for GCC complex integer extension.
2294cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
2304cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff    return CT->getElementType()->isIntegerType();
231f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
2324bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isComplexIntegerType();
2334cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  return false;
2344cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff}
2354cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff
2364cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroffconst ComplexType *Type::getAsComplexIntegerType() const {
2374cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // Are we directly a complex type?
2384cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  if (const ComplexType *CTy = dyn_cast<ComplexType>(this)) {
2394cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff    if (CTy->getElementType()->isIntegerType())
2404cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff      return CTy;
2414bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return 0;
2424cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  }
2434bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner
2442a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // If the canonical form of this type isn't what we want, reject it.
2452a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (!isa<ComplexType>(CanonicalType)) {
246f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    // Look through type qualifiers (e.g. ExtQualType's).
2472a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    if (isa<ComplexType>(CanonicalType.getUnqualifiedType()))
2482a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return CanonicalType.getUnqualifiedType()->getAsComplexIntegerType();
2494cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff    return 0;
2502a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  }
2512a18dfe292cf3c406a769c3672080970ac586345Chris Lattner
2524cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // If this is a typedef for a complex type, strip the typedef off without
2534cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // losing all typedef information.
2542fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ComplexType>(getDesugaredType());
2554cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff}
2564cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff
25777878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroffconst BuiltinType *Type::getAsBuiltinType() const {
25877878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  // If this is directly a builtin type, return it.
25977878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  if (const BuiltinType *BTy = dyn_cast<BuiltinType>(this))
26077878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff    return BTy;
261dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
262dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't a builtin type, reject it.
263ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<BuiltinType>(CanonicalType)) {
264f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    // Look through type qualifiers (e.g. ExtQualType's).
265ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<BuiltinType>(CanonicalType.getUnqualifiedType()))
266ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsBuiltinType();
267dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
268ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
269dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
27077878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  // If this is a typedef for a builtin type, strip the typedef off without
27177878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  // losing all typedef information.
2722fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<BuiltinType>(getDesugaredType());
27377878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff}
27477878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff
275c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst FunctionType *Type::getAsFunctionType() const {
2767064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is directly a function type, return it.
2777064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
2787064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    return FTy;
279ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
280dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
281ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<FunctionType>(CanonicalType)) {
282ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
283ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<FunctionType>(CanonicalType.getUnqualifiedType()))
284ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsFunctionType();
285dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
286ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
287dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
2887064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is a typedef for a function type, strip the typedef off without
2897064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // losing all typedef information.
2902fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<FunctionType>(getDesugaredType());
2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
29372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorconst FunctionNoProtoType *Type::getAsFunctionNoProtoType() const {
29472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  return dyn_cast_or_null<FunctionNoProtoType>(getAsFunctionType());
295afa74448a07a16c3146accbe0ff03e9c8b0995e5Daniel Dunbar}
296afa74448a07a16c3146accbe0ff03e9c8b0995e5Daniel Dunbar
29772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorconst FunctionProtoType *Type::getAsFunctionProtoType() const {
29872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  return dyn_cast_or_null<FunctionProtoType>(getAsFunctionType());
299b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner}
300b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner
30114108da7f7fc059772711e4ffee1322a27b152a7Steve NaroffQualType Type::getPointeeType() const {
3026217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType *PT = getAs<PointerType>())
30314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return PT->getPointeeType();
30414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
30514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return OPT->getPointeeType();
3066217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const BlockPointerType *BPT = getAs<BlockPointerType>())
30714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return BPT->getPointeeType();
30814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  return QualType();
30914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff}
310b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner
311d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman/// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length
312d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman/// array types and types that contain variable array types in their
313d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman/// declarator
314d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroffbool Type::isVariablyModifiedType() const {
315c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // A VLA is a variably modified type.
316c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (isVariableArrayType())
317d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman    return true;
318d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
319d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // An array can contain a variably modified type
320c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const Type *T = getArrayElementTypeNoTypeQual())
321c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return T->isVariablyModifiedType();
322d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
323f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // A pointer can point to a variably modified type.
324f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // Also, C++ references and member pointers can point to a variably modified
325f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // type, where VLAs appear as an extension to C++, and should be treated
326f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // correctly.
3276217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType *PT = getAs<PointerType>())
328d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman    return PT->getPointeeType()->isVariablyModifiedType();
3296217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const ReferenceType *RT = getAs<ReferenceType>())
33068694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar    return RT->getPointeeType()->isVariablyModifiedType();
3316217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const MemberPointerType *PT = getAs<MemberPointerType>())
3328edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl    return PT->getPointeeType()->isVariablyModifiedType();
333d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
334d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // A function can return a variably modified type
335d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // This one isn't completely obvious, but it follows from the
336d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // definition in C99 6.7.5p3. Because of this rule, it's
337d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // illegal to declare a function returning a variably modified type.
3382a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (const FunctionType *FT = getAsFunctionType())
339d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman    return FT->getResultType()->isVariablyModifiedType();
340d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
341d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff  return false;
342d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff}
343d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff
344c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst RecordType *Type::getAsStructureType() const {
3457064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is directly a structure type, return it.
346c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(this)) {
34739ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (RT->getDecl()->isStruct())
348c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner      return RT;
3497064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  }
350dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
351dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
352c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
35339ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (!RT->getDecl()->isStruct())
354dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner      return 0;
355dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
356dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // If this is a typedef for a structure type, strip the typedef off without
357dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // losing all typedef information.
3582fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return cast<RecordType>(getDesugaredType());
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
360ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // Look through type qualifiers
361ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
362ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    return CanonicalType.getUnqualifiedType()->getAsStructureType();
3637064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  return 0;
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
366c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst RecordType *Type::getAsUnionType() const {
3677064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is directly a union type, return it.
368c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(this)) {
36939ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (RT->getDecl()->isUnion())
370c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner      return RT;
3717064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  }
372ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
373dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
374c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
37539ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (!RT->getDecl()->isUnion())
376dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner      return 0;
377dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
378dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // If this is a typedef for a union type, strip the typedef off without
379dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // losing all typedef information.
3802fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return cast<RecordType>(getDesugaredType());
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
382ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
383ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // Look through type qualifiers
384ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
385ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    return CanonicalType.getUnqualifiedType()->getAsUnionType();
3867064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  return 0;
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
389ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedmanconst EnumType *Type::getAsEnumType() const {
390ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  // Check the canonicalized unqualified type directly; the more complex
391ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  // version is unnecessary because there isn't any typedef information
392ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  // to preserve.
393ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  return dyn_cast<EnumType>(CanonicalType.getUnqualifiedType());
394ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman}
395ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman
396c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattnerconst ComplexType *Type::getAsComplexType() const {
397c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  // Are we directly a complex type?
398c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  if (const ComplexType *CTy = dyn_cast<ComplexType>(this))
399c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner    return CTy;
400c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner
401dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
402ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<ComplexType>(CanonicalType)) {
403ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
404ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<ComplexType>(CanonicalType.getUnqualifiedType()))
405ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsComplexType();
406dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
407ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
408dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
409c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  // If this is a typedef for a complex type, strip the typedef off without
410c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  // losing all typedef information.
4112fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ComplexType>(getDesugaredType());
4127a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner}
4137a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner
414c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst VectorType *Type::getAsVectorType() const {
4157a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  // Are we directly a vector type?
4167a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  if (const VectorType *VTy = dyn_cast<VectorType>(this))
4177a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner    return VTy;
418a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
419dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
420ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<VectorType>(CanonicalType)) {
421ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
422ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<VectorType>(CanonicalType.getUnqualifiedType()))
423ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsVectorType();
424dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
425ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
426dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
427a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // If this is a typedef for a vector type, strip the typedef off without
428a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // losing all typedef information.
4292fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<VectorType>(getDesugaredType());
4307a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner}
4317a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner
432213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begemanconst ExtVectorType *Type::getAsExtVectorType() const {
4337064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // Are we directly an OpenCU vector type?
434213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  if (const ExtVectorType *VTy = dyn_cast<ExtVectorType>(this))
4357064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    return VTy;
4367064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
437dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
438213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  if (!isa<ExtVectorType>(CanonicalType)) {
439ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
440213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman    if (isa<ExtVectorType>(CanonicalType.getUnqualifiedType()))
441213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman      return CanonicalType.getUnqualifiedType()->getAsExtVectorType();
442dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
443ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
4447064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
445213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  // If this is a typedef for an extended vector type, strip the typedef off
446213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  // without losing all typedef information.
4472fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ExtVectorType>(getDesugaredType());
4487064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff}
4497064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
450368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattnerconst ObjCInterfaceType *Type::getAsObjCInterfaceType() const {
451eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // There is no sugar for ObjCInterfaceType's, just return the canonical
4522a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // type pointer if it is the right class.  There is no typedef information to
4532a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // return and these cannot be Address-space qualified.
454fb41ca86eeede2fce02933034cf8b6e5aea84b79Fariborz Jahanian  return dyn_cast<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
455368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner}
456368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner
457c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroffconst ObjCInterfaceType *Type::getAsObjCQualifiedInterfaceType() const {
458c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  // There is no sugar for ObjCInterfaceType's, just return the canonical
459c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  // type pointer if it is the right class.  There is no typedef information to
460c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  // return and these cannot be Address-space qualified.
461c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  if (const ObjCInterfaceType *OIT = getAsObjCInterfaceType())
462c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    if (OIT->getNumProtocols())
463c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff      return OIT;
464c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  return 0;
465c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff}
466c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
467c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroffbool Type::isObjCQualifiedInterfaceType() const {
468e61ad0b7063fcd97204b1cce5558685144267eb6Steve Naroff  return getAsObjCQualifiedInterfaceType() != 0;
469c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff}
470c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
471d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffconst ObjCObjectPointerType *Type::getAsObjCObjectPointerType() const {
472d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  // There is no sugar for ObjCObjectPointerType's, just return the
473d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  // canonical type pointer if it is the right class.
474d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  return dyn_cast<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
475d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff}
476d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
477d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffconst ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
478eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // There is no sugar for ObjCQualifiedIdType's, just return the canonical
479eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // type pointer if it is the right class.
480d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
481d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    if (OPT->isObjCQualifiedIdType())
482d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      return OPT;
483d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  }
484d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  return 0;
485368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner}
486368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner
48714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroffconst ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
48814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
48914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    if (OPT->getInterfaceType())
49014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      return OPT;
49114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
49214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  return 0;
49314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff}
49414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
49572c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregorconst TemplateTypeParmType *Type::getAsTemplateTypeParmType() const {
49672c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  // There is no sugar for template type parameters, so just return
49772c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  // the canonical type pointer if it is the right class.
4982a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // FIXME: can these be address-space qualified?
49972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  return dyn_cast<TemplateTypeParmType>(CanonicalType);
50072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor}
501368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner
502a91d6a6619a91d0ca7102d8ab5678d855f04d850Fariborz Jahanianconst CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const {
5036217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const PointerType *PT = getAs<PointerType>())
5046217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>())
505a91d6a6619a91d0ca7102d8ab5678d855f04d850Fariborz Jahanian      return dyn_cast<CXXRecordDecl>(RT->getDecl());
506a91d6a6619a91d0ca7102d8ab5678d855f04d850Fariborz Jahanian  return 0;
507a91d6a6619a91d0ca7102d8ab5678d855f04d850Fariborz Jahanian}
508a91d6a6619a91d0ca7102d8ab5678d855f04d850Fariborz Jahanian
5097532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregorconst TemplateSpecializationType *
5107532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorType::getAsTemplateSpecializationType() const {
51155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // There is no sugar for class template specialization types, so
51255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // just return the canonical type pointer if it is the right class.
5137532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  return dyn_cast<TemplateSpecializationType>(CanonicalType);
51455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
51555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isIntegerType() const {
5175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Bool &&
5192df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner           BT->getKind() <= BuiltinType::Int128;
5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
521834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    // Incomplete enum types are not treated as integer types.
5228e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor    // FIXME: In C++, enum types are never integer types.
523834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
5245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return true;
525f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
526f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
527c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
528c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isIntegerType();
529f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
530f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isIntegerType();
5315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
5325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
53433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanianbool Type::isIntegralType() const {
53533e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
53633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    return BT->getKind() >= BuiltinType::Bool &&
53733e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    BT->getKind() <= BuiltinType::LongLong;
53833e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
539834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
540834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner      return true;  // Complete enum types are integral.
5418e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor                    // FIXME: In C++, enum types are never integral.
542f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
543f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
544f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
545f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isIntegralType();
54633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  return false;
54733e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian}
54833e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
54913b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroffbool Type::isEnumeralType() const {
55013b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
55139ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    return TT->getDecl()->isEnum();
552f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
553f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isEnumeralType();
55413b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  return false;
55513b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff}
55613b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff
55713b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroffbool Type::isBooleanType() const {
55813b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
55913b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff    return BT->getKind() == BuiltinType::Bool;
560f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
561f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isBooleanType();
56213b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  return false;
56313b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff}
56413b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff
56513b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroffbool Type::isCharType() const {
56613b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
56713b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff    return BT->getKind() == BuiltinType::Char_U ||
56813b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff           BT->getKind() == BuiltinType::UChar ||
569c67ad5f299bb2c09e4567def8ff0d34bd15a42fdAnders Carlsson           BT->getKind() == BuiltinType::Char_S ||
570c67ad5f299bb2c09e4567def8ff0d34bd15a42fdAnders Carlsson           BT->getKind() == BuiltinType::SChar;
571f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
572f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isCharType();
57313b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  return false;
57413b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff}
57513b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff
57677a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregorbool Type::isWideCharType() const {
57777a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
57877a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor    return BT->getKind() == BuiltinType::WChar;
579f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
580f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isWideCharType();
58177a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor  return false;
58277a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor}
58377a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor
584d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// isSignedIntegerType - Return true if this is an integer type that is
585d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
586d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// an enum decl which has a signed representation, or a vector of signed
587d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// integer element type.
5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isSignedIntegerType() const {
5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Char_S &&
5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongLong;
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
593d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
59437c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
59537c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    return ET->getDecl()->getIntegerType()->isSignedIntegerType();
596d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
597f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (const FixedWidthIntType *FWIT =
598f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman          dyn_cast<FixedWidthIntType>(CanonicalType))
599f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return FWIT->isSigned();
600f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
601c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
602c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isSignedIntegerType();
603f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
604f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isSignedIntegerType();
6055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
608d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// isUnsignedIntegerType - Return true if this is an integer type that is
609d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
610d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// decl which has an unsigned representation, or a vector of unsigned integer
611d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// element type.
6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isUnsignedIntegerType() const {
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Bool &&
6155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::ULongLong;
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
617d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
61837c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
61937c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
620d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
621f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (const FixedWidthIntType *FWIT =
622f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman          dyn_cast<FixedWidthIntType>(CanonicalType))
623f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return !FWIT->isSigned();
624f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
625c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
626c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isUnsignedIntegerType();
627f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
628f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isUnsignedIntegerType();
6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isFloatingType() const {
6335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
6345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Float &&
6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongDouble;
6365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
637729a2131228cb7fcbc00bd8af36bc6f14d12317dChris Lattner    return CT->getElementType()->isFloatingType();
638c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
639c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isFloatingType();
640f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
641f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isFloatingType();
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isRealFloatingType() const {
6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
6475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Float &&
6485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongDouble;
649c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
650c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isRealFloatingType();
651f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
652f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isRealFloatingType();
6535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isRealType() const {
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Bool &&
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongDouble;
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
661834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition();
662f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
663f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
664c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
665c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isRealType();
666f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
667f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isRealType();
6685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isArithmeticType() const {
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
673a7fbf7282eadebaf1293d9f970b01fb57f4b0ae4Douglas Gregor    return BT->getKind() >= BuiltinType::Bool &&
674a7fbf7282eadebaf1293d9f970b01fb57f4b0ae4Douglas Gregor           BT->getKind() <= BuiltinType::LongDouble;
67537c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
67637c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
67737c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    // If a body isn't seen by the time we get here, return false.
67837c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    return ET->getDecl()->isDefinition();
679f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
680f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
681f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
682f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isArithmeticType();
6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
6845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isScalarType() const {
6875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
6885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() != BuiltinType::Void;
6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
690834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    // Enums are scalar types, but only if they are defined.  Incomplete enums
691834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    // are not treated as scalar types.
692834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return true;
6945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return false;
6955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
696f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
697f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isScalarType();
698f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
699f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
7005618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  return isa<PointerType>(CanonicalType) ||
7015618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff         isa<BlockPointerType>(CanonicalType) ||
702f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl         isa<MemberPointerType>(CanonicalType) ||
7035618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff         isa<ComplexType>(CanonicalType) ||
704d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff         isa<ObjCObjectPointerType>(CanonicalType);
7055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
707d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// \brief Determines whether the type is a C++ aggregate type or C
708d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// aggregate or union type.
709d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor///
710d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// An aggregate type is an array or a class type (struct, union, or
711d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// class) that has no user-declared constructors, no private or
712d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// protected non-static data members, no base classes, and no virtual
713d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type
714d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// subsumes the notion of C aggregates (C99 6.2.5p21) because it also
715d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// includes union types.
7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isAggregateType() const {
717c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor  if (const RecordType *Record = dyn_cast<RecordType>(CanonicalType)) {
718c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor    if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl()))
719c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor      return ClassDecl->isAggregate();
720c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor
721d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor    return true;
722c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor  }
723c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor
724f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
725f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isAggregateType();
726c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  return isa<ArrayType>(CanonicalType);
7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7299bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner/// isConstantSizeType - Return true if this is not a variable sized type,
7309bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner/// according to the rules of C99 6.7.5p3.  It is not legal to call this on
731898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// incomplete types or dependent types.
7323c2b3170041f69a92904e3bab9b6d654eaf260acEli Friedmanbool Type::isConstantSizeType() const {
733f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
734f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isConstantSizeType();
735d52a4578144ab2887912e52eabec58a857a44adbChris Lattner  assert(!isIncompleteType() && "This doesn't make sense for incomplete types");
736898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  assert(!isDependentType() && "This doesn't make sense for dependent types");
7379bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner  // The VAT must have a size, as it is known to be complete.
7389bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner  return !isa<VariableArrayType>(CanonicalType);
7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// - a type that can describe objects, but which lacks information needed to
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// determine its size.
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isIncompleteType() const {
7455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (CanonicalType->getTypeClass()) {
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default: return false;
747f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  case ExtQual:
748f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return cast<ExtQualType>(CanonicalType)->getBaseType()->isIncompleteType();
7495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Builtin:
7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Void is the only incomplete builtin type.  Per C99 6.2.5p19, it can never
7515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // be completed.
7525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return isVoidType();
75372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Record:
75472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Enum:
7555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // A tagged type (struct/union/enum/class) is incomplete if the decl is a
7565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // forward declaration, but not a full definition (C99 6.2.5p22).
7575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
758c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  case IncompleteArray:
7595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // An array of unknown size is an incomplete type (C99 6.2.5p22).
760c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    return true;
7611efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner  case ObjCInterface:
7621efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner    // ObjC interfaces are incomplete if they are @class, not @interface.
7631efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner    return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl();
7645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
76764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10)
76864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redlbool Type::isPODType() const {
76964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  // The compiler shouldn't query this for incomplete types, but the user might.
77064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  // We return false for that case.
77164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  if (isIncompleteType())
77264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return false;
77364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
77464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  switch (CanonicalType->getTypeClass()) {
77564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    // Everything not explicitly mentioned is not POD.
77664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  default: return false;
777f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  case ExtQual:
778f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return cast<ExtQualType>(CanonicalType)->getBaseType()->isPODType();
77964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case VariableArray:
78064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case ConstantArray:
78164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    // IncompleteArray is caught by isIncompleteType() above.
78264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return cast<ArrayType>(CanonicalType)->getElementType()->isPODType();
78364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
78464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Builtin:
78564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Complex:
78664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Pointer:
787f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  case MemberPointer:
78864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Vector:
78964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case ExtVector:
790d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  case ObjCObjectPointer:
79164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return true;
79264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
79372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Enum:
79472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return true;
79572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor
79672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Record:
797c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor    if (CXXRecordDecl *ClassDecl
798c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor          = dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl()))
799c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor      return ClassDecl->isPOD();
800c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor
80164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    // C struct/union is POD.
80264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return true;
80364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  }
80464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl}
80564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
8065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isPromotableIntegerType() const {
8072a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (const BuiltinType *BT = getAsBuiltinType())
8082a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    switch (BT->getKind()) {
8092a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Bool:
8102a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Char_S:
8112a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Char_U:
8122a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::SChar:
8132a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::UChar:
8142a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Short:
8152a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::UShort:
8162a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return true;
8172a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    default:
8182a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return false;
8192a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    }
8202a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  return false;
8215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8236e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redlbool Type::isNullPtrType() const {
8246e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  if (const BuiltinType *BT = getAsBuiltinType())
8256e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl    return BT->getKind() == BuiltinType::NullPtr;
8266e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  return false;
8276e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl}
8286e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl
82922b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedmanbool Type::isSpecifierType() const {
83022b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  // Note that this intentionally does not use the canonical type.
83122b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  switch (getTypeClass()) {
83222b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Builtin:
83322b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Record:
83422b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Enum:
83522b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Typedef:
836c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case Complex:
837c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TypeOfExpr:
838c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TypeOf:
839c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TemplateTypeParm:
840c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TemplateSpecialization:
841c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case QualifiedName:
842c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case Typename:
843c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case ObjCInterface:
844d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  case ObjCObjectPointer:
84522b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    return true;
84622b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  default:
84722b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    return false;
84822b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  }
84922b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman}
85022b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
851e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerconst char *BuiltinType::getName(const LangOptions &LO) const {
8525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (getKind()) {
8535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default: assert(0 && "Unknown builtin type!");
8545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Void:              return "void";
855e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  case Bool:              return LO.Bool ? "bool" : "_Bool";
8565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Char_S:            return "char";
8575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Char_U:            return "char";
8585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case SChar:             return "signed char";
8595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Short:             return "short";
8605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Int:               return "int";
8615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Long:              return "long";
8625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case LongLong:          return "long long";
8632df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner  case Int128:            return "__int128_t";
8645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case UChar:             return "unsigned char";
8655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case UShort:            return "unsigned short";
8665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case UInt:              return "unsigned int";
8675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ULong:             return "unsigned long";
8685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ULongLong:         return "unsigned long long";
8692df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner  case UInt128:           return "__uint128_t";
8705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Float:             return "float";
8715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Double:            return "double";
8725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case LongDouble:        return "long double";
87346713efe13c89f4ec9cd9546c7b598fe7186089bArgyrios Kyrtzidis  case WChar:             return "wchar_t";
874f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith  case Char16:            return "char16_t";
875f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith  case Char32:            return "char32_t";
8766e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  case NullPtr:           return "nullptr_t";
8778e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  case Overload:          return "<overloaded function type>";
878898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  case Dependent:         return "<dependent type>";
8796a75cd9c1d54625fca7b5477ab9545bcdbd85ea4Anders Carlsson  case UndeducedAuto:     return "auto";
880de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  case ObjCId:            return "id";
881de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  case ObjCClass:         return "Class";
8825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
88572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorvoid FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
886942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner                                arg_type_iterator ArgTys,
887971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis                                unsigned NumArgs, bool isVariadic,
888465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                                unsigned TypeQuals, bool hasExceptionSpec,
889465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                                bool anyExceptionSpec, unsigned NumExceptions,
8902455636163fdd18581d7fdae816433f886d88213Mike Stump                                exception_iterator Exs, bool NoReturn) {
8915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ID.AddPointer(Result.getAsOpaquePtr());
8925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0; i != NumArgs; ++i)
8935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ArgTys[i].getAsOpaquePtr());
8945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ID.AddInteger(isVariadic);
895971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  ID.AddInteger(TypeQuals);
896465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  ID.AddInteger(hasExceptionSpec);
897465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  if (hasExceptionSpec) {
898465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    ID.AddInteger(anyExceptionSpec);
899465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    for(unsigned i = 0; i != NumExceptions; ++i)
900465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      ID.AddPointer(Exs[i].getAsOpaquePtr());
901465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  }
9022455636163fdd18581d7fdae816433f886d88213Mike Stump  ID.AddInteger(NoReturn);
9035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
90572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorvoid FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
906971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
907465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl          getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(),
9082455636163fdd18581d7fdae816433f886d88213Mike Stump          getNumExceptions(), exception_begin(), getNoReturnAttr());
9095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
911d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
91214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff                                    QualType OIT, ObjCProtocolDecl **protocols,
913d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                    unsigned NumProtocols) {
91414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  ID.AddPointer(OIT.getAsOpaquePtr());
9154b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  for (unsigned i = 0; i != NumProtocols; i++)
9164b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian    ID.AddPointer(protocols[i]);
9174b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian}
9184b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
919d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
92014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  if (getNumProtocols())
92114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    Profile(ID, getPointeeType(), &Protocols[0], getNumProtocols());
92214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  else
92314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    Profile(ID, getPointeeType(), 0, 0);
9244b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian}
9254b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
926a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
927a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// potentially looking through *all* consequtive typedefs.  This returns the
928a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// sum of the type qualifiers, so if you have:
929a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner///   typedef const int A;
930a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner///   typedef volatile A B;
931a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// looking through the typedefs for B will give you "const volatile A".
932a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner///
933a2c7767ce7d8feb10253f4b650826a20f3324c6fChris LattnerQualType TypedefType::LookThroughTypedefs() const {
934a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // Usually, there is only a single level of typedefs, be fast in that case.
935a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  QualType FirstType = getDecl()->getUnderlyingType();
936a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  if (!isa<TypedefType>(FirstType))
937a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    return FirstType;
938a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
939a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // Otherwise, do the fully general loop.
940a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  unsigned TypeQuals = 0;
941a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  const TypedefType *TDT = this;
942a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  while (1) {
943a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    QualType CurType = TDT->getDecl()->getUnderlyingType();
944f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner
945f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner
946f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    /// FIXME:
947f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    /// FIXME: This is incorrect for ExtQuals!
948f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    /// FIXME:
949f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    TypeQuals |= CurType.getCVRQualifiers();
950a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
951a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    TDT = dyn_cast<TypedefType>(CurType);
952a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    if (TDT == 0)
953a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner      return QualType(CurType.getTypePtr(), TypeQuals);
954a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  }
955a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner}
9565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
95772564e73277e29f6db3305d1f27ba408abb7ed88Douglas GregorTypeOfExprType::TypeOfExprType(Expr *E, QualType can)
95872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) {
959898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
960898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
961b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregorvoid DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
962b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor                                      ASTContext &Context, Expr *E) {
963b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor  E->Profile(ID, Context, true);
964b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor}
965b197572cf1cd70a817a1f546478cb2cb9112c48eDouglas Gregor
966563a03b1338d31c2462def43253a722bc885d384Anders CarlssonDecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
967563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  : Type(Decltype, can, E->isTypeDependent()), E(E),
968563a03b1338d31c2462def43253a722bc885d384Anders Carlsson  UnderlyingType(underlyingType) {
969395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson}
970395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson
9717da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas GregorTagType::TagType(TypeClass TC, TagDecl *D, QualType can)
9727da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  : Type(TC, can, D->isDependentType()), decl(D, 0) {}
9737da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
9742daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattnerbool RecordType::classof(const TagType *TT) {
9752daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  return isa<RecordDecl>(TT->getDecl());
9765edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner}
9775edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner
9782daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattnerbool EnumType::classof(const TagType *TT) {
9792daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  return isa<EnumDecl>(TT->getDecl());
9805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
98240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregorbool
9837532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::
98440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas GregoranyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
98540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
98640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    switch (Args[Idx].getKind()) {
987d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor    case TemplateArgument::Null:
988d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor      assert(false && "Should not have a NULL template argument");
989d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor      break;
990d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor
99140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Type:
99240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      if (Args[Idx].getAsType()->isDependentType())
99340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor        return true;
99440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
99540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
99640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Declaration:
99740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Integral:
99840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      // Never dependent
99940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
100040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
100140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Expression:
100240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      if (Args[Idx].getAsExpr()->isTypeDependent() ||
100340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor          Args[Idx].getAsExpr()->isValueDependent())
100440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor        return true;
100540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
1006d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
1007d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson    case TemplateArgument::Pack:
1008d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      assert(0 && "FIXME: Implement!");
1009d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      break;
101055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    }
101155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  }
101240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
101340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  return false;
101455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
101555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
10167532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::
1017828e226ab7ed08b3eb766549e9d3306432137460Douglas GregorTemplateSpecializationType(ASTContext &Context, TemplateName T,
1018828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor                           const TemplateArgument *Args,
10197532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                           unsigned NumArgs, QualType Canon)
10207532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  : Type(TemplateSpecialization,
102140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor         Canon.isNull()? QualType(this, 0) : Canon,
10227532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor         T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
1023828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Context(Context),
102440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    Template(T), NumArgs(NumArgs)
102555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor{
102640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  assert((!Canon.isNull() ||
10277532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor          T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
102840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor         "No canonical type for non-dependent class template specialization");
102955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
103040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  TemplateArgument *TemplateArgs
103140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    = reinterpret_cast<TemplateArgument *>(this + 1);
103255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
103340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
103455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
103555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
10367532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregorvoid TemplateSpecializationType::Destroy(ASTContext& C) {
1037ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1038ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    // FIXME: Not all expressions get cloned, so we can't yet perform
1039ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    // this destruction.
1040ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    //    if (Expr *E = getArg(Arg).getAsExpr())
1041ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    //      E->Destroy(C);
1042ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor  }
104340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor}
104440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
10457532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::iterator
10467532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::end() const {
104740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  return begin() + getNumArgs();
10485908e9f25bc9a334c99c095e0b1e6a515445be2dDouglas Gregor}
10495908e9f25bc9a334c99c095e0b1e6a515445be2dDouglas Gregor
105040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregorconst TemplateArgument &
10517532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::getArg(unsigned Idx) const {
105240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  assert(Idx < getNumArgs() && "Template argument out of range");
105340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  return getArgs()[Idx];
105455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
105555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
105640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregorvoid
10577532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
10587532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                                    TemplateName T,
10597532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                                    const TemplateArgument *Args,
1060828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor                                    unsigned NumArgs,
1061828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor                                    ASTContext &Context) {
10627532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  T.Profile(ID);
106340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
1064828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Args[Idx].Profile(ID, Context);
106555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
106697e0179f1ae545e07d9f5e7c1d2ef5c5bab06676Anders Carlsson
10675e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregorconst Type *QualifierSet::strip(const Type* T) {
10685e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor  QualType DT = T->getDesugaredType();
10697a1bcdf26d48c2c40e900a973f7ffca45f451526John McCall  addCVR(DT.getCVRQualifiers());
10705e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor
10715e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor  if (const ExtQualType* EQT = dyn_cast<ExtQualType>(DT)) {
10725e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor    if (EQT->getAddressSpace())
10737a1bcdf26d48c2c40e900a973f7ffca45f451526John McCall      addAddressSpace(EQT->getAddressSpace());
10745e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor    if (EQT->getObjCGCAttr())
10757a1bcdf26d48c2c40e900a973f7ffca45f451526John McCall      addObjCGCAttrType(EQT->getObjCGCAttr());
10765e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor    return EQT->getBaseType();
10772455636163fdd18581d7fdae816433f886d88213Mike Stump  } else {
10785e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor    // Use the sugared type unless desugaring found extra qualifiers.
10795e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor    return (DT.getCVRQualifiers() ? DT.getTypePtr() : T);
10805e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor  }
10815e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor}
10825e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor
10835e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas GregorQualType QualifierSet::apply(QualType QT, ASTContext& C) {
10847a1bcdf26d48c2c40e900a973f7ffca45f451526John McCall  QT = QT.getWithAdditionalQualifiers(getCVRMask());
10857a1bcdf26d48c2c40e900a973f7ffca45f451526John McCall  if (hasObjCGCAttrType()) QT = C.getObjCGCQualType(QT, getObjCGCAttrType());
10867a1bcdf26d48c2c40e900a973f7ffca45f451526John McCall  if (hasAddressSpace()) QT = C.getAddrSpaceQualType(QT, getAddressSpace());
10875e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor  return QT;
10885e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor}
10895e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor
10905e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor
10915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
10925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Type Printing
10935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
10945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid QualType::dump(const char *msg) const {
109639caea961530bc95d19114ab546ebcdb229263c9Chris Lattner  std::string R = "identifier";
1097e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  LangOptions LO;
1098e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  getAsStringInternal(R, PrintingPolicy(LO));
10995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (msg)
11005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "%s: %s\n", msg, R.c_str());
11015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else
11025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "%s\n", R.c_str());
11035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1104c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattnervoid QualType::dump() const {
1105c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  dump("");
1106c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner}
1107c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner
1108c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattnervoid Type::dump() const {
1109c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  std::string S = "identifier";
1110e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  LangOptions LO;
1111e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  getAsStringInternal(S, PrintingPolicy(LO));
1112c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  fprintf(stderr, "%s\n", S.c_str());
1113c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner}
1114c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner
1115c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner
11165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
11185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Note: funkiness to ensure we get a space only between quals.
11195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NonePrinted = true;
11205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (TypeQuals & QualType::Const)
11215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "const", NonePrinted = false;
11225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (TypeQuals & QualType::Volatile)
11235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += (NonePrinted+" volatile"), NonePrinted = false;
11245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (TypeQuals & QualType::Restrict)
11255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += (NonePrinted+" restrict"), NonePrinted = false;
11265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1128d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorstd::string QualType::getAsString() const {
1129d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  std::string S;
1130e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  LangOptions LO;
1131e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  getAsStringInternal(S, PrintingPolicy(LO));
1132d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  return S;
1133d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor}
1134d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor
1135d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid
1136d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorQualType::getAsStringInternal(std::string &S,
1137d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                              const PrintingPolicy &Policy) const {
11385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isNull()) {
113961366e9cd41a6dbde4e66416dac21269c8ac1d94Douglas Gregor    S += "NULL TYPE";
11405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
11415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
114222b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
114342f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  if (Policy.SuppressSpecifiers && getTypePtr()->isSpecifierType())
114422b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    return;
114522b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
11465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Print qualifiers as appropriate.
11473513e138cc75205b48d3078dfa4669355adb5714Gabor Greif  if (unsigned Tq = getCVRQualifiers()) {
11485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string TQS;
11493513e138cc75205b48d3078dfa4669355adb5714Gabor Greif    AppendTypeQualList(TQS, Tq);
11505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (!S.empty())
11515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      S = TQS + ' ' + S;
11525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
11535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      S = TQS;
11545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1156d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getTypePtr()->getAsStringInternal(S, Policy);
11575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1159d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid BuiltinType::getAsStringInternal(std::string &S,
1160d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                      const PrintingPolicy &Policy) const {
11615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (S.empty()) {
1162e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner    S = getName(Policy.LangOpts);
11635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
11645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Prefix the basic type, e.g. 'int X'.
11655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = ' ' + S;
1166e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner    S = getName(Policy.LangOpts) + S;
11675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1170d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid FixedWidthIntType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1171f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Once we get bitwidth attribute, write as
1172f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // "int __attribute__((bitwidth(x)))".
1173f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  std::string prefix = "__clang_fixedwidth";
1174f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  prefix += llvm::utostr_32(Width);
1175f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  prefix += (char)(Signed ? 'S' : 'U');
1176f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (S.empty()) {
1177f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    S = prefix;
1178f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  } else {
1179f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    // Prefix the basic type, e.g. 'int X'.
1180f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    S = prefix + S;
1181f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  }
1182f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman}
1183f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
1184f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
1185d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ComplexType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1186d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  ElementType->getAsStringInternal(S, Policy);
11875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S = "_Complex " + S;
11885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1190d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ExtQualType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
11913b6b83b8311ecdfa43cbb37ccc38c107d3b8d88bChris Lattner  bool NeedsSpace = false;
11924886a4204ff2b20bc226ce70d837de5fcd4a79abFariborz Jahanian  if (AddressSpace) {
119359d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
11943b6b83b8311ecdfa43cbb37ccc38c107d3b8d88bChris Lattner    NeedsSpace = true;
119559d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian  }
1196d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian  if (GCAttrType != QualType::GCNone) {
11973b6b83b8311ecdfa43cbb37ccc38c107d3b8d88bChris Lattner    if (NeedsSpace)
119859d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian      S += ' ';
119959d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    S += "__attribute__((objc_gc(";
1200d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian    if (GCAttrType == QualType::Weak)
120159d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian      S += "weak";
120259d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    else
120359d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian      S += "strong";
120459d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    S += ")))";
120559d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian  }
1206d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  BaseType->getAsStringInternal(S, Policy);
1207ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb}
1208ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
1209d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid PointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S = '*' + S;
12115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle things like 'int (*A)[4];' correctly.
12135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: this should include vectors, but vectors use attributes I guess.
1214bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  if (isa<ArrayType>(getPointeeType()))
12155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = '(' + S + ')';
12165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1217d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
12185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1220d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid BlockPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12215618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  S = '^' + S;
1222d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  PointeeType.getAsStringInternal(S, Policy);
12235618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff}
12245618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
1225d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S = '&' + S;
12277c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
12285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle things like 'int (&A)[4];' correctly.
12295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: this should include vectors, but vectors use attributes I guess.
1230bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  if (isa<ArrayType>(getPointeeType()))
12315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = '(' + S + ')';
12327c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1233d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
12347c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl}
12357c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1236d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12377c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  S = "&&" + S;
12387c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
12397c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // Handle things like 'int (&&A)[4];' correctly.
12407c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // FIXME: this should include vectors, but vectors use attributes I guess.
12417c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (isa<ArrayType>(getPointeeType()))
12427c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    S = '(' + S + ')';
12437c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1244d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
12455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1247d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1248f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  std::string C;
1249d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  Class->getAsStringInternal(C, Policy);
1250f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  C += "::*";
1251f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  S = C + S;
1252f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
12537c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // Handle things like 'int (Cls::*A)[4];' correctly.
1254f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // FIXME: this should include vectors, but vectors use attributes I guess.
1255f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  if (isa<ArrayType>(getPointeeType()))
1256f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    S = '(' + S + ')';
1257f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1258d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
1259f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl}
1260f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1261d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1262fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  S += '[';
12636b91cd9af12fe1340e48e03e9b988d9888b4889fSteve Naroff  S += llvm::utostr(getSize().getZExtValue());
1264fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  S += ']';
1265fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
1266d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
1267fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff}
1268fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
12697e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregorvoid ConstantArrayWithExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12707e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  if (Policy.ConstantArraySizeAsWritten) {
12717e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    std::string SStr;
12727e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    llvm::raw_string_ostream s(SStr);
12737e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
12747e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    S += '[';
12757e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    S += s.str();
12767e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    S += ']';
12777e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    getElementType().getAsStringInternal(S, Policy);
12787e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  }
12797e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  else
12807e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    ConstantArrayType::getAsStringInternal(S, Policy);
12817e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor}
12827e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor
12837e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregorvoid ConstantArrayWithoutExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12847e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  if (Policy.ConstantArraySizeAsWritten) {
12857e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    S += "[]";
12867e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    getElementType().getAsStringInternal(S, Policy);
12877e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  }
12887e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  else
12897e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor    ConstantArrayType::getAsStringInternal(S, Policy);
12907e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor}
12917e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor
1292d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1293c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  S += "[]";
1294c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
1295d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
1296c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman}
1297c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
1298d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid VariableArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += '[';
13005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1301c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  if (getIndexTypeQualifier()) {
1302c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff    AppendTypeQualList(S, getIndexTypeQualifier());
13035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += ' ';
13045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
13055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1306c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  if (getSizeModifier() == Static)
13075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "static";
1308c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  else if (getSizeModifier() == Star)
13095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += '*';
13105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1311fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  if (getSizeExpr()) {
1312a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    std::string SStr;
1313a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    llvm::raw_string_ostream s(SStr);
1314d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
1315fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    S += s.str();
1316fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  }
13175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += ']';
13185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1319d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
13205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1322d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid DependentSizedArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1323898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  S += '[';
1324898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1325898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  if (getIndexTypeQualifier()) {
1326898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    AppendTypeQualList(S, getIndexTypeQualifier());
1327898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += ' ';
1328898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
1329898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1330898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  if (getSizeModifier() == Static)
1331898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += "static";
1332898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  else if (getSizeModifier() == Star)
1333898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += '*';
1334898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1335898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  if (getSizeExpr()) {
1336898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    std::string SStr;
1337898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    llvm::raw_string_ostream s(SStr);
1338d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
1339898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += s.str();
1340898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
1341898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  S += ']';
1342898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1343d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
1344898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
1345898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
13469cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
13479cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
13489cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1349f6ddb737cb882ffbf0b75a9abd50b930cc2b9068Douglas Gregor  S += " __attribute__((ext_vector_type(";
13509cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (getSizeExpr()) {
13519cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    std::string SStr;
13529cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    llvm::raw_string_ostream s(SStr);
13539cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
13549cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S += s.str();
13559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  }
13569cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  S += ")))";
13579cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor}
13589cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1359d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
13605620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  // FIXME: We prefer to print the size directly here, but have no way
13615620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  // to get the size of the type.
13627ee261c8e71f363d86461f4d1a37e3def354c976Chris Lattner  S += " __attribute__((__vector_size__(";
13635620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  S += llvm::utostr_32(NumElements); // convert back to bytes.
13645620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  S += " * sizeof(" + ElementType.getAsString() + "))))";
1365d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  ElementType.getAsStringInternal(S, Policy);
13665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1368d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1369213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  S += " __attribute__((ext_vector_type(";
137031a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff  S += llvm::utostr_32(NumElements);
137131a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff  S += ")))";
1372d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  ElementType.getAsStringInternal(S, Policy);
137331a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff}
137431a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff
1375d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypeOfExprType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1376363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
1377363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff    InnerString = ' ' + InnerString;
1378a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek  std::string Str;
1379a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek  llvm::raw_string_ostream s(Str);
1380d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getUnderlyingExpr()->printPretty(s, 0, Policy);
13816409625011e4a11ff07956ff46a44d6ca4473992Argyrios Kyrtzidis  InnerString = "typeof " + s.str() + InnerString;
1382d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff}
1383d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
1384d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypeOfType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1385363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
1386363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff    InnerString = ' ' + InnerString;
1387d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  std::string Tmp;
1388d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getUnderlyingType().getAsStringInternal(Tmp, Policy);
1389363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff  InnerString = "typeof(" + Tmp + ")" + InnerString;
1390d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff}
1391d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
1392395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlssonvoid DecltypeType::getAsStringInternal(std::string &InnerString,
1393395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson                                       const PrintingPolicy &Policy) const {
1394395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  if (!InnerString.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
1395395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson    InnerString = ' ' + InnerString;
1396395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  std::string Str;
1397395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  llvm::raw_string_ostream s(Str);
1398395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  getUnderlyingExpr()->printPretty(s, 0, Policy);
1399395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  InnerString = "decltype(" + s.str() + ")" + InnerString;
1400395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson}
1401395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson
1402d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid FunctionNoProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
14035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If needed for precedence reasons, wrap the inner part in grouping parens.
14045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!S.empty())
14055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = "(" + S + ")";
14065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += "()";
14082455636163fdd18581d7fdae816433f886d88213Mike Stump  if (getNoReturnAttr())
14092455636163fdd18581d7fdae816433f886d88213Mike Stump    S += " __attribute__((noreturn))";
1410d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getResultType().getAsStringInternal(S, Policy);
14115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1413d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
14145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If needed for precedence reasons, wrap the inner part in grouping parens.
14155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!S.empty())
14165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = "(" + S + ")";
14175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += "(";
14195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::string Tmp;
142022b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  PrintingPolicy ParamPolicy(Policy);
142142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  ParamPolicy.SuppressSpecifiers = false;
14225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
14235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (i) S += ", ";
142422b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    getArgType(i).getAsStringInternal(Tmp, ParamPolicy);
14255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += Tmp;
14265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Tmp.clear();
14275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isVariadic()) {
14305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (getNumArgs())
14315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      S += ", ";
14325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "...";
1433e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  } else if (getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
14345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Do not emit int() if we have a proto, emit 'int(void)'.
14355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "void";
14365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += ")";
14392455636163fdd18581d7fdae816433f886d88213Mike Stump  if (getNoReturnAttr())
14402455636163fdd18581d7fdae816433f886d88213Mike Stump    S += " __attribute__((noreturn))";
1441d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getResultType().getAsStringInternal(S, Policy);
14425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1445d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
14465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
14475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InnerString = ' ' + InnerString;
14485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InnerString = getDecl()->getIdentifier()->getName() + InnerString;
14495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1451d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
145272c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  if (!InnerString.empty())    // Prefix the basic type, e.g. 'parmname X'.
145372c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor    InnerString = ' ' + InnerString;
1454fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
1455fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  if (!Name)
1456fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' +
1457fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor      llvm::utostr_32(Index) + InnerString;
1458fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  else
1459fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    InnerString = Name->getName() + InnerString;
146072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor}
146172c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
1462d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorstd::string
1463d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorTemplateSpecializationType::PrintTemplateArgumentList(
1464d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                  const TemplateArgument *Args,
1465d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                  unsigned NumArgs,
1466d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                  const PrintingPolicy &Policy) {
146798137534e612c274ba270af99d73429043957e53Douglas Gregor  std::string SpecString;
146855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  SpecString += '<';
146955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
147055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    if (Arg)
147155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor      SpecString += ", ";
147255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
147355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // Print the argument into a string.
147455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    std::string ArgString;
147598137534e612c274ba270af99d73429043957e53Douglas Gregor    switch (Args[Arg].getKind()) {
147638999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor    case TemplateArgument::Null:
147738999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor      assert(false && "Null template argument");
147838999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor      break;
147938999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor
148040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Type:
1481d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor      Args[Arg].getAsType().getAsStringInternal(ArgString, Policy);
148240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
148340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
148440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Declaration:
148598137534e612c274ba270af99d73429043957e53Douglas Gregor      ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
148640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
148740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
148840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Integral:
148998137534e612c274ba270af99d73429043957e53Douglas Gregor      ArgString = Args[Arg].getAsIntegral()->toString(10, true);
149040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
149140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
149240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Expression: {
149355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor      llvm::raw_string_ostream s(ArgString);
1494d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor      Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
149540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
149640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    }
1497d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson    case TemplateArgument::Pack:
1498d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      assert(0 && "FIXME: Implement!");
1499d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      break;
150055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    }
150155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
150255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // If this is the first argument and its string representation
150355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // begins with the global scope specifier ('::foo'), add a space
150455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // to avoid printing the diagraph '<:'.
150555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
150655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor      SpecString += ' ';
150755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
150855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    SpecString += ArgString;
150955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  }
151055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
151155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // If the last character of our string is '>', add another space to
151255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // keep the two '>''s separate tokens. We don't *have* to do this in
151355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // C++0x, but it's still good hygiene.
151455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  if (SpecString[SpecString.size() - 1] == '>')
151555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    SpecString += ' ';
151655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
151755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  SpecString += '>';
151855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
151998137534e612c274ba270af99d73429043957e53Douglas Gregor  return SpecString;
152098137534e612c274ba270af99d73429043957e53Douglas Gregor}
152198137534e612c274ba270af99d73429043957e53Douglas Gregor
152298137534e612c274ba270af99d73429043957e53Douglas Gregorvoid
15237532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::
1524d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorgetAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
15257532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  std::string SpecString;
15267532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor
15277532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  {
15287532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor    llvm::raw_string_ostream OS(SpecString);
1529d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    Template.print(OS, Policy);
15307532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  }
15317532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor
1532d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs(), Policy);
153355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  if (InnerString.empty())
153455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    InnerString.swap(SpecString);
153555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  else
153655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    InnerString = SpecString + ' ' + InnerString;
153755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
153855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
1539d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid QualifiedNameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1540e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  std::string MyString;
1541e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1542bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor  {
1543bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor    llvm::raw_string_ostream OS(MyString);
1544d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    NNS->print(OS, Policy);
1545e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
1546e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1547e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  std::string TypeStr;
1548d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  PrintingPolicy InnerPolicy(Policy);
1549d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  InnerPolicy.SuppressTagKind = true;
1550d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  NamedType.getAsStringInternal(TypeStr, InnerPolicy);
1551e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1552e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  MyString += TypeStr;
1553e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  if (InnerString.empty())
1554d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    InnerString.swap(MyString);
1555d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  else
1556d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    InnerString = MyString + ' ' + InnerString;
1557d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor}
1558d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1559d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypenameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1560d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  std::string MyString;
1561d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1562d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  {
1563d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    llvm::raw_string_ostream OS(MyString);
1564d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    OS << "typename ";
1565d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    NNS->print(OS, Policy);
15661734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
15671734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    if (const IdentifierInfo *Ident = getIdentifier())
15681734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      OS << Ident->getName();
15691734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    else if (const TemplateSpecializationType *Spec = getTemplateId()) {
1570d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor      Spec->getTemplateName().print(OS, Policy, true);
15711734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      OS << TemplateSpecializationType::PrintTemplateArgumentList(
1572d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                               Spec->getArgs(),
1573d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                            Spec->getNumArgs(),
1574d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                               Policy);
15751734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    }
1576d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  }
1577d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1578d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  if (InnerString.empty())
1579e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    InnerString.swap(MyString);
1580e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  else
1581e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    InnerString = MyString + ' ' + InnerString;
1582e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
1583e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1584c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroffvoid ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
1585c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff                                         const ObjCInterfaceDecl *Decl,
1586c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff                                         ObjCProtocolDecl **protocols,
1587c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff                                         unsigned NumProtocols) {
1588c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  ID.AddPointer(Decl);
1589c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  for (unsigned i = 0; i != NumProtocols; i++)
1590c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    ID.AddPointer(protocols[i]);
1591c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff}
1592c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
1593c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroffvoid ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
1594c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  if (getNumProtocols())
1595c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
1596c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  else
1597c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    Profile(ID, getDecl(), 0, 0);
1598c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff}
1599c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
1600c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroffvoid ObjCInterfaceType::getAsStringInternal(std::string &InnerString,
1601c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff                                           const PrintingPolicy &Policy) const {
16023536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
16033536b443bc50d58a79f14fca9b6842541a434854Steve Naroff    InnerString = ' ' + InnerString;
1604c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
1605c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  std::string ObjCQIString = getDecl()->getNameAsString();
1606c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  if (getNumProtocols()) {
1607c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    ObjCQIString += '<';
1608c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    bool isFirst = true;
1609c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
1610c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff      if (isFirst)
1611c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff        isFirst = false;
1612c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff      else
1613c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff        ObjCQIString += ',';
1614c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff      ObjCQIString += (*I)->getNameAsString();
1615c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    }
1616c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff    ObjCQIString += '>';
1617c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  }
1618c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff  InnerString = ObjCQIString + InnerString;
16193536b443bc50d58a79f14fca9b6842541a434854Steve Naroff}
16203536b443bc50d58a79f14fca9b6842541a434854Steve Naroff
1621d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
1622d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                                const PrintingPolicy &Policy) const {
1623de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  std::string ObjCQIString;
1624de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff
1625de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  if (isObjCIdType() || isObjCQualifiedIdType())
1626de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    ObjCQIString = "id";
1627470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff  else if (isObjCClassType() || isObjCQualifiedClassType())
1628de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    ObjCQIString = "Class";
1629de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff  else
1630de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff    ObjCQIString = getInterfaceDecl()->getNameAsString();
1631d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
1632d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (!qual_empty()) {
1633d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCQIString += '<';
1634d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
1635d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      ObjCQIString += (*I)->getNameAsString();
1636d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      if (I+1 != E)
1637d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff        ObjCQIString += ',';
1638d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    }
1639d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCQIString += '>';
1640d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  }
164114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  if (!isObjCIdType() && !isObjCQualifiedIdType())
164214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    ObjCQIString += " *"; // Don't forget the implicit pointer.
164314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  else if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
164414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    InnerString = ' ' + InnerString;
164514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
1646d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  InnerString = ObjCQIString + InnerString;
1647d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff}
1648d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
1649d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
165042f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  if (Policy.SuppressTag)
165142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    return;
165242f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
16535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
16545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InnerString = ' ' + InnerString;
16555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1656d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName();
16575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *ID;
16585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const IdentifierInfo *II = getDecl()->getIdentifier())
16595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID = II->getName();
16604e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor  else if (TypedefDecl *Typedef = getDecl()->getTypedefForAnonDecl()) {
16614e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    Kind = 0;
16624e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    assert(Typedef->getIdentifier() && "Typedef without identifier?");
16634e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    ID = Typedef->getIdentifier()->getName();
16644e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor  } else
16655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID = "<anonymous>";
16665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
166798137534e612c274ba270af99d73429043957e53Douglas Gregor  // If this is a class template specialization, print the template
166898137534e612c274ba270af99d73429043957e53Douglas Gregor  // arguments.
166998137534e612c274ba270af99d73429043957e53Douglas Gregor  if (ClassTemplateSpecializationDecl *Spec
167098137534e612c274ba270af99d73429043957e53Douglas Gregor        = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
16717e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
16727e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    std::string TemplateArgsStr
16737532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor      = TemplateSpecializationType::PrintTemplateArgumentList(
16747e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                            TemplateArgs.getFlatArgumentList(),
1675d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                            TemplateArgs.flat_size(),
1676d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                              Policy);
16777e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    InnerString = TemplateArgsStr + InnerString;
167898137534e612c274ba270af99d73429043957e53Douglas Gregor  }
167998137534e612c274ba270af99d73429043957e53Douglas Gregor
168024c46b3133b03e254877a680f92f035e56058a39Douglas Gregor  if (Kind) {
168124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    // Compute the full nested-name-specifier for this type. In C,
168224c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    // this will always be empty.
168324c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    std::string ContextStr;
168424c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    for (DeclContext *DC = getDecl()->getDeclContext();
168524c46b3133b03e254877a680f92f035e56058a39Douglas Gregor         !DC->isTranslationUnit(); DC = DC->getParent()) {
168624c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      std::string MyPart;
168724c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
168824c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        if (NS->getIdentifier())
168924c46b3133b03e254877a680f92f035e56058a39Douglas Gregor          MyPart = NS->getNameAsString();
169024c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      } else if (ClassTemplateSpecializationDecl *Spec
169124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor                   = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
16927e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
16937e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor        std::string TemplateArgsStr
16947532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor          = TemplateSpecializationType::PrintTemplateArgumentList(
16957e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                           TemplateArgs.getFlatArgumentList(),
1696d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                           TemplateArgs.flat_size(),
1697d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                           Policy);
16987e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor        MyPart = Spec->getIdentifier()->getName() + TemplateArgsStr;
169924c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
170024c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
170124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor          MyPart = Typedef->getIdentifier()->getName();
170224c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        else if (Tag->getIdentifier())
170324c46b3133b03e254877a680f92f035e56058a39Douglas Gregor          MyPart = Tag->getIdentifier()->getName();
170424c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      }
170524c46b3133b03e254877a680f92f035e56058a39Douglas Gregor
170624c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      if (!MyPart.empty())
170724c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        ContextStr = MyPart + "::" + ContextStr;
170824c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    }
170924c46b3133b03e254877a680f92f035e56058a39Douglas Gregor
171024c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    InnerString = std::string(Kind) + " " + ContextStr + ID + InnerString;
171124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor  } else
17124e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    InnerString = ID + InnerString;
17135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1714