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