Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1 | //===--- Type.cpp - Type representation and manipulation ------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements type-related functionality. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Nuno Lopes | b381aac | 2008-09-01 11:33:04 +0000 | [diff] [blame] | 14 | #include "clang/AST/ASTContext.h" |
Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 15 | #include "clang/AST/CharUnits.h" |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 16 | #include "clang/AST/Type.h" |
Argyrios Kyrtzidis | 49aa7ff | 2008-08-07 20:55:28 +0000 | [diff] [blame] | 17 | #include "clang/AST/DeclCXX.h" |
Steve Naroff | 980e508 | 2007-10-01 19:00:59 +0000 | [diff] [blame] | 18 | #include "clang/AST/DeclObjC.h" |
Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 19 | #include "clang/AST/DeclTemplate.h" |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 20 | #include "clang/AST/Expr.h" |
Douglas Gregor | d249e1d1f | 2009-05-29 20:38:28 +0000 | [diff] [blame] | 21 | #include "clang/AST/PrettyPrinter.h" |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 22 | #include "clang/AST/TypeVisitor.h" |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 23 | #include "clang/Basic/Specifiers.h" |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/StringExtras.h" |
Douglas Gregor | bad3518 | 2009-03-19 03:51:16 +0000 | [diff] [blame] | 25 | #include "llvm/Support/raw_ostream.h" |
Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 26 | #include <algorithm> |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 27 | using namespace clang; |
| 28 | |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 29 | bool QualType::isConstant(QualType T, ASTContext &Ctx) { |
| 30 | if (T.isConstQualified()) |
Nuno Lopes | b381aac | 2008-09-01 11:33:04 +0000 | [diff] [blame] | 31 | return true; |
| 32 | |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 33 | if (const ArrayType *AT = Ctx.getAsArrayType(T)) |
| 34 | return AT->getElementType().isConstant(Ctx); |
Nuno Lopes | b381aac | 2008-09-01 11:33:04 +0000 | [diff] [blame] | 35 | |
| 36 | return false; |
| 37 | } |
| 38 | |
Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 39 | unsigned ConstantArrayType::getNumAddressingBits(ASTContext &Context, |
| 40 | QualType ElementType, |
| 41 | const llvm::APInt &NumElements) { |
| 42 | llvm::APSInt SizeExtended(NumElements, true); |
| 43 | unsigned SizeTypeBits = Context.getTypeSize(Context.getSizeType()); |
Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 44 | SizeExtended = SizeExtended.extend(std::max(SizeTypeBits, |
| 45 | SizeExtended.getBitWidth()) * 2); |
Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 46 | |
| 47 | uint64_t ElementSize |
| 48 | = Context.getTypeSizeInChars(ElementType).getQuantity(); |
| 49 | llvm::APSInt TotalSize(llvm::APInt(SizeExtended.getBitWidth(), ElementSize)); |
| 50 | TotalSize *= SizeExtended; |
| 51 | |
| 52 | return TotalSize.getActiveBits(); |
| 53 | } |
| 54 | |
| 55 | unsigned ConstantArrayType::getMaxSizeBits(ASTContext &Context) { |
| 56 | unsigned Bits = Context.getTypeSize(Context.getSizeType()); |
| 57 | |
| 58 | // GCC appears to only allow 63 bits worth of address space when compiling |
| 59 | // for 64-bit, so we do the same. |
| 60 | if (Bits == 64) |
| 61 | --Bits; |
| 62 | |
| 63 | return Bits; |
| 64 | } |
| 65 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 66 | void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, |
Douglas Gregor | 04d4bee | 2009-07-31 00:23:35 +0000 | [diff] [blame] | 67 | ASTContext &Context, |
| 68 | QualType ET, |
| 69 | ArraySizeModifier SizeMod, |
| 70 | unsigned TypeQuals, |
| 71 | Expr *E) { |
| 72 | ID.AddPointer(ET.getAsOpaquePtr()); |
| 73 | ID.AddInteger(SizeMod); |
| 74 | ID.AddInteger(TypeQuals); |
| 75 | E->Profile(ID, Context, true); |
| 76 | } |
| 77 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 78 | void |
| 79 | DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, |
Douglas Gregor | 2ec09f1 | 2009-07-31 03:54:25 +0000 | [diff] [blame] | 80 | ASTContext &Context, |
| 81 | QualType ElementType, Expr *SizeExpr) { |
| 82 | ID.AddPointer(ElementType.getAsOpaquePtr()); |
| 83 | SizeExpr->Profile(ID, Context, true); |
| 84 | } |
| 85 | |
Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 86 | /// getArrayElementTypeNoTypeQual - If this is an array type, return the |
| 87 | /// element type of the array, potentially with type qualifiers missing. |
| 88 | /// This method should never be used when type qualifiers are meaningful. |
| 89 | const Type *Type::getArrayElementTypeNoTypeQual() const { |
| 90 | // If this is directly an array type, return it. |
| 91 | if (const ArrayType *ATy = dyn_cast<ArrayType>(this)) |
| 92 | return ATy->getElementType().getTypePtr(); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 93 | |
Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 94 | // If the canonical form of this type isn't the right kind, reject it. |
John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 95 | if (!isa<ArrayType>(CanonicalType)) |
Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 96 | return 0; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 97 | |
Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 98 | // If this is a typedef for an array type, strip the typedef off without |
| 99 | // losing all typedef information. |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 100 | return cast<ArrayType>(getUnqualifiedDesugaredType()) |
| 101 | ->getElementType().getTypePtr(); |
Chris Lattner | 2fa8c25 | 2009-03-17 22:51:02 +0000 | [diff] [blame] | 102 | } |
| 103 | |
Douglas Gregor | fa1a06e | 2009-11-17 00:55:50 +0000 | [diff] [blame] | 104 | /// \brief Retrieve the unqualified variant of the given type, removing as |
| 105 | /// little sugar as possible. |
| 106 | /// |
| 107 | /// This routine looks through various kinds of sugar to find the |
| 108 | /// least-desuraged type that is unqualified. For example, given: |
| 109 | /// |
| 110 | /// \code |
| 111 | /// typedef int Integer; |
| 112 | /// typedef const Integer CInteger; |
| 113 | /// typedef CInteger DifferenceType; |
| 114 | /// \endcode |
| 115 | /// |
| 116 | /// Executing \c getUnqualifiedTypeSlow() on the type \c DifferenceType will |
| 117 | /// desugar until we hit the type \c Integer, which has no qualifiers on it. |
| 118 | QualType QualType::getUnqualifiedTypeSlow() const { |
| 119 | QualType Cur = *this; |
| 120 | while (true) { |
| 121 | if (!Cur.hasQualifiers()) |
| 122 | return Cur; |
| 123 | |
| 124 | const Type *CurTy = Cur.getTypePtr(); |
| 125 | switch (CurTy->getTypeClass()) { |
| 126 | #define ABSTRACT_TYPE(Class, Parent) |
| 127 | #define TYPE(Class, Parent) \ |
| 128 | case Type::Class: { \ |
| 129 | const Class##Type *Ty = cast<Class##Type>(CurTy); \ |
| 130 | if (!Ty->isSugared()) \ |
| 131 | return Cur.getLocalUnqualifiedType(); \ |
| 132 | Cur = Ty->desugar(); \ |
| 133 | break; \ |
| 134 | } |
| 135 | #include "clang/AST/TypeNodes.def" |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | return Cur.getUnqualifiedType(); |
| 140 | } |
| 141 | |
Chris Lattner | 2fa8c25 | 2009-03-17 22:51:02 +0000 | [diff] [blame] | 142 | /// getDesugaredType - Return the specified type with any "sugar" removed from |
| 143 | /// the type. This takes off typedefs, typeof's etc. If the outer level of |
| 144 | /// the type is already concrete, it returns it unmodified. This is similar |
| 145 | /// to getting the canonical type, but it doesn't remove *all* typedefs. For |
| 146 | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is |
| 147 | /// concrete. |
John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 148 | QualType QualType::getDesugaredType(QualType T, ASTContext &Context) { |
| 149 | SplitQualType split = getSplitDesugaredType(T); |
| 150 | return Context.getQualifiedType(split.first, split.second); |
| 151 | } |
| 152 | |
| 153 | SplitQualType QualType::getSplitDesugaredType(QualType T) { |
John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 154 | QualifierCollector Qs; |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 155 | |
| 156 | QualType Cur = T; |
| 157 | while (true) { |
| 158 | const Type *CurTy = Qs.strip(Cur); |
| 159 | switch (CurTy->getTypeClass()) { |
| 160 | #define ABSTRACT_TYPE(Class, Parent) |
| 161 | #define TYPE(Class, Parent) \ |
| 162 | case Type::Class: { \ |
| 163 | const Class##Type *Ty = cast<Class##Type>(CurTy); \ |
| 164 | if (!Ty->isSugared()) \ |
John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 165 | return SplitQualType(Ty, Qs); \ |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 166 | Cur = Ty->desugar(); \ |
| 167 | break; \ |
| 168 | } |
| 169 | #include "clang/AST/TypeNodes.def" |
| 170 | } |
| 171 | } |
Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 172 | } |
| 173 | |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 174 | /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic |
| 175 | /// sugar off the given type. This should produce an object of the |
| 176 | /// same dynamic type as the canonical type. |
| 177 | const Type *Type::getUnqualifiedDesugaredType() const { |
| 178 | const Type *Cur = this; |
Douglas Gregor | 969c689 | 2009-04-01 15:47:24 +0000 | [diff] [blame] | 179 | |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 180 | while (true) { |
| 181 | switch (Cur->getTypeClass()) { |
| 182 | #define ABSTRACT_TYPE(Class, Parent) |
| 183 | #define TYPE(Class, Parent) \ |
| 184 | case Class: { \ |
| 185 | const Class##Type *Ty = cast<Class##Type>(Cur); \ |
| 186 | if (!Ty->isSugared()) return Cur; \ |
| 187 | Cur = Ty->desugar().getTypePtr(); \ |
| 188 | break; \ |
| 189 | } |
| 190 | #include "clang/AST/TypeNodes.def" |
| 191 | } |
Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 192 | } |
Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 193 | } |
| 194 | |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 195 | /// isVoidType - Helper method to determine if this is the 'void' type. |
| 196 | bool Type::isVoidType() const { |
| 197 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 198 | return BT->getKind() == BuiltinType::Void; |
| 199 | return false; |
| 200 | } |
| 201 | |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 202 | bool Type::isDerivedType() const { |
| 203 | switch (CanonicalType->getTypeClass()) { |
| 204 | case Pointer: |
Steve Naroff | fb22d96 | 2007-08-30 01:06:46 +0000 | [diff] [blame] | 205 | case VariableArray: |
| 206 | case ConstantArray: |
Eli Friedman | c5773c4 | 2008-02-15 18:16:39 +0000 | [diff] [blame] | 207 | case IncompleteArray: |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 208 | case FunctionProto: |
| 209 | case FunctionNoProto: |
Sebastian Redl | 7c80bd6 | 2009-03-16 23:22:08 +0000 | [diff] [blame] | 210 | case LValueReference: |
| 211 | case RValueReference: |
Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 212 | case Record: |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 213 | return true; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 214 | default: |
| 215 | return false; |
| 216 | } |
| 217 | } |
| 218 | |
Chris Lattner | 99dc914 | 2008-04-13 18:59:07 +0000 | [diff] [blame] | 219 | bool Type::isClassType() const { |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 220 | if (const RecordType *RT = getAs<RecordType>()) |
Chris Lattner | f728a4a | 2009-01-11 23:59:49 +0000 | [diff] [blame] | 221 | return RT->getDecl()->isClass(); |
Chris Lattner | 99dc914 | 2008-04-13 18:59:07 +0000 | [diff] [blame] | 222 | return false; |
| 223 | } |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 224 | bool Type::isStructureType() const { |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 225 | if (const RecordType *RT = getAs<RecordType>()) |
Chris Lattner | f728a4a | 2009-01-11 23:59:49 +0000 | [diff] [blame] | 226 | return RT->getDecl()->isStruct(); |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 227 | return false; |
| 228 | } |
Douglas Gregor | fb87b89 | 2010-04-26 21:31:17 +0000 | [diff] [blame] | 229 | bool Type::isStructureOrClassType() const { |
| 230 | if (const RecordType *RT = getAs<RecordType>()) |
| 231 | return RT->getDecl()->isStruct() || RT->getDecl()->isClass(); |
| 232 | return false; |
| 233 | } |
Steve Naroff | 7154a77 | 2009-07-01 14:36:47 +0000 | [diff] [blame] | 234 | bool Type::isVoidPointerType() const { |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 235 | if (const PointerType *PT = getAs<PointerType>()) |
Steve Naroff | 7154a77 | 2009-07-01 14:36:47 +0000 | [diff] [blame] | 236 | return PT->getPointeeType()->isVoidType(); |
| 237 | return false; |
| 238 | } |
| 239 | |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 240 | bool Type::isUnionType() const { |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 241 | if (const RecordType *RT = getAs<RecordType>()) |
Chris Lattner | f728a4a | 2009-01-11 23:59:49 +0000 | [diff] [blame] | 242 | return RT->getDecl()->isUnion(); |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 243 | return false; |
| 244 | } |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 245 | |
Chris Lattner | c6fb90a | 2007-08-21 16:54:08 +0000 | [diff] [blame] | 246 | bool Type::isComplexType() const { |
Steve Naroff | 02f62a9 | 2008-01-15 19:36:10 +0000 | [diff] [blame] | 247 | if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType)) |
| 248 | return CT->getElementType()->isFloatingType(); |
| 249 | return false; |
Chris Lattner | c6fb90a | 2007-08-21 16:54:08 +0000 | [diff] [blame] | 250 | } |
| 251 | |
Steve Naroff | 4cdec1c | 2008-01-15 01:41:59 +0000 | [diff] [blame] | 252 | bool Type::isComplexIntegerType() const { |
| 253 | // Check for GCC complex integer extension. |
John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 254 | return getAsComplexIntegerType(); |
Steve Naroff | 4cdec1c | 2008-01-15 01:41:59 +0000 | [diff] [blame] | 255 | } |
| 256 | |
| 257 | const ComplexType *Type::getAsComplexIntegerType() const { |
John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 258 | if (const ComplexType *Complex = getAs<ComplexType>()) |
| 259 | if (Complex->getElementType()->isIntegerType()) |
| 260 | return Complex; |
| 261 | return 0; |
Steve Naroff | 4cdec1c | 2008-01-15 01:41:59 +0000 | [diff] [blame] | 262 | } |
| 263 | |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 264 | QualType Type::getPointeeType() const { |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 265 | if (const PointerType *PT = getAs<PointerType>()) |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 266 | return PT->getPointeeType(); |
John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 267 | if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 268 | return OPT->getPointeeType(); |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 269 | if (const BlockPointerType *BPT = getAs<BlockPointerType>()) |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 270 | return BPT->getPointeeType(); |
Mike Stump | 9c21289 | 2009-11-03 19:03:17 +0000 | [diff] [blame] | 271 | if (const ReferenceType *RT = getAs<ReferenceType>()) |
| 272 | return RT->getPointeeType(); |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 273 | return QualType(); |
| 274 | } |
Chris Lattner | b77792e | 2008-07-26 22:17:49 +0000 | [diff] [blame] | 275 | |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 276 | const RecordType *Type::getAsStructureType() const { |
Steve Naroff | 7064f5c | 2007-07-26 18:32:01 +0000 | [diff] [blame] | 277 | // If this is directly a structure type, return it. |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 278 | if (const RecordType *RT = dyn_cast<RecordType>(this)) { |
Argyrios Kyrtzidis | 39ba4ae | 2008-06-09 23:19:58 +0000 | [diff] [blame] | 279 | if (RT->getDecl()->isStruct()) |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 280 | return RT; |
Steve Naroff | 7064f5c | 2007-07-26 18:32:01 +0000 | [diff] [blame] | 281 | } |
Chris Lattner | dea6146 | 2007-10-29 03:41:11 +0000 | [diff] [blame] | 282 | |
| 283 | // If the canonical form of this type isn't the right kind, reject it. |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 284 | if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) { |
Argyrios Kyrtzidis | 39ba4ae | 2008-06-09 23:19:58 +0000 | [diff] [blame] | 285 | if (!RT->getDecl()->isStruct()) |
Chris Lattner | dea6146 | 2007-10-29 03:41:11 +0000 | [diff] [blame] | 286 | return 0; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 287 | |
Chris Lattner | dea6146 | 2007-10-29 03:41:11 +0000 | [diff] [blame] | 288 | // If this is a typedef for a structure type, strip the typedef off without |
| 289 | // losing all typedef information. |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 290 | return cast<RecordType>(getUnqualifiedDesugaredType()); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 291 | } |
Steve Naroff | 7064f5c | 2007-07-26 18:32:01 +0000 | [diff] [blame] | 292 | return 0; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 293 | } |
| 294 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 295 | const RecordType *Type::getAsUnionType() const { |
Steve Naroff | 7064f5c | 2007-07-26 18:32:01 +0000 | [diff] [blame] | 296 | // If this is directly a union type, return it. |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 297 | if (const RecordType *RT = dyn_cast<RecordType>(this)) { |
Argyrios Kyrtzidis | 39ba4ae | 2008-06-09 23:19:58 +0000 | [diff] [blame] | 298 | if (RT->getDecl()->isUnion()) |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 299 | return RT; |
Steve Naroff | 7064f5c | 2007-07-26 18:32:01 +0000 | [diff] [blame] | 300 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 301 | |
Chris Lattner | dea6146 | 2007-10-29 03:41:11 +0000 | [diff] [blame] | 302 | // If the canonical form of this type isn't the right kind, reject it. |
Chris Lattner | c862963 | 2007-07-31 19:29:30 +0000 | [diff] [blame] | 303 | if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) { |
Argyrios Kyrtzidis | 39ba4ae | 2008-06-09 23:19:58 +0000 | [diff] [blame] | 304 | if (!RT->getDecl()->isUnion()) |
Chris Lattner | dea6146 | 2007-10-29 03:41:11 +0000 | [diff] [blame] | 305 | return 0; |
| 306 | |
| 307 | // If this is a typedef for a union type, strip the typedef off without |
| 308 | // losing all typedef information. |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 309 | return cast<RecordType>(getUnqualifiedDesugaredType()); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 310 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 311 | |
Steve Naroff | 7064f5c | 2007-07-26 18:32:01 +0000 | [diff] [blame] | 312 | return 0; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 313 | } |
| 314 | |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 315 | ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, |
| 316 | ObjCProtocolDecl * const *Protocols, |
| 317 | unsigned NumProtocols) |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 318 | : Type(ObjCObject, Canonical, false, false), |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 319 | BaseType(Base) { |
John McCall | b870b88 | 2010-10-14 21:48:26 +0000 | [diff] [blame] | 320 | ObjCObjectTypeBits.NumProtocols = NumProtocols; |
John McCall | 71c3673 | 2010-10-14 03:00:17 +0000 | [diff] [blame] | 321 | assert(getNumProtocols() == NumProtocols && |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 322 | "bitfield overflow in protocol count"); |
| 323 | if (NumProtocols) |
| 324 | memcpy(getProtocolStorage(), Protocols, |
| 325 | NumProtocols * sizeof(ObjCProtocolDecl*)); |
| 326 | } |
| 327 | |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 328 | const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const { |
| 329 | // There is no sugar for ObjCObjectType's, just return the canonical |
Steve Naroff | c15cb2a | 2009-07-18 15:33:26 +0000 | [diff] [blame] | 330 | // type pointer if it is the right class. There is no typedef information to |
| 331 | // return and these cannot be Address-space qualified. |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 332 | if (const ObjCObjectType *T = getAs<ObjCObjectType>()) |
| 333 | if (T->getNumProtocols() && T->getInterface()) |
| 334 | return T; |
Steve Naroff | c15cb2a | 2009-07-18 15:33:26 +0000 | [diff] [blame] | 335 | return 0; |
| 336 | } |
| 337 | |
| 338 | bool Type::isObjCQualifiedInterfaceType() const { |
Steve Naroff | e61ad0b | 2009-07-18 15:38:31 +0000 | [diff] [blame] | 339 | return getAsObjCQualifiedInterfaceType() != 0; |
Steve Naroff | c15cb2a | 2009-07-18 15:33:26 +0000 | [diff] [blame] | 340 | } |
| 341 | |
Steve Naroff | d1b3c2d | 2009-06-17 22:40:22 +0000 | [diff] [blame] | 342 | const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const { |
Chris Lattner | eca7be6 | 2008-04-07 05:30:13 +0000 | [diff] [blame] | 343 | // There is no sugar for ObjCQualifiedIdType's, just return the canonical |
| 344 | // type pointer if it is the right class. |
John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 345 | if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) { |
Steve Naroff | d1b3c2d | 2009-06-17 22:40:22 +0000 | [diff] [blame] | 346 | if (OPT->isObjCQualifiedIdType()) |
| 347 | return OPT; |
| 348 | } |
| 349 | return 0; |
Chris Lattner | 368eefa | 2008-04-07 00:27:04 +0000 | [diff] [blame] | 350 | } |
| 351 | |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 352 | const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const { |
John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 353 | if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) { |
Steve Naroff | 14108da | 2009-07-10 23:34:53 +0000 | [diff] [blame] | 354 | if (OPT->getInterfaceType()) |
| 355 | return OPT; |
| 356 | } |
| 357 | return 0; |
| 358 | } |
| 359 | |
Fariborz Jahanian | a91d6a6 | 2009-07-29 00:44:13 +0000 | [diff] [blame] | 360 | const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const { |
Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 361 | if (const PointerType *PT = getAs<PointerType>()) |
| 362 | if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>()) |
Fariborz Jahanian | a91d6a6 | 2009-07-29 00:44:13 +0000 | [diff] [blame] | 363 | return dyn_cast<CXXRecordDecl>(RT->getDecl()); |
| 364 | return 0; |
| 365 | } |
| 366 | |
Douglas Gregor | c96be1e | 2010-04-27 18:19:34 +0000 | [diff] [blame] | 367 | CXXRecordDecl *Type::getAsCXXRecordDecl() const { |
| 368 | if (const RecordType *RT = getAs<RecordType>()) |
| 369 | return dyn_cast<CXXRecordDecl>(RT->getDecl()); |
| 370 | else if (const InjectedClassNameType *Injected |
| 371 | = getAs<InjectedClassNameType>()) |
| 372 | return Injected->getDecl(); |
| 373 | |
| 374 | return 0; |
| 375 | } |
| 376 | |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 377 | bool Type::isIntegerType() const { |
| 378 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 379 | return BT->getKind() >= BuiltinType::Bool && |
Chris Lattner | 2df9ced | 2009-04-30 02:43:43 +0000 | [diff] [blame] | 380 | BT->getKind() <= BuiltinType::Int128; |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 381 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
Chris Lattner | 834a72a | 2008-07-25 23:18:17 +0000 | [diff] [blame] | 382 | // Incomplete enum types are not treated as integer types. |
Douglas Gregor | 8e9bebd | 2008-10-21 16:13:35 +0000 | [diff] [blame] | 383 | // FIXME: In C++, enum types are never integer types. |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 384 | return ET->getDecl()->isComplete(); |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 385 | return false; |
| 386 | } |
| 387 | |
| 388 | bool Type::hasIntegerRepresentation() const { |
Steve Naroff | c63b96a | 2007-07-12 21:46:55 +0000 | [diff] [blame] | 389 | if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) |
| 390 | return VT->getElementType()->isIntegerType(); |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 391 | else |
| 392 | return isIntegerType(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 393 | } |
| 394 | |
Douglas Gregor | 9d3347a | 2010-06-16 00:35:25 +0000 | [diff] [blame] | 395 | /// \brief Determine whether this type is an integral type. |
| 396 | /// |
| 397 | /// This routine determines whether the given type is an integral type per |
| 398 | /// C++ [basic.fundamental]p7. Although the C standard does not define the |
| 399 | /// term "integral type", it has a similar term "integer type", and in C++ |
| 400 | /// the two terms are equivalent. However, C's "integer type" includes |
| 401 | /// enumeration types, while C++'s "integer type" does not. The \c ASTContext |
| 402 | /// parameter is used to determine whether we should be following the C or |
| 403 | /// C++ rules when determining whether this type is an integral/integer type. |
| 404 | /// |
| 405 | /// For cases where C permits "an integer type" and C++ permits "an integral |
| 406 | /// type", use this routine. |
| 407 | /// |
| 408 | /// For cases where C permits "an integer type" and C++ permits "an integral |
| 409 | /// or enumeration type", use \c isIntegralOrEnumerationType() instead. |
| 410 | /// |
| 411 | /// \param Ctx The context in which this type occurs. |
| 412 | /// |
| 413 | /// \returns true if the type is considered an integral type, false otherwise. |
| 414 | bool Type::isIntegralType(ASTContext &Ctx) const { |
Fariborz Jahanian | 33e1d64 | 2007-10-29 22:57:28 +0000 | [diff] [blame] | 415 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 416 | return BT->getKind() >= BuiltinType::Bool && |
Anders Carlsson | f5f7d86 | 2009-12-29 07:07:36 +0000 | [diff] [blame] | 417 | BT->getKind() <= BuiltinType::Int128; |
Douglas Gregor | 9d3347a | 2010-06-16 00:35:25 +0000 | [diff] [blame] | 418 | |
| 419 | if (!Ctx.getLangOptions().CPlusPlus) |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 420 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
| 421 | return ET->getDecl()->isComplete(); // Complete enum types are integral in C. |
Douglas Gregor | 9d3347a | 2010-06-16 00:35:25 +0000 | [diff] [blame] | 422 | |
Fariborz Jahanian | 33e1d64 | 2007-10-29 22:57:28 +0000 | [diff] [blame] | 423 | return false; |
| 424 | } |
| 425 | |
Douglas Gregor | 2ade35e | 2010-06-16 00:17:44 +0000 | [diff] [blame] | 426 | bool Type::isIntegralOrEnumerationType() const { |
| 427 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 428 | return BT->getKind() >= BuiltinType::Bool && |
| 429 | BT->getKind() <= BuiltinType::Int128; |
Eli Friedman | 34fd628 | 2010-08-19 04:39:37 +0000 | [diff] [blame] | 430 | |
| 431 | // Check for a complete enum type; incomplete enum types are not properly an |
| 432 | // enumeration type in the sense required here. |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 433 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
| 434 | return ET->getDecl()->isComplete(); |
Eli Friedman | 34fd628 | 2010-08-19 04:39:37 +0000 | [diff] [blame] | 435 | |
Douglas Gregor | 2ade35e | 2010-06-16 00:17:44 +0000 | [diff] [blame] | 436 | return false; |
| 437 | } |
| 438 | |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 439 | bool Type::isIntegralOrUnscopedEnumerationType() const { |
| 440 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 441 | return BT->getKind() >= BuiltinType::Bool && |
| 442 | BT->getKind() <= BuiltinType::Int128; |
| 443 | |
| 444 | // Check for a complete enum type; incomplete enum types are not properly an |
| 445 | // enumeration type in the sense required here. |
| 446 | // C++0x: However, if the underlying type of the enum is fixed, it is |
| 447 | // considered complete. |
| 448 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
| 449 | return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); |
| 450 | |
| 451 | return false; |
| 452 | } |
| 453 | |
| 454 | |
Steve Naroff | 13b7c5f | 2007-08-08 22:15:55 +0000 | [diff] [blame] | 455 | bool Type::isBooleanType() const { |
| 456 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 457 | return BT->getKind() == BuiltinType::Bool; |
| 458 | return false; |
| 459 | } |
| 460 | |
| 461 | bool Type::isCharType() const { |
| 462 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 463 | return BT->getKind() == BuiltinType::Char_U || |
| 464 | BT->getKind() == BuiltinType::UChar || |
Anders Carlsson | c67ad5f | 2007-10-29 02:52:18 +0000 | [diff] [blame] | 465 | BT->getKind() == BuiltinType::Char_S || |
| 466 | BT->getKind() == BuiltinType::SChar; |
Steve Naroff | 13b7c5f | 2007-08-08 22:15:55 +0000 | [diff] [blame] | 467 | return false; |
| 468 | } |
| 469 | |
Douglas Gregor | 77a5223 | 2008-09-12 00:47:35 +0000 | [diff] [blame] | 470 | bool Type::isWideCharType() const { |
| 471 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 472 | return BT->getKind() == BuiltinType::WChar; |
Douglas Gregor | 77a5223 | 2008-09-12 00:47:35 +0000 | [diff] [blame] | 473 | return false; |
| 474 | } |
| 475 | |
Douglas Gregor | 20093b4 | 2009-12-09 23:02:17 +0000 | [diff] [blame] | 476 | /// \brief Determine whether this type is any of the built-in character |
| 477 | /// types. |
| 478 | bool Type::isAnyCharacterType() const { |
| 479 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 480 | return (BT->getKind() >= BuiltinType::Char_U && |
| 481 | BT->getKind() <= BuiltinType::Char32) || |
| 482 | (BT->getKind() >= BuiltinType::Char_S && |
| 483 | BT->getKind() <= BuiltinType::WChar); |
| 484 | |
| 485 | return false; |
| 486 | } |
| 487 | |
Chris Lattner | d5bbce4 | 2007-08-29 17:48:46 +0000 | [diff] [blame] | 488 | /// isSignedIntegerType - Return true if this is an integer type that is |
| 489 | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 490 | /// an enum decl which has a signed representation |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 491 | bool Type::isSignedIntegerType() const { |
| 492 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
| 493 | return BT->getKind() >= BuiltinType::Char_S && |
Anders Carlsson | f5f7d86 | 2009-12-29 07:07:36 +0000 | [diff] [blame] | 494 | BT->getKind() <= BuiltinType::Int128; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 495 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 496 | |
Fariborz Jahanian | bbd3407 | 2010-11-29 23:18:09 +0000 | [diff] [blame] | 497 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { |
| 498 | // Incomplete enum types are not treated as integer types. |
| 499 | // FIXME: In C++, enum types are never integer types. |
| 500 | if (ET->getDecl()->isComplete()) |
| 501 | return ET->getDecl()->getIntegerType()->isSignedIntegerType(); |
| 502 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 503 | |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 504 | return false; |
| 505 | } |
| 506 | |
| 507 | bool Type::hasSignedIntegerRepresentation() const { |
Steve Naroff | c63b96a | 2007-07-12 21:46:55 +0000 | [diff] [blame] | 508 | if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) |
| 509 | return VT->getElementType()->isSignedIntegerType(); |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 510 | else |
| 511 | return isSignedIntegerType(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 512 | } |
| 513 | |
Chris Lattner | d5bbce4 | 2007-08-29 17:48:46 +0000 | [diff] [blame] | 514 | /// isUnsignedIntegerType - Return true if this is an integer type that is |
| 515 | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 516 | /// decl which has an unsigned representation |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 517 | bool Type::isUnsignedIntegerType() const { |
| 518 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
| 519 | return BT->getKind() >= BuiltinType::Bool && |
Anders Carlsson | 1c03ca3 | 2009-11-09 17:34:18 +0000 | [diff] [blame] | 520 | BT->getKind() <= BuiltinType::UInt128; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 521 | } |
Chris Lattner | d5bbce4 | 2007-08-29 17:48:46 +0000 | [diff] [blame] | 522 | |
Fariborz Jahanian | bbd3407 | 2010-11-29 23:18:09 +0000 | [diff] [blame] | 523 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { |
| 524 | // Incomplete enum types are not treated as integer types. |
| 525 | // FIXME: In C++, enum types are never integer types. |
| 526 | if (ET->getDecl()->isComplete()) |
| 527 | return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); |
| 528 | } |
Chris Lattner | d5bbce4 | 2007-08-29 17:48:46 +0000 | [diff] [blame] | 529 | |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 530 | return false; |
| 531 | } |
| 532 | |
| 533 | bool Type::hasUnsignedIntegerRepresentation() const { |
Steve Naroff | c63b96a | 2007-07-12 21:46:55 +0000 | [diff] [blame] | 534 | if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) |
| 535 | return VT->getElementType()->isUnsignedIntegerType(); |
Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 536 | else |
| 537 | return isUnsignedIntegerType(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 538 | } |
| 539 | |
| 540 | bool Type::isFloatingType() const { |
| 541 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 542 | return BT->getKind() >= BuiltinType::Float && |
| 543 | BT->getKind() <= BuiltinType::LongDouble; |
| 544 | if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType)) |
Chris Lattner | 729a213 | 2007-08-30 06:19:11 +0000 | [diff] [blame] | 545 | return CT->getElementType()->isFloatingType(); |
Douglas Gregor | 8eee119 | 2010-06-22 22:12:46 +0000 | [diff] [blame] | 546 | return false; |
| 547 | } |
| 548 | |
| 549 | bool Type::hasFloatingRepresentation() const { |
Steve Naroff | c63b96a | 2007-07-12 21:46:55 +0000 | [diff] [blame] | 550 | if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) |
| 551 | return VT->getElementType()->isFloatingType(); |
Douglas Gregor | 8eee119 | 2010-06-22 22:12:46 +0000 | [diff] [blame] | 552 | else |
| 553 | return isFloatingType(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 554 | } |
| 555 | |
| 556 | bool Type::isRealFloatingType() const { |
| 557 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
John McCall | 680523a | 2009-11-07 03:30:10 +0000 | [diff] [blame] | 558 | return BT->isFloatingPoint(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 559 | return false; |
| 560 | } |
| 561 | |
| 562 | bool Type::isRealType() const { |
| 563 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
| 564 | return BT->getKind() >= BuiltinType::Bool && |
| 565 | BT->getKind() <= BuiltinType::LongDouble; |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 566 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
| 567 | return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 568 | return false; |
| 569 | } |
| 570 | |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 571 | bool Type::isArithmeticType() const { |
| 572 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
Douglas Gregor | a7fbf72 | 2008-10-30 13:47:07 +0000 | [diff] [blame] | 573 | return BT->getKind() >= BuiltinType::Bool && |
| 574 | BT->getKind() <= BuiltinType::LongDouble; |
Chris Lattner | 37c1b78 | 2008-04-06 22:29:16 +0000 | [diff] [blame] | 575 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
| 576 | // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2). |
| 577 | // If a body isn't seen by the time we get here, return false. |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 578 | // |
| 579 | // C++0x: Enumerations are not arithmetic types. For now, just return |
| 580 | // false for scoped enumerations since that will disable any |
| 581 | // unwanted implicit conversions. |
| 582 | return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete(); |
Douglas Gregor | 0061962 | 2010-06-22 23:41:02 +0000 | [diff] [blame] | 583 | return isa<ComplexType>(CanonicalType); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 584 | } |
| 585 | |
| 586 | bool Type::isScalarType() const { |
| 587 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 588 | return BT->getKind() > BuiltinType::Void && |
| 589 | BT->getKind() <= BuiltinType::NullPtr; |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 590 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
Chris Lattner | 834a72a | 2008-07-25 23:18:17 +0000 | [diff] [blame] | 591 | // Enums are scalar types, but only if they are defined. Incomplete enums |
| 592 | // are not treated as scalar types. |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 593 | return ET->getDecl()->isComplete(); |
Steve Naroff | 5618bd4 | 2008-08-27 16:04:49 +0000 | [diff] [blame] | 594 | return isa<PointerType>(CanonicalType) || |
| 595 | isa<BlockPointerType>(CanonicalType) || |
Sebastian Redl | f30208a | 2009-01-24 21:16:55 +0000 | [diff] [blame] | 596 | isa<MemberPointerType>(CanonicalType) || |
Steve Naroff | 5618bd4 | 2008-08-27 16:04:49 +0000 | [diff] [blame] | 597 | isa<ComplexType>(CanonicalType) || |
Steve Naroff | d1b3c2d | 2009-06-17 22:40:22 +0000 | [diff] [blame] | 598 | isa<ObjCObjectPointerType>(CanonicalType); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 599 | } |
| 600 | |
John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 601 | Type::ScalarTypeKind Type::getScalarTypeKind() const { |
| 602 | assert(isScalarType()); |
| 603 | |
| 604 | const Type *T = CanonicalType.getTypePtr(); |
| 605 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(T)) { |
| 606 | if (BT->getKind() == BuiltinType::Bool) return STK_Bool; |
| 607 | if (BT->getKind() == BuiltinType::NullPtr) return STK_Pointer; |
| 608 | if (BT->isInteger()) return STK_Integral; |
| 609 | if (BT->isFloatingPoint()) return STK_Floating; |
| 610 | llvm_unreachable("unknown scalar builtin type"); |
| 611 | } else if (isa<PointerType>(T) || |
| 612 | isa<BlockPointerType>(T) || |
| 613 | isa<ObjCObjectPointerType>(T)) { |
| 614 | return STK_Pointer; |
| 615 | } else if (isa<MemberPointerType>(T)) { |
| 616 | return STK_MemberPointer; |
| 617 | } else if (isa<EnumType>(T)) { |
| 618 | assert(cast<EnumType>(T)->getDecl()->isComplete()); |
| 619 | return STK_Integral; |
| 620 | } else if (const ComplexType *CT = dyn_cast<ComplexType>(T)) { |
| 621 | if (CT->getElementType()->isRealFloatingType()) |
| 622 | return STK_FloatingComplex; |
| 623 | return STK_IntegralComplex; |
| 624 | } |
| 625 | |
| 626 | llvm_unreachable("unknown scalar type"); |
| 627 | return STK_Pointer; |
| 628 | } |
| 629 | |
Douglas Gregor | d7eb846 | 2009-01-30 17:31:00 +0000 | [diff] [blame] | 630 | /// \brief Determines whether the type is a C++ aggregate type or C |
| 631 | /// aggregate or union type. |
| 632 | /// |
| 633 | /// An aggregate type is an array or a class type (struct, union, or |
| 634 | /// class) that has no user-declared constructors, no private or |
| 635 | /// protected non-static data members, no base classes, and no virtual |
| 636 | /// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type |
| 637 | /// subsumes the notion of C aggregates (C99 6.2.5p21) because it also |
| 638 | /// includes union types. |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 639 | bool Type::isAggregateType() const { |
Douglas Gregor | c1efaec | 2009-02-28 01:32:25 +0000 | [diff] [blame] | 640 | if (const RecordType *Record = dyn_cast<RecordType>(CanonicalType)) { |
| 641 | if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl())) |
| 642 | return ClassDecl->isAggregate(); |
| 643 | |
Douglas Gregor | d7eb846 | 2009-01-30 17:31:00 +0000 | [diff] [blame] | 644 | return true; |
Douglas Gregor | c1efaec | 2009-02-28 01:32:25 +0000 | [diff] [blame] | 645 | } |
| 646 | |
Eli Friedman | c5773c4 | 2008-02-15 18:16:39 +0000 | [diff] [blame] | 647 | return isa<ArrayType>(CanonicalType); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 648 | } |
| 649 | |
Chris Lattner | 9bfa73c | 2007-12-18 07:18:16 +0000 | [diff] [blame] | 650 | /// isConstantSizeType - Return true if this is not a variable sized type, |
| 651 | /// according to the rules of C99 6.7.5p3. It is not legal to call this on |
Douglas Gregor | 898574e | 2008-12-05 23:32:09 +0000 | [diff] [blame] | 652 | /// incomplete types or dependent types. |
Eli Friedman | 3c2b317 | 2008-02-15 12:20:59 +0000 | [diff] [blame] | 653 | bool Type::isConstantSizeType() const { |
Chris Lattner | d52a457 | 2007-12-18 07:03:30 +0000 | [diff] [blame] | 654 | assert(!isIncompleteType() && "This doesn't make sense for incomplete types"); |
Douglas Gregor | 898574e | 2008-12-05 23:32:09 +0000 | [diff] [blame] | 655 | assert(!isDependentType() && "This doesn't make sense for dependent types"); |
Chris Lattner | 9bfa73c | 2007-12-18 07:18:16 +0000 | [diff] [blame] | 656 | // The VAT must have a size, as it is known to be complete. |
| 657 | return !isa<VariableArrayType>(CanonicalType); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 658 | } |
| 659 | |
| 660 | /// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1) |
| 661 | /// - a type that can describe objects, but which lacks information needed to |
| 662 | /// determine its size. |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 663 | bool Type::isIncompleteType() const { |
| 664 | switch (CanonicalType->getTypeClass()) { |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 665 | default: return false; |
| 666 | case Builtin: |
| 667 | // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never |
| 668 | // be completed. |
| 669 | return isVoidType(); |
Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 670 | case Enum: |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 671 | // An enumeration with fixed underlying type is complete (C++0x 7.2p3). |
| 672 | if (cast<EnumType>(CanonicalType)->getDecl()->isFixed()) |
| 673 | return false; |
| 674 | // Fall through. |
| 675 | case Record: |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 676 | // A tagged type (struct/union/enum/class) is incomplete if the decl is a |
| 677 | // forward declaration, but not a full definition (C99 6.2.5p22). |
| 678 | return !cast<TagType>(CanonicalType)->getDecl()->isDefinition(); |
Sebastian Redl | 923d56d | 2009-11-05 15:52:31 +0000 | [diff] [blame] | 679 | case ConstantArray: |
| 680 | // An array is incomplete if its element type is incomplete |
| 681 | // (C++ [dcl.array]p1). |
| 682 | // We don't handle variable arrays (they're not allowed in C++) or |
| 683 | // dependent-sized arrays (dependent types are never treated as incomplete). |
| 684 | return cast<ArrayType>(CanonicalType)->getElementType()->isIncompleteType(); |
Eli Friedman | c5773c4 | 2008-02-15 18:16:39 +0000 | [diff] [blame] | 685 | case IncompleteArray: |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 686 | // An array of unknown size is an incomplete type (C99 6.2.5p22). |
Eli Friedman | c5773c4 | 2008-02-15 18:16:39 +0000 | [diff] [blame] | 687 | return true; |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 688 | case ObjCObject: |
Douglas Gregor | d022152 | 2010-07-29 22:17:04 +0000 | [diff] [blame] | 689 | return cast<ObjCObjectType>(CanonicalType)->getBaseType() |
| 690 | ->isIncompleteType(); |
Chris Lattner | 1efaa95 | 2009-04-24 00:30:45 +0000 | [diff] [blame] | 691 | case ObjCInterface: |
Chris Lattner | 1efaa95 | 2009-04-24 00:30:45 +0000 | [diff] [blame] | 692 | // ObjC interfaces are incomplete if they are @class, not @interface. |
Douglas Gregor | d022152 | 2010-07-29 22:17:04 +0000 | [diff] [blame] | 693 | return cast<ObjCInterfaceType>(CanonicalType)->getDecl()->isForwardDecl(); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 694 | } |
| 695 | } |
| 696 | |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 697 | /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10) |
| 698 | bool Type::isPODType() const { |
| 699 | // The compiler shouldn't query this for incomplete types, but the user might. |
Sebastian Redl | 607a178 | 2010-09-08 00:48:43 +0000 | [diff] [blame] | 700 | // We return false for that case. Except for incomplete arrays of PODs, which |
| 701 | // are PODs according to the standard. |
| 702 | if (isIncompleteArrayType() && |
| 703 | cast<ArrayType>(CanonicalType)->getElementType()->isPODType()) |
| 704 | return true; |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 705 | if (isIncompleteType()) |
| 706 | return false; |
| 707 | |
| 708 | switch (CanonicalType->getTypeClass()) { |
| 709 | // Everything not explicitly mentioned is not POD. |
| 710 | default: return false; |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 711 | case VariableArray: |
| 712 | case ConstantArray: |
Sebastian Redl | 607a178 | 2010-09-08 00:48:43 +0000 | [diff] [blame] | 713 | // IncompleteArray is handled above. |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 714 | return cast<ArrayType>(CanonicalType)->getElementType()->isPODType(); |
| 715 | |
| 716 | case Builtin: |
| 717 | case Complex: |
| 718 | case Pointer: |
Sebastian Redl | f30208a | 2009-01-24 21:16:55 +0000 | [diff] [blame] | 719 | case MemberPointer: |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 720 | case Vector: |
| 721 | case ExtVector: |
Steve Naroff | d1b3c2d | 2009-06-17 22:40:22 +0000 | [diff] [blame] | 722 | case ObjCObjectPointer: |
Fariborz Jahanian | 2263f82 | 2010-03-09 18:34:52 +0000 | [diff] [blame] | 723 | case BlockPointer: |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 724 | return true; |
| 725 | |
Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 726 | case Enum: |
| 727 | return true; |
| 728 | |
| 729 | case Record: |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 730 | if (CXXRecordDecl *ClassDecl |
Douglas Gregor | c1efaec | 2009-02-28 01:32:25 +0000 | [diff] [blame] | 731 | = dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl())) |
| 732 | return ClassDecl->isPOD(); |
| 733 | |
Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 734 | // C struct/union is POD. |
| 735 | return true; |
| 736 | } |
| 737 | } |
| 738 | |
Sebastian Redl | ccf4350 | 2009-12-03 00:13:20 +0000 | [diff] [blame] | 739 | bool Type::isLiteralType() const { |
| 740 | if (isIncompleteType()) |
| 741 | return false; |
| 742 | |
| 743 | // C++0x [basic.types]p10: |
| 744 | // A type is a literal type if it is: |
| 745 | switch (CanonicalType->getTypeClass()) { |
| 746 | // We're whitelisting |
| 747 | default: return false; |
| 748 | |
| 749 | // -- a scalar type |
| 750 | case Builtin: |
| 751 | case Complex: |
| 752 | case Pointer: |
| 753 | case MemberPointer: |
| 754 | case Vector: |
| 755 | case ExtVector: |
| 756 | case ObjCObjectPointer: |
| 757 | case Enum: |
| 758 | return true; |
| 759 | |
| 760 | // -- a class type with ... |
| 761 | case Record: |
| 762 | // FIXME: Do the tests |
| 763 | return false; |
| 764 | |
| 765 | // -- an array of literal type |
| 766 | // Extension: variable arrays cannot be literal types, since they're |
| 767 | // runtime-sized. |
| 768 | case ConstantArray: |
| 769 | return cast<ArrayType>(CanonicalType)->getElementType()->isLiteralType(); |
| 770 | } |
| 771 | } |
| 772 | |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 773 | bool Type::isPromotableIntegerType() const { |
John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 774 | if (const BuiltinType *BT = getAs<BuiltinType>()) |
Chris Lattner | 2a18dfe | 2009-01-12 00:21:19 +0000 | [diff] [blame] | 775 | switch (BT->getKind()) { |
| 776 | case BuiltinType::Bool: |
| 777 | case BuiltinType::Char_S: |
| 778 | case BuiltinType::Char_U: |
| 779 | case BuiltinType::SChar: |
| 780 | case BuiltinType::UChar: |
| 781 | case BuiltinType::Short: |
| 782 | case BuiltinType::UShort: |
| 783 | return true; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 784 | default: |
Chris Lattner | 2a18dfe | 2009-01-12 00:21:19 +0000 | [diff] [blame] | 785 | return false; |
| 786 | } |
Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 787 | |
| 788 | // Enumerated types are promotable to their compatible integer types |
| 789 | // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2). |
| 790 | if (const EnumType *ET = getAs<EnumType>()){ |
Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 791 | if (this->isDependentType() || ET->getDecl()->getPromotionType().isNull() |
| 792 | || ET->getDecl()->isScoped()) |
Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 793 | return false; |
| 794 | |
| 795 | const BuiltinType *BT |
| 796 | = ET->getDecl()->getPromotionType()->getAs<BuiltinType>(); |
| 797 | return BT->getKind() == BuiltinType::Int |
| 798 | || BT->getKind() == BuiltinType::UInt; |
| 799 | } |
| 800 | |
Chris Lattner | 2a18dfe | 2009-01-12 00:21:19 +0000 | [diff] [blame] | 801 | return false; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 802 | } |
| 803 | |
Sebastian Redl | 6e8ed16 | 2009-05-10 18:38:11 +0000 | [diff] [blame] | 804 | bool Type::isNullPtrType() const { |
John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 805 | if (const BuiltinType *BT = getAs<BuiltinType>()) |
Sebastian Redl | 6e8ed16 | 2009-05-10 18:38:11 +0000 | [diff] [blame] | 806 | return BT->getKind() == BuiltinType::NullPtr; |
| 807 | return false; |
| 808 | } |
| 809 | |
Eli Friedman | 22b61e9 | 2009-05-30 00:10:16 +0000 | [diff] [blame] | 810 | bool Type::isSpecifierType() const { |
| 811 | // Note that this intentionally does not use the canonical type. |
| 812 | switch (getTypeClass()) { |
| 813 | case Builtin: |
| 814 | case Record: |
| 815 | case Enum: |
| 816 | case Typedef: |
Eli Friedman | c8f2c61 | 2009-05-30 01:45:29 +0000 | [diff] [blame] | 817 | case Complex: |
| 818 | case TypeOfExpr: |
| 819 | case TypeOf: |
| 820 | case TemplateTypeParm: |
John McCall | 49a832b | 2009-10-18 09:09:24 +0000 | [diff] [blame] | 821 | case SubstTemplateTypeParm: |
Eli Friedman | c8f2c61 | 2009-05-30 01:45:29 +0000 | [diff] [blame] | 822 | case TemplateSpecialization: |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 823 | case Elaborated: |
Douglas Gregor | 4714c12 | 2010-03-31 17:34:00 +0000 | [diff] [blame] | 824 | case DependentName: |
John McCall | 3350095 | 2010-06-11 00:33:02 +0000 | [diff] [blame] | 825 | case DependentTemplateSpecialization: |
Eli Friedman | c8f2c61 | 2009-05-30 01:45:29 +0000 | [diff] [blame] | 826 | case ObjCInterface: |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 827 | case ObjCObject: |
| 828 | case ObjCObjectPointer: // FIXME: object pointers aren't really specifiers |
Eli Friedman | 22b61e9 | 2009-05-30 00:10:16 +0000 | [diff] [blame] | 829 | return true; |
| 830 | default: |
| 831 | return false; |
| 832 | } |
| 833 | } |
| 834 | |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 835 | ElaboratedTypeKeyword |
| 836 | TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) { |
| 837 | switch (TypeSpec) { |
| 838 | default: return ETK_None; |
| 839 | case TST_typename: return ETK_Typename; |
| 840 | case TST_class: return ETK_Class; |
| 841 | case TST_struct: return ETK_Struct; |
| 842 | case TST_union: return ETK_Union; |
| 843 | case TST_enum: return ETK_Enum; |
Douglas Gregor | 4033642 | 2010-03-31 22:19:08 +0000 | [diff] [blame] | 844 | } |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 845 | } |
| 846 | |
| 847 | TagTypeKind |
| 848 | TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) { |
| 849 | switch(TypeSpec) { |
| 850 | case TST_class: return TTK_Class; |
| 851 | case TST_struct: return TTK_Struct; |
| 852 | case TST_union: return TTK_Union; |
| 853 | case TST_enum: return TTK_Enum; |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 854 | } |
Douglas Gregor | 7907fad | 2010-11-30 19:14:03 +0000 | [diff] [blame] | 855 | |
| 856 | llvm_unreachable("Type specifier is not a tag type kind."); |
| 857 | return TTK_Union; |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 858 | } |
| 859 | |
| 860 | ElaboratedTypeKeyword |
| 861 | TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) { |
| 862 | switch (Kind) { |
| 863 | case TTK_Class: return ETK_Class; |
| 864 | case TTK_Struct: return ETK_Struct; |
| 865 | case TTK_Union: return ETK_Union; |
| 866 | case TTK_Enum: return ETK_Enum; |
| 867 | } |
| 868 | llvm_unreachable("Unknown tag type kind."); |
| 869 | } |
| 870 | |
| 871 | TagTypeKind |
| 872 | TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) { |
| 873 | switch (Keyword) { |
| 874 | case ETK_Class: return TTK_Class; |
| 875 | case ETK_Struct: return TTK_Struct; |
| 876 | case ETK_Union: return TTK_Union; |
| 877 | case ETK_Enum: return TTK_Enum; |
| 878 | case ETK_None: // Fall through. |
| 879 | case ETK_Typename: |
| 880 | llvm_unreachable("Elaborated type keyword is not a tag type kind."); |
| 881 | } |
| 882 | llvm_unreachable("Unknown elaborated type keyword."); |
| 883 | } |
| 884 | |
| 885 | bool |
| 886 | TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) { |
| 887 | switch (Keyword) { |
| 888 | case ETK_None: |
| 889 | case ETK_Typename: |
| 890 | return false; |
| 891 | case ETK_Class: |
| 892 | case ETK_Struct: |
| 893 | case ETK_Union: |
| 894 | case ETK_Enum: |
| 895 | return true; |
| 896 | } |
| 897 | llvm_unreachable("Unknown elaborated type keyword."); |
| 898 | } |
| 899 | |
| 900 | const char* |
| 901 | TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) { |
| 902 | switch (Keyword) { |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 903 | case ETK_None: return ""; |
| 904 | case ETK_Typename: return "typename"; |
| 905 | case ETK_Class: return "class"; |
| 906 | case ETK_Struct: return "struct"; |
| 907 | case ETK_Union: return "union"; |
| 908 | case ETK_Enum: return "enum"; |
| 909 | } |
Douglas Gregor | 7907fad | 2010-11-30 19:14:03 +0000 | [diff] [blame] | 910 | |
| 911 | llvm_unreachable("Unknown elaborated type keyword."); |
| 912 | return ""; |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 913 | } |
| 914 | |
John McCall | 3350095 | 2010-06-11 00:33:02 +0000 | [diff] [blame] | 915 | DependentTemplateSpecializationType::DependentTemplateSpecializationType( |
John McCall | ef99001 | 2010-06-11 11:07:21 +0000 | [diff] [blame] | 916 | ElaboratedTypeKeyword Keyword, |
John McCall | 3350095 | 2010-06-11 00:33:02 +0000 | [diff] [blame] | 917 | NestedNameSpecifier *NNS, const IdentifierInfo *Name, |
| 918 | unsigned NumArgs, const TemplateArgument *Args, |
| 919 | QualType Canon) |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 920 | : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, |
| 921 | false), |
John McCall | ef99001 | 2010-06-11 11:07:21 +0000 | [diff] [blame] | 922 | NNS(NNS), Name(Name), NumArgs(NumArgs) { |
John McCall | 3350095 | 2010-06-11 00:33:02 +0000 | [diff] [blame] | 923 | assert(NNS && NNS->isDependent() && |
| 924 | "DependentTemplateSpecializatonType requires dependent qualifier"); |
| 925 | for (unsigned I = 0; I != NumArgs; ++I) |
| 926 | new (&getArgBuffer()[I]) TemplateArgument(Args[I]); |
| 927 | } |
| 928 | |
| 929 | void |
| 930 | DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, |
| 931 | ASTContext &Context, |
| 932 | ElaboratedTypeKeyword Keyword, |
| 933 | NestedNameSpecifier *Qualifier, |
| 934 | const IdentifierInfo *Name, |
| 935 | unsigned NumArgs, |
| 936 | const TemplateArgument *Args) { |
| 937 | ID.AddInteger(Keyword); |
| 938 | ID.AddPointer(Qualifier); |
| 939 | ID.AddPointer(Name); |
| 940 | for (unsigned Idx = 0; Idx < NumArgs; ++Idx) |
| 941 | Args[Idx].Profile(ID, Context); |
| 942 | } |
| 943 | |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 944 | bool Type::isElaboratedTypeSpecifier() const { |
| 945 | ElaboratedTypeKeyword Keyword; |
| 946 | if (const ElaboratedType *Elab = dyn_cast<ElaboratedType>(this)) |
| 947 | Keyword = Elab->getKeyword(); |
| 948 | else if (const DependentNameType *DepName = dyn_cast<DependentNameType>(this)) |
| 949 | Keyword = DepName->getKeyword(); |
John McCall | 3350095 | 2010-06-11 00:33:02 +0000 | [diff] [blame] | 950 | else if (const DependentTemplateSpecializationType *DepTST = |
| 951 | dyn_cast<DependentTemplateSpecializationType>(this)) |
| 952 | Keyword = DepTST->getKeyword(); |
Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 953 | else |
| 954 | return false; |
| 955 | |
| 956 | return TypeWithKeyword::KeywordIsTagTypeKind(Keyword); |
Douglas Gregor | 4033642 | 2010-03-31 22:19:08 +0000 | [diff] [blame] | 957 | } |
| 958 | |
Argyrios Kyrtzidis | cd01f17 | 2009-09-29 19:41:13 +0000 | [diff] [blame] | 959 | const char *Type::getTypeClassName() const { |
John McCall | b870b88 | 2010-10-14 21:48:26 +0000 | [diff] [blame] | 960 | switch (TypeBits.TC) { |
Argyrios Kyrtzidis | cd01f17 | 2009-09-29 19:41:13 +0000 | [diff] [blame] | 961 | #define ABSTRACT_TYPE(Derived, Base) |
| 962 | #define TYPE(Derived, Base) case Derived: return #Derived; |
| 963 | #include "clang/AST/TypeNodes.def" |
| 964 | } |
Douglas Gregor | 7907fad | 2010-11-30 19:14:03 +0000 | [diff] [blame] | 965 | |
| 966 | llvm_unreachable("Invalid type class."); |
| 967 | return 0; |
Argyrios Kyrtzidis | cd01f17 | 2009-09-29 19:41:13 +0000 | [diff] [blame] | 968 | } |
| 969 | |
Chris Lattner | e4f2142 | 2009-06-30 01:26:17 +0000 | [diff] [blame] | 970 | const char *BuiltinType::getName(const LangOptions &LO) const { |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 971 | switch (getKind()) { |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 972 | case Void: return "void"; |
Chris Lattner | e4f2142 | 2009-06-30 01:26:17 +0000 | [diff] [blame] | 973 | case Bool: return LO.Bool ? "bool" : "_Bool"; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 974 | case Char_S: return "char"; |
| 975 | case Char_U: return "char"; |
| 976 | case SChar: return "signed char"; |
| 977 | case Short: return "short"; |
| 978 | case Int: return "int"; |
| 979 | case Long: return "long"; |
| 980 | case LongLong: return "long long"; |
Chris Lattner | 2df9ced | 2009-04-30 02:43:43 +0000 | [diff] [blame] | 981 | case Int128: return "__int128_t"; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 982 | case UChar: return "unsigned char"; |
| 983 | case UShort: return "unsigned short"; |
| 984 | case UInt: return "unsigned int"; |
| 985 | case ULong: return "unsigned long"; |
| 986 | case ULongLong: return "unsigned long long"; |
Chris Lattner | 2df9ced | 2009-04-30 02:43:43 +0000 | [diff] [blame] | 987 | case UInt128: return "__uint128_t"; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 988 | case Float: return "float"; |
| 989 | case Double: return "double"; |
| 990 | case LongDouble: return "long double"; |
Argyrios Kyrtzidis | 46713ef | 2008-08-09 17:11:33 +0000 | [diff] [blame] | 991 | case WChar: return "wchar_t"; |
Alisdair Meredith | f5c209d | 2009-07-14 06:30:34 +0000 | [diff] [blame] | 992 | case Char16: return "char16_t"; |
| 993 | case Char32: return "char32_t"; |
Sebastian Redl | 6e8ed16 | 2009-05-10 18:38:11 +0000 | [diff] [blame] | 994 | case NullPtr: return "nullptr_t"; |
Douglas Gregor | 8e9bebd | 2008-10-21 16:13:35 +0000 | [diff] [blame] | 995 | case Overload: return "<overloaded function type>"; |
Douglas Gregor | 898574e | 2008-12-05 23:32:09 +0000 | [diff] [blame] | 996 | case Dependent: return "<dependent type>"; |
Anders Carlsson | 6a75cd9 | 2009-07-11 00:34:39 +0000 | [diff] [blame] | 997 | case UndeducedAuto: return "auto"; |
Steve Naroff | de2e22d | 2009-07-15 18:40:39 +0000 | [diff] [blame] | 998 | case ObjCId: return "id"; |
| 999 | case ObjCClass: return "Class"; |
Chris Lattner | bef0efd | 2010-05-13 01:02:19 +0000 | [diff] [blame] | 1000 | case ObjCSel: return "SEL"; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1001 | } |
Douglas Gregor | 7907fad | 2010-11-30 19:14:03 +0000 | [diff] [blame] | 1002 | |
Nick Lewycky | aab440b | 2010-11-30 07:50:28 +0000 | [diff] [blame] | 1003 | llvm_unreachable("Invalid builtin type."); |
| 1004 | return 0; |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1005 | } |
| 1006 | |
Douglas Gregor | 6398235 | 2010-07-13 18:40:04 +0000 | [diff] [blame] | 1007 | QualType QualType::getNonLValueExprType(ASTContext &Context) const { |
Douglas Gregor | 5291c3c | 2010-07-13 08:18:22 +0000 | [diff] [blame] | 1008 | if (const ReferenceType *RefType = getTypePtr()->getAs<ReferenceType>()) |
| 1009 | return RefType->getPointeeType(); |
| 1010 | |
| 1011 | // C++0x [basic.lval]: |
| 1012 | // Class prvalues can have cv-qualified types; non-class prvalues always |
| 1013 | // have cv-unqualified types. |
| 1014 | // |
| 1015 | // See also C99 6.3.2.1p2. |
| 1016 | if (!Context.getLangOptions().CPlusPlus || |
Chandler Carruth | 6dc1ef8 | 2010-07-13 17:07:17 +0000 | [diff] [blame] | 1017 | (!getTypePtr()->isDependentType() && !getTypePtr()->isRecordType())) |
Douglas Gregor | 5291c3c | 2010-07-13 08:18:22 +0000 | [diff] [blame] | 1018 | return getUnqualifiedType(); |
| 1019 | |
| 1020 | return *this; |
| 1021 | } |
| 1022 | |
John McCall | 04a67a6 | 2010-02-05 21:31:56 +0000 | [diff] [blame] | 1023 | llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) { |
| 1024 | switch (CC) { |
Douglas Gregor | 7907fad | 2010-11-30 19:14:03 +0000 | [diff] [blame] | 1025 | case CC_Default: |
| 1026 | llvm_unreachable("no name for default cc"); |
| 1027 | return ""; |
John McCall | 04a67a6 | 2010-02-05 21:31:56 +0000 | [diff] [blame] | 1028 | |
| 1029 | case CC_C: return "cdecl"; |
| 1030 | case CC_X86StdCall: return "stdcall"; |
| 1031 | case CC_X86FastCall: return "fastcall"; |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 1032 | case CC_X86ThisCall: return "thiscall"; |
Dawn Perchik | 52fc314 | 2010-09-03 01:29:35 +0000 | [diff] [blame] | 1033 | case CC_X86Pascal: return "pascal"; |
John McCall | 04a67a6 | 2010-02-05 21:31:56 +0000 | [diff] [blame] | 1034 | } |
Douglas Gregor | 7907fad | 2010-11-30 19:14:03 +0000 | [diff] [blame] | 1035 | |
| 1036 | llvm_unreachable("Invalid calling convention."); |
| 1037 | return ""; |
John McCall | 04a67a6 | 2010-02-05 21:31:56 +0000 | [diff] [blame] | 1038 | } |
| 1039 | |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1040 | FunctionProtoType::FunctionProtoType(QualType Result, const QualType *ArgArray, |
| 1041 | unsigned numArgs, bool isVariadic, |
| 1042 | unsigned typeQuals, bool hasExs, |
| 1043 | bool hasAnyExs, const QualType *ExArray, |
| 1044 | unsigned numExs, QualType Canonical, |
| 1045 | const ExtInfo &Info) |
| 1046 | : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, |
| 1047 | Result->isDependentType(), |
| 1048 | Result->isVariablyModifiedType(), |
| 1049 | Info), |
| 1050 | NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs), |
| 1051 | AnyExceptionSpec(hasAnyExs) |
| 1052 | { |
| 1053 | // Fill in the trailing argument array. |
| 1054 | QualType *ArgInfo = reinterpret_cast<QualType*>(this+1); |
| 1055 | for (unsigned i = 0; i != numArgs; ++i) { |
| 1056 | if (ArgArray[i]->isDependentType()) |
| 1057 | setDependent(); |
| 1058 | |
| 1059 | ArgInfo[i] = ArgArray[i]; |
| 1060 | } |
| 1061 | |
| 1062 | // Fill in the exception array. |
| 1063 | QualType *Ex = ArgInfo + numArgs; |
| 1064 | for (unsigned i = 0; i != numExs; ++i) |
| 1065 | Ex[i] = ExArray[i]; |
| 1066 | } |
| 1067 | |
| 1068 | |
Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 1069 | void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, |
Chris Lattner | 942cfd3 | 2007-07-20 18:48:28 +0000 | [diff] [blame] | 1070 | arg_type_iterator ArgTys, |
Argyrios Kyrtzidis | 971c4fa | 2008-10-24 21:46:40 +0000 | [diff] [blame] | 1071 | unsigned NumArgs, bool isVariadic, |
Sebastian Redl | 465226e | 2009-05-27 22:11:52 +0000 | [diff] [blame] | 1072 | unsigned TypeQuals, bool hasExceptionSpec, |
| 1073 | bool anyExceptionSpec, unsigned NumExceptions, |
Rafael Espindola | 264ba48 | 2010-03-30 20:24:48 +0000 | [diff] [blame] | 1074 | exception_iterator Exs, |
John McCall | 71c3673 | 2010-10-14 03:00:17 +0000 | [diff] [blame] | 1075 | FunctionType::ExtInfo Info) { |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1076 | ID.AddPointer(Result.getAsOpaquePtr()); |
| 1077 | for (unsigned i = 0; i != NumArgs; ++i) |
| 1078 | ID.AddPointer(ArgTys[i].getAsOpaquePtr()); |
| 1079 | ID.AddInteger(isVariadic); |
Argyrios Kyrtzidis | 971c4fa | 2008-10-24 21:46:40 +0000 | [diff] [blame] | 1080 | ID.AddInteger(TypeQuals); |
Sebastian Redl | 465226e | 2009-05-27 22:11:52 +0000 | [diff] [blame] | 1081 | ID.AddInteger(hasExceptionSpec); |
| 1082 | if (hasExceptionSpec) { |
| 1083 | ID.AddInteger(anyExceptionSpec); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1084 | for (unsigned i = 0; i != NumExceptions; ++i) |
Sebastian Redl | 465226e | 2009-05-27 22:11:52 +0000 | [diff] [blame] | 1085 | ID.AddPointer(Exs[i].getAsOpaquePtr()); |
| 1086 | } |
John McCall | 71c3673 | 2010-10-14 03:00:17 +0000 | [diff] [blame] | 1087 | Info.Profile(ID); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1088 | } |
| 1089 | |
Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 1090 | void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) { |
Argyrios Kyrtzidis | 971c4fa | 2008-10-24 21:46:40 +0000 | [diff] [blame] | 1091 | Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(), |
Sebastian Redl | 465226e | 2009-05-27 22:11:52 +0000 | [diff] [blame] | 1092 | getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(), |
Rafael Espindola | 264ba48 | 2010-03-30 20:24:48 +0000 | [diff] [blame] | 1093 | getNumExceptions(), exception_begin(), |
| 1094 | getExtInfo()); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1095 | } |
| 1096 | |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 1097 | QualType TypedefType::desugar() const { |
| 1098 | return getDecl()->getUnderlyingType(); |
| 1099 | } |
| 1100 | |
Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 1101 | TypeOfExprType::TypeOfExprType(Expr *E, QualType can) |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1102 | : Type(TypeOfExpr, can, E->isTypeDependent(), |
| 1103 | E->getType()->isVariablyModifiedType()), TOExpr(E) { |
Douglas Gregor | 898574e | 2008-12-05 23:32:09 +0000 | [diff] [blame] | 1104 | } |
| 1105 | |
John McCall | bf1cc05 | 2009-09-29 23:03:30 +0000 | [diff] [blame] | 1106 | QualType TypeOfExprType::desugar() const { |
| 1107 | return getUnderlyingExpr()->getType(); |
| 1108 | } |
| 1109 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1110 | void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, |
Douglas Gregor | b197572 | 2009-07-30 23:18:24 +0000 | [diff] [blame] | 1111 | ASTContext &Context, Expr *E) { |
| 1112 | E->Profile(ID, Context, true); |
| 1113 | } |
| 1114 | |
Anders Carlsson | 563a03b | 2009-07-10 19:20:26 +0000 | [diff] [blame] | 1115 | DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1116 | : Type(Decltype, can, E->isTypeDependent(), |
| 1117 | E->getType()->isVariablyModifiedType()), E(E), |
Anders Carlsson | 563a03b | 2009-07-10 19:20:26 +0000 | [diff] [blame] | 1118 | UnderlyingType(underlyingType) { |
Anders Carlsson | 395b475 | 2009-06-24 19:06:50 +0000 | [diff] [blame] | 1119 | } |
| 1120 | |
Douglas Gregor | 9d702ae | 2009-07-30 23:36:40 +0000 | [diff] [blame] | 1121 | DependentDecltypeType::DependentDecltypeType(ASTContext &Context, Expr *E) |
| 1122 | : DecltypeType(E, Context.DependentTy), Context(Context) { } |
| 1123 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1124 | void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, |
Douglas Gregor | 9d702ae | 2009-07-30 23:36:40 +0000 | [diff] [blame] | 1125 | ASTContext &Context, Expr *E) { |
| 1126 | E->Profile(ID, Context, true); |
| 1127 | } |
| 1128 | |
John McCall | 19c8576 | 2010-02-16 03:57:14 +0000 | [diff] [blame] | 1129 | TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1130 | : Type(TC, can, D->isDependentType(), /*VariablyModified=*/false), |
Sebastian Redl | ed48a8f | 2010-08-02 18:27:05 +0000 | [diff] [blame] | 1131 | decl(const_cast<TagDecl*>(D)) {} |
| 1132 | |
| 1133 | static TagDecl *getInterestingTagDecl(TagDecl *decl) { |
| 1134 | for (TagDecl::redecl_iterator I = decl->redecls_begin(), |
| 1135 | E = decl->redecls_end(); |
| 1136 | I != E; ++I) { |
| 1137 | if (I->isDefinition() || I->isBeingDefined()) |
| 1138 | return *I; |
| 1139 | } |
| 1140 | // If there's no definition (not even in progress), return what we have. |
| 1141 | return decl; |
| 1142 | } |
| 1143 | |
| 1144 | TagDecl *TagType::getDecl() const { |
| 1145 | return getInterestingTagDecl(decl); |
| 1146 | } |
| 1147 | |
| 1148 | bool TagType::isBeingDefined() const { |
| 1149 | return getDecl()->isBeingDefined(); |
| 1150 | } |
| 1151 | |
| 1152 | CXXRecordDecl *InjectedClassNameType::getDecl() const { |
| 1153 | return cast<CXXRecordDecl>(getInterestingTagDecl(Decl)); |
| 1154 | } |
Douglas Gregor | 7da97d0 | 2009-05-10 22:57:19 +0000 | [diff] [blame] | 1155 | |
Chris Lattner | 2daa5df | 2008-04-06 22:04:54 +0000 | [diff] [blame] | 1156 | bool RecordType::classof(const TagType *TT) { |
| 1157 | return isa<RecordDecl>(TT->getDecl()); |
Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1158 | } |
| 1159 | |
Chris Lattner | 2daa5df | 2008-04-06 22:04:54 +0000 | [diff] [blame] | 1160 | bool EnumType::classof(const TagType *TT) { |
| 1161 | return isa<EnumDecl>(TT->getDecl()); |
Chris Lattner | 5edb8bf | 2008-04-06 21:58:47 +0000 | [diff] [blame] | 1162 | } |
| 1163 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1164 | static bool isDependent(const TemplateArgument &Arg) { |
| 1165 | switch (Arg.getKind()) { |
| 1166 | case TemplateArgument::Null: |
| 1167 | assert(false && "Should not have a NULL template argument"); |
| 1168 | return false; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1169 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1170 | case TemplateArgument::Type: |
| 1171 | return Arg.getAsType()->isDependentType(); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1172 | |
Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 1173 | case TemplateArgument::Template: |
| 1174 | return Arg.getAsTemplate().isDependent(); |
| 1175 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1176 | case TemplateArgument::Declaration: |
Douglas Gregor | bb6e73f | 2010-05-11 08:41:30 +0000 | [diff] [blame] | 1177 | if (DeclContext *DC = dyn_cast<DeclContext>(Arg.getAsDecl())) |
| 1178 | return DC->isDependentContext(); |
| 1179 | return Arg.getAsDecl()->getDeclContext()->isDependentContext(); |
| 1180 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1181 | case TemplateArgument::Integral: |
| 1182 | // Never dependent |
| 1183 | return false; |
Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1184 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1185 | case TemplateArgument::Expression: |
| 1186 | return (Arg.getAsExpr()->isTypeDependent() || |
| 1187 | Arg.getAsExpr()->isValueDependent()); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1188 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1189 | case TemplateArgument::Pack: |
Douglas Gregor | bb6e73f | 2010-05-11 08:41:30 +0000 | [diff] [blame] | 1190 | for (TemplateArgument::pack_iterator P = Arg.pack_begin(), |
| 1191 | PEnd = Arg.pack_end(); |
| 1192 | P != PEnd; ++P) { |
| 1193 | if (isDependent(*P)) |
| 1194 | return true; |
| 1195 | } |
| 1196 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1197 | return false; |
Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1198 | } |
Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1199 | |
| 1200 | return false; |
Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1201 | } |
| 1202 | |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1203 | bool TemplateSpecializationType:: |
John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1204 | anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) { |
| 1205 | return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size()); |
| 1206 | } |
| 1207 | |
| 1208 | bool TemplateSpecializationType:: |
John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1209 | anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { |
| 1210 | for (unsigned i = 0; i != N; ++i) |
| 1211 | if (isDependent(Args[i].getArgument())) |
| 1212 | return true; |
| 1213 | return false; |
| 1214 | } |
| 1215 | |
| 1216 | bool TemplateSpecializationType:: |
| 1217 | anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) { |
| 1218 | for (unsigned i = 0; i != N; ++i) |
| 1219 | if (isDependent(Args[i])) |
| 1220 | return true; |
| 1221 | return false; |
| 1222 | } |
| 1223 | |
Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1224 | TemplateSpecializationType:: |
John McCall | ef99001 | 2010-06-11 11:07:21 +0000 | [diff] [blame] | 1225 | TemplateSpecializationType(TemplateName T, |
Douglas Gregor | 828e226 | 2009-07-29 16:09:57 +0000 | [diff] [blame] | 1226 | const TemplateArgument *Args, |
Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1227 | unsigned NumArgs, QualType Canon) |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1228 | : Type(TemplateSpecialization, |
Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1229 | Canon.isNull()? QualType(this, 0) : Canon, |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1230 | T.isDependent(), false), |
| 1231 | Template(T), NumArgs(NumArgs) |
| 1232 | { |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1233 | assert((!Canon.isNull() || |
Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1234 | T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) && |
Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1235 | "No canonical type for non-dependent class template specialization"); |
Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1236 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1237 | TemplateArgument *TemplateArgs |
Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1238 | = reinterpret_cast<TemplateArgument *>(this + 1); |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1239 | for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { |
| 1240 | // Update dependent and variably-modified bits. |
| 1241 | if (isDependent(Args[Arg])) |
| 1242 | setDependent(); |
| 1243 | if (Args[Arg].getKind() == TemplateArgument::Type && |
| 1244 | Args[Arg].getAsType()->isVariablyModifiedType()) |
| 1245 | setVariablyModified(); |
| 1246 | |
Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1247 | new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]); |
Douglas Gregor | 35495eb | 2010-10-13 16:58:14 +0000 | [diff] [blame] | 1248 | } |
Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1249 | } |
| 1250 | |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1251 | void |
| 1252 | TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, |
| 1253 | TemplateName T, |
| 1254 | const TemplateArgument *Args, |
Douglas Gregor | 828e226 | 2009-07-29 16:09:57 +0000 | [diff] [blame] | 1255 | unsigned NumArgs, |
| 1256 | ASTContext &Context) { |
Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1257 | T.Profile(ID); |
Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1258 | for (unsigned Idx = 0; Idx < NumArgs; ++Idx) |
Douglas Gregor | 828e226 | 2009-07-29 16:09:57 +0000 | [diff] [blame] | 1259 | Args[Idx].Profile(ID, Context); |
Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1260 | } |
Anders Carlsson | 97e0179 | 2008-12-21 00:16:32 +0000 | [diff] [blame] | 1261 | |
John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 1262 | QualType QualifierCollector::apply(ASTContext &Context, QualType QT) const { |
John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 1263 | if (!hasNonFastQualifiers()) |
| 1264 | return QT.withFastQualifiers(getFastQualifiers()); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1265 | |
John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 1266 | return Context.getQualifiedType(QT, *this); |
Douglas Gregor | 5e03f9e | 2009-07-23 23:49:00 +0000 | [diff] [blame] | 1267 | } |
| 1268 | |
John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 1269 | QualType QualifierCollector::apply(ASTContext &Context, const Type *T) const { |
John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 1270 | if (!hasNonFastQualifiers()) |
| 1271 | return QualType(T, getFastQualifiers()); |
| 1272 | |
John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 1273 | return Context.getQualifiedType(T, *this); |
Douglas Gregor | 5e03f9e | 2009-07-23 23:49:00 +0000 | [diff] [blame] | 1274 | } |
| 1275 | |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 1276 | void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID, |
| 1277 | QualType BaseType, |
| 1278 | ObjCProtocolDecl * const *Protocols, |
| 1279 | unsigned NumProtocols) { |
| 1280 | ID.AddPointer(BaseType.getAsOpaquePtr()); |
Steve Naroff | c15cb2a | 2009-07-18 15:33:26 +0000 | [diff] [blame] | 1281 | for (unsigned i = 0; i != NumProtocols; i++) |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 1282 | ID.AddPointer(Protocols[i]); |
Steve Naroff | c15cb2a | 2009-07-18 15:33:26 +0000 | [diff] [blame] | 1283 | } |
| 1284 | |
John McCall | c12c5bb | 2010-05-15 11:32:37 +0000 | [diff] [blame] | 1285 | void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) { |
| 1286 | Profile(ID, getBaseType(), qual_begin(), getNumProtocols()); |
Steve Naroff | c15cb2a | 2009-07-18 15:33:26 +0000 | [diff] [blame] | 1287 | } |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1288 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1289 | namespace { |
| 1290 | |
| 1291 | /// \brief The cached properties of a type. |
| 1292 | class CachedProperties { |
| 1293 | char linkage; |
| 1294 | char visibility; |
| 1295 | bool local; |
| 1296 | |
| 1297 | public: |
| 1298 | CachedProperties(Linkage linkage, Visibility visibility, bool local) |
| 1299 | : linkage(linkage), visibility(visibility), local(local) {} |
| 1300 | |
| 1301 | Linkage getLinkage() const { return (Linkage) linkage; } |
| 1302 | Visibility getVisibility() const { return (Visibility) visibility; } |
| 1303 | bool hasLocalOrUnnamedType() const { return local; } |
| 1304 | |
| 1305 | friend CachedProperties merge(CachedProperties L, CachedProperties R) { |
| 1306 | return CachedProperties(minLinkage(L.getLinkage(), R.getLinkage()), |
| 1307 | minVisibility(L.getVisibility(), R.getVisibility()), |
| 1308 | L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType()); |
| 1309 | } |
| 1310 | }; |
John McCall | 1fb0caa | 2010-10-22 21:05:15 +0000 | [diff] [blame] | 1311 | } |
| 1312 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1313 | static CachedProperties computeCachedProperties(const Type *T); |
John McCall | 1fb0caa | 2010-10-22 21:05:15 +0000 | [diff] [blame] | 1314 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1315 | namespace clang { |
| 1316 | /// The type-property cache. This is templated so as to be |
| 1317 | /// instantiated at an internal type to prevent unnecessary symbol |
| 1318 | /// leakage. |
| 1319 | template <class Private> class TypePropertyCache { |
| 1320 | public: |
| 1321 | static CachedProperties get(QualType T) { |
| 1322 | return get(T.getTypePtr()); |
| 1323 | } |
| 1324 | |
| 1325 | static CachedProperties get(const Type *T) { |
| 1326 | ensure(T); |
| 1327 | return CachedProperties(T->TypeBits.getLinkage(), |
| 1328 | T->TypeBits.getVisibility(), |
| 1329 | T->TypeBits.hasLocalOrUnnamedType()); |
| 1330 | } |
| 1331 | |
| 1332 | static void ensure(const Type *T) { |
| 1333 | // If the cache is valid, we're okay. |
| 1334 | if (T->TypeBits.isCacheValid()) return; |
| 1335 | |
| 1336 | // If this type is non-canonical, ask its canonical type for the |
| 1337 | // relevant information. |
| 1338 | if (QualType(T, 0) != T->CanonicalType) { |
| 1339 | const Type *CT = T->CanonicalType.getTypePtr(); |
| 1340 | ensure(CT); |
| 1341 | T->TypeBits.CacheValidAndVisibility = |
| 1342 | CT->TypeBits.CacheValidAndVisibility; |
| 1343 | T->TypeBits.CachedLinkage = CT->TypeBits.CachedLinkage; |
| 1344 | T->TypeBits.CachedLocalOrUnnamed = CT->TypeBits.CachedLocalOrUnnamed; |
| 1345 | return; |
| 1346 | } |
| 1347 | |
| 1348 | // Compute the cached properties and then set the cache. |
| 1349 | CachedProperties Result = computeCachedProperties(T); |
| 1350 | T->TypeBits.CacheValidAndVisibility = Result.getVisibility() + 1U; |
| 1351 | assert(T->TypeBits.isCacheValid() && |
| 1352 | T->TypeBits.getVisibility() == Result.getVisibility()); |
| 1353 | T->TypeBits.CachedLinkage = Result.getLinkage(); |
| 1354 | T->TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType(); |
| 1355 | } |
| 1356 | }; |
John McCall | 1fb0caa | 2010-10-22 21:05:15 +0000 | [diff] [blame] | 1357 | } |
| 1358 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1359 | // Instantiate the friend template at a private class. In a |
| 1360 | // reasonable implementation, these symbols will be internal. |
| 1361 | // It is terrible that this is the best way to accomplish this. |
| 1362 | namespace { class Private {}; } |
| 1363 | typedef TypePropertyCache<Private> Cache; |
John McCall | 1fb0caa | 2010-10-22 21:05:15 +0000 | [diff] [blame] | 1364 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1365 | static CachedProperties computeCachedProperties(const Type *T) { |
| 1366 | switch (T->getTypeClass()) { |
| 1367 | #define TYPE(Class,Base) |
| 1368 | #define NON_CANONICAL_TYPE(Class,Base) case Type::Class: |
| 1369 | #include "clang/AST/TypeNodes.def" |
| 1370 | llvm_unreachable("didn't expect a non-canonical type here"); |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1371 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1372 | #define TYPE(Class,Base) |
| 1373 | #define DEPENDENT_TYPE(Class,Base) case Type::Class: |
| 1374 | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class: |
| 1375 | #include "clang/AST/TypeNodes.def" |
| 1376 | // Treat dependent types as external. |
| 1377 | assert(T->isDependentType()); |
John McCall | 1fb0caa | 2010-10-22 21:05:15 +0000 | [diff] [blame] | 1378 | return CachedProperties(ExternalLinkage, DefaultVisibility, false); |
| 1379 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1380 | case Type::Builtin: |
| 1381 | // C++ [basic.link]p8: |
| 1382 | // A type is said to have linkage if and only if: |
| 1383 | // - it is a fundamental type (3.9.1); or |
| 1384 | return CachedProperties(ExternalLinkage, DefaultVisibility, false); |
| 1385 | |
| 1386 | case Type::Record: |
| 1387 | case Type::Enum: { |
| 1388 | const TagDecl *Tag = cast<TagType>(T)->getDecl(); |
| 1389 | |
| 1390 | // C++ [basic.link]p8: |
| 1391 | // - it is a class or enumeration type that is named (or has a name |
| 1392 | // for linkage purposes (7.1.3)) and the name has linkage; or |
| 1393 | // - it is a specialization of a class template (14); or |
| 1394 | NamedDecl::LinkageInfo LV = Tag->getLinkageAndVisibility(); |
| 1395 | bool IsLocalOrUnnamed = |
| 1396 | Tag->getDeclContext()->isFunctionOrMethod() || |
| 1397 | (!Tag->getIdentifier() && !Tag->getTypedefForAnonDecl()); |
| 1398 | return CachedProperties(LV.linkage(), LV.visibility(), IsLocalOrUnnamed); |
| 1399 | } |
| 1400 | |
| 1401 | // C++ [basic.link]p8: |
| 1402 | // - it is a compound type (3.9.2) other than a class or enumeration, |
| 1403 | // compounded exclusively from types that have linkage; or |
| 1404 | case Type::Complex: |
| 1405 | return Cache::get(cast<ComplexType>(T)->getElementType()); |
| 1406 | case Type::Pointer: |
| 1407 | return Cache::get(cast<PointerType>(T)->getPointeeType()); |
| 1408 | case Type::BlockPointer: |
| 1409 | return Cache::get(cast<BlockPointerType>(T)->getPointeeType()); |
| 1410 | case Type::LValueReference: |
| 1411 | case Type::RValueReference: |
| 1412 | return Cache::get(cast<ReferenceType>(T)->getPointeeType()); |
| 1413 | case Type::MemberPointer: { |
| 1414 | const MemberPointerType *MPT = cast<MemberPointerType>(T); |
| 1415 | return merge(Cache::get(MPT->getClass()), |
| 1416 | Cache::get(MPT->getPointeeType())); |
| 1417 | } |
| 1418 | case Type::ConstantArray: |
| 1419 | case Type::IncompleteArray: |
| 1420 | case Type::VariableArray: |
| 1421 | return Cache::get(cast<ArrayType>(T)->getElementType()); |
| 1422 | case Type::Vector: |
| 1423 | case Type::ExtVector: |
| 1424 | return Cache::get(cast<VectorType>(T)->getElementType()); |
| 1425 | case Type::FunctionNoProto: |
| 1426 | return Cache::get(cast<FunctionType>(T)->getResultType()); |
| 1427 | case Type::FunctionProto: { |
| 1428 | const FunctionProtoType *FPT = cast<FunctionProtoType>(T); |
| 1429 | CachedProperties result = Cache::get(FPT->getResultType()); |
| 1430 | for (FunctionProtoType::arg_type_iterator ai = FPT->arg_type_begin(), |
| 1431 | ae = FPT->arg_type_end(); ai != ae; ++ai) |
| 1432 | result = merge(result, Cache::get(*ai)); |
| 1433 | return result; |
| 1434 | } |
| 1435 | case Type::ObjCInterface: { |
| 1436 | NamedDecl::LinkageInfo LV = |
| 1437 | cast<ObjCInterfaceType>(T)->getDecl()->getLinkageAndVisibility(); |
| 1438 | return CachedProperties(LV.linkage(), LV.visibility(), false); |
| 1439 | } |
| 1440 | case Type::ObjCObject: |
| 1441 | return Cache::get(cast<ObjCObjectType>(T)->getBaseType()); |
| 1442 | case Type::ObjCObjectPointer: |
| 1443 | return Cache::get(cast<ObjCObjectPointerType>(T)->getPointeeType()); |
| 1444 | } |
| 1445 | |
| 1446 | llvm_unreachable("unhandled type class"); |
| 1447 | |
John McCall | 1fb0caa | 2010-10-22 21:05:15 +0000 | [diff] [blame] | 1448 | // C++ [basic.link]p8: |
| 1449 | // Names not covered by these rules have no linkage. |
| 1450 | return CachedProperties(NoLinkage, DefaultVisibility, false); |
| 1451 | } |
| 1452 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1453 | /// \brief Determine the linkage of this type. |
| 1454 | Linkage Type::getLinkage() const { |
| 1455 | Cache::ensure(this); |
| 1456 | return TypeBits.getLinkage(); |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1457 | } |
| 1458 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1459 | /// \brief Determine the linkage of this type. |
| 1460 | Visibility Type::getVisibility() const { |
| 1461 | Cache::ensure(this); |
| 1462 | return TypeBits.getVisibility(); |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1463 | } |
| 1464 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1465 | bool Type::hasUnnamedOrLocalType() const { |
| 1466 | Cache::ensure(this); |
| 1467 | return TypeBits.hasLocalOrUnnamedType(); |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1468 | } |
| 1469 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1470 | std::pair<Linkage,Visibility> Type::getLinkageAndVisibility() const { |
| 1471 | Cache::ensure(this); |
| 1472 | return std::make_pair(TypeBits.getLinkage(), TypeBits.getVisibility()); |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1473 | } |
| 1474 | |
John McCall | b7b2688 | 2010-12-01 08:12:46 +0000 | [diff] [blame] | 1475 | void Type::ClearLinkageCache() { |
| 1476 | TypeBits.CacheValidAndVisibility = 0; |
| 1477 | if (QualType(this, 0) != CanonicalType) |
| 1478 | CanonicalType->TypeBits.CacheValidAndVisibility = 0; |
Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 1479 | } |