blob: dc3ee8ebcb19690b986e7b616473dcc648ef5e19 [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"
21using namespace clang;
22
23Type::~Type() {}
24
25/// isVoidType - Helper method to determine if this is the 'void' type.
26bool Type::isVoidType() const {
27 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
28 return BT->getKind() == BuiltinType::Void;
29 return false;
30}
31
32bool Type::isObjectType() const {
33 if (isa<FunctionType>(CanonicalType))
34 return false;
35 else if (CanonicalType->isIncompleteType())
36 return false;
37 else
38 return true;
39}
40
41bool Type::isDerivedType() const {
42 switch (CanonicalType->getTypeClass()) {
43 case Pointer:
44 case Array:
45 case FunctionProto:
46 case FunctionNoProto:
47 case Reference:
48 return true;
49 case Tagged: {
50 const TagType *TT = cast<TagType>(CanonicalType);
51 const Decl::Kind Kind = TT->getDecl()->getKind();
52 return Kind == Decl::Struct || Kind == Decl::Union;
53 }
54 default:
55 return false;
56 }
57}
58
Chris Lattnerc8629632007-07-31 19:29:30 +000059// FIXME: move inline
60bool Type::isFunctionType() const { return isa<FunctionType>(CanonicalType); }
61bool Type::isPointerType() const { return isa<PointerType>(CanonicalType); }
62bool Type::isReferenceType() const { return isa<ReferenceType>(CanonicalType); }
63bool Type::isArrayType() const { return isa<ArrayType>(CanonicalType); }
64bool Type::isRecordType() const { return isa<RecordType>(CanonicalType); }
65bool Type::isStructureType() const {
66 if (const RecordType *RT = dyn_cast<RecordType>(this))
67 if (RT->getDecl()->getKind() == Decl::Struct)
68 return true;
69 return false;
70}
71bool Type::isUnionType() const {
72 if (const RecordType *RT = dyn_cast<RecordType>(this))
73 if (RT->getDecl()->getKind() == Decl::Union)
74 return true;
75 return false;
76}
77bool Type::isVectorType() const { return isa<VectorType>(CanonicalType); }
78bool Type::isOCUVectorType() const { return isa<OCUVectorType>(CanonicalType); }
79
80
81const FunctionType *Type::getAsFunctionType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +000082 // If this is directly a function type, return it.
83 if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
84 return FTy;
Chris Lattnerc8629632007-07-31 19:29:30 +000085
Steve Naroff7064f5c2007-07-26 18:32:01 +000086 // If this is a typedef for a function type, strip the typedef off without
87 // losing all typedef information.
88 if (isa<FunctionType>(CanonicalType))
89 return cast<FunctionType>(cast<TypedefType>(this)->LookThroughTypedefs());
90 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000091}
92
Chris Lattnerbefee482007-07-31 16:53:04 +000093const PointerType *Type::getAsPointerType() const {
Chris Lattner7a2e0472007-07-16 00:23:25 +000094 // If this is directly a pointer type, return it.
95 if (const PointerType *PTy = dyn_cast<PointerType>(this))
96 return PTy;
Chris Lattnera2c77672007-07-16 22:05:22 +000097
98 // If this is a typedef for a pointer type, strip the typedef off without
99 // losing all typedef information.
100 if (isa<PointerType>(CanonicalType))
101 return cast<PointerType>(cast<TypedefType>(this)->LookThroughTypedefs());
Chris Lattner3acb1382007-07-16 00:13:25 +0000102 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000103}
104
Chris Lattnera1d9fde2007-07-31 16:56:34 +0000105const ReferenceType *Type::getAsReferenceType() const {
Bill Wendlingea5e79f2007-07-17 04:16:47 +0000106 // If this is directly a reference type, return it.
107 if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
108 return RTy;
109
110 // If this is a typedef for a reference type, strip the typedef off without
111 // losing all typedef information.
112 if (isa<ReferenceType>(CanonicalType))
113 return cast<ReferenceType>(cast<TypedefType>(this)->LookThroughTypedefs());
114 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000115}
116
Chris Lattnerc8629632007-07-31 19:29:30 +0000117const ArrayType *Type::getAsArrayType() const {
Steve Naroff700204c2007-07-24 21:46:40 +0000118 // If this is directly a reference type, return it.
119 if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
120 return ATy;
121
122 // If this is a typedef for an array type, strip the typedef off without
123 // losing all typedef information.
124 if (isa<ArrayType>(CanonicalType))
125 return cast<ArrayType>(cast<TypedefType>(this)->LookThroughTypedefs());
126 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000127}
128
Chris Lattnerc8629632007-07-31 19:29:30 +0000129const RecordType *Type::getAsRecordType() const {
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000130 // If this is directly a reference type, return it.
131 if (const RecordType *RTy = dyn_cast<RecordType>(this))
132 return RTy;
133
134 // If this is a typedef for an record type, strip the typedef off without
135 // losing all typedef information.
136 if (isa<RecordType>(CanonicalType))
137 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Steve Naroffadc01852007-07-26 03:18:02 +0000138 return 0;
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000139}
140
Chris Lattnerc8629632007-07-31 19:29:30 +0000141const RecordType *Type::getAsStructureType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000142 // If this is directly a structure type, return it.
Chris Lattnerc8629632007-07-31 19:29:30 +0000143 if (const RecordType *RT = dyn_cast<RecordType>(this)) {
144 if (RT->getDecl()->getKind() == Decl::Struct)
145 return RT;
Steve Naroff7064f5c2007-07-26 18:32:01 +0000146 }
147 // If this is a typedef for a structure type, strip the typedef off without
148 // losing all typedef information.
Chris Lattnerc8629632007-07-31 19:29:30 +0000149 if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
150 if (RT->getDecl()->getKind() == Decl::Struct)
151 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000152 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000153 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000154}
155
Chris Lattnerc8629632007-07-31 19:29:30 +0000156const RecordType *Type::getAsUnionType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000157 // If this is directly a union type, return it.
Chris Lattnerc8629632007-07-31 19:29:30 +0000158 if (const RecordType *RT = dyn_cast<RecordType>(this)) {
159 if (RT->getDecl()->getKind() == Decl::Union)
160 return RT;
Steve Naroff7064f5c2007-07-26 18:32:01 +0000161 }
162 // If this is a typedef for a union type, strip the typedef off without
163 // losing all typedef information.
Chris Lattnerc8629632007-07-31 19:29:30 +0000164 if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
165 if (RT->getDecl()->getKind() == Decl::Union)
166 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000167 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000168 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000169}
170
Chris Lattner7a2e0472007-07-16 00:23:25 +0000171bool Type::isComplexType() const {
172 return isa<ComplexType>(CanonicalType);
173}
174
Chris Lattnerc8629632007-07-31 19:29:30 +0000175const VectorType *Type::getAsVectorType() const {
Chris Lattner7a2e0472007-07-16 00:23:25 +0000176 // Are we directly a vector type?
177 if (const VectorType *VTy = dyn_cast<VectorType>(this))
178 return VTy;
Chris Lattnera2c77672007-07-16 22:05:22 +0000179
180 // If this is a typedef for a vector type, strip the typedef off without
181 // losing all typedef information.
182 if (isa<VectorType>(CanonicalType))
183 return cast<VectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
184
Chris Lattner7a2e0472007-07-16 00:23:25 +0000185 return 0;
186}
187
Chris Lattnerc8629632007-07-31 19:29:30 +0000188const OCUVectorType *Type::getAsOCUVectorType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000189 // Are we directly an OpenCU vector type?
190 if (const OCUVectorType *VTy = dyn_cast<OCUVectorType>(this))
191 return VTy;
192
193 // If this is a typedef for an OpenCU vector type, strip the typedef off
194 // without losing all typedef information.
195 if (isa<OCUVectorType>(CanonicalType))
196 return cast<OCUVectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
197
198 return 0;
199}
200
Chris Lattner7a2e0472007-07-16 00:23:25 +0000201
Reid Spencer5f016e22007-07-11 17:01:13 +0000202// C99 6.2.7p1: If both are complete types, then the following additional
203// requirements apply...FIXME (handle compatibility across source files).
204bool Type::tagTypesAreCompatible(QualType lhs, QualType rhs) {
205 TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
206 TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
207
208 if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
209 if (ldecl->getIdentifier() == rdecl->getIdentifier())
210 return true;
211 }
212 if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
213 if (ldecl->getIdentifier() == rdecl->getIdentifier())
214 return true;
215 }
216 return false;
217}
218
219bool Type::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
220 // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
221 // identically qualified and both shall be pointers to compatible types.
222 if (lhs.getQualifiers() != rhs.getQualifiers())
223 return false;
224
225 QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
226 QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
227
228 return typesAreCompatible(ltype, rtype);
229}
230
231// C++ 5.17p6: When the left opperand of an assignment operator denotes a
232// reference to T, the operation assigns to the object of type T denoted by the
233// reference.
234bool Type::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
235 QualType ltype = lhs;
236
237 if (lhs->isReferenceType())
238 ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
239
240 QualType rtype = rhs;
241
242 if (rhs->isReferenceType())
243 rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
244
245 return typesAreCompatible(ltype, rtype);
246}
247
248bool Type::functionTypesAreCompatible(QualType lhs, QualType rhs) {
249 const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
250 const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
251 const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
252 const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
253
254 // first check the return types (common between C99 and K&R).
255 if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
256 return false;
257
258 if (lproto && rproto) { // two C99 style function prototypes
259 unsigned lproto_nargs = lproto->getNumArgs();
260 unsigned rproto_nargs = rproto->getNumArgs();
261
262 if (lproto_nargs != rproto_nargs)
263 return false;
264
265 // both prototypes have the same number of arguments.
266 if ((lproto->isVariadic() && !rproto->isVariadic()) ||
267 (rproto->isVariadic() && !lproto->isVariadic()))
268 return false;
269
270 // The use of ellipsis agree...now check the argument types.
271 for (unsigned i = 0; i < lproto_nargs; i++)
272 if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
273 return false;
274 return true;
275 }
276 if (!lproto && !rproto) // two K&R style function decls, nothing to do.
277 return true;
278
279 // we have a mixture of K&R style with C99 prototypes
280 const FunctionTypeProto *proto = lproto ? lproto : rproto;
281
282 if (proto->isVariadic())
283 return false;
284
285 // FIXME: Each parameter type T in the prototype must be compatible with the
286 // type resulting from applying the usual argument conversions to T.
287 return true;
288}
289
290bool Type::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
291 QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
292 QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
293
294 if (!typesAreCompatible(ltype, rtype))
295 return false;
296
297 // FIXME: If both types specify constant sizes, then the sizes must also be
298 // the same. Even if the sizes are the same, GCC produces an error.
299 return true;
300}
301
302/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
303/// both shall have the identically qualified version of a compatible type.
304/// C99 6.2.7p1: Two types have compatible types if their types are the
305/// same. See 6.7.[2,3,5] for additional rules.
306bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
307 QualType lcanon = lhs.getCanonicalType();
308 QualType rcanon = rhs.getCanonicalType();
309
310 // If two types are identical, they are are compatible
311 if (lcanon == rcanon)
312 return true;
313
314 // If the canonical type classes don't match, they can't be compatible
315 if (lcanon->getTypeClass() != rcanon->getTypeClass())
316 return false;
317
318 switch (lcanon->getTypeClass()) {
319 case Type::Pointer:
320 return pointerTypesAreCompatible(lcanon, rcanon);
321 case Type::Reference:
322 return referenceTypesAreCompatible(lcanon, rcanon);
323 case Type::Array:
324 return arrayTypesAreCompatible(lcanon, rcanon);
325 case Type::FunctionNoProto:
326 case Type::FunctionProto:
327 return functionTypesAreCompatible(lcanon, rcanon);
328 case Type::Tagged: // handle structures, unions
329 return tagTypesAreCompatible(lcanon, rcanon);
330 case Type::Builtin:
331 return false;
332 default:
333 assert(0 && "unexpected type");
334 }
335 return true; // should never get here...
336}
337
338bool Type::isIntegerType() const {
339 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
340 return BT->getKind() >= BuiltinType::Bool &&
341 BT->getKind() <= BuiltinType::LongLong;
342 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
343 if (TT->getDecl()->getKind() == Decl::Enum)
344 return true;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000345 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
346 return VT->getElementType()->isIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000347 return false;
348}
349
350bool Type::isSignedIntegerType() const {
351 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
352 return BT->getKind() >= BuiltinType::Char_S &&
353 BT->getKind() <= BuiltinType::LongLong;
354 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000355 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
356 return VT->getElementType()->isSignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000357 return false;
358}
359
360bool Type::isUnsignedIntegerType() const {
361 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
362 return BT->getKind() >= BuiltinType::Bool &&
363 BT->getKind() <= BuiltinType::ULongLong;
364 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000365 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
366 return VT->getElementType()->isUnsignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000367 return false;
368}
369
370bool Type::isFloatingType() const {
371 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
372 return BT->getKind() >= BuiltinType::Float &&
373 BT->getKind() <= BuiltinType::LongDouble;
374 if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
375 return CT->isFloatingType();
Steve Naroffc63b96a2007-07-12 21:46:55 +0000376 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
377 return VT->getElementType()->isFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000378 return false;
379}
380
381bool Type::isRealFloatingType() const {
382 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
383 return BT->getKind() >= BuiltinType::Float &&
384 BT->getKind() <= BuiltinType::LongDouble;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000385 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
386 return VT->getElementType()->isRealFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000387 return false;
388}
389
390bool Type::isRealType() const {
391 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
392 return BT->getKind() >= BuiltinType::Bool &&
393 BT->getKind() <= BuiltinType::LongDouble;
394 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
395 return TT->getDecl()->getKind() == Decl::Enum;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000396 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
397 return VT->getElementType()->isRealType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000398 return false;
399}
400
Reid Spencer5f016e22007-07-11 17:01:13 +0000401bool Type::isArithmeticType() const {
402 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
403 return BT->getKind() != BuiltinType::Void;
404 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
405 if (TT->getDecl()->getKind() == Decl::Enum)
406 return true;
407 return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
408}
409
410bool Type::isScalarType() const {
411 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
412 return BT->getKind() != BuiltinType::Void;
413 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
414 if (TT->getDecl()->getKind() == Decl::Enum)
415 return true;
416 return false;
417 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000418 return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
419 isa<VectorType>(CanonicalType);
Reid Spencer5f016e22007-07-11 17:01:13 +0000420}
421
422bool Type::isAggregateType() const {
423 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
424 if (TT->getDecl()->getKind() == Decl::Struct)
425 return true;
426 return false;
427 }
428 return CanonicalType->getTypeClass() == Array;
429}
430
431// The only variable size types are auto arrays within a function. Structures
432// cannot contain a VLA member. They can have a flexible array member, however
433// the structure is still constant size (C99 6.7.2.1p16).
Chris Lattner590b6642007-07-15 23:26:56 +0000434bool Type::isConstantSizeType(ASTContext &Ctx, SourceLocation *loc) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000435 if (const ArrayType *Ary = dyn_cast<ArrayType>(CanonicalType)) {
Chris Lattner8b9023b2007-07-13 03:05:23 +0000436 assert(Ary->getSizeExpr() && "Incomplete types don't have a size at all!");
437 // Variable Length Array?
Chris Lattner590b6642007-07-15 23:26:56 +0000438 return Ary->getSizeExpr()->isIntegerConstantExpr(Ctx, loc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000439 }
440 return true;
441}
442
443/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
444/// - a type that can describe objects, but which lacks information needed to
445/// determine its size.
446bool Type::isIncompleteType() const {
447 switch (CanonicalType->getTypeClass()) {
448 default: return false;
449 case Builtin:
450 // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never
451 // be completed.
452 return isVoidType();
453 case Tagged:
454 // A tagged type (struct/union/enum/class) is incomplete if the decl is a
455 // forward declaration, but not a full definition (C99 6.2.5p22).
456 return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
457 case Array:
458 // An array of unknown size is an incomplete type (C99 6.2.5p22).
Chris Lattner8b9023b2007-07-13 03:05:23 +0000459 return cast<ArrayType>(CanonicalType)->getSizeExpr() == 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000460 }
461}
462
463bool Type::isPromotableIntegerType() const {
464 const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
465 if (!BT) return false;
466 switch (BT->getKind()) {
467 case BuiltinType::Bool:
468 case BuiltinType::Char_S:
469 case BuiltinType::Char_U:
470 case BuiltinType::SChar:
471 case BuiltinType::UChar:
472 case BuiltinType::Short:
473 case BuiltinType::UShort:
474 return true;
475 default:
476 return false;
477 }
478}
479
480const char *BuiltinType::getName() const {
481 switch (getKind()) {
482 default: assert(0 && "Unknown builtin type!");
483 case Void: return "void";
484 case Bool: return "_Bool";
485 case Char_S: return "char";
486 case Char_U: return "char";
487 case SChar: return "signed char";
488 case Short: return "short";
489 case Int: return "int";
490 case Long: return "long";
491 case LongLong: return "long long";
492 case UChar: return "unsigned char";
493 case UShort: return "unsigned short";
494 case UInt: return "unsigned int";
495 case ULong: return "unsigned long";
496 case ULongLong: return "unsigned long long";
497 case Float: return "float";
498 case Double: return "double";
499 case LongDouble: return "long double";
500 }
501}
502
Reid Spencer5f016e22007-07-11 17:01:13 +0000503void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
Chris Lattner942cfd32007-07-20 18:48:28 +0000504 arg_type_iterator ArgTys,
Reid Spencer5f016e22007-07-11 17:01:13 +0000505 unsigned NumArgs, bool isVariadic) {
506 ID.AddPointer(Result.getAsOpaquePtr());
507 for (unsigned i = 0; i != NumArgs; ++i)
508 ID.AddPointer(ArgTys[i].getAsOpaquePtr());
509 ID.AddInteger(isVariadic);
510}
511
512void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
Chris Lattner942cfd32007-07-20 18:48:28 +0000513 Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
Reid Spencer5f016e22007-07-11 17:01:13 +0000514}
515
Chris Lattnera2c77672007-07-16 22:05:22 +0000516/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
517/// potentially looking through *all* consequtive typedefs. This returns the
518/// sum of the type qualifiers, so if you have:
519/// typedef const int A;
520/// typedef volatile A B;
521/// looking through the typedefs for B will give you "const volatile A".
522///
523QualType TypedefType::LookThroughTypedefs() const {
524 // Usually, there is only a single level of typedefs, be fast in that case.
525 QualType FirstType = getDecl()->getUnderlyingType();
526 if (!isa<TypedefType>(FirstType))
527 return FirstType;
528
529 // Otherwise, do the fully general loop.
530 unsigned TypeQuals = 0;
531 const TypedefType *TDT = this;
532 while (1) {
533 QualType CurType = TDT->getDecl()->getUnderlyingType();
534 TypeQuals |= CurType.getQualifiers();
535
536 TDT = dyn_cast<TypedefType>(CurType);
537 if (TDT == 0)
538 return QualType(CurType.getTypePtr(), TypeQuals);
539 }
540}
Reid Spencer5f016e22007-07-11 17:01:13 +0000541
542bool RecordType::classof(const Type *T) {
543 if (const TagType *TT = dyn_cast<TagType>(T))
544 return isa<RecordDecl>(TT->getDecl());
545 return false;
546}
547
548
549//===----------------------------------------------------------------------===//
550// Type Printing
551//===----------------------------------------------------------------------===//
552
553void QualType::dump(const char *msg) const {
554 std::string R = "foo";
555 getAsStringInternal(R);
556 if (msg)
557 fprintf(stderr, "%s: %s\n", msg, R.c_str());
558 else
559 fprintf(stderr, "%s\n", R.c_str());
560}
561
562static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
563 // Note: funkiness to ensure we get a space only between quals.
564 bool NonePrinted = true;
565 if (TypeQuals & QualType::Const)
566 S += "const", NonePrinted = false;
567 if (TypeQuals & QualType::Volatile)
568 S += (NonePrinted+" volatile"), NonePrinted = false;
569 if (TypeQuals & QualType::Restrict)
570 S += (NonePrinted+" restrict"), NonePrinted = false;
571}
572
573void QualType::getAsStringInternal(std::string &S) const {
574 if (isNull()) {
575 S += "NULL TYPE\n";
576 return;
577 }
578
579 // Print qualifiers as appropriate.
Anton Korobeynikovb7b50bc2007-07-13 00:48:55 +0000580 unsigned TQ = getQualifiers();
581 if (TQ) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000582 std::string TQS;
583 AppendTypeQualList(TQS, TQ);
584 if (!S.empty())
585 S = TQS + ' ' + S;
586 else
587 S = TQS;
588 }
589
590 getTypePtr()->getAsStringInternal(S);
591}
592
593void BuiltinType::getAsStringInternal(std::string &S) const {
594 if (S.empty()) {
595 S = getName();
596 } else {
597 // Prefix the basic type, e.g. 'int X'.
598 S = ' ' + S;
599 S = getName() + S;
600 }
601}
602
603void ComplexType::getAsStringInternal(std::string &S) const {
604 ElementType->getAsStringInternal(S);
605 S = "_Complex " + S;
606}
607
608void PointerType::getAsStringInternal(std::string &S) const {
609 S = '*' + S;
610
611 // Handle things like 'int (*A)[4];' correctly.
612 // FIXME: this should include vectors, but vectors use attributes I guess.
613 if (isa<ArrayType>(PointeeType.getTypePtr()))
614 S = '(' + S + ')';
615
616 PointeeType.getAsStringInternal(S);
617}
618
619void ReferenceType::getAsStringInternal(std::string &S) const {
620 S = '&' + S;
621
622 // Handle things like 'int (&A)[4];' correctly.
623 // FIXME: this should include vectors, but vectors use attributes I guess.
624 if (isa<ArrayType>(ReferenceeType.getTypePtr()))
625 S = '(' + S + ')';
626
627 ReferenceeType.getAsStringInternal(S);
628}
629
630void ArrayType::getAsStringInternal(std::string &S) const {
631 S += '[';
632
633 if (IndexTypeQuals) {
634 AppendTypeQualList(S, IndexTypeQuals);
635 S += ' ';
636 }
637
638 if (SizeModifier == Static)
639 S += "static";
640 else if (SizeModifier == Star)
641 S += '*';
642
643 S += ']';
644
645 ElementType.getAsStringInternal(S);
646}
647
648void VectorType::getAsStringInternal(std::string &S) const {
Chris Lattnere107b5d2007-07-13 21:01:17 +0000649 S += " __attribute__((vector_size(";
650 // FIXME: should multiply by element size somehow.
Reid Spencer5f016e22007-07-11 17:01:13 +0000651 S += llvm::utostr_32(NumElements*4); // convert back to bytes.
Chris Lattnere107b5d2007-07-13 21:01:17 +0000652 S += ")))";
Reid Spencer5f016e22007-07-11 17:01:13 +0000653 ElementType.getAsStringInternal(S);
654}
655
Steve Naroff31a45842007-07-28 23:10:27 +0000656void OCUVectorType::getAsStringInternal(std::string &S) const {
657 S += " __attribute__((ocu_vector_type(";
658 S += llvm::utostr_32(NumElements);
659 S += ")))";
660 ElementType.getAsStringInternal(S);
661}
662
Steve Naroffd1861fd2007-07-31 12:34:36 +0000663void TypeOfExpr::getAsStringInternal(std::string &InnerString) const {
664 // FIXME: output expression, getUnderlyingExpr()->print().
665 // At the moment, Stmt::print(std::ostream) doesn't work for us here.
666 InnerString = "typeof(<expr>) " + InnerString;
667}
668
669void TypeOfType::getAsStringInternal(std::string &S) const {
670 std::string Tmp;
671 getUnderlyingType().getAsStringInternal(Tmp);
672 S += "typeof(" + Tmp + ")";
673}
674
Reid Spencer5f016e22007-07-11 17:01:13 +0000675void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
676 // If needed for precedence reasons, wrap the inner part in grouping parens.
677 if (!S.empty())
678 S = "(" + S + ")";
679
680 S += "()";
681 getResultType().getAsStringInternal(S);
682}
683
684void FunctionTypeProto::getAsStringInternal(std::string &S) const {
685 // If needed for precedence reasons, wrap the inner part in grouping parens.
686 if (!S.empty())
687 S = "(" + S + ")";
688
689 S += "(";
690 std::string Tmp;
691 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
692 if (i) S += ", ";
693 getArgType(i).getAsStringInternal(Tmp);
694 S += Tmp;
695 Tmp.clear();
696 }
697
698 if (isVariadic()) {
699 if (getNumArgs())
700 S += ", ";
701 S += "...";
702 } else if (getNumArgs() == 0) {
703 // Do not emit int() if we have a proto, emit 'int(void)'.
704 S += "void";
705 }
706
707 S += ")";
708 getResultType().getAsStringInternal(S);
709}
710
711
712void TypedefType::getAsStringInternal(std::string &InnerString) const {
713 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
714 InnerString = ' ' + InnerString;
715 InnerString = getDecl()->getIdentifier()->getName() + InnerString;
716}
717
718void TagType::getAsStringInternal(std::string &InnerString) const {
719 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
720 InnerString = ' ' + InnerString;
721
722 const char *Kind = getDecl()->getKindName();
723 const char *ID;
724 if (const IdentifierInfo *II = getDecl()->getIdentifier())
725 ID = II->getName();
726 else
727 ID = "<anonymous>";
728
729 InnerString = std::string(Kind) + " " + ID + InnerString;
730}