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