Type.cpp revision d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bc
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
404b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenekvoid VariableArrayType::Destroy(ASTContext& C) {
41f91f5c8a66ffd812f61819836529f8ad437f7e2bEli Friedman  if (SizeExpr)
42f91f5c8a66ffd812f61819836529f8ad437f7e2bEli Friedman    SizeExpr->Destroy(C);
43566c2ba743065ec090f5154d5c30cf593aa12a6eTed Kremenek  this->~VariableArrayType();
443e9704981d7691fdd44913bf1786e8d760d8a627Steve Naroff  C.Deallocate(this);
454b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek}
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
47898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorvoid DependentSizedArrayType::Destroy(ASTContext& C) {
48898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  SizeExpr->Destroy(C);
49566c2ba743065ec090f5154d5c30cf593aa12a6eTed Kremenek  this->~DependentSizedArrayType();
503e9704981d7691fdd44913bf1786e8d760d8a627Steve Naroff  C.Deallocate(this);
51898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
52c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
539cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid DependentSizedExtVectorType::Destroy(ASTContext& C) {
549cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (SizeExpr)
559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    SizeExpr->Destroy(C);
569cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  this->~DependentSizedExtVectorType();
579cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  C.Deallocate(this);
589cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor}
599cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
60c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// getArrayElementTypeNoTypeQual - If this is an array type, return the
61c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// element type of the array, potentially with type qualifiers missing.
62c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// This method should never be used when type qualifiers are meaningful.
63c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattnerconst Type *Type::getArrayElementTypeNoTypeQual() const {
64c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // If this is directly an array type, return it.
65c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
66c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return ATy->getElementType().getTypePtr();
67c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
68c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
69c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (!isa<ArrayType>(CanonicalType)) {
70c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    // Look through type qualifiers
71c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    if (ArrayType *AT = dyn_cast<ArrayType>(CanonicalType.getUnqualifiedType()))
72c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner      return AT->getElementType().getTypePtr();
73c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return 0;
74c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  }
75c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
76c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // If this is a typedef for an array type, strip the typedef off without
77c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // losing all typedef information.
782fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ArrayType>(getDesugaredType())->getElementType().getTypePtr();
792fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner}
802fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner
812fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// getDesugaredType - Return the specified type with any "sugar" removed from
822fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// the type.  This takes off typedefs, typeof's etc.  If the outer level of
832fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// the type is already concrete, it returns it unmodified.  This is similar
842fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
852fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
862fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner/// concrete.
87969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor///
88969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// \param ForDisplay When true, the desugaring is provided for
89969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// display purposes only. In this case, we apply more heuristics to
90969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// decide whether it is worth providing a desugared form of the type
91969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// or not.
92969c689d893a248eca4f049f5b89f747e66e4bffDouglas GregorQualType QualType::getDesugaredType(bool ForDisplay) const {
93969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  return getTypePtr()->getDesugaredType(ForDisplay)
942fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner     .getWithAdditionalQualifiers(getCVRQualifiers());
95c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
96c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
97c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// getDesugaredType - Return the specified type with any "sugar" removed from
98c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// type type.  This takes off typedefs, typeof's etc.  If the outer level of
99c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// the type is already concrete, it returns it unmodified.  This is similar
100c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
101c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// example, it return "T*" as "T*", (not as "int*"), because the pointer is
102c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner/// concrete.
103969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor///
104969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// \param ForDisplay When true, the desugaring is provided for
105969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// display purposes only. In this case, we apply more heuristics to
106969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// decide whether it is worth providing a desugared form of the type
107969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor/// or not.
108969c689d893a248eca4f049f5b89f747e66e4bffDouglas GregorQualType Type::getDesugaredType(bool ForDisplay) const {
109c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
1102fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return TDT->LookThroughTypedefs().getDesugaredType();
11172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  if (const TypeOfExprType *TOE = dyn_cast<TypeOfExprType>(this))
1122fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return TOE->getUnderlyingExpr()->getType().getDesugaredType();
113c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
1142fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return TOT->getUnderlyingType().getDesugaredType();
1157532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  if (const TemplateSpecializationType *Spec
116c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor        = dyn_cast<TemplateSpecializationType>(this)) {
117969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor    if (ForDisplay)
118969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      return QualType(this, 0);
119969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor
120c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    QualType Canon = Spec->getCanonicalTypeInternal();
121c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (Canon->getAsTemplateSpecializationType())
122c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor      return QualType(this, 0);
123c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    return Canon->getDesugaredType();
124c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor  }
125969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  if (const QualifiedNameType *QualName  = dyn_cast<QualifiedNameType>(this)) {
126969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor    if (ForDisplay) {
127969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      // If desugaring the type that the qualified name is referring to
128969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      // produces something interesting, that's our desugared type.
129969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      QualType NamedType = QualName->getNamedType().getDesugaredType();
130969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      if (NamedType != QualName->getNamedType())
131969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor        return NamedType;
132969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor    } else
133969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor      return QualName->getNamedType().getDesugaredType();
134969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  }
1355cdf82164dd7c2b2320d6735c63ace4331e0716dDouglas Gregor
136969c689d893a248eca4f049f5b89f747e66e4bffDouglas Gregor  return QualType(this, 0);
137c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner}
138c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// isVoidType - Helper method to determine if this is the 'void' type.
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isVoidType() const {
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() == BuiltinType::Void;
143f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
1444bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isVoidType();
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isObjectType() const {
149bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType) ||
150bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor      isa<IncompleteArrayType>(CanonicalType) || isVoidType())
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return false;
152f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
1534bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isObjectType();
154bad0e656c3732e3539a9cd6525de721d7e47408bDouglas Gregor  return true;
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isDerivedType() const {
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (CanonicalType->getTypeClass()) {
159f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  case ExtQual:
160f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return cast<ExtQualType>(CanonicalType)->getBaseType()->isDerivedType();
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Pointer:
162fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  case VariableArray:
163fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  case ConstantArray:
164c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  case IncompleteArray:
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case FunctionProto:
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case FunctionNoProto:
1677c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  case LValueReference:
1687c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  case RValueReference:
16972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Record:
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return true;
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default:
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return false;
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17699dc91422144483c20d1c7381bc9ac634b646b04Chris Lattnerbool Type::isClassType() const {
177f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner  if (const RecordType *RT = getAsRecordType())
178f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner    return RT->getDecl()->isClass();
17999dc91422144483c20d1c7381bc9ac634b646b04Chris Lattner  return false;
18099dc91422144483c20d1c7381bc9ac634b646b04Chris Lattner}
181c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerbool Type::isStructureType() const {
182f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner  if (const RecordType *RT = getAsRecordType())
183f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner    return RT->getDecl()->isStruct();
184c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  return false;
185c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner}
186c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerbool Type::isUnionType() const {
187f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner  if (const RecordType *RT = getAsRecordType())
188f728a4a05df2455e1c6e62173ab720a92cd4a074Chris Lattner    return RT->getDecl()->isUnion();
189c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  return false;
190c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner}
191c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner
192c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattnerbool Type::isComplexType() const {
19302f62a9fedbc370fba081303399410a3afdde29fSteve Naroff  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
19402f62a9fedbc370fba081303399410a3afdde29fSteve Naroff    return CT->getElementType()->isFloatingType();
195f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
1964bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isComplexType();
19702f62a9fedbc370fba081303399410a3afdde29fSteve Naroff  return false;
198c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner}
199c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner
2004cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroffbool Type::isComplexIntegerType() const {
2014cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // Check for GCC complex integer extension.
2024cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
2034cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff    return CT->getElementType()->isIntegerType();
204f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *AS = dyn_cast<ExtQualType>(CanonicalType))
2054bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return AS->getBaseType()->isComplexIntegerType();
2064cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  return false;
2074cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff}
2084cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff
2094cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroffconst ComplexType *Type::getAsComplexIntegerType() const {
2104cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // Are we directly a complex type?
2114cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  if (const ComplexType *CTy = dyn_cast<ComplexType>(this)) {
2124cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff    if (CTy->getElementType()->isIntegerType())
2134cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff      return CTy;
2144bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner    return 0;
2154cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  }
2164bbce9901f7296ab030c58f0877be0b042bd70d3Chris Lattner
2172a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // If the canonical form of this type isn't what we want, reject it.
2182a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (!isa<ComplexType>(CanonicalType)) {
219f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    // Look through type qualifiers (e.g. ExtQualType's).
2202a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    if (isa<ComplexType>(CanonicalType.getUnqualifiedType()))
2212a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return CanonicalType.getUnqualifiedType()->getAsComplexIntegerType();
2224cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff    return 0;
2232a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  }
2242a18dfe292cf3c406a769c3672080970ac586345Chris Lattner
2254cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // If this is a typedef for a complex type, strip the typedef off without
2264cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff  // losing all typedef information.
2272fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ComplexType>(getDesugaredType());
2284cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff}
2294cdec1c3ca80124024a787ce32833fd5b20cbb15Steve Naroff
23077878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroffconst BuiltinType *Type::getAsBuiltinType() const {
23177878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  // If this is directly a builtin type, return it.
23277878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  if (const BuiltinType *BTy = dyn_cast<BuiltinType>(this))
23377878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff    return BTy;
234dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
235dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't a builtin type, reject it.
236ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<BuiltinType>(CanonicalType)) {
237f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    // Look through type qualifiers (e.g. ExtQualType's).
238ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<BuiltinType>(CanonicalType.getUnqualifiedType()))
239ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsBuiltinType();
240dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
241ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
242dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
24377878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  // If this is a typedef for a builtin type, strip the typedef off without
24477878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff  // losing all typedef information.
2452fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<BuiltinType>(getDesugaredType());
24677878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff}
24777878cc5aa6ad01fc0c91bac1a61819dbf3bf691Steve Naroff
248c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst FunctionType *Type::getAsFunctionType() const {
2497064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is directly a function type, return it.
2507064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
2517064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    return FTy;
252ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
253dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
254ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<FunctionType>(CanonicalType)) {
255ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
256ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<FunctionType>(CanonicalType.getUnqualifiedType()))
257ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsFunctionType();
258dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
259ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
260dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
2617064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is a typedef for a function type, strip the typedef off without
2627064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // losing all typedef information.
2632fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<FunctionType>(getDesugaredType());
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
26672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorconst FunctionNoProtoType *Type::getAsFunctionNoProtoType() const {
26772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  return dyn_cast_or_null<FunctionNoProtoType>(getAsFunctionType());
268afa74448a07a16c3146accbe0ff03e9c8b0995e5Daniel Dunbar}
269afa74448a07a16c3146accbe0ff03e9c8b0995e5Daniel Dunbar
27072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorconst FunctionProtoType *Type::getAsFunctionProtoType() const {
27172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  return dyn_cast_or_null<FunctionProtoType>(getAsFunctionType());
272b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner}
273b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner
274b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner
275befee48ff2a1dab236c5700f00ecca1cfdcd5837Chris Lattnerconst PointerType *Type::getAsPointerType() const {
2767a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  // If this is directly a pointer type, return it.
2777a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  if (const PointerType *PTy = dyn_cast<PointerType>(this))
2787a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner    return PTy;
279a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
280dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
281ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<PointerType>(CanonicalType)) {
282ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
283ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<PointerType>(CanonicalType.getUnqualifiedType()))
284ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsPointerType();
285dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
286ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
287dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
288a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // If this is a typedef for a pointer type, strip the typedef off without
289a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // losing all typedef information.
2902fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<PointerType>(getDesugaredType());
2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2935618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroffconst BlockPointerType *Type::getAsBlockPointerType() const {
2945618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  // If this is directly a block pointer type, return it.
2955618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  if (const BlockPointerType *PTy = dyn_cast<BlockPointerType>(this))
2965618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff    return PTy;
2975618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
2985618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  // If the canonical form of this type isn't the right kind, reject it.
2992a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (!isa<BlockPointerType>(CanonicalType)) {
3002a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    // Look through type qualifiers
3012a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    if (isa<BlockPointerType>(CanonicalType.getUnqualifiedType()))
3022a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return CanonicalType.getUnqualifiedType()->getAsBlockPointerType();
3035618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff    return 0;
3042a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  }
3055618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
3065618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  // If this is a typedef for a block pointer type, strip the typedef off
3075618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  // without losing all typedef information.
3082fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<BlockPointerType>(getDesugaredType());
3095618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff}
3105618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
311a1d9fdea79ba7bbd71862b9f9f78f5f117331fc7Chris Lattnerconst ReferenceType *Type::getAsReferenceType() const {
312ea5e79f930bcab2087646d1cb4fc1fe9dcf986a1Bill Wendling  // If this is directly a reference type, return it.
313ea5e79f930bcab2087646d1cb4fc1fe9dcf986a1Bill Wendling  if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
314ea5e79f930bcab2087646d1cb4fc1fe9dcf986a1Bill Wendling    return RTy;
3157c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
316dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
3177c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (!isa<ReferenceType>(CanonicalType)) {
318ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
319ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<ReferenceType>(CanonicalType.getUnqualifiedType()))
320ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsReferenceType();
321dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
322ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
323dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
324ea5e79f930bcab2087646d1cb4fc1fe9dcf986a1Bill Wendling  // If this is a typedef for a reference type, strip the typedef off without
325ea5e79f930bcab2087646d1cb4fc1fe9dcf986a1Bill Wendling  // losing all typedef information.
3262fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ReferenceType>(getDesugaredType());
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3297c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlconst LValueReferenceType *Type::getAsLValueReferenceType() const {
3307c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // If this is directly an lvalue reference type, return it.
3317c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (const LValueReferenceType *RTy = dyn_cast<LValueReferenceType>(this))
3327c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return RTy;
3337c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
3347c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // If the canonical form of this type isn't the right kind, reject it.
3357c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (!isa<LValueReferenceType>(CanonicalType)) {
3367c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    // Look through type qualifiers
3377c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    if (isa<LValueReferenceType>(CanonicalType.getUnqualifiedType()))
3387c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl      return CanonicalType.getUnqualifiedType()->getAsLValueReferenceType();
3397c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return 0;
3407c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  }
3417c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
3427c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // If this is a typedef for an lvalue reference type, strip the typedef off
3437c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // without losing all typedef information.
3442fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<LValueReferenceType>(getDesugaredType());
3457c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl}
3467c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
3477c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redlconst RValueReferenceType *Type::getAsRValueReferenceType() const {
3487c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // If this is directly an rvalue reference type, return it.
3497c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (const RValueReferenceType *RTy = dyn_cast<RValueReferenceType>(this))
3507c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return RTy;
3517c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
3527c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // If the canonical form of this type isn't the right kind, reject it.
3537c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (!isa<RValueReferenceType>(CanonicalType)) {
3547c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    // Look through type qualifiers
3557c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    if (isa<RValueReferenceType>(CanonicalType.getUnqualifiedType()))
3567c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl      return CanonicalType.getUnqualifiedType()->getAsRValueReferenceType();
3577c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    return 0;
3587c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  }
3597c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
3607c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // If this is a typedef for an rvalue reference type, strip the typedef off
3617c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // without losing all typedef information.
3622fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<RValueReferenceType>(getDesugaredType());
3637c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl}
3647c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
365f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlconst MemberPointerType *Type::getAsMemberPointerType() const {
366f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // If this is directly a member pointer type, return it.
367f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  if (const MemberPointerType *MTy = dyn_cast<MemberPointerType>(this))
368f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    return MTy;
369f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
370f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // If the canonical form of this type isn't the right kind, reject it.
371f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  if (!isa<MemberPointerType>(CanonicalType)) {
372f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    // Look through type qualifiers
373f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    if (isa<MemberPointerType>(CanonicalType.getUnqualifiedType()))
374f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl      return CanonicalType.getUnqualifiedType()->getAsMemberPointerType();
375f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    return 0;
376f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  }
377f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
378f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // If this is a typedef for a member pointer type, strip the typedef off
379f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // without losing all typedef information.
3802fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<MemberPointerType>(getDesugaredType());
381f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl}
382f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
383d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman/// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length
384d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman/// array types and types that contain variable array types in their
385d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman/// declarator
386d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroffbool Type::isVariablyModifiedType() const {
387c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  // A VLA is a variably modified type.
388c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (isVariableArrayType())
389d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman    return true;
390d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
391d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // An array can contain a variably modified type
392c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const Type *T = getArrayElementTypeNoTypeQual())
393c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    return T->isVariablyModifiedType();
394d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
395f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // A pointer can point to a variably modified type.
396f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // Also, C++ references and member pointers can point to a variably modified
397f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // type, where VLAs appear as an extension to C++, and should be treated
398f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // correctly.
39968694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar  if (const PointerType *PT = getAsPointerType())
400d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman    return PT->getPointeeType()->isVariablyModifiedType();
40168694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar  if (const ReferenceType *RT = getAsReferenceType())
40268694ada8f4d8f6c4b00ea5b900df96428b28fc8Daniel Dunbar    return RT->getPointeeType()->isVariablyModifiedType();
4038edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl  if (const MemberPointerType *PT = getAsMemberPointerType())
4048edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl    return PT->getPointeeType()->isVariablyModifiedType();
405d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
406d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // A function can return a variably modified type
407d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // This one isn't completely obvious, but it follows from the
408d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // definition in C99 6.7.5p3. Because of this rule, it's
409d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman  // illegal to declare a function returning a variably modified type.
4102a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (const FunctionType *FT = getAsFunctionType())
411d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman    return FT->getResultType()->isVariablyModifiedType();
412d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0Eli Friedman
413d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff  return false;
414d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff}
415d7444aac1af1c2c1d5e5b7467ecf6006ee2d8abeSteve Naroff
416c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst RecordType *Type::getAsRecordType() const {
417fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  // If this is directly a record type, return it.
418dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  if (const RecordType *RTy = dyn_cast<RecordType>(this))
419dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff    return RTy;
420dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff
421dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
422ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<RecordType>(CanonicalType)) {
423ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
424ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
425ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsRecordType();
426dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
427ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
428dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
429dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If this is a typedef for a record type, strip the typedef off without
430dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  // losing all typedef information.
4312fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<RecordType>(getDesugaredType());
432dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff}
433dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff
434fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregorconst TagType *Type::getAsTagType() const {
435fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  // If this is directly a tag type, return it.
436fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  if (const TagType *TagTy = dyn_cast<TagType>(this))
437fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    return TagTy;
438fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
439fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  // If the canonical form of this type isn't the right kind, reject it.
440fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  if (!isa<TagType>(CanonicalType)) {
441fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    // Look through type qualifiers
442fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    if (isa<TagType>(CanonicalType.getUnqualifiedType()))
443fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor      return CanonicalType.getUnqualifiedType()->getAsTagType();
444fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    return 0;
445fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
446fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
447fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  // If this is a typedef for a tag type, strip the typedef off without
448fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  // losing all typedef information.
4492fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<TagType>(getDesugaredType());
450fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor}
451fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
452c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst RecordType *Type::getAsStructureType() const {
4537064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is directly a structure type, return it.
454c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(this)) {
45539ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (RT->getDecl()->isStruct())
456c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner      return RT;
4577064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  }
458dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
459dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
460c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
46139ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (!RT->getDecl()->isStruct())
462dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner      return 0;
463dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
464dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // If this is a typedef for a structure type, strip the typedef off without
465dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // losing all typedef information.
4662fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return cast<RecordType>(getDesugaredType());
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
468ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // Look through type qualifiers
469ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
470ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    return CanonicalType.getUnqualifiedType()->getAsStructureType();
4717064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  return 0;
4725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
474c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst RecordType *Type::getAsUnionType() const {
4757064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // If this is directly a union type, return it.
476c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(this)) {
47739ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (RT->getDecl()->isUnion())
478c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner      return RT;
4797064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  }
480ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
481dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
482c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattner  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
48339ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    if (!RT->getDecl()->isUnion())
484dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner      return 0;
485dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
486dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // If this is a typedef for a union type, strip the typedef off without
487dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    // losing all typedef information.
4882fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner    return cast<RecordType>(getDesugaredType());
4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
490ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
491ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  // Look through type qualifiers
492ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
493ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    return CanonicalType.getUnqualifiedType()->getAsUnionType();
4947064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  return 0;
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
497ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedmanconst EnumType *Type::getAsEnumType() const {
498ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  // Check the canonicalized unqualified type directly; the more complex
499ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  // version is unnecessary because there isn't any typedef information
500ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  // to preserve.
501ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman  return dyn_cast<EnumType>(CanonicalType.getUnqualifiedType());
502ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman}
503ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman
504c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattnerconst ComplexType *Type::getAsComplexType() const {
505c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  // Are we directly a complex type?
506c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  if (const ComplexType *CTy = dyn_cast<ComplexType>(this))
507c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner    return CTy;
508c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner
509dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
510ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<ComplexType>(CanonicalType)) {
511ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
512ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<ComplexType>(CanonicalType.getUnqualifiedType()))
513ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsComplexType();
514dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
515ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
516dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
517c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  // If this is a typedef for a complex type, strip the typedef off without
518c6fb90a7246c2d5d3233e70107bf9d8c7c9e535bChris Lattner  // losing all typedef information.
5192fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ComplexType>(getDesugaredType());
5207a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner}
5217a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner
522c8629630ce3e7f0da231bf10a4b39240caaac68aChris Lattnerconst VectorType *Type::getAsVectorType() const {
5237a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  // Are we directly a vector type?
5247a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner  if (const VectorType *VTy = dyn_cast<VectorType>(this))
5257a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner    return VTy;
526a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
527dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
528ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  if (!isa<VectorType>(CanonicalType)) {
529ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
530ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    if (isa<VectorType>(CanonicalType.getUnqualifiedType()))
531ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb      return CanonicalType.getUnqualifiedType()->getAsVectorType();
532dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
533ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
534dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner
535a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // If this is a typedef for a vector type, strip the typedef off without
536a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // losing all typedef information.
5372fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<VectorType>(getDesugaredType());
5387a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner}
5397a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner
540213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begemanconst ExtVectorType *Type::getAsExtVectorType() const {
5417064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  // Are we directly an OpenCU vector type?
542213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  if (const ExtVectorType *VTy = dyn_cast<ExtVectorType>(this))
5437064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    return VTy;
5447064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
545dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner  // If the canonical form of this type isn't the right kind, reject it.
546213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  if (!isa<ExtVectorType>(CanonicalType)) {
547ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    // Look through type qualifiers
548213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman    if (isa<ExtVectorType>(CanonicalType.getUnqualifiedType()))
549213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman      return CanonicalType.getUnqualifiedType()->getAsExtVectorType();
550dea6146deede4b89a1757d46cd92ebf158659c25Chris Lattner    return 0;
551ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb  }
5527064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
553213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  // If this is a typedef for an extended vector type, strip the typedef off
554213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  // without losing all typedef information.
5552fa8c2598c2615da4639b4e42e9079647bd3aea4Chris Lattner  return cast<ExtVectorType>(getDesugaredType());
5567064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff}
5577064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
558368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattnerconst ObjCInterfaceType *Type::getAsObjCInterfaceType() const {
559eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // There is no sugar for ObjCInterfaceType's, just return the canonical
5602a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // type pointer if it is the right class.  There is no typedef information to
5612a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // return and these cannot be Address-space qualified.
562fb41ca86eeede2fce02933034cf8b6e5aea84b79Fariborz Jahanian  return dyn_cast<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
563368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner}
564368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner
565d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffconst ObjCObjectPointerType *Type::getAsObjCObjectPointerType() const {
566d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  // There is no sugar for ObjCObjectPointerType's, just return the
567d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  // canonical type pointer if it is the right class.
568d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  return dyn_cast<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
569d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff}
570d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
571368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattnerconst ObjCQualifiedInterfaceType *
572368eefa081d12f0a265ee90ee8ec61b54168d57dChris LattnerType::getAsObjCQualifiedInterfaceType() const {
5732a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // There is no sugar for ObjCQualifiedInterfaceType's, just return the
5742a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // canonical type pointer if it is the right class.
575fb41ca86eeede2fce02933034cf8b6e5aea84b79Fariborz Jahanian  return dyn_cast<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
576eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
577eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
578d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffconst ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
579eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // There is no sugar for ObjCQualifiedIdType's, just return the canonical
580eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // type pointer if it is the right class.
581d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
582d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    if (OPT->isObjCQualifiedIdType())
583d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      return OPT;
584d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  }
585d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  return 0;
586368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner}
587368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner
58872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregorconst TemplateTypeParmType *Type::getAsTemplateTypeParmType() const {
58972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  // There is no sugar for template type parameters, so just return
59072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  // the canonical type pointer if it is the right class.
5912a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  // FIXME: can these be address-space qualified?
59272c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  return dyn_cast<TemplateTypeParmType>(CanonicalType);
59372c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor}
594368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner
5957532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregorconst TemplateSpecializationType *
5967532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorType::getAsTemplateSpecializationType() const {
59755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // There is no sugar for class template specialization types, so
59855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // just return the canonical type pointer if it is the right class.
5997532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  return dyn_cast<TemplateSpecializationType>(CanonicalType);
60055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
60155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
6025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isIntegerType() const {
6035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Bool &&
6052df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner           BT->getKind() <= BuiltinType::Int128;
6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
607834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    // Incomplete enum types are not treated as integer types.
6088e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor    // FIXME: In C++, enum types are never integer types.
609834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return true;
611f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
612f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
613c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
614c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isIntegerType();
615f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
616f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isIntegerType();
6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
62033e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanianbool Type::isIntegralType() const {
62133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
62233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    return BT->getKind() >= BuiltinType::Bool &&
62333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    BT->getKind() <= BuiltinType::LongLong;
62433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
625834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
626834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner      return true;  // Complete enum types are integral.
6278e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor                    // FIXME: In C++, enum types are never integral.
628f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
629f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
630f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
631f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isIntegralType();
63233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  return false;
63333e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian}
63433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
63513b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroffbool Type::isEnumeralType() const {
63613b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
63739ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis    return TT->getDecl()->isEnum();
638f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
639f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isEnumeralType();
64013b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  return false;
64113b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff}
64213b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff
64313b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroffbool Type::isBooleanType() const {
64413b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
64513b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff    return BT->getKind() == BuiltinType::Bool;
646f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
647f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isBooleanType();
64813b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  return false;
64913b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff}
65013b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff
65113b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroffbool Type::isCharType() const {
65213b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
65313b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff    return BT->getKind() == BuiltinType::Char_U ||
65413b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff           BT->getKind() == BuiltinType::UChar ||
655c67ad5f299bb2c09e4567def8ff0d34bd15a42fdAnders Carlsson           BT->getKind() == BuiltinType::Char_S ||
656c67ad5f299bb2c09e4567def8ff0d34bd15a42fdAnders Carlsson           BT->getKind() == BuiltinType::SChar;
657f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
658f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isCharType();
65913b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff  return false;
66013b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff}
66113b7c5ff42d6077a8d59e2c9ec9e7fedd0150ae6Steve Naroff
66277a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregorbool Type::isWideCharType() const {
66377a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
66477a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor    return BT->getKind() == BuiltinType::WChar;
665f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
666f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isWideCharType();
66777a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor  return false;
66877a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor}
66977a52233f7c0f162672652051bfe78b65ad4f789Douglas Gregor
670d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// isSignedIntegerType - Return true if this is an integer type that is
671d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
672d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// an enum decl which has a signed representation, or a vector of signed
673d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// integer element type.
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isSignedIntegerType() const {
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Char_S &&
6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongLong;
6785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
679d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
68037c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
68137c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    return ET->getDecl()->getIntegerType()->isSignedIntegerType();
682d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
683f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (const FixedWidthIntType *FWIT =
684f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman          dyn_cast<FixedWidthIntType>(CanonicalType))
685f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return FWIT->isSigned();
686f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
687c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
688c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isSignedIntegerType();
689f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
690f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isSignedIntegerType();
6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
6925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
694d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// isUnsignedIntegerType - Return true if this is an integer type that is
695d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
696d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// decl which has an unsigned representation, or a vector of unsigned integer
697d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner/// element type.
6985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isUnsignedIntegerType() const {
6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
7005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Bool &&
7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::ULongLong;
7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
703d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
70437c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
70537c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
706d5bbce4382622feb4ca5978c4bb8fcceb7aaec00Chris Lattner
707f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (const FixedWidthIntType *FWIT =
708f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman          dyn_cast<FixedWidthIntType>(CanonicalType))
709f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return !FWIT->isSigned();
710f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
711c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
712c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isUnsignedIntegerType();
713f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
714f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isUnsignedIntegerType();
7155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isFloatingType() const {
7195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
7205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Float &&
7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongDouble;
7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
723729a2131228cb7fcbc00bd8af36bc6f14d12317dChris Lattner    return CT->getElementType()->isFloatingType();
724c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
725c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isFloatingType();
726f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
727f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isFloatingType();
7285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isRealFloatingType() const {
7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Float &&
7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongDouble;
735c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
736c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isRealFloatingType();
737f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
738f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isRealFloatingType();
7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isRealType() const {
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() >= BuiltinType::Bool &&
7455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           BT->getKind() <= BuiltinType::LongDouble;
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
747834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition();
748f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
749f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
750c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
751c63b96ad706e054a1390dd2ab53af9f05d33bbb1Steve Naroff    return VT->getElementType()->isRealType();
752f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
753f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isRealType();
7545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return false;
7555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isArithmeticType() const {
7585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
759a7fbf7282eadebaf1293d9f970b01fb57f4b0ae4Douglas Gregor    return BT->getKind() >= BuiltinType::Bool &&
760a7fbf7282eadebaf1293d9f970b01fb57f4b0ae4Douglas Gregor           BT->getKind() <= BuiltinType::LongDouble;
76137c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
76237c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
76337c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    // If a body isn't seen by the time we get here, return false.
76437c1b78a20a09b0456aa5caa15e159027010ca22Chris Lattner    return ET->getDecl()->isDefinition();
765f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
766f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
767f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
768f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isArithmeticType();
7695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
7705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isScalarType() const {
7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
7745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return BT->getKind() != BuiltinType::Void;
7755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
776834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    // Enums are scalar types, but only if they are defined.  Incomplete enums
777834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    // are not treated as scalar types.
778834a72ac74cf4ff07ba6215545dba3db578f8a07Chris Lattner    if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return true;
7805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return false;
7815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
782f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
783f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isScalarType();
784f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (isa<FixedWidthIntType>(CanonicalType))
785f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    return true;
7865618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  return isa<PointerType>(CanonicalType) ||
7875618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff         isa<BlockPointerType>(CanonicalType) ||
788f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl         isa<MemberPointerType>(CanonicalType) ||
7895618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff         isa<ComplexType>(CanonicalType) ||
790d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff         isa<ObjCObjectPointerType>(CanonicalType);
7915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
793d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// \brief Determines whether the type is a C++ aggregate type or C
794d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// aggregate or union type.
795d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor///
796d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// An aggregate type is an array or a class type (struct, union, or
797d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// class) that has no user-declared constructors, no private or
798d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// protected non-static data members, no base classes, and no virtual
799d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type
800d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// subsumes the notion of C aggregates (C99 6.2.5p21) because it also
801d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor/// includes union types.
8025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isAggregateType() const {
803c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor  if (const RecordType *Record = dyn_cast<RecordType>(CanonicalType)) {
804c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor    if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl()))
805c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor      return ClassDecl->isAggregate();
806c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor
807d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013Douglas Gregor    return true;
808c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor  }
809c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor
810f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
811f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isAggregateType();
812c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  return isa<ArrayType>(CanonicalType);
8135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8159bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner/// isConstantSizeType - Return true if this is not a variable sized type,
8169bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner/// according to the rules of C99 6.7.5p3.  It is not legal to call this on
817898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor/// incomplete types or dependent types.
8183c2b3170041f69a92904e3bab9b6d654eaf260acEli Friedmanbool Type::isConstantSizeType() const {
819f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CanonicalType))
820f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return EXTQT->getBaseType()->isConstantSizeType();
821d52a4578144ab2887912e52eabec58a857a44adbChris Lattner  assert(!isIncompleteType() && "This doesn't make sense for incomplete types");
822898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  assert(!isDependentType() && "This doesn't make sense for dependent types");
8239bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner  // The VAT must have a size, as it is known to be complete.
8249bfa73c5ab7bf4b0e749d04f29da6884e8d5bd9fChris Lattner  return !isa<VariableArrayType>(CanonicalType);
8255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
8285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// - a type that can describe objects, but which lacks information needed to
8295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// determine its size.
8305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isIncompleteType() const {
8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (CanonicalType->getTypeClass()) {
8325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default: return false;
833f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  case ExtQual:
834f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return cast<ExtQualType>(CanonicalType)->getBaseType()->isIncompleteType();
8355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Builtin:
8365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Void is the only incomplete builtin type.  Per C99 6.2.5p19, it can never
8375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // be completed.
8385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return isVoidType();
83972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Record:
84072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Enum:
8415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // A tagged type (struct/union/enum/class) is incomplete if the decl is a
8425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // forward declaration, but not a full definition (C99 6.2.5p22).
8435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
844c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  case IncompleteArray:
8455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // An array of unknown size is an incomplete type (C99 6.2.5p22).
846c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    return true;
8471efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner  case ObjCInterface:
8481efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner  case ObjCQualifiedInterface:
8491efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner    // ObjC interfaces are incomplete if they are @class, not @interface.
8501efaa9594a81709a17658fd80ae7e783e1026407Chris Lattner    return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl();
8515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
85464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10)
85564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redlbool Type::isPODType() const {
85664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  // The compiler shouldn't query this for incomplete types, but the user might.
85764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  // We return false for that case.
85864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  if (isIncompleteType())
85964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return false;
86064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
86164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  switch (CanonicalType->getTypeClass()) {
86264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    // Everything not explicitly mentioned is not POD.
86364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  default: return false;
864f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian  case ExtQual:
865f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    return cast<ExtQualType>(CanonicalType)->getBaseType()->isPODType();
86664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case VariableArray:
86764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case ConstantArray:
86864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    // IncompleteArray is caught by isIncompleteType() above.
86964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return cast<ArrayType>(CanonicalType)->getElementType()->isPODType();
87064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
87164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Builtin:
87264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Complex:
87364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Pointer:
874f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  case MemberPointer:
87564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case Vector:
87664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  case ExtVector:
877d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  case ObjCObjectPointer:
87864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return true;
87964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
88072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Enum:
88172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return true;
88272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor
88372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  case Record:
884c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor    if (CXXRecordDecl *ClassDecl
885c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor          = dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl()))
886c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor      return ClassDecl->isPOD();
887c1efaecf0373f1a55c5ef4c234357cf726fc0600Douglas Gregor
88864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    // C struct/union is POD.
88964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl    return true;
89064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl  }
89164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl}
89264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl
8935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool Type::isPromotableIntegerType() const {
8942a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  if (const BuiltinType *BT = getAsBuiltinType())
8952a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    switch (BT->getKind()) {
8962a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Bool:
8972a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Char_S:
8982a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Char_U:
8992a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::SChar:
9002a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::UChar:
9012a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::Short:
9022a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    case BuiltinType::UShort:
9032a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return true;
9042a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    default:
9052a18dfe292cf3c406a769c3672080970ac586345Chris Lattner      return false;
9062a18dfe292cf3c406a769c3672080970ac586345Chris Lattner    }
9072a18dfe292cf3c406a769c3672080970ac586345Chris Lattner  return false;
9085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9106e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redlbool Type::isNullPtrType() const {
9116e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  if (const BuiltinType *BT = getAsBuiltinType())
9126e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl    return BT->getKind() == BuiltinType::NullPtr;
9136e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  return false;
9146e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl}
9156e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl
91622b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedmanbool Type::isSpecifierType() const {
91722b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  // Note that this intentionally does not use the canonical type.
91822b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  switch (getTypeClass()) {
91922b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Builtin:
92022b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Record:
92122b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Enum:
92222b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  case Typedef:
923c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case Complex:
924c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TypeOfExpr:
925c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TypeOf:
926c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TemplateTypeParm:
927c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case TemplateSpecialization:
928c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case QualifiedName:
929c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case Typename:
930c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case ObjCInterface:
931c8f2c61f4f667c2bc3e4e74b274fa397a4232393Eli Friedman  case ObjCQualifiedInterface:
932d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  case ObjCObjectPointer:
93322b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    return true;
93422b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  default:
93522b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    return false;
93622b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  }
93722b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman}
93822b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
939d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorconst char *BuiltinType::getName(bool CPlusPlus) const {
9405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (getKind()) {
9415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  default: assert(0 && "Unknown builtin type!");
9425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Void:              return "void";
943d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  case Bool:              return CPlusPlus? "bool" : "_Bool";
9445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Char_S:            return "char";
9455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Char_U:            return "char";
9465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case SChar:             return "signed char";
9475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Short:             return "short";
9485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Int:               return "int";
9495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Long:              return "long";
9505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case LongLong:          return "long long";
9512df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner  case Int128:            return "__int128_t";
9525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case UChar:             return "unsigned char";
9535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case UShort:            return "unsigned short";
9545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case UInt:              return "unsigned int";
9555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ULong:             return "unsigned long";
9565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case ULongLong:         return "unsigned long long";
9572df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner  case UInt128:           return "__uint128_t";
9585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Float:             return "float";
9595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Double:            return "double";
9605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case LongDouble:        return "long double";
96146713efe13c89f4ec9cd9546c7b598fe7186089bArgyrios Kyrtzidis  case WChar:             return "wchar_t";
9626e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  case NullPtr:           return "nullptr_t";
9638e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  case Overload:          return "<overloaded function type>";
964898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  case Dependent:         return "<dependent type>";
9655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
9665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
96872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorvoid FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
969942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner                                arg_type_iterator ArgTys,
970971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis                                unsigned NumArgs, bool isVariadic,
971465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                                unsigned TypeQuals, bool hasExceptionSpec,
972465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                                bool anyExceptionSpec, unsigned NumExceptions,
973465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl                                exception_iterator Exs) {
9745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ID.AddPointer(Result.getAsOpaquePtr());
9755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0; i != NumArgs; ++i)
9765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID.AddPointer(ArgTys[i].getAsOpaquePtr());
9775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ID.AddInteger(isVariadic);
978971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  ID.AddInteger(TypeQuals);
979465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  ID.AddInteger(hasExceptionSpec);
980465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  if (hasExceptionSpec) {
981465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    ID.AddInteger(anyExceptionSpec);
982465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    for(unsigned i = 0; i != NumExceptions; ++i)
983465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      ID.AddPointer(Exs[i].getAsOpaquePtr());
984465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  }
9855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
98772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregorvoid FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
988971c4fae6092976338b755af1d47dac07c8f16e3Argyrios Kyrtzidis  Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
989465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl          getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(),
990465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl          getNumExceptions(), exception_begin());
9915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
993d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
994d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                    const ObjCInterfaceDecl *Decl,
995d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                    ObjCProtocolDecl **protocols,
996d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                    unsigned NumProtocols) {
9971ee0700c7dbe3554df09b4558e0b35a53d487ff2Chris Lattner  ID.AddPointer(Decl);
9984b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  for (unsigned i = 0; i != NumProtocols; i++)
9994b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian    ID.AddPointer(protocols[i]);
10004b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian}
10014b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
1002d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
10031ee0700c7dbe3554df09b4558e0b35a53d487ff2Chris Lattner  Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
10044b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian}
10054b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
1006d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
1007d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                         const ObjCInterfaceDecl *Decl,
1008d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                         ObjCProtocolDecl **protocols,
1009d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                         unsigned NumProtocols) {
1010d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  ID.AddPointer(Decl);
1011c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian  for (unsigned i = 0; i != NumProtocols; i++)
1012c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian    ID.AddPointer(protocols[i]);
1013c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian}
1014c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
1015d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
1016d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
1017c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian}
1018c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
1019a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
1020a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// potentially looking through *all* consequtive typedefs.  This returns the
1021a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// sum of the type qualifiers, so if you have:
1022a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner///   typedef const int A;
1023a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner///   typedef volatile A B;
1024a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner/// looking through the typedefs for B will give you "const volatile A".
1025a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner///
1026a2c7767ce7d8feb10253f4b650826a20f3324c6fChris LattnerQualType TypedefType::LookThroughTypedefs() const {
1027a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // Usually, there is only a single level of typedefs, be fast in that case.
1028a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  QualType FirstType = getDecl()->getUnderlyingType();
1029a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  if (!isa<TypedefType>(FirstType))
1030a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    return FirstType;
1031a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
1032a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  // Otherwise, do the fully general loop.
1033a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  unsigned TypeQuals = 0;
1034a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  const TypedefType *TDT = this;
1035a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  while (1) {
1036a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    QualType CurType = TDT->getDecl()->getUnderlyingType();
1037f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner
1038f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner
1039f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    /// FIXME:
1040f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian    /// FIXME: This is incorrect for ExtQuals!
1041f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    /// FIXME:
1042f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    TypeQuals |= CurType.getCVRQualifiers();
1043a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
1044a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    TDT = dyn_cast<TypedefType>(CurType);
1045a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner    if (TDT == 0)
1046a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner      return QualType(CurType.getTypePtr(), TypeQuals);
1047a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  }
1048a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner}
10495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
105072564e73277e29f6db3305d1f27ba408abb7ed88Douglas GregorTypeOfExprType::TypeOfExprType(Expr *E, QualType can)
105172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) {
1052898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  assert(!isa<TypedefType>(can) && "Invalid canonical type");
1053898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
1054898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
10557da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas GregorTagType::TagType(TypeClass TC, TagDecl *D, QualType can)
10567da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  : Type(TC, can, D->isDependentType()), decl(D, 0) {}
10577da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
10582daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattnerbool RecordType::classof(const TagType *TT) {
10592daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  return isa<RecordDecl>(TT->getDecl());
10605edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner}
10615edb8bfe8472e7d7bf6a82386394ef27359eb846Chris Lattner
10622daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattnerbool EnumType::classof(const TagType *TT) {
10632daa5df1b53f7ef745d724771384409f6f5df5c1Chris Lattner  return isa<EnumDecl>(TT->getDecl());
10645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
106640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregorbool
10677532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::
106840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas GregoranyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
106940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
107040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    switch (Args[Idx].getKind()) {
1071d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor    case TemplateArgument::Null:
1072d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor      assert(false && "Should not have a NULL template argument");
1073d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor      break;
1074d560d5025a0e5b1942d99d5f39005337b03a64c2Douglas Gregor
107540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Type:
107640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      if (Args[Idx].getAsType()->isDependentType())
107740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor        return true;
107840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
107940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
108040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Declaration:
108140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Integral:
108240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      // Never dependent
108340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
108440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
108540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Expression:
108640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      if (Args[Idx].getAsExpr()->isTypeDependent() ||
108740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor          Args[Idx].getAsExpr()->isValueDependent())
108840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor        return true;
108940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
1090d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
1091d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson    case TemplateArgument::Pack:
1092d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      assert(0 && "FIXME: Implement!");
1093d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      break;
109455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    }
109555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  }
109640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
109740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  return false;
109855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
109955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
11007532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::
11017532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType(TemplateName T, const TemplateArgument *Args,
11027532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                           unsigned NumArgs, QualType Canon)
11037532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  : Type(TemplateSpecialization,
110440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor         Canon.isNull()? QualType(this, 0) : Canon,
11057532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor         T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
110640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    Template(T), NumArgs(NumArgs)
110755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor{
110840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  assert((!Canon.isNull() ||
11097532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor          T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
111040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor         "No canonical type for non-dependent class template specialization");
111155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
111240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  TemplateArgument *TemplateArgs
111340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    = reinterpret_cast<TemplateArgument *>(this + 1);
111455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
111540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
111655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
111755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
11187532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregorvoid TemplateSpecializationType::Destroy(ASTContext& C) {
1119ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1120ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    // FIXME: Not all expressions get cloned, so we can't yet perform
1121ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    // this destruction.
1122ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    //    if (Expr *E = getArg(Arg).getAsExpr())
1123ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    //      E->Destroy(C);
1124ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor  }
112540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor}
112640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
11277532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::iterator
11287532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::end() const {
112940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  return begin() + getNumArgs();
11305908e9f25bc9a334c99c095e0b1e6a515445be2dDouglas Gregor}
11315908e9f25bc9a334c99c095e0b1e6a515445be2dDouglas Gregor
113240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregorconst TemplateArgument &
11337532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::getArg(unsigned Idx) const {
113440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  assert(Idx < getNumArgs() && "Template argument out of range");
113540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  return getArgs()[Idx];
113655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
113755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
113840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregorvoid
11397532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
11407532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                                    TemplateName T,
11417532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                                    const TemplateArgument *Args,
11427532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                                    unsigned NumArgs) {
11437532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  T.Profile(ID);
114440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
114540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    Args[Idx].Profile(ID);
114655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
114797e0179f1ae545e07d9f5e7c1d2ef5c5bab06676Anders Carlsson
11485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
11495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Type Printing
11505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
11515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid QualType::dump(const char *msg) const {
1153d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  PrintingPolicy Policy;
115439caea961530bc95d19114ab546ebcdb229263c9Chris Lattner  std::string R = "identifier";
1155d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getAsStringInternal(R, Policy);
11565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (msg)
11575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "%s: %s\n", msg, R.c_str());
11585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  else
11595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    fprintf(stderr, "%s\n", R.c_str());
11605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1161c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattnervoid QualType::dump() const {
1162c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  dump("");
1163c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner}
1164c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner
1165c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattnervoid Type::dump() const {
1166c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  std::string S = "identifier";
1167d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getAsStringInternal(S, PrintingPolicy());
1168c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner  fprintf(stderr, "%s\n", S.c_str());
1169c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner}
1170c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner
1171c36d405a02fab41f6c45cb2bc750d64949742903Chris Lattner
11725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
11745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Note: funkiness to ensure we get a space only between quals.
11755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NonePrinted = true;
11765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (TypeQuals & QualType::Const)
11775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "const", NonePrinted = false;
11785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (TypeQuals & QualType::Volatile)
11795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += (NonePrinted+" volatile"), NonePrinted = false;
11805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (TypeQuals & QualType::Restrict)
11815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += (NonePrinted+" restrict"), NonePrinted = false;
11825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
11835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1184d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorstd::string QualType::getAsString() const {
1185d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  std::string S;
1186d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getAsStringInternal(S, PrintingPolicy());
1187d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  return S;
1188d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor}
1189d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor
1190d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid
1191d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorQualType::getAsStringInternal(std::string &S,
1192d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                              const PrintingPolicy &Policy) const {
11935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isNull()) {
119461366e9cd41a6dbde4e66416dac21269c8ac1d94Douglas Gregor    S += "NULL TYPE";
11955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
11965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
119722b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
119842f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  if (Policy.SuppressSpecifiers && getTypePtr()->isSpecifierType())
119922b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    return;
120022b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman
12015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Print qualifiers as appropriate.
12023513e138cc75205b48d3078dfa4669355adb5714Gabor Greif  if (unsigned Tq = getCVRQualifiers()) {
12035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string TQS;
12043513e138cc75205b48d3078dfa4669355adb5714Gabor Greif    AppendTypeQualList(TQS, Tq);
12055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (!S.empty())
12065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      S = TQS + ' ' + S;
12075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
12085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      S = TQS;
12095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
12105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1211d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getTypePtr()->getAsStringInternal(S, Policy);
12125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1214d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid BuiltinType::getAsStringInternal(std::string &S,
1215d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                      const PrintingPolicy &Policy) const {
12165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (S.empty()) {
1217d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    S = getName(Policy.CPlusPlus);
12185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
12195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Prefix the basic type, e.g. 'int X'.
12205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = ' ' + S;
1221d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    S = getName(Policy.CPlusPlus) + S;
12225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
12235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1225d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid FixedWidthIntType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1226f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Once we get bitwidth attribute, write as
1227f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // "int __attribute__((bitwidth(x)))".
1228f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  std::string prefix = "__clang_fixedwidth";
1229f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  prefix += llvm::utostr_32(Width);
1230f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  prefix += (char)(Signed ? 'S' : 'U');
1231f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  if (S.empty()) {
1232f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    S = prefix;
1233f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  } else {
1234f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    // Prefix the basic type, e.g. 'int X'.
1235f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    S = prefix + S;
1236f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  }
1237f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman}
1238f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
1239f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman
1240d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ComplexType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1241d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  ElementType->getAsStringInternal(S, Policy);
12425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S = "_Complex " + S;
12435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1245d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ExtQualType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12463b6b83b8311ecdfa43cbb37ccc38c107d3b8d88bChris Lattner  bool NeedsSpace = false;
12474886a4204ff2b20bc226ce70d837de5fcd4a79abFariborz Jahanian  if (AddressSpace) {
124859d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
12493b6b83b8311ecdfa43cbb37ccc38c107d3b8d88bChris Lattner    NeedsSpace = true;
125059d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian  }
1251d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian  if (GCAttrType != QualType::GCNone) {
12523b6b83b8311ecdfa43cbb37ccc38c107d3b8d88bChris Lattner    if (NeedsSpace)
125359d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian      S += ' ';
125459d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    S += "__attribute__((objc_gc(";
1255d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian    if (GCAttrType == QualType::Weak)
125659d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian      S += "weak";
125759d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    else
125859d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian      S += "strong";
125959d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian    S += ")))";
126059d16d1402d76a298ab7fc5f362e9d3dfd744aa5Fariborz Jahanian  }
1261d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  BaseType->getAsStringInternal(S, Policy);
1262ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb}
1263ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb
1264d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid PointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S = '*' + S;
12665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle things like 'int (*A)[4];' correctly.
12685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: this should include vectors, but vectors use attributes I guess.
1269bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  if (isa<ArrayType>(getPointeeType()))
12705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = '(' + S + ')';
12715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1272d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
12735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
12745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1275d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid BlockPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12765618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  S = '^' + S;
1277d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  PointeeType.getAsStringInternal(S, Policy);
12785618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff}
12795618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff
1280d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S = '&' + S;
12827c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
12835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Handle things like 'int (&A)[4];' correctly.
12845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: this should include vectors, but vectors use attributes I guess.
1285bdcd637c29ec1540f912ea6860c88b910e78c329Chris Lattner  if (isa<ArrayType>(getPointeeType()))
12865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = '(' + S + ')';
12877c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1288d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
12897c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl}
12907c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1291d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
12927c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  S = "&&" + S;
12937c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
12947c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // Handle things like 'int (&&A)[4];' correctly.
12957c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // FIXME: this should include vectors, but vectors use attributes I guess.
12967c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  if (isa<ArrayType>(getPointeeType()))
12977c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl    S = '(' + S + ')';
12987c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl
1299d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
13005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1302d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1303f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  std::string C;
1304d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  Class->getAsStringInternal(C, Policy);
1305f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  C += "::*";
1306f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  S = C + S;
1307f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
13087c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  // Handle things like 'int (Cls::*A)[4];' correctly.
1309f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  // FIXME: this should include vectors, but vectors use attributes I guess.
1310f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl  if (isa<ArrayType>(getPointeeType()))
1311f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl    S = '(' + S + ')';
1312f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1313d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getPointeeType().getAsStringInternal(S, Policy);
1314f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl}
1315f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
1316d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1317fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  S += '[';
13186b91cd9af12fe1340e48e03e9b988d9888b4889fSteve Naroff  S += llvm::utostr(getSize().getZExtValue());
1319fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  S += ']';
1320fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
1321d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
1322fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff}
1323fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff
1324d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1325c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  S += "[]";
1326c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
1327d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
1328c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman}
1329c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
1330d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid VariableArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
13315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += '[';
13325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1333c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  if (getIndexTypeQualifier()) {
1334c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff    AppendTypeQualList(S, getIndexTypeQualifier());
13355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += ' ';
13365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
13375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1338c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  if (getSizeModifier() == Static)
13395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "static";
1340c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff  else if (getSizeModifier() == Star)
13415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += '*';
13425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1343fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  if (getSizeExpr()) {
1344a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    std::string SStr;
1345a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    llvm::raw_string_ostream s(SStr);
1346d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
1347fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff    S += s.str();
1348fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff  }
13495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += ']';
13505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1351d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
13525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1354d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid DependentSizedArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1355898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  S += '[';
1356898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1357898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  if (getIndexTypeQualifier()) {
1358898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    AppendTypeQualList(S, getIndexTypeQualifier());
1359898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += ' ';
1360898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
1361898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1362898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  if (getSizeModifier() == Static)
1363898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += "static";
1364898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  else if (getSizeModifier() == Star)
1365898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += '*';
1366898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1367898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  if (getSizeExpr()) {
1368898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    std::string SStr;
1369898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    llvm::raw_string_ostream s(SStr);
1370d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
1371898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    S += s.str();
1372898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
1373898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  S += ']';
1374898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1375d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
1376898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
1377898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
13789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
13799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  getElementType().getAsStringInternal(S, Policy);
13809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
13819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  S += " __attribute__((ext_vector_  type(";
13829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (getSizeExpr()) {
13839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    std::string SStr;
13849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    llvm::raw_string_ostream s(SStr);
13859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    getSizeExpr()->printPretty(s, 0, Policy);
13869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S += s.str();
13879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  }
13889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  S += ")))";
13899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor}
13909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1391d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
13925620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  // FIXME: We prefer to print the size directly here, but have no way
13935620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  // to get the size of the type.
13947ee261c8e71f363d86461f4d1a37e3def354c976Chris Lattner  S += " __attribute__((__vector_size__(";
13955620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  S += llvm::utostr_32(NumElements); // convert back to bytes.
13965620b50f8f81854b2a6fea16c69ff1853f8f4d9bDaniel Dunbar  S += " * sizeof(" + ElementType.getAsString() + "))))";
1397d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  ElementType.getAsStringInternal(S, Policy);
13985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1400d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
1401213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman  S += " __attribute__((ext_vector_type(";
140231a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff  S += llvm::utostr_32(NumElements);
140331a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff  S += ")))";
1404d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  ElementType.getAsStringInternal(S, Policy);
140531a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff}
140631a458462c6cf417a84e0c47852b18fb22d79acbSteve Naroff
1407d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypeOfExprType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1408363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
1409363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff    InnerString = ' ' + InnerString;
1410a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek  std::string Str;
1411a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek  llvm::raw_string_ostream s(Str);
1412d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getUnderlyingExpr()->printPretty(s, 0, Policy);
14136409625011e4a11ff07956ff46a44d6ca4473992Argyrios Kyrtzidis  InnerString = "typeof " + s.str() + InnerString;
1414d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff}
1415d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
1416d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypeOfType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1417363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
1418363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff    InnerString = ' ' + InnerString;
1419d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  std::string Tmp;
1420d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getUnderlyingType().getAsStringInternal(Tmp, Policy);
1421363bcff47df2fda3cfcfcd994b7888157df58c43Steve Naroff  InnerString = "typeof(" + Tmp + ")" + InnerString;
1422d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff}
1423d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff
1424d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid FunctionNoProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
14255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If needed for precedence reasons, wrap the inner part in grouping parens.
14265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!S.empty())
14275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = "(" + S + ")";
14285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += "()";
1430d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getResultType().getAsStringInternal(S, Policy);
14315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1433d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
14345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If needed for precedence reasons, wrap the inner part in grouping parens.
14355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!S.empty())
14365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S = "(" + S + ")";
14375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += "(";
14395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::string Tmp;
144022b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman  PrintingPolicy ParamPolicy(Policy);
144142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  ParamPolicy.SuppressSpecifiers = false;
14425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
14435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (i) S += ", ";
144422b61e937dcd8ba2e14764c367f975a392ec7da0Eli Friedman    getArgType(i).getAsStringInternal(Tmp, ParamPolicy);
14455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += Tmp;
14465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Tmp.clear();
14475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isVariadic()) {
14505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (getNumArgs())
14515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      S += ", ";
14525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "...";
14537c94c4bb7b875dc1a2b23f77f1ed8013cf94abdbArgyrios Kyrtzidis  } else if (getNumArgs() == 0 && !Policy.CPlusPlus) {
14545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Do not emit int() if we have a proto, emit 'int(void)'.
14555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    S += "void";
14565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  S += ")";
1459d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  getResultType().getAsStringInternal(S, Policy);
14605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1463d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
14645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
14655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InnerString = ' ' + InnerString;
14665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InnerString = getDecl()->getIdentifier()->getName() + InnerString;
14675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1469d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
147072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  if (!InnerString.empty())    // Prefix the basic type, e.g. 'parmname X'.
147172c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor    InnerString = ' ' + InnerString;
1472fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor
1473fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  if (!Name)
1474fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' +
1475fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor      llvm::utostr_32(Index) + InnerString;
1476fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  else
1477fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor    InnerString = Name->getName() + InnerString;
147872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor}
147972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
1480d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorstd::string
1481d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorTemplateSpecializationType::PrintTemplateArgumentList(
1482d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                  const TemplateArgument *Args,
1483d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                  unsigned NumArgs,
1484d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                  const PrintingPolicy &Policy) {
148598137534e612c274ba270af99d73429043957e53Douglas Gregor  std::string SpecString;
148655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  SpecString += '<';
148755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
148855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    if (Arg)
148955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor      SpecString += ", ";
149055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
149155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // Print the argument into a string.
149255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    std::string ArgString;
149398137534e612c274ba270af99d73429043957e53Douglas Gregor    switch (Args[Arg].getKind()) {
149438999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor    case TemplateArgument::Null:
149538999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor      assert(false && "Null template argument");
149638999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor      break;
149738999462749c22d49d1e1707206aaa4997636f4cDouglas Gregor
149840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Type:
1499d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor      Args[Arg].getAsType().getAsStringInternal(ArgString, Policy);
150040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
150140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
150240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Declaration:
150398137534e612c274ba270af99d73429043957e53Douglas Gregor      ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
150440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
150540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
150640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Integral:
150798137534e612c274ba270af99d73429043957e53Douglas Gregor      ArgString = Args[Arg].getAsIntegral()->toString(10, true);
150840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
150940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
151040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    case TemplateArgument::Expression: {
151155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor      llvm::raw_string_ostream s(ArgString);
1512d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor      Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
151340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor      break;
151440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    }
1515d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson    case TemplateArgument::Pack:
1516d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      assert(0 && "FIXME: Implement!");
1517d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson      break;
151855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    }
151955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
152055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // If this is the first argument and its string representation
152155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // begins with the global scope specifier ('::foo'), add a space
152255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    // to avoid printing the diagraph '<:'.
152355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
152455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor      SpecString += ' ';
152555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
152655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    SpecString += ArgString;
152755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  }
152855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
152955f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // If the last character of our string is '>', add another space to
153055f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // keep the two '>''s separate tokens. We don't *have* to do this in
153155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  // C++0x, but it's still good hygiene.
153255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  if (SpecString[SpecString.size() - 1] == '>')
153355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    SpecString += ' ';
153455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
153555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  SpecString += '>';
153655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
153798137534e612c274ba270af99d73429043957e53Douglas Gregor  return SpecString;
153898137534e612c274ba270af99d73429043957e53Douglas Gregor}
153998137534e612c274ba270af99d73429043957e53Douglas Gregor
154098137534e612c274ba270af99d73429043957e53Douglas Gregorvoid
15417532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas GregorTemplateSpecializationType::
1542d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorgetAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
15437532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  std::string SpecString;
15447532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor
15457532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  {
15467532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor    llvm::raw_string_ostream OS(SpecString);
1547d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    Template.print(OS, Policy);
15487532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  }
15497532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor
1550d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs(), Policy);
155155f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  if (InnerString.empty())
155255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    InnerString.swap(SpecString);
155355f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor  else
155455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor    InnerString = SpecString + ' ' + InnerString;
155555f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor}
155655f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
1557d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid QualifiedNameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1558e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  std::string MyString;
1559e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1560bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor  {
1561bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor    llvm::raw_string_ostream OS(MyString);
1562d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    NNS->print(OS, Policy);
1563e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
1564e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1565e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  std::string TypeStr;
1566d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  PrintingPolicy InnerPolicy(Policy);
1567d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  InnerPolicy.SuppressTagKind = true;
1568d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  NamedType.getAsStringInternal(TypeStr, InnerPolicy);
1569e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1570e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  MyString += TypeStr;
1571e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  if (InnerString.empty())
1572d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    InnerString.swap(MyString);
1573d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  else
1574d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    InnerString = MyString + ' ' + InnerString;
1575d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor}
1576d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1577d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TypenameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
1578d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  std::string MyString;
1579d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1580d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  {
1581d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    llvm::raw_string_ostream OS(MyString);
1582d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    OS << "typename ";
1583d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    NNS->print(OS, Policy);
15841734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor
15851734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    if (const IdentifierInfo *Ident = getIdentifier())
15861734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      OS << Ident->getName();
15871734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    else if (const TemplateSpecializationType *Spec = getTemplateId()) {
1588d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor      Spec->getTemplateName().print(OS, Policy, true);
15891734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      OS << TemplateSpecializationType::PrintTemplateArgumentList(
1590d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                               Spec->getArgs(),
1591d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                            Spec->getNumArgs(),
1592d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                               Policy);
15931734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    }
1594d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  }
1595d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1596d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  if (InnerString.empty())
1597e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    InnerString.swap(MyString);
1598e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  else
1599e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    InnerString = MyString + ' ' + InnerString;
1600e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
1601e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1602d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
16033536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
16043536b443bc50d58a79f14fca9b6842541a434854Steve Naroff    InnerString = ' ' + InnerString;
16053536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  InnerString = getDecl()->getIdentifier()->getName() + InnerString;
16063536b443bc50d58a79f14fca9b6842541a434854Steve Naroff}
16073536b443bc50d58a79f14fca9b6842541a434854Steve Naroff
1608d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroffvoid ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
1609d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                                                const PrintingPolicy &Policy) const {
1610d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
1611d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    InnerString = ' ' + InnerString;
1612d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
1613d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  std::string ObjCQIString;
1614d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
1615d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (getDecl())
1616d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCQIString = getDecl()->getNameAsString();
1617d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  else
1618d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCQIString = "id";
1619d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
1620d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (!qual_empty()) {
1621d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCQIString += '<';
1622d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
1623d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      ObjCQIString += (*I)->getNameAsString();
1624d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      if (I+1 != E)
1625d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff        ObjCQIString += ',';
1626d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    }
1627d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCQIString += '>';
1628d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  }
1629d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  InnerString = ObjCQIString + InnerString;
1630d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff}
1631d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
1632d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid
1633d249e1d1f1498b81314459ceda19d6ff25c278adDouglas GregorObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString,
1634d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                           const PrintingPolicy &Policy) const {
1635dfbcce2b55ca8b45ce9d9c09c32e43c3bd73ac2aFariborz Jahanian  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
1636dfbcce2b55ca8b45ce9d9c09c32e43c3bd73ac2aFariborz Jahanian    InnerString = ' ' + InnerString;
163739f34e97d6a468f0a7dfa5664c61217cffc65b74Chris Lattner  std::string ObjCQIString = getDecl()->getNameAsString();
1638a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQIString += '<';
1639cdce6d17be572ae49417022357906ce04b54137dChris Lattner  bool isFirst = true;
1640cdce6d17be572ae49417022357906ce04b54137dChris Lattner  for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
1641cdce6d17be572ae49417022357906ce04b54137dChris Lattner    if (isFirst)
1642cdce6d17be572ae49417022357906ce04b54137dChris Lattner      isFirst = false;
1643cdce6d17be572ae49417022357906ce04b54137dChris Lattner    else
1644a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCQIString += ',';
164539f34e97d6a468f0a7dfa5664c61217cffc65b74Chris Lattner    ObjCQIString += (*I)->getNameAsString();
16464b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  }
1647a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCQIString += '>';
1648a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  InnerString = ObjCQIString + InnerString;
16494b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian}
16504b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian
1651d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorvoid TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
165242f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  if (Policy.SuppressTag)
165342f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    return;
165442f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
16555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
16565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    InnerString = ' ' + InnerString;
16575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1658d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName();
16595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *ID;
16605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const IdentifierInfo *II = getDecl()->getIdentifier())
16615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID = II->getName();
16624e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor  else if (TypedefDecl *Typedef = getDecl()->getTypedefForAnonDecl()) {
16634e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    Kind = 0;
16644e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    assert(Typedef->getIdentifier() && "Typedef without identifier?");
16654e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    ID = Typedef->getIdentifier()->getName();
16664e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor  } else
16675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ID = "<anonymous>";
16685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
166998137534e612c274ba270af99d73429043957e53Douglas Gregor  // If this is a class template specialization, print the template
167098137534e612c274ba270af99d73429043957e53Douglas Gregor  // arguments.
167198137534e612c274ba270af99d73429043957e53Douglas Gregor  if (ClassTemplateSpecializationDecl *Spec
167298137534e612c274ba270af99d73429043957e53Douglas Gregor        = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
16737e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
16747e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    std::string TemplateArgsStr
16757532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor      = TemplateSpecializationType::PrintTemplateArgumentList(
16767e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                            TemplateArgs.getFlatArgumentList(),
1677d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                            TemplateArgs.flat_size(),
1678d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                                              Policy);
16797e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    InnerString = TemplateArgsStr + InnerString;
168098137534e612c274ba270af99d73429043957e53Douglas Gregor  }
168198137534e612c274ba270af99d73429043957e53Douglas Gregor
168224c46b3133b03e254877a680f92f035e56058a39Douglas Gregor  if (Kind) {
168324c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    // Compute the full nested-name-specifier for this type. In C,
168424c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    // this will always be empty.
168524c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    std::string ContextStr;
168624c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    for (DeclContext *DC = getDecl()->getDeclContext();
168724c46b3133b03e254877a680f92f035e56058a39Douglas Gregor         !DC->isTranslationUnit(); DC = DC->getParent()) {
168824c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      std::string MyPart;
168924c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
169024c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        if (NS->getIdentifier())
169124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor          MyPart = NS->getNameAsString();
169224c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      } else if (ClassTemplateSpecializationDecl *Spec
169324c46b3133b03e254877a680f92f035e56058a39Douglas Gregor                   = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
16947e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
16957e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor        std::string TemplateArgsStr
16967532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor          = TemplateSpecializationType::PrintTemplateArgumentList(
16977e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                           TemplateArgs.getFlatArgumentList(),
1698d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                           TemplateArgs.flat_size(),
1699d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor                                           Policy);
17007e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor        MyPart = Spec->getIdentifier()->getName() + TemplateArgsStr;
170124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
170224c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
170324c46b3133b03e254877a680f92f035e56058a39Douglas Gregor          MyPart = Typedef->getIdentifier()->getName();
170424c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        else if (Tag->getIdentifier())
170524c46b3133b03e254877a680f92f035e56058a39Douglas Gregor          MyPart = Tag->getIdentifier()->getName();
170624c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      }
170724c46b3133b03e254877a680f92f035e56058a39Douglas Gregor
170824c46b3133b03e254877a680f92f035e56058a39Douglas Gregor      if (!MyPart.empty())
170924c46b3133b03e254877a680f92f035e56058a39Douglas Gregor        ContextStr = MyPart + "::" + ContextStr;
171024c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    }
171124c46b3133b03e254877a680f92f035e56058a39Douglas Gregor
171224c46b3133b03e254877a680f92f035e56058a39Douglas Gregor    InnerString = std::string(Kind) + " " + ContextStr + ID + InnerString;
171324c46b3133b03e254877a680f92f035e56058a39Douglas Gregor  } else
17144e16d0478407b556c819b5836a3564a9fdee8d5fDouglas Gregor    InnerString = ID + InnerString;
17155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1716