blob: bde2eb5d1dd751c11474c53ce4e9bc1694d91e36 [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
Reid Spencer5f016e22007-07-11 17:01:13 +000014#include "clang/AST/Type.h"
15#include "clang/AST/Decl.h"
Steve Naroff980e5082007-10-01 19:00:59 +000016#include "clang/AST/DeclObjC.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000017#include "clang/AST/Expr.h"
Chris Lattnerc7229c32007-10-07 08:58:51 +000018#include "clang/Basic/IdentifierTable.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000019#include "clang/Basic/TargetInfo.h"
20#include "llvm/Support/Streams.h"
21#include "llvm/ADT/StringExtras.h"
Steve Naroff8d1a3b82007-08-01 17:20:42 +000022#include <sstream>
23
Reid Spencer5f016e22007-07-11 17:01:13 +000024using namespace clang;
25
26Type::~Type() {}
27
28/// isVoidType - Helper method to determine if this is the 'void' type.
29bool Type::isVoidType() const {
30 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
31 return BT->getKind() == BuiltinType::Void;
32 return false;
33}
34
35bool Type::isObjectType() const {
36 if (isa<FunctionType>(CanonicalType))
37 return false;
38 else if (CanonicalType->isIncompleteType())
39 return false;
40 else
41 return true;
42}
43
44bool Type::isDerivedType() const {
45 switch (CanonicalType->getTypeClass()) {
46 case Pointer:
Steve Narofffb22d962007-08-30 01:06:46 +000047 case VariableArray:
48 case ConstantArray:
Reid Spencer5f016e22007-07-11 17:01:13 +000049 case FunctionProto:
50 case FunctionNoProto:
51 case Reference:
52 return true;
53 case Tagged: {
54 const TagType *TT = cast<TagType>(CanonicalType);
55 const Decl::Kind Kind = TT->getDecl()->getKind();
56 return Kind == Decl::Struct || Kind == Decl::Union;
57 }
58 default:
59 return false;
60 }
61}
62
Chris Lattnerc8629632007-07-31 19:29:30 +000063bool Type::isStructureType() const {
64 if (const RecordType *RT = dyn_cast<RecordType>(this))
65 if (RT->getDecl()->getKind() == Decl::Struct)
66 return true;
67 return false;
68}
69bool Type::isUnionType() const {
70 if (const RecordType *RT = dyn_cast<RecordType>(this))
71 if (RT->getDecl()->getKind() == Decl::Union)
72 return true;
73 return false;
74}
Chris Lattnerc8629632007-07-31 19:29:30 +000075
Chris Lattnerc6fb90a2007-08-21 16:54:08 +000076bool Type::isComplexType() const {
77 return isa<ComplexType>(CanonicalType);
78}
79
Steve Naroff77878cc2007-08-27 04:08:11 +000080const BuiltinType *Type::getAsBuiltinType() const {
81 // If this is directly a builtin type, return it.
82 if (const BuiltinType *BTy = dyn_cast<BuiltinType>(this))
83 return BTy;
84
85 // If this is a typedef for a builtin type, strip the typedef off without
86 // losing all typedef information.
87 if (isa<BuiltinType>(CanonicalType))
88 return cast<BuiltinType>(cast<TypedefType>(this)->LookThroughTypedefs());
89 return 0;
90}
91
Chris Lattnerc8629632007-07-31 19:29:30 +000092const FunctionType *Type::getAsFunctionType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +000093 // If this is directly a function type, return it.
94 if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
95 return FTy;
Chris Lattnerc8629632007-07-31 19:29:30 +000096
Steve Naroff7064f5c2007-07-26 18:32:01 +000097 // If this is a typedef for a function type, strip the typedef off without
98 // losing all typedef information.
99 if (isa<FunctionType>(CanonicalType))
100 return cast<FunctionType>(cast<TypedefType>(this)->LookThroughTypedefs());
101 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000102}
103
Chris Lattnerbefee482007-07-31 16:53:04 +0000104const PointerType *Type::getAsPointerType() const {
Chris Lattner7a2e0472007-07-16 00:23:25 +0000105 // If this is directly a pointer type, return it.
106 if (const PointerType *PTy = dyn_cast<PointerType>(this))
107 return PTy;
Chris Lattnera2c77672007-07-16 22:05:22 +0000108
109 // If this is a typedef for a pointer type, strip the typedef off without
110 // losing all typedef information.
111 if (isa<PointerType>(CanonicalType))
112 return cast<PointerType>(cast<TypedefType>(this)->LookThroughTypedefs());
Chris Lattner3acb1382007-07-16 00:13:25 +0000113 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000114}
115
Chris Lattnera1d9fde2007-07-31 16:56:34 +0000116const ReferenceType *Type::getAsReferenceType() const {
Bill Wendlingea5e79f2007-07-17 04:16:47 +0000117 // If this is directly a reference type, return it.
118 if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
119 return RTy;
120
121 // If this is a typedef for a reference type, strip the typedef off without
122 // losing all typedef information.
123 if (isa<ReferenceType>(CanonicalType))
124 return cast<ReferenceType>(cast<TypedefType>(this)->LookThroughTypedefs());
125 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000126}
127
Chris Lattnerc8629632007-07-31 19:29:30 +0000128const ArrayType *Type::getAsArrayType() const {
Steve Naroffd7444aa2007-08-31 17:20:07 +0000129 // If this is directly an array type, return it.
Steve Naroff700204c2007-07-24 21:46:40 +0000130 if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
131 return ATy;
132
133 // If this is a typedef for an array type, strip the typedef off without
134 // losing all typedef information.
135 if (isa<ArrayType>(CanonicalType))
136 return cast<ArrayType>(cast<TypedefType>(this)->LookThroughTypedefs());
137 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000138}
139
Steve Naroffd7444aa2007-08-31 17:20:07 +0000140const ConstantArrayType *Type::getAsConstantArrayType() const {
141 // If this is directly a constant array type, return it.
142 if (const ConstantArrayType *ATy = dyn_cast<ConstantArrayType>(this))
143 return ATy;
144
145 // If this is a typedef for an array type, strip the typedef off without
146 // losing all typedef information.
147 if (isa<ConstantArrayType>(CanonicalType))
148 return cast<ConstantArrayType>(cast<TypedefType>(this)->LookThroughTypedefs());
149 return 0;
150}
151
152const VariableArrayType *Type::getAsVariableArrayType() const {
153 // If this is directly a variable array type, return it.
154 if (const VariableArrayType *ATy = dyn_cast<VariableArrayType>(this))
155 return ATy;
156
157 // If this is a typedef for an array type, strip the typedef off without
158 // losing all typedef information.
159 if (isa<VariableArrayType>(CanonicalType))
160 return cast<VariableArrayType>(cast<TypedefType>(this)->LookThroughTypedefs());
161 return 0;
162}
163
164/// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
165/// types that have a non-constant expression. This does not include "[]".
166bool Type::isVariablyModifiedType() const {
167 if (const VariableArrayType *VAT = getAsVariableArrayType()) {
168 if (VAT->getSizeExpr())
169 return true;
170 }
171 return false;
172}
173
174const VariableArrayType *Type::getAsVariablyModifiedType() const {
175 if (const VariableArrayType *VAT = getAsVariableArrayType()) {
176 if (VAT->getSizeExpr())
177 return VAT;
178 }
179 return 0;
180}
181
Chris Lattnerc8629632007-07-31 19:29:30 +0000182const RecordType *Type::getAsRecordType() const {
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000183 // If this is directly a reference type, return it.
184 if (const RecordType *RTy = dyn_cast<RecordType>(this))
185 return RTy;
186
187 // If this is a typedef for an record type, strip the typedef off without
188 // losing all typedef information.
189 if (isa<RecordType>(CanonicalType))
190 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Steve Naroffadc01852007-07-26 03:18:02 +0000191 return 0;
Steve Naroffdfa6aae2007-07-26 03:11:44 +0000192}
193
Chris Lattnerc8629632007-07-31 19:29:30 +0000194const RecordType *Type::getAsStructureType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000195 // If this is directly a structure type, return it.
Chris Lattnerc8629632007-07-31 19:29:30 +0000196 if (const RecordType *RT = dyn_cast<RecordType>(this)) {
197 if (RT->getDecl()->getKind() == Decl::Struct)
198 return RT;
Steve Naroff7064f5c2007-07-26 18:32:01 +0000199 }
200 // If this is a typedef for a structure type, strip the typedef off without
201 // losing all typedef information.
Chris Lattnerc8629632007-07-31 19:29:30 +0000202 if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
203 if (RT->getDecl()->getKind() == Decl::Struct)
204 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000205 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000206 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000207}
208
Chris Lattnerc8629632007-07-31 19:29:30 +0000209const RecordType *Type::getAsUnionType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000210 // If this is directly a union type, return it.
Chris Lattnerc8629632007-07-31 19:29:30 +0000211 if (const RecordType *RT = dyn_cast<RecordType>(this)) {
212 if (RT->getDecl()->getKind() == Decl::Union)
213 return RT;
Steve Naroff7064f5c2007-07-26 18:32:01 +0000214 }
215 // If this is a typedef for a union type, strip the typedef off without
216 // losing all typedef information.
Chris Lattnerc8629632007-07-31 19:29:30 +0000217 if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
218 if (RT->getDecl()->getKind() == Decl::Union)
219 return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
Reid Spencer5f016e22007-07-11 17:01:13 +0000220 }
Steve Naroff7064f5c2007-07-26 18:32:01 +0000221 return 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000222}
223
Chris Lattnerc6fb90a2007-08-21 16:54:08 +0000224const ComplexType *Type::getAsComplexType() const {
225 // Are we directly a complex type?
226 if (const ComplexType *CTy = dyn_cast<ComplexType>(this))
227 return CTy;
228
229 // If this is a typedef for a complex type, strip the typedef off without
230 // losing all typedef information.
231 if (isa<ComplexType>(CanonicalType))
232 return cast<ComplexType>(cast<TypedefType>(this)->LookThroughTypedefs());
233
234 return 0;
Chris Lattner7a2e0472007-07-16 00:23:25 +0000235}
236
Chris Lattnerc8629632007-07-31 19:29:30 +0000237const VectorType *Type::getAsVectorType() const {
Chris Lattner7a2e0472007-07-16 00:23:25 +0000238 // Are we directly a vector type?
239 if (const VectorType *VTy = dyn_cast<VectorType>(this))
240 return VTy;
Chris Lattnera2c77672007-07-16 22:05:22 +0000241
242 // If this is a typedef for a vector type, strip the typedef off without
243 // losing all typedef information.
244 if (isa<VectorType>(CanonicalType))
245 return cast<VectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
246
Chris Lattner7a2e0472007-07-16 00:23:25 +0000247 return 0;
248}
249
Chris Lattnerc8629632007-07-31 19:29:30 +0000250const OCUVectorType *Type::getAsOCUVectorType() const {
Steve Naroff7064f5c2007-07-26 18:32:01 +0000251 // Are we directly an OpenCU vector type?
252 if (const OCUVectorType *VTy = dyn_cast<OCUVectorType>(this))
253 return VTy;
254
255 // If this is a typedef for an OpenCU vector type, strip the typedef off
256 // without losing all typedef information.
257 if (isa<OCUVectorType>(CanonicalType))
258 return cast<OCUVectorType>(cast<TypedefType>(this)->LookThroughTypedefs());
259
260 return 0;
261}
262
Reid Spencer5f016e22007-07-11 17:01:13 +0000263bool Type::isIntegerType() const {
264 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
265 return BT->getKind() >= BuiltinType::Bool &&
266 BT->getKind() <= BuiltinType::LongLong;
267 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
268 if (TT->getDecl()->getKind() == Decl::Enum)
269 return true;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000270 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
271 return VT->getElementType()->isIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000272 return false;
273}
274
Steve Naroff13b7c5f2007-08-08 22:15:55 +0000275bool Type::isEnumeralType() const {
276 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
277 return TT->getDecl()->getKind() == Decl::Enum;
278 return false;
279}
280
281bool Type::isBooleanType() const {
282 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
283 return BT->getKind() == BuiltinType::Bool;
284 return false;
285}
286
287bool Type::isCharType() const {
288 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
289 return BT->getKind() == BuiltinType::Char_U ||
290 BT->getKind() == BuiltinType::UChar ||
Anders Carlssonc67ad5f2007-10-29 02:52:18 +0000291 BT->getKind() == BuiltinType::Char_S ||
292 BT->getKind() == BuiltinType::SChar;
Steve Naroff13b7c5f2007-08-08 22:15:55 +0000293 return false;
294}
295
Chris Lattnerd5bbce42007-08-29 17:48:46 +0000296/// isSignedIntegerType - Return true if this is an integer type that is
297/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
298/// an enum decl which has a signed representation, or a vector of signed
299/// integer element type.
Reid Spencer5f016e22007-07-11 17:01:13 +0000300bool Type::isSignedIntegerType() const {
301 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
302 return BT->getKind() >= BuiltinType::Char_S &&
303 BT->getKind() <= BuiltinType::LongLong;
304 }
Chris Lattnerd5bbce42007-08-29 17:48:46 +0000305
306 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
307 if (const EnumDecl *ED = dyn_cast<EnumDecl>(TT->getDecl()))
308 return ED->getIntegerType()->isSignedIntegerType();
309
Steve Naroffc63b96a2007-07-12 21:46:55 +0000310 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
311 return VT->getElementType()->isSignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000312 return false;
313}
314
Chris Lattnerd5bbce42007-08-29 17:48:46 +0000315/// isUnsignedIntegerType - Return true if this is an integer type that is
316/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
317/// decl which has an unsigned representation, or a vector of unsigned integer
318/// element type.
Reid Spencer5f016e22007-07-11 17:01:13 +0000319bool Type::isUnsignedIntegerType() const {
320 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
321 return BT->getKind() >= BuiltinType::Bool &&
322 BT->getKind() <= BuiltinType::ULongLong;
323 }
Chris Lattnerd5bbce42007-08-29 17:48:46 +0000324
325 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
326 if (const EnumDecl *ED = dyn_cast<EnumDecl>(TT->getDecl()))
327 return ED->getIntegerType()->isUnsignedIntegerType();
328
Steve Naroffc63b96a2007-07-12 21:46:55 +0000329 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
330 return VT->getElementType()->isUnsignedIntegerType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000331 return false;
332}
333
334bool Type::isFloatingType() const {
335 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
336 return BT->getKind() >= BuiltinType::Float &&
337 BT->getKind() <= BuiltinType::LongDouble;
338 if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
Chris Lattner729a2132007-08-30 06:19:11 +0000339 return CT->getElementType()->isFloatingType();
Steve Naroffc63b96a2007-07-12 21:46:55 +0000340 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
341 return VT->getElementType()->isFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000342 return false;
343}
344
345bool Type::isRealFloatingType() const {
346 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
347 return BT->getKind() >= BuiltinType::Float &&
348 BT->getKind() <= BuiltinType::LongDouble;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000349 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
350 return VT->getElementType()->isRealFloatingType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000351 return false;
352}
353
354bool Type::isRealType() const {
355 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
356 return BT->getKind() >= BuiltinType::Bool &&
357 BT->getKind() <= BuiltinType::LongDouble;
358 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
359 return TT->getDecl()->getKind() == Decl::Enum;
Steve Naroffc63b96a2007-07-12 21:46:55 +0000360 if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
361 return VT->getElementType()->isRealType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000362 return false;
363}
364
Reid Spencer5f016e22007-07-11 17:01:13 +0000365bool Type::isArithmeticType() const {
366 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
367 return BT->getKind() != BuiltinType::Void;
368 if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
369 if (TT->getDecl()->getKind() == Decl::Enum)
370 return true;
371 return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
372}
373
374bool Type::isScalarType() const {
375 if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
376 return BT->getKind() != BuiltinType::Void;
377 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
378 if (TT->getDecl()->getKind() == Decl::Enum)
379 return true;
380 return false;
381 }
Steve Naroffc63b96a2007-07-12 21:46:55 +0000382 return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
383 isa<VectorType>(CanonicalType);
Reid Spencer5f016e22007-07-11 17:01:13 +0000384}
385
386bool Type::isAggregateType() const {
387 if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
388 if (TT->getDecl()->getKind() == Decl::Struct)
389 return true;
390 return false;
391 }
Steve Narofffb22d962007-08-30 01:06:46 +0000392 return CanonicalType->getTypeClass() == ConstantArray ||
393 CanonicalType->getTypeClass() == VariableArray;
Reid Spencer5f016e22007-07-11 17:01:13 +0000394}
395
396// The only variable size types are auto arrays within a function. Structures
397// cannot contain a VLA member. They can have a flexible array member, however
398// the structure is still constant size (C99 6.7.2.1p16).
Chris Lattner590b6642007-07-15 23:26:56 +0000399bool Type::isConstantSizeType(ASTContext &Ctx, SourceLocation *loc) const {
Steve Narofffb22d962007-08-30 01:06:46 +0000400 if (isa<VariableArrayType>(CanonicalType))
401 return false;
Reid Spencer5f016e22007-07-11 17:01:13 +0000402 return true;
403}
404
405/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
406/// - a type that can describe objects, but which lacks information needed to
407/// determine its size.
408bool Type::isIncompleteType() const {
409 switch (CanonicalType->getTypeClass()) {
410 default: return false;
411 case Builtin:
412 // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never
413 // be completed.
414 return isVoidType();
415 case Tagged:
416 // A tagged type (struct/union/enum/class) is incomplete if the decl is a
417 // forward declaration, but not a full definition (C99 6.2.5p22).
418 return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
Steve Narofffb22d962007-08-30 01:06:46 +0000419 case VariableArray:
Reid Spencer5f016e22007-07-11 17:01:13 +0000420 // An array of unknown size is an incomplete type (C99 6.2.5p22).
Steve Narofffb22d962007-08-30 01:06:46 +0000421 return cast<VariableArrayType>(CanonicalType)->getSizeExpr() == 0;
Reid Spencer5f016e22007-07-11 17:01:13 +0000422 }
423}
424
425bool Type::isPromotableIntegerType() const {
426 const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
427 if (!BT) return false;
428 switch (BT->getKind()) {
429 case BuiltinType::Bool:
430 case BuiltinType::Char_S:
431 case BuiltinType::Char_U:
432 case BuiltinType::SChar:
433 case BuiltinType::UChar:
434 case BuiltinType::Short:
435 case BuiltinType::UShort:
436 return true;
437 default:
438 return false;
439 }
440}
441
442const char *BuiltinType::getName() const {
443 switch (getKind()) {
444 default: assert(0 && "Unknown builtin type!");
445 case Void: return "void";
446 case Bool: return "_Bool";
447 case Char_S: return "char";
448 case Char_U: return "char";
449 case SChar: return "signed char";
450 case Short: return "short";
451 case Int: return "int";
452 case Long: return "long";
453 case LongLong: return "long long";
454 case UChar: return "unsigned char";
455 case UShort: return "unsigned short";
456 case UInt: return "unsigned int";
457 case ULong: return "unsigned long";
458 case ULongLong: return "unsigned long long";
459 case Float: return "float";
460 case Double: return "double";
461 case LongDouble: return "long double";
462 }
463}
464
Reid Spencer5f016e22007-07-11 17:01:13 +0000465void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
Chris Lattner942cfd32007-07-20 18:48:28 +0000466 arg_type_iterator ArgTys,
Reid Spencer5f016e22007-07-11 17:01:13 +0000467 unsigned NumArgs, bool isVariadic) {
468 ID.AddPointer(Result.getAsOpaquePtr());
469 for (unsigned i = 0; i != NumArgs; ++i)
470 ID.AddPointer(ArgTys[i].getAsOpaquePtr());
471 ID.AddInteger(isVariadic);
472}
473
474void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
Chris Lattner942cfd32007-07-20 18:48:28 +0000475 Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
Reid Spencer5f016e22007-07-11 17:01:13 +0000476}
477
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000478void ObjcQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
479 ObjcInterfaceType *interfaceType,
480 ObjcProtocolDecl **protocols,
481 unsigned NumProtocols) {
482 ID.AddPointer(interfaceType);
483 for (unsigned i = 0; i != NumProtocols; i++)
484 ID.AddPointer(protocols[i]);
485}
486
487void ObjcQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
488 Profile(ID, getInterfaceType(), &Protocols[0], getNumProtocols());
489}
490
Chris Lattnera2c77672007-07-16 22:05:22 +0000491/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
492/// potentially looking through *all* consequtive typedefs. This returns the
493/// sum of the type qualifiers, so if you have:
494/// typedef const int A;
495/// typedef volatile A B;
496/// looking through the typedefs for B will give you "const volatile A".
497///
498QualType TypedefType::LookThroughTypedefs() const {
499 // Usually, there is only a single level of typedefs, be fast in that case.
500 QualType FirstType = getDecl()->getUnderlyingType();
501 if (!isa<TypedefType>(FirstType))
502 return FirstType;
503
504 // Otherwise, do the fully general loop.
505 unsigned TypeQuals = 0;
506 const TypedefType *TDT = this;
507 while (1) {
508 QualType CurType = TDT->getDecl()->getUnderlyingType();
509 TypeQuals |= CurType.getQualifiers();
510
511 TDT = dyn_cast<TypedefType>(CurType);
512 if (TDT == 0)
513 return QualType(CurType.getTypePtr(), TypeQuals);
514 }
515}
Reid Spencer5f016e22007-07-11 17:01:13 +0000516
517bool RecordType::classof(const Type *T) {
518 if (const TagType *TT = dyn_cast<TagType>(T))
519 return isa<RecordDecl>(TT->getDecl());
520 return false;
521}
522
523
524//===----------------------------------------------------------------------===//
525// Type Printing
526//===----------------------------------------------------------------------===//
527
528void QualType::dump(const char *msg) const {
529 std::string R = "foo";
530 getAsStringInternal(R);
531 if (msg)
532 fprintf(stderr, "%s: %s\n", msg, R.c_str());
533 else
534 fprintf(stderr, "%s\n", R.c_str());
535}
536
537static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
538 // Note: funkiness to ensure we get a space only between quals.
539 bool NonePrinted = true;
540 if (TypeQuals & QualType::Const)
541 S += "const", NonePrinted = false;
542 if (TypeQuals & QualType::Volatile)
543 S += (NonePrinted+" volatile"), NonePrinted = false;
544 if (TypeQuals & QualType::Restrict)
545 S += (NonePrinted+" restrict"), NonePrinted = false;
546}
547
548void QualType::getAsStringInternal(std::string &S) const {
549 if (isNull()) {
550 S += "NULL TYPE\n";
551 return;
552 }
553
554 // Print qualifiers as appropriate.
Anton Korobeynikovb7b50bc2007-07-13 00:48:55 +0000555 unsigned TQ = getQualifiers();
556 if (TQ) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000557 std::string TQS;
558 AppendTypeQualList(TQS, TQ);
559 if (!S.empty())
560 S = TQS + ' ' + S;
561 else
562 S = TQS;
563 }
564
565 getTypePtr()->getAsStringInternal(S);
566}
567
568void BuiltinType::getAsStringInternal(std::string &S) const {
569 if (S.empty()) {
570 S = getName();
571 } else {
572 // Prefix the basic type, e.g. 'int X'.
573 S = ' ' + S;
574 S = getName() + S;
575 }
576}
577
578void ComplexType::getAsStringInternal(std::string &S) const {
579 ElementType->getAsStringInternal(S);
580 S = "_Complex " + S;
581}
582
583void PointerType::getAsStringInternal(std::string &S) const {
584 S = '*' + S;
585
586 // Handle things like 'int (*A)[4];' correctly.
587 // FIXME: this should include vectors, but vectors use attributes I guess.
588 if (isa<ArrayType>(PointeeType.getTypePtr()))
589 S = '(' + S + ')';
590
591 PointeeType.getAsStringInternal(S);
592}
593
594void ReferenceType::getAsStringInternal(std::string &S) const {
595 S = '&' + S;
596
597 // Handle things like 'int (&A)[4];' correctly.
598 // FIXME: this should include vectors, but vectors use attributes I guess.
599 if (isa<ArrayType>(ReferenceeType.getTypePtr()))
600 S = '(' + S + ')';
601
602 ReferenceeType.getAsStringInternal(S);
603}
604
Steve Narofffb22d962007-08-30 01:06:46 +0000605void ConstantArrayType::getAsStringInternal(std::string &S) const {
606 S += '[';
Steve Naroff6b91cd92007-08-30 18:45:57 +0000607 S += llvm::utostr(getSize().getZExtValue());
Steve Narofffb22d962007-08-30 01:06:46 +0000608 S += ']';
609
610 getElementType().getAsStringInternal(S);
611}
612
613void VariableArrayType::getAsStringInternal(std::string &S) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000614 S += '[';
615
Steve Naroffc9406122007-08-30 18:10:14 +0000616 if (getIndexTypeQualifier()) {
617 AppendTypeQualList(S, getIndexTypeQualifier());
Reid Spencer5f016e22007-07-11 17:01:13 +0000618 S += ' ';
619 }
620
Steve Naroffc9406122007-08-30 18:10:14 +0000621 if (getSizeModifier() == Static)
Reid Spencer5f016e22007-07-11 17:01:13 +0000622 S += "static";
Steve Naroffc9406122007-08-30 18:10:14 +0000623 else if (getSizeModifier() == Star)
Reid Spencer5f016e22007-07-11 17:01:13 +0000624 S += '*';
625
Steve Narofffb22d962007-08-30 01:06:46 +0000626 if (getSizeExpr()) {
627 std::ostringstream s;
628 getSizeExpr()->printPretty(s);
629 S += s.str();
630 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000631 S += ']';
632
Steve Narofffb22d962007-08-30 01:06:46 +0000633 getElementType().getAsStringInternal(S);
Reid Spencer5f016e22007-07-11 17:01:13 +0000634}
635
636void VectorType::getAsStringInternal(std::string &S) const {
Chris Lattnere107b5d2007-07-13 21:01:17 +0000637 S += " __attribute__((vector_size(";
638 // FIXME: should multiply by element size somehow.
Reid Spencer5f016e22007-07-11 17:01:13 +0000639 S += llvm::utostr_32(NumElements*4); // convert back to bytes.
Chris Lattnere107b5d2007-07-13 21:01:17 +0000640 S += ")))";
Reid Spencer5f016e22007-07-11 17:01:13 +0000641 ElementType.getAsStringInternal(S);
642}
643
Steve Naroff31a45842007-07-28 23:10:27 +0000644void OCUVectorType::getAsStringInternal(std::string &S) const {
645 S += " __attribute__((ocu_vector_type(";
646 S += llvm::utostr_32(NumElements);
647 S += ")))";
648 ElementType.getAsStringInternal(S);
649}
650
Steve Naroffd1861fd2007-07-31 12:34:36 +0000651void TypeOfExpr::getAsStringInternal(std::string &InnerString) const {
Steve Naroff363bcff2007-08-01 23:45:51 +0000652 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(e) X'.
653 InnerString = ' ' + InnerString;
Steve Naroff8d1a3b82007-08-01 17:20:42 +0000654 std::ostringstream s;
Chris Lattner6000dac2007-08-08 22:51:59 +0000655 getUnderlyingExpr()->printPretty(s);
Steve Naroff1bfd5cc2007-08-05 03:24:45 +0000656 InnerString = "typeof(" + s.str() + ")" + InnerString;
Steve Naroffd1861fd2007-07-31 12:34:36 +0000657}
658
Steve Naroff363bcff2007-08-01 23:45:51 +0000659void TypeOfType::getAsStringInternal(std::string &InnerString) const {
660 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(t) X'.
661 InnerString = ' ' + InnerString;
Steve Naroffd1861fd2007-07-31 12:34:36 +0000662 std::string Tmp;
663 getUnderlyingType().getAsStringInternal(Tmp);
Steve Naroff363bcff2007-08-01 23:45:51 +0000664 InnerString = "typeof(" + Tmp + ")" + InnerString;
Steve Naroffd1861fd2007-07-31 12:34:36 +0000665}
666
Reid Spencer5f016e22007-07-11 17:01:13 +0000667void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
668 // If needed for precedence reasons, wrap the inner part in grouping parens.
669 if (!S.empty())
670 S = "(" + S + ")";
671
672 S += "()";
673 getResultType().getAsStringInternal(S);
674}
675
676void FunctionTypeProto::getAsStringInternal(std::string &S) const {
677 // If needed for precedence reasons, wrap the inner part in grouping parens.
678 if (!S.empty())
679 S = "(" + S + ")";
680
681 S += "(";
682 std::string Tmp;
683 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
684 if (i) S += ", ";
685 getArgType(i).getAsStringInternal(Tmp);
686 S += Tmp;
687 Tmp.clear();
688 }
689
690 if (isVariadic()) {
691 if (getNumArgs())
692 S += ", ";
693 S += "...";
694 } else if (getNumArgs() == 0) {
695 // Do not emit int() if we have a proto, emit 'int(void)'.
696 S += "void";
697 }
698
699 S += ")";
700 getResultType().getAsStringInternal(S);
701}
702
703
704void TypedefType::getAsStringInternal(std::string &InnerString) const {
705 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
706 InnerString = ' ' + InnerString;
707 InnerString = getDecl()->getIdentifier()->getName() + InnerString;
708}
709
Steve Naroff3536b442007-09-06 21:24:23 +0000710void ObjcInterfaceType::getAsStringInternal(std::string &InnerString) const {
711 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
712 InnerString = ' ' + InnerString;
713 InnerString = getDecl()->getIdentifier()->getName() + InnerString;
714}
715
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000716void ObjcQualifiedInterfaceType::getAsStringInternal(
717 std::string &InnerString) const {
Fariborz Jahaniandfbcce22007-10-11 18:08:47 +0000718 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
719 InnerString = ' ' + InnerString;
720 std::string ObjcQIString = getInterfaceType()->getDecl()->getName();
721 ObjcQIString += '<';
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000722 int num = getNumProtocols();
723 for (int i = 0; i < num; i++) {
Fariborz Jahaniandfbcce22007-10-11 18:08:47 +0000724 ObjcQIString += getProtocols(i)->getName();
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000725 if (i < num-1)
Fariborz Jahaniandfbcce22007-10-11 18:08:47 +0000726 ObjcQIString += ',';
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000727 }
Fariborz Jahaniandfbcce22007-10-11 18:08:47 +0000728 ObjcQIString += '>';
729 InnerString = ObjcQIString + InnerString;
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000730}
731
Reid Spencer5f016e22007-07-11 17:01:13 +0000732void TagType::getAsStringInternal(std::string &InnerString) const {
733 if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
734 InnerString = ' ' + InnerString;
735
736 const char *Kind = getDecl()->getKindName();
737 const char *ID;
738 if (const IdentifierInfo *II = getDecl()->getIdentifier())
739 ID = II->getName();
740 else
741 ID = "<anonymous>";
742
743 InnerString = std::string(Kind) + " " + ID + InnerString;
744}