blob: 90cd7d0098642ea290fa490650c1f5892aeac653 [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
Steve Naroff7064f5c2007-07-26 18:32:01 +000059const FunctionType *Type::isFunctionType() const {
60 // If this is directly a function type, return it.
61 if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
62 return FTy;
63
64 // If this is a typedef for a function type, strip the typedef off without
65 // losing all typedef information.
66 if (isa<FunctionType>(CanonicalType))
67 return cast<FunctionType>(cast<TypedefType>(this)->LookThroughTypedefs());
68 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000069}
70
Chris Lattner7a2e0472007-07-16 00:23:25 +000071const PointerType *Type::isPointerType() const {
72 // If this is directly a pointer type, return it.
73 if (const PointerType *PTy = dyn_cast<PointerType>(this))
74 return PTy;
Chris Lattnera2c77672007-07-16 22:05:22 +000075
76 // If this is a typedef for a pointer type, strip the typedef off without
77 // losing all typedef information.
78 if (isa<PointerType>(CanonicalType))
79 return cast<PointerType>(cast<TypedefType>(this)->LookThroughTypedefs());
Chris Lattner3acb1382007-07-16 00:13:25 +000080 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000081}
82
Bill Wendling251dcaf2007-07-17 04:47:36 +000083const ReferenceType *Type::isReferenceType() const {
Bill Wendlingea5e79f2007-07-17 04:16:47 +000084 // If this is directly a reference type, return it.
85 if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
86 return RTy;
87
88 // If this is a typedef for a reference type, strip the typedef off without
89 // losing all typedef information.
90 if (isa<ReferenceType>(CanonicalType))
91 return cast<ReferenceType>(cast<TypedefType>(this)->LookThroughTypedefs());
92 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000093}
94
Steve Naroff700204c2007-07-24 21:46:40 +000095const ArrayType *Type::isArrayType() const {
96 // If this is directly a reference type, return it.
97 if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
98 return ATy;
99
100 // If this is a typedef for an array type, strip the typedef off without
101 // losing all typedef information.
102 if (isa<ArrayType>(CanonicalType))
103 return cast<ArrayType>(cast<TypedefType>(this)->LookThroughTypedefs());
104 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000105}
106
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000107const RecordType *Type::isRecordType() const {
108 // If this is directly a reference type, return it.
109 if (const RecordType *RTy = dyn_cast<RecordType>(this))
110 return RTy;
111
112 // If this is a typedef for an record type, strip the typedef off without
113 // losing all typedef information.
114 if (isa<RecordType>(CanonicalType))
115 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Steve Naroffadc01852007-07-26 03:18:02 +0000116 return 0;
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000117}
118
Steve Naroff7064f5c2007-07-26 18:32:01 +0000119const TagType *Type::isStructureType() const {
120 // If this is directly a structure type, return it.
121 if (const TagType *TT = dyn_cast<TagType>(this)) {
122 if (TT->getDecl()->getKind() == Decl::Struct)
123 return TT;
124 }
125 // If this is a typedef for a structure type, strip the typedef off without
126 // losing all typedef information.
Reid Spencer5f016e22007-07-11 17:01:13 +0000127 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
128 if (TT->getDecl()->getKind() == Decl::Struct)
Steve Naroff7064f5c2007-07-26 18:32:01 +0000129 return cast<TagType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000130 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000131 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000132}
133
Steve Naroff7064f5c2007-07-26 18:32:01 +0000134const TagType *Type::isUnionType() const {
135 // If this is directly a union type, return it.
136 if (const TagType *TT = dyn_cast<TagType>(this)) {
137 if (TT->getDecl()->getKind() == Decl::Union)
138 return TT;
139 }
140 // If this is a typedef for a union type, strip the typedef off without
141 // losing all typedef information.
Reid Spencer5f016e22007-07-11 17:01:13 +0000142 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
143 if (TT->getDecl()->getKind() == Decl::Union)
Steve Naroff7064f5c2007-07-26 18:32:01 +0000144 return cast<TagType>(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 Lattner7a2e0472007-07-16 00:23:25 +0000149bool Type::isComplexType() const {
150 return isa<ComplexType>(CanonicalType);
151}
152
153const VectorType *Type::isVectorType() const {
154 // Are we directly a vector type?
155 if (const VectorType *VTy = dyn_cast<VectorType>(this))
156 return VTy;
Chris Lattnera2c77672007-07-16 22:05:22 +0000157
158 // If this is a typedef for a vector type, strip the typedef off without
159 // losing all typedef information.
160 if (isa<VectorType>(CanonicalType))
161 return cast<VectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
162
Chris Lattner7a2e0472007-07-16 00:23:25 +0000163 return 0;
164}
165
Steve Naroff7064f5c2007-07-26 18:32:01 +0000166const OCUVectorType *Type::isOCUVectorType() const {
167 // Are we directly an OpenCU vector type?
168 if (const OCUVectorType *VTy = dyn_cast<OCUVectorType>(this))
169 return VTy;
170
171 // If this is a typedef for an OpenCU vector type, strip the typedef off
172 // without losing all typedef information.
173 if (isa<OCUVectorType>(CanonicalType))
174 return cast<OCUVectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
175
176 return 0;
177}
178
Chris Lattner7a2e0472007-07-16 00:23:25 +0000179
Reid Spencer5f016e22007-07-11 17:01:13 +0000180// C99 6.2.7p1: If both are complete types, then the following additional
181// requirements apply...FIXME (handle compatibility across source files).
182bool Type::tagTypesAreCompatible(QualType lhs, QualType rhs) {
183 TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
184 TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
185
186 if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
187 if (ldecl->getIdentifier() == rdecl->getIdentifier())
188 return true;
189 }
190 if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
191 if (ldecl->getIdentifier() == rdecl->getIdentifier())
192 return true;
193 }
194 return false;
195}
196
197bool Type::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
198 // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
199 // identically qualified and both shall be pointers to compatible types.
200 if (lhs.getQualifiers() != rhs.getQualifiers())
201 return false;
202
203 QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
204 QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
205
206 return typesAreCompatible(ltype, rtype);
207}
208
209// C++ 5.17p6: When the left opperand of an assignment operator denotes a
210// reference to T, the operation assigns to the object of type T denoted by the
211// reference.
212bool Type::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
213 QualType ltype = lhs;
214
215 if (lhs->isReferenceType())
216 ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
217
218 QualType rtype = rhs;
219
220 if (rhs->isReferenceType())
221 rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
222
223 return typesAreCompatible(ltype, rtype);
224}
225
226bool Type::functionTypesAreCompatible(QualType lhs, QualType rhs) {
227 const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
228 const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
229 const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
230 const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
231
232 // first check the return types (common between C99 and K&R).
233 if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
234 return false;
235
236 if (lproto && rproto) { // two C99 style function prototypes
237 unsigned lproto_nargs = lproto->getNumArgs();
238 unsigned rproto_nargs = rproto->getNumArgs();
239
240 if (lproto_nargs != rproto_nargs)
241 return false;
242
243 // both prototypes have the same number of arguments.
244 if ((lproto->isVariadic() && !rproto->isVariadic()) ||
245 (rproto->isVariadic() && !lproto->isVariadic()))
246 return false;
247
248 // The use of ellipsis agree...now check the argument types.
249 for (unsigned i = 0; i < lproto_nargs; i++)
250 if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
251 return false;
252 return true;
253 }
254 if (!lproto && !rproto) // two K&R style function decls, nothing to do.
255 return true;
256
257 // we have a mixture of K&R style with C99 prototypes
258 const FunctionTypeProto *proto = lproto ? lproto : rproto;
259
260 if (proto->isVariadic())
261 return false;
262
263 // FIXME: Each parameter type T in the prototype must be compatible with the
264 // type resulting from applying the usual argument conversions to T.
265 return true;
266}
267
268bool Type::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
269 QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
270 QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
271
272 if (!typesAreCompatible(ltype, rtype))
273 return false;
274
275 // FIXME: If both types specify constant sizes, then the sizes must also be
276 // the same. Even if the sizes are the same, GCC produces an error.
277 return true;
278}
279
280/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
281/// both shall have the identically qualified version of a compatible type.
282/// C99 6.2.7p1: Two types have compatible types if their types are the
283/// same. See 6.7.[2,3,5] for additional rules.
284bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
285 QualType lcanon = lhs.getCanonicalType();
286 QualType rcanon = rhs.getCanonicalType();
287
288 // If two types are identical, they are are compatible
289 if (lcanon == rcanon)
290 return true;
291
292 // If the canonical type classes don't match, they can't be compatible
293 if (lcanon->getTypeClass() != rcanon->getTypeClass())
294 return false;
295
296 switch (lcanon->getTypeClass()) {
297 case Type::Pointer:
298 return pointerTypesAreCompatible(lcanon, rcanon);
299 case Type::Reference:
300 return referenceTypesAreCompatible(lcanon, rcanon);
301 case Type::Array:
302 return arrayTypesAreCompatible(lcanon, rcanon);
303 case Type::FunctionNoProto:
304 case Type::FunctionProto:
305 return functionTypesAreCompatible(lcanon, rcanon);
306 case Type::Tagged: // handle structures, unions
307 return tagTypesAreCompatible(lcanon, rcanon);
308 case Type::Builtin:
309 return false;
310 default:
311 assert(0 && "unexpected type");
312 }
313 return true; // should never get here...
314}
315
316bool Type::isIntegerType() const {
317 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
318 return BT->getKind() >= BuiltinType::Bool &&
319 BT->getKind() <= BuiltinType::LongLong;
320 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
321 if (TT->getDecl()->getKind() == Decl::Enum)
322 return true;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000323 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
324 return VT->getElementType()->isIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000325 return false;
326}
327
328bool Type::isSignedIntegerType() const {
329 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
330 return BT->getKind() >= BuiltinType::Char_S &&
331 BT->getKind() <= BuiltinType::LongLong;
332 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000333 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
334 return VT->getElementType()->isSignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000335 return false;
336}
337
338bool Type::isUnsignedIntegerType() const {
339 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
340 return BT->getKind() >= BuiltinType::Bool &&
341 BT->getKind() <= BuiltinType::ULongLong;
342 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000343 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
344 return VT->getElementType()->isUnsignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000345 return false;
346}
347
348bool Type::isFloatingType() const {
349 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
350 return BT->getKind() >= BuiltinType::Float &&
351 BT->getKind() <= BuiltinType::LongDouble;
352 if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
353 return CT->isFloatingType();
Steve Naroffc63b96a2007-07-12 21:46:55 +0000354 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
355 return VT->getElementType()->isFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000356 return false;
357}
358
359bool Type::isRealFloatingType() const {
360 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
361 return BT->getKind() >= BuiltinType::Float &&
362 BT->getKind() <= BuiltinType::LongDouble;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000363 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
364 return VT->getElementType()->isRealFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000365 return false;
366}
367
368bool Type::isRealType() const {
369 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
370 return BT->getKind() >= BuiltinType::Bool &&
371 BT->getKind() <= BuiltinType::LongDouble;
372 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
373 return TT->getDecl()->getKind() == Decl::Enum;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000374 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
375 return VT->getElementType()->isRealType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000376 return false;
377}
378
Reid Spencer5f016e22007-07-11 17:01:13 +0000379bool Type::isArithmeticType() const {
380 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
381 return BT->getKind() != BuiltinType::Void;
382 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
383 if (TT->getDecl()->getKind() == Decl::Enum)
384 return true;
385 return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
386}
387
388bool Type::isScalarType() const {
389 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
390 return BT->getKind() != BuiltinType::Void;
391 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
392 if (TT->getDecl()->getKind() == Decl::Enum)
393 return true;
394 return false;
395 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000396 return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
397 isa<VectorType>(CanonicalType);
Reid Spencer5f016e22007-07-11 17:01:13 +0000398}
399
400bool Type::isAggregateType() const {
401 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
402 if (TT->getDecl()->getKind() == Decl::Struct)
403 return true;
404 return false;
405 }
406 return CanonicalType->getTypeClass() == Array;
407}
408
409// The only variable size types are auto arrays within a function. Structures
410// cannot contain a VLA member. They can have a flexible array member, however
411// the structure is still constant size (C99 6.7.2.1p16).
Chris Lattner590b6642007-07-15 23:26:56 +0000412bool Type::isConstantSizeType(ASTContext &Ctx, SourceLocation *loc) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000413 if (const ArrayType *Ary = dyn_cast<ArrayType>(CanonicalType)) {
Chris Lattner8b9023b2007-07-13 03:05:23 +0000414 assert(Ary->getSizeExpr() && "Incomplete types don't have a size at all!");
415 // Variable Length Array?
Chris Lattner590b6642007-07-15 23:26:56 +0000416 return Ary->getSizeExpr()->isIntegerConstantExpr(Ctx, loc);
Reid Spencer5f016e22007-07-11 17:01:13 +0000417 }
418 return true;
419}
420
421/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
422/// - a type that can describe objects, but which lacks information needed to
423/// determine its size.
424bool Type::isIncompleteType() const {
425 switch (CanonicalType->getTypeClass()) {
426 default: return false;
427 case Builtin:
428 // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never
429 // be completed.
430 return isVoidType();
431 case Tagged:
432 // A tagged type (struct/union/enum/class) is incomplete if the decl is a
433 // forward declaration, but not a full definition (C99 6.2.5p22).
434 return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
435 case Array:
436 // An array of unknown size is an incomplete type (C99 6.2.5p22).
Chris Lattner8b9023b2007-07-13 03:05:23 +0000437 return cast<ArrayType>(CanonicalType)->getSizeExpr() == 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000438 }
439}
440
441bool Type::isPromotableIntegerType() const {
442 const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
443 if (!BT) return false;
444 switch (BT->getKind()) {
445 case BuiltinType::Bool:
446 case BuiltinType::Char_S:
447 case BuiltinType::Char_U:
448 case BuiltinType::SChar:
449 case BuiltinType::UChar:
450 case BuiltinType::Short:
451 case BuiltinType::UShort:
452 return true;
453 default:
454 return false;
455 }
456}
457
458const char *BuiltinType::getName() const {
459 switch (getKind()) {
460 default: assert(0 && "Unknown builtin type!");
461 case Void: return "void";
462 case Bool: return "_Bool";
463 case Char_S: return "char";
464 case Char_U: return "char";
465 case SChar: return "signed char";
466 case Short: return "short";
467 case Int: return "int";
468 case Long: return "long";
469 case LongLong: return "long long";
470 case UChar: return "unsigned char";
471 case UShort: return "unsigned short";
472 case UInt: return "unsigned int";
473 case ULong: return "unsigned long";
474 case ULongLong: return "unsigned long long";
475 case Float: return "float";
476 case Double: return "double";
477 case LongDouble: return "long double";
478 }
479}
480
Reid Spencer5f016e22007-07-11 17:01:13 +0000481void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
Chris Lattner942cfd32007-07-20 18:48:28 +0000482 arg_type_iterator ArgTys,
Reid Spencer5f016e22007-07-11 17:01:13 +0000483 unsigned NumArgs, bool isVariadic) {
484 ID.AddPointer(Result.getAsOpaquePtr());
485 for (unsigned i = 0; i != NumArgs; ++i)
486 ID.AddPointer(ArgTys[i].getAsOpaquePtr());
487 ID.AddInteger(isVariadic);
488}
489
490void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
Chris Lattner942cfd32007-07-20 18:48:28 +0000491 Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
Reid Spencer5f016e22007-07-11 17:01:13 +0000492}
493
Chris Lattnera2c77672007-07-16 22:05:22 +0000494/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
495/// potentially looking through *all* consequtive typedefs. This returns the
496/// sum of the type qualifiers, so if you have:
497/// typedef const int A;
498/// typedef volatile A B;
499/// looking through the typedefs for B will give you "const volatile A".
500///
501QualType TypedefType::LookThroughTypedefs() const {
502 // Usually, there is only a single level of typedefs, be fast in that case.
503 QualType FirstType = getDecl()->getUnderlyingType();
504 if (!isa<TypedefType>(FirstType))
505 return FirstType;
506
507 // Otherwise, do the fully general loop.
508 unsigned TypeQuals = 0;
509 const TypedefType *TDT = this;
510 while (1) {
511 QualType CurType = TDT->getDecl()->getUnderlyingType();
512 TypeQuals |= CurType.getQualifiers();
513
514 TDT = dyn_cast<TypedefType>(CurType);
515 if (TDT == 0)
516 return QualType(CurType.getTypePtr(), TypeQuals);
517 }
518}
Reid Spencer5f016e22007-07-11 17:01:13 +0000519
520bool RecordType::classof(const Type *T) {
521 if (const TagType *TT = dyn_cast<TagType>(T))
522 return isa<RecordDecl>(TT->getDecl());
523 return false;
524}
525
526
527//===----------------------------------------------------------------------===//
528// Type Printing
529//===----------------------------------------------------------------------===//
530
531void QualType::dump(const char *msg) const {
532 std::string R = "foo";
533 getAsStringInternal(R);
534 if (msg)
535 fprintf(stderr, "%s: %s\n", msg, R.c_str());
536 else
537 fprintf(stderr, "%s\n", R.c_str());
538}
539
540static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
541 // Note: funkiness to ensure we get a space only between quals.
542 bool NonePrinted = true;
543 if (TypeQuals & QualType::Const)
544 S += "const", NonePrinted = false;
545 if (TypeQuals & QualType::Volatile)
546 S += (NonePrinted+" volatile"), NonePrinted = false;
547 if (TypeQuals & QualType::Restrict)
548 S += (NonePrinted+" restrict"), NonePrinted = false;
549}
550
551void QualType::getAsStringInternal(std::string &S) const {
552 if (isNull()) {
553 S += "NULL TYPE\n";
554 return;
555 }
556
557 // Print qualifiers as appropriate.
Anton Korobeynikovb7b50bc2007-07-13 00:48:55 +0000558 unsigned TQ = getQualifiers();
559 if (TQ) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000560 std::string TQS;
561 AppendTypeQualList(TQS, TQ);
562 if (!S.empty())
563 S = TQS + ' ' + S;
564 else
565 S = TQS;
566 }
567
568 getTypePtr()->getAsStringInternal(S);
569}
570
571void BuiltinType::getAsStringInternal(std::string &S) const {
572 if (S.empty()) {
573 S = getName();
574 } else {
575 // Prefix the basic type, e.g. 'int X'.
576 S = ' ' + S;
577 S = getName() + S;
578 }
579}
580
581void ComplexType::getAsStringInternal(std::string &S) const {
582 ElementType->getAsStringInternal(S);
583 S = "_Complex " + S;
584}
585
586void PointerType::getAsStringInternal(std::string &S) const {
587 S = '*' + S;
588
589 // Handle things like 'int (*A)[4];' correctly.
590 // FIXME: this should include vectors, but vectors use attributes I guess.
591 if (isa<ArrayType>(PointeeType.getTypePtr()))
592 S = '(' + S + ')';
593
594 PointeeType.getAsStringInternal(S);
595}
596
597void ReferenceType::getAsStringInternal(std::string &S) const {
598 S = '&' + S;
599
600 // Handle things like 'int (&A)[4];' correctly.
601 // FIXME: this should include vectors, but vectors use attributes I guess.
602 if (isa<ArrayType>(ReferenceeType.getTypePtr()))
603 S = '(' + S + ')';
604
605 ReferenceeType.getAsStringInternal(S);
606}
607
608void ArrayType::getAsStringInternal(std::string &S) const {
609 S += '[';
610
611 if (IndexTypeQuals) {
612 AppendTypeQualList(S, IndexTypeQuals);
613 S += ' ';
614 }
615
616 if (SizeModifier == Static)
617 S += "static";
618 else if (SizeModifier == Star)
619 S += '*';
620
621 S += ']';
622
623 ElementType.getAsStringInternal(S);
624}
625
626void VectorType::getAsStringInternal(std::string &S) const {
Chris Lattnere107b5d2007-07-13 21:01:17 +0000627 S += " __attribute__((vector_size(";
628 // FIXME: should multiply by element size somehow.
Reid Spencer5f016e22007-07-11 17:01:13 +0000629 S += llvm::utostr_32(NumElements*4); // convert back to bytes.
Chris Lattnere107b5d2007-07-13 21:01:17 +0000630 S += ")))";
Reid Spencer5f016e22007-07-11 17:01:13 +0000631 ElementType.getAsStringInternal(S);
632}
633
634void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
635 // If needed for precedence reasons, wrap the inner part in grouping parens.
636 if (!S.empty())
637 S = "(" + S + ")";
638
639 S += "()";
640 getResultType().getAsStringInternal(S);
641}
642
643void FunctionTypeProto::getAsStringInternal(std::string &S) const {
644 // If needed for precedence reasons, wrap the inner part in grouping parens.
645 if (!S.empty())
646 S = "(" + S + ")";
647
648 S += "(";
649 std::string Tmp;
650 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
651 if (i) S += ", ";
652 getArgType(i).getAsStringInternal(Tmp);
653 S += Tmp;
654 Tmp.clear();
655 }
656
657 if (isVariadic()) {
658 if (getNumArgs())
659 S += ", ";
660 S += "...";
661 } else if (getNumArgs() == 0) {
662 // Do not emit int() if we have a proto, emit 'int(void)'.
663 S += "void";
664 }
665
666 S += ")";
667 getResultType().getAsStringInternal(S);
668}
669
670
671void TypedefType::getAsStringInternal(std::string &InnerString) const {
672 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
673 InnerString = ' ' + InnerString;
674 InnerString = getDecl()->getIdentifier()->getName() + InnerString;
675}
676
677void TagType::getAsStringInternal(std::string &InnerString) const {
678 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
679 InnerString = ' ' + InnerString;
680
681 const char *Kind = getDecl()->getKindName();
682 const char *ID;
683 if (const IdentifierInfo *II = getDecl()->getIdentifier())
684 ID = II->getName();
685 else
686 ID = "<anonymous>";
687
688 InnerString = std::string(Kind) + " " + ID + InnerString;
689}