blob: 27453ca9813ee890a43fbb647ef51a1bf8b48e19 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Type.cpp - Type representation and manipulation ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements type-related functionality.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/IdentifierTable.h"
15#include "clang/AST/Type.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/Expr.h"
18#include "clang/Basic/TargetInfo.h"
19#include "llvm/Support/Streams.h"
20#include "llvm/ADT/StringExtras.h"
Steve Naroff8d1a3b82007-08-01 17:20:42 +000021#include <sstream>
22
Reid Spencer5f016e22007-07-11 17:01:13 +000023using namespace clang;
24
25Type::~Type() {}
26
27/// isVoidType - Helper method to determine if this is the 'void' type.
28bool Type::isVoidType() const {
29 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
30 return BT->getKind() == BuiltinType::Void;
31 return false;
32}
33
34bool Type::isObjectType() const {
35 if (isa<FunctionType>(CanonicalType))
36 return false;
37 else if (CanonicalType->isIncompleteType())
38 return false;
39 else
40 return true;
41}
42
43bool Type::isDerivedType() const {
44 switch (CanonicalType->getTypeClass()) {
45 case Pointer:
46 case Array:
47 case FunctionProto:
48 case FunctionNoProto:
49 case Reference:
50 return true;
51 case Tagged: {
52 const TagType *TT = cast<TagType>(CanonicalType);
53 const Decl::Kind Kind = TT->getDecl()->getKind();
54 return Kind == Decl::Struct || Kind == Decl::Union;
55 }
56 default:
57 return false;
58 }
59}
60
Chris Lattnerc8629632007-07-31 19:29:30 +000061bool Type::isStructureType() const {
62 if (const RecordType *RT = dyn_cast<RecordType>(this))
63 if (RT->getDecl()->getKind() == Decl::Struct)
64 return true;
65 return false;
66}
67bool Type::isUnionType() const {
68 if (const RecordType *RT = dyn_cast<RecordType>(this))
69 if (RT->getDecl()->getKind() == Decl::Union)
70 return true;
71 return false;
72}
Chris Lattnerc8629632007-07-31 19:29:30 +000073
74const FunctionType *Type::getAsFunctionType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +000075 // If this is directly a function type, return it.
76 if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
77 return FTy;
Chris Lattnerc8629632007-07-31 19:29:30 +000078
Steve Naroff7064f5c2007-07-26 18:32:01 +000079 // If this is a typedef for a function type, strip the typedef off without
80 // losing all typedef information.
81 if (isa<FunctionType>(CanonicalType))
82 return cast<FunctionType>(cast<TypedefType>(this)->LookThroughTypedefs());
83 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000084}
85
Chris Lattnerbefee482007-07-31 16:53:04 +000086const PointerType *Type::getAsPointerType() const {
Chris Lattner7a2e0472007-07-16 00:23:25 +000087 // If this is directly a pointer type, return it.
88 if (const PointerType *PTy = dyn_cast<PointerType>(this))
89 return PTy;
Chris Lattnera2c77672007-07-16 22:05:22 +000090
91 // If this is a typedef for a pointer type, strip the typedef off without
92 // losing all typedef information.
93 if (isa<PointerType>(CanonicalType))
94 return cast<PointerType>(cast<TypedefType>(this)->LookThroughTypedefs());
Chris Lattner3acb1382007-07-16 00:13:25 +000095 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000096}
97
Chris Lattnera1d9fde2007-07-31 16:56:34 +000098const ReferenceType *Type::getAsReferenceType() const {
Bill Wendlingea5e79f2007-07-17 04:16:47 +000099 // If this is directly a reference type, return it.
100 if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
101 return RTy;
102
103 // If this is a typedef for a reference type, strip the typedef off without
104 // losing all typedef information.
105 if (isa<ReferenceType>(CanonicalType))
106 return cast<ReferenceType>(cast<TypedefType>(this)->LookThroughTypedefs());
107 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000108}
109
Chris Lattnerc8629632007-07-31 19:29:30 +0000110const ArrayType *Type::getAsArrayType() const {
Steve Naroff700204c2007-07-24 21:46:40 +0000111 // If this is directly a reference type, return it.
112 if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
113 return ATy;
114
115 // If this is a typedef for an array type, strip the typedef off without
116 // losing all typedef information.
117 if (isa<ArrayType>(CanonicalType))
118 return cast<ArrayType>(cast<TypedefType>(this)->LookThroughTypedefs());
119 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000120}
121
Chris Lattnerc8629632007-07-31 19:29:30 +0000122const RecordType *Type::getAsRecordType() const {
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000123 // If this is directly a reference type, return it.
124 if (const RecordType *RTy = dyn_cast<RecordType>(this))
125 return RTy;
126
127 // If this is a typedef for an record type, strip the typedef off without
128 // losing all typedef information.
129 if (isa<RecordType>(CanonicalType))
130 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Steve Naroffadc01852007-07-26 03:18:02 +0000131 return 0;
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000132}
133
Chris Lattnerc8629632007-07-31 19:29:30 +0000134const RecordType *Type::getAsStructureType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000135 // If this is directly a structure type, return it.
Chris Lattnerc8629632007-07-31 19:29:30 +0000136 if (const RecordType *RT = dyn_cast<RecordType>(this)) {
137 if (RT->getDecl()->getKind() == Decl::Struct)
138 return RT;
Steve Naroff7064f5c2007-07-26 18:32:01 +0000139 }
140 // If this is a typedef for a structure type, strip the typedef off without
141 // losing all typedef information.
Chris Lattnerc8629632007-07-31 19:29:30 +0000142 if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
143 if (RT->getDecl()->getKind() == Decl::Struct)
144 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000145 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000146 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000147}
148
Chris Lattnerc8629632007-07-31 19:29:30 +0000149const RecordType *Type::getAsUnionType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000150 // If this is directly a union type, return it.
Chris Lattnerc8629632007-07-31 19:29:30 +0000151 if (const RecordType *RT = dyn_cast<RecordType>(this)) {
152 if (RT->getDecl()->getKind() == Decl::Union)
153 return RT;
Steve Naroff7064f5c2007-07-26 18:32:01 +0000154 }
155 // If this is a typedef for a union type, strip the typedef off without
156 // losing all typedef information.
Chris Lattnerc8629632007-07-31 19:29:30 +0000157 if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
158 if (RT->getDecl()->getKind() == Decl::Union)
159 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000160 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000161 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000162}
163
Chris Lattner7a2e0472007-07-16 00:23:25 +0000164bool Type::isComplexType() const {
165 return isa<ComplexType>(CanonicalType);
166}
167
Chris Lattnerc8629632007-07-31 19:29:30 +0000168const VectorType *Type::getAsVectorType() const {
Chris Lattner7a2e0472007-07-16 00:23:25 +0000169 // Are we directly a vector type?
170 if (const VectorType *VTy = dyn_cast<VectorType>(this))
171 return VTy;
Chris Lattnera2c77672007-07-16 22:05:22 +0000172
173 // If this is a typedef for a vector type, strip the typedef off without
174 // losing all typedef information.
175 if (isa<VectorType>(CanonicalType))
176 return cast<VectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
177
Chris Lattner7a2e0472007-07-16 00:23:25 +0000178 return 0;
179}
180
Chris Lattnerc8629632007-07-31 19:29:30 +0000181const OCUVectorType *Type::getAsOCUVectorType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000182 // Are we directly an OpenCU vector type?
183 if (const OCUVectorType *VTy = dyn_cast<OCUVectorType>(this))
184 return VTy;
185
186 // If this is a typedef for an OpenCU vector type, strip the typedef off
187 // without losing all typedef information.
188 if (isa<OCUVectorType>(CanonicalType))
189 return cast<OCUVectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
190
191 return 0;
192}
193
Chris Lattner7a2e0472007-07-16 00:23:25 +0000194
Reid Spencer5f016e22007-07-11 17:01:13 +0000195// C99 6.2.7p1: If both are complete types, then the following additional
196// requirements apply...FIXME (handle compatibility across source files).
197bool Type::tagTypesAreCompatible(QualType lhs, QualType rhs) {
198 TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
199 TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
200
201 if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
202 if (ldecl->getIdentifier() == rdecl->getIdentifier())
203 return true;
204 }
205 if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
206 if (ldecl->getIdentifier() == rdecl->getIdentifier())
207 return true;
208 }
209 return false;
210}
211
212bool Type::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
213 // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
214 // identically qualified and both shall be pointers to compatible types.
215 if (lhs.getQualifiers() != rhs.getQualifiers())
216 return false;
217
218 QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
219 QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
220
221 return typesAreCompatible(ltype, rtype);
222}
223
224// C++ 5.17p6: When the left opperand of an assignment operator denotes a
225// reference to T, the operation assigns to the object of type T denoted by the
226// reference.
227bool Type::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
228 QualType ltype = lhs;
229
230 if (lhs->isReferenceType())
231 ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
232
233 QualType rtype = rhs;
234
235 if (rhs->isReferenceType())
236 rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
237
238 return typesAreCompatible(ltype, rtype);
239}
240
241bool Type::functionTypesAreCompatible(QualType lhs, QualType rhs) {
242 const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
243 const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
244 const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
245 const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
246
247 // first check the return types (common between C99 and K&R).
248 if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
249 return false;
250
251 if (lproto && rproto) { // two C99 style function prototypes
252 unsigned lproto_nargs = lproto->getNumArgs();
253 unsigned rproto_nargs = rproto->getNumArgs();
254
255 if (lproto_nargs != rproto_nargs)
256 return false;
257
258 // both prototypes have the same number of arguments.
259 if ((lproto->isVariadic() && !rproto->isVariadic()) ||
260 (rproto->isVariadic() && !lproto->isVariadic()))
261 return false;
262
263 // The use of ellipsis agree...now check the argument types.
264 for (unsigned i = 0; i < lproto_nargs; i++)
265 if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
266 return false;
267 return true;
268 }
269 if (!lproto && !rproto) // two K&R style function decls, nothing to do.
270 return true;
271
272 // we have a mixture of K&R style with C99 prototypes
273 const FunctionTypeProto *proto = lproto ? lproto : rproto;
274
275 if (proto->isVariadic())
276 return false;
277
278 // FIXME: Each parameter type T in the prototype must be compatible with the
279 // type resulting from applying the usual argument conversions to T.
280 return true;
281}
282
283bool Type::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
284 QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
285 QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
286
287 if (!typesAreCompatible(ltype, rtype))
288 return false;
289
290 // FIXME: If both types specify constant sizes, then the sizes must also be
291 // the same. Even if the sizes are the same, GCC produces an error.
292 return true;
293}
294
295/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
296/// both shall have the identically qualified version of a compatible type.
297/// C99 6.2.7p1: Two types have compatible types if their types are the
298/// same. See 6.7.[2,3,5] for additional rules.
299bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
300 QualType lcanon = lhs.getCanonicalType();
301 QualType rcanon = rhs.getCanonicalType();
302
303 // If two types are identical, they are are compatible
304 if (lcanon == rcanon)
305 return true;
306
307 // If the canonical type classes don't match, they can't be compatible
308 if (lcanon->getTypeClass() != rcanon->getTypeClass())
309 return false;
310
311 switch (lcanon->getTypeClass()) {
312 case Type::Pointer:
313 return pointerTypesAreCompatible(lcanon, rcanon);
314 case Type::Reference:
315 return referenceTypesAreCompatible(lcanon, rcanon);
316 case Type::Array:
317 return arrayTypesAreCompatible(lcanon, rcanon);
318 case Type::FunctionNoProto:
319 case Type::FunctionProto:
320 return functionTypesAreCompatible(lcanon, rcanon);
321 case Type::Tagged: // handle structures, unions
322 return tagTypesAreCompatible(lcanon, rcanon);
323 case Type::Builtin:
324 return false;
325 default:
326 assert(0 && "unexpected type");
327 }
328 return true; // should never get here...
329}
330
331bool Type::isIntegerType() const {
332 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
333 return BT->getKind() >= BuiltinType::Bool &&
334 BT->getKind() <= BuiltinType::LongLong;
335 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
336 if (TT->getDecl()->getKind() == Decl::Enum)
337 return true;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000338 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
339 return VT->getElementType()->isIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000340 return false;
341}
342
Steve Naroff13b7c5f2007-08-08 22:15:55 +0000343bool Type::isEnumeralType() const {
344 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
345 return TT->getDecl()->getKind() == Decl::Enum;
346 return false;
347}
348
349bool Type::isBooleanType() const {
350 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
351 return BT->getKind() == BuiltinType::Bool;
352 return false;
353}
354
355bool Type::isCharType() const {
356 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
357 return BT->getKind() == BuiltinType::Char_U ||
358 BT->getKind() == BuiltinType::UChar ||
359 BT->getKind() == BuiltinType::Char_S;
360 return false;
361}
362
Reid Spencer5f016e22007-07-11 17:01:13 +0000363bool Type::isSignedIntegerType() const {
364 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
365 return BT->getKind() >= BuiltinType::Char_S &&
366 BT->getKind() <= BuiltinType::LongLong;
367 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000368 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
369 return VT->getElementType()->isSignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000370 return false;
371}
372
373bool Type::isUnsignedIntegerType() const {
374 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
375 return BT->getKind() >= BuiltinType::Bool &&
376 BT->getKind() <= BuiltinType::ULongLong;
377 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000378 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
379 return VT->getElementType()->isUnsignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000380 return false;
381}
382
383bool Type::isFloatingType() const {
384 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
385 return BT->getKind() >= BuiltinType::Float &&
386 BT->getKind() <= BuiltinType::LongDouble;
387 if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
388 return CT->isFloatingType();
Steve Naroffc63b96a2007-07-12 21:46:55 +0000389 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
390 return VT->getElementType()->isFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000391 return false;
392}
393
394bool Type::isRealFloatingType() const {
395 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
396 return BT->getKind() >= BuiltinType::Float &&
397 BT->getKind() <= BuiltinType::LongDouble;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000398 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
399 return VT->getElementType()->isRealFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000400 return false;
401}
402
403bool Type::isRealType() const {
404 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
405 return BT->getKind() >= BuiltinType::Bool &&
406 BT->getKind() <= BuiltinType::LongDouble;
407 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
408 return TT->getDecl()->getKind() == Decl::Enum;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000409 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
410 return VT->getElementType()->isRealType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000411 return false;
412}
413
Reid Spencer5f016e22007-07-11 17:01:13 +0000414bool Type::isArithmeticType() const {
415 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
416 return BT->getKind() != BuiltinType::Void;
417 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
418 if (TT->getDecl()->getKind() == Decl::Enum)
419 return true;
420 return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
421}
422
423bool Type::isScalarType() const {
424 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
425 return BT->getKind() != BuiltinType::Void;
426 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
427 if (TT->getDecl()->getKind() == Decl::Enum)
428 return true;
429 return false;
430 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000431 return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
432 isa<VectorType>(CanonicalType);
Reid Spencer5f016e22007-07-11 17:01:13 +0000433}
434
435bool Type::isAggregateType() const {
436 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
437 if (TT->getDecl()->getKind() == Decl::Struct)
438 return true;
439 return false;
440 }
441 return CanonicalType->getTypeClass() == Array;
442}
443
444// The only variable size types are auto arrays within a function. Structures
445// cannot contain a VLA member. They can have a flexible array member, however
446// the structure is still constant size (C99 6.7.2.1p16).
Chris Lattner590b6642007-07-15 23:26:56 +0000447bool Type::isConstantSizeType(ASTContext &Ctx, SourceLocation *loc) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000448 if (const ArrayType *Ary = dyn_cast<ArrayType>(CanonicalType)) {
Chris Lattner8b9023b2007-07-13 03:05:23 +0000449 assert(Ary->getSizeExpr() && "Incomplete types don't have a size at all!");
450 // Variable Length Array?
Chris Lattner590b6642007-07-15 23:26:56 +0000451 return Ary->getSizeExpr()->isIntegerConstantExpr(Ctx, loc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000452 }
453 return true;
454}
455
456/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
457/// - a type that can describe objects, but which lacks information needed to
458/// determine its size.
459bool Type::isIncompleteType() const {
460 switch (CanonicalType->getTypeClass()) {
461 default: return false;
462 case Builtin:
463 // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never
464 // be completed.
465 return isVoidType();
466 case Tagged:
467 // A tagged type (struct/union/enum/class) is incomplete if the decl is a
468 // forward declaration, but not a full definition (C99 6.2.5p22).
469 return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
470 case Array:
471 // An array of unknown size is an incomplete type (C99 6.2.5p22).
Chris Lattner8b9023b2007-07-13 03:05:23 +0000472 return cast<ArrayType>(CanonicalType)->getSizeExpr() == 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000473 }
474}
475
476bool Type::isPromotableIntegerType() const {
477 const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
478 if (!BT) return false;
479 switch (BT->getKind()) {
480 case BuiltinType::Bool:
481 case BuiltinType::Char_S:
482 case BuiltinType::Char_U:
483 case BuiltinType::SChar:
484 case BuiltinType::UChar:
485 case BuiltinType::Short:
486 case BuiltinType::UShort:
487 return true;
488 default:
489 return false;
490 }
491}
492
493const char *BuiltinType::getName() const {
494 switch (getKind()) {
495 default: assert(0 && "Unknown builtin type!");
496 case Void: return "void";
497 case Bool: return "_Bool";
498 case Char_S: return "char";
499 case Char_U: return "char";
500 case SChar: return "signed char";
501 case Short: return "short";
502 case Int: return "int";
503 case Long: return "long";
504 case LongLong: return "long long";
505 case UChar: return "unsigned char";
506 case UShort: return "unsigned short";
507 case UInt: return "unsigned int";
508 case ULong: return "unsigned long";
509 case ULongLong: return "unsigned long long";
510 case Float: return "float";
511 case Double: return "double";
512 case LongDouble: return "long double";
513 }
514}
515
Reid Spencer5f016e22007-07-11 17:01:13 +0000516void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
Chris Lattner942cfd32007-07-20 18:48:28 +0000517 arg_type_iterator ArgTys,
Reid Spencer5f016e22007-07-11 17:01:13 +0000518 unsigned NumArgs, bool isVariadic) {
519 ID.AddPointer(Result.getAsOpaquePtr());
520 for (unsigned i = 0; i != NumArgs; ++i)
521 ID.AddPointer(ArgTys[i].getAsOpaquePtr());
522 ID.AddInteger(isVariadic);
523}
524
525void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
Chris Lattner942cfd32007-07-20 18:48:28 +0000526 Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
Reid Spencer5f016e22007-07-11 17:01:13 +0000527}
528
Chris Lattnera2c77672007-07-16 22:05:22 +0000529/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
530/// potentially looking through *all* consequtive typedefs. This returns the
531/// sum of the type qualifiers, so if you have:
532/// typedef const int A;
533/// typedef volatile A B;
534/// looking through the typedefs for B will give you "const volatile A".
535///
536QualType TypedefType::LookThroughTypedefs() const {
537 // Usually, there is only a single level of typedefs, be fast in that case.
538 QualType FirstType = getDecl()->getUnderlyingType();
539 if (!isa<TypedefType>(FirstType))
540 return FirstType;
541
542 // Otherwise, do the fully general loop.
543 unsigned TypeQuals = 0;
544 const TypedefType *TDT = this;
545 while (1) {
546 QualType CurType = TDT->getDecl()->getUnderlyingType();
547 TypeQuals |= CurType.getQualifiers();
548
549 TDT = dyn_cast<TypedefType>(CurType);
550 if (TDT == 0)
551 return QualType(CurType.getTypePtr(), TypeQuals);
552 }
553}
Reid Spencer5f016e22007-07-11 17:01:13 +0000554
555bool RecordType::classof(const Type *T) {
556 if (const TagType *TT = dyn_cast<TagType>(T))
557 return isa<RecordDecl>(TT->getDecl());
558 return false;
559}
560
561
562//===----------------------------------------------------------------------===//
563// Type Printing
564//===----------------------------------------------------------------------===//
565
566void QualType::dump(const char *msg) const {
567 std::string R = "foo";
568 getAsStringInternal(R);
569 if (msg)
570 fprintf(stderr, "%s: %s\n", msg, R.c_str());
571 else
572 fprintf(stderr, "%s\n", R.c_str());
573}
574
575static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
576 // Note: funkiness to ensure we get a space only between quals.
577 bool NonePrinted = true;
578 if (TypeQuals & QualType::Const)
579 S += "const", NonePrinted = false;
580 if (TypeQuals & QualType::Volatile)
581 S += (NonePrinted+" volatile"), NonePrinted = false;
582 if (TypeQuals & QualType::Restrict)
583 S += (NonePrinted+" restrict"), NonePrinted = false;
584}
585
586void QualType::getAsStringInternal(std::string &S) const {
587 if (isNull()) {
588 S += "NULL TYPE\n";
589 return;
590 }
591
592 // Print qualifiers as appropriate.
Anton Korobeynikovb7b50bc2007-07-13 00:48:55 +0000593 unsigned TQ = getQualifiers();
594 if (TQ) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000595 std::string TQS;
596 AppendTypeQualList(TQS, TQ);
597 if (!S.empty())
598 S = TQS + ' ' + S;
599 else
600 S = TQS;
601 }
602
603 getTypePtr()->getAsStringInternal(S);
604}
605
606void BuiltinType::getAsStringInternal(std::string &S) const {
607 if (S.empty()) {
608 S = getName();
609 } else {
610 // Prefix the basic type, e.g. 'int X'.
611 S = ' ' + S;
612 S = getName() + S;
613 }
614}
615
616void ComplexType::getAsStringInternal(std::string &S) const {
617 ElementType->getAsStringInternal(S);
618 S = "_Complex " + S;
619}
620
621void PointerType::getAsStringInternal(std::string &S) const {
622 S = '*' + S;
623
624 // Handle things like 'int (*A)[4];' correctly.
625 // FIXME: this should include vectors, but vectors use attributes I guess.
626 if (isa<ArrayType>(PointeeType.getTypePtr()))
627 S = '(' + S + ')';
628
629 PointeeType.getAsStringInternal(S);
630}
631
632void ReferenceType::getAsStringInternal(std::string &S) const {
633 S = '&' + S;
634
635 // Handle things like 'int (&A)[4];' correctly.
636 // FIXME: this should include vectors, but vectors use attributes I guess.
637 if (isa<ArrayType>(ReferenceeType.getTypePtr()))
638 S = '(' + S + ')';
639
640 ReferenceeType.getAsStringInternal(S);
641}
642
643void ArrayType::getAsStringInternal(std::string &S) const {
644 S += '[';
645
646 if (IndexTypeQuals) {
647 AppendTypeQualList(S, IndexTypeQuals);
648 S += ' ';
649 }
650
651 if (SizeModifier == Static)
652 S += "static";
653 else if (SizeModifier == Star)
654 S += '*';
655
656 S += ']';
657
658 ElementType.getAsStringInternal(S);
659}
660
661void VectorType::getAsStringInternal(std::string &S) const {
Chris Lattnere107b5d2007-07-13 21:01:17 +0000662 S += " __attribute__((vector_size(";
663 // FIXME: should multiply by element size somehow.
Reid Spencer5f016e22007-07-11 17:01:13 +0000664 S += llvm::utostr_32(NumElements*4); // convert back to bytes.
Chris Lattnere107b5d2007-07-13 21:01:17 +0000665 S += ")))";
Reid Spencer5f016e22007-07-11 17:01:13 +0000666 ElementType.getAsStringInternal(S);
667}
668
Steve Naroff31a45842007-07-28 23:10:27 +0000669void OCUVectorType::getAsStringInternal(std::string &S) const {
670 S += " __attribute__((ocu_vector_type(";
671 S += llvm::utostr_32(NumElements);
672 S += ")))";
673 ElementType.getAsStringInternal(S);
674}
675
Steve Naroffd1861fd2007-07-31 12:34:36 +0000676void TypeOfExpr::getAsStringInternal(std::string &InnerString) const {
Steve Naroff363bcff2007-08-01 23:45:51 +0000677 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(e) X'.
678 InnerString = ' ' + InnerString;
Steve Naroff8d1a3b82007-08-01 17:20:42 +0000679 std::ostringstream s;
680 getUnderlyingExpr()->print(s);
Steve Naroff1bfd5cc2007-08-05 03:24:45 +0000681 InnerString = "typeof(" + s.str() + ")" + InnerString;
Steve Naroffd1861fd2007-07-31 12:34:36 +0000682}
683
Steve Naroff363bcff2007-08-01 23:45:51 +0000684void TypeOfType::getAsStringInternal(std::string &InnerString) const {
685 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(t) X'.
686 InnerString = ' ' + InnerString;
Steve Naroffd1861fd2007-07-31 12:34:36 +0000687 std::string Tmp;
688 getUnderlyingType().getAsStringInternal(Tmp);
Steve Naroff363bcff2007-08-01 23:45:51 +0000689 InnerString = "typeof(" + Tmp + ")" + InnerString;
Steve Naroffd1861fd2007-07-31 12:34:36 +0000690}
691
Reid Spencer5f016e22007-07-11 17:01:13 +0000692void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
693 // If needed for precedence reasons, wrap the inner part in grouping parens.
694 if (!S.empty())
695 S = "(" + S + ")";
696
697 S += "()";
698 getResultType().getAsStringInternal(S);
699}
700
701void FunctionTypeProto::getAsStringInternal(std::string &S) const {
702 // If needed for precedence reasons, wrap the inner part in grouping parens.
703 if (!S.empty())
704 S = "(" + S + ")";
705
706 S += "(";
707 std::string Tmp;
708 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
709 if (i) S += ", ";
710 getArgType(i).getAsStringInternal(Tmp);
711 S += Tmp;
712 Tmp.clear();
713 }
714
715 if (isVariadic()) {
716 if (getNumArgs())
717 S += ", ";
718 S += "...";
719 } else if (getNumArgs() == 0) {
720 // Do not emit int() if we have a proto, emit 'int(void)'.
721 S += "void";
722 }
723
724 S += ")";
725 getResultType().getAsStringInternal(S);
726}
727
728
729void TypedefType::getAsStringInternal(std::string &InnerString) const {
730 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
731 InnerString = ' ' + InnerString;
732 InnerString = getDecl()->getIdentifier()->getName() + InnerString;
733}
734
735void TagType::getAsStringInternal(std::string &InnerString) const {
736 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
737 InnerString = ' ' + InnerString;
738
739 const char *Kind = getDecl()->getKindName();
740 const char *ID;
741 if (const IdentifierInfo *II = getDecl()->getIdentifier())
742 ID = II->getName();
743 else
744 ID = "<anonymous>";
745
746 InnerString = std::string(Kind) + " " + ID + InnerString;
747}