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