blob: ec7cd7b558838ab6daaadeaa83179c687843ef62 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===//
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 the ASTContext interface.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ASTContext.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/Basic/TargetInfo.h"
18#include "llvm/ADT/SmallVector.h"
Anders Carlsson85f9bce2007-10-29 05:01:08 +000019#include "llvm/ADT/StringExtras.h"
20
Reid Spencer5f016e22007-07-11 17:01:13 +000021using namespace clang;
22
23enum FloatingRank {
24 FloatRank, DoubleRank, LongDoubleRank
25};
26
27ASTContext::~ASTContext() {
28 // Deallocate all the types.
29 while (!Types.empty()) {
30 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(Types.back())) {
31 // Destroy the object, but don't call delete. These are malloc'd.
32 FT->~FunctionTypeProto();
33 free(FT);
34 } else {
35 delete Types.back();
36 }
37 Types.pop_back();
38 }
39}
40
41void ASTContext::PrintStats() const {
42 fprintf(stderr, "*** AST Context Stats:\n");
43 fprintf(stderr, " %d types total.\n", (int)Types.size());
44 unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
Chris Lattner6d87fc62007-07-18 05:50:59 +000045 unsigned NumVector = 0, NumComplex = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000046 unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
47
48 unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
Steve Naroff3f128ad2007-09-17 14:16:13 +000049 unsigned NumObjcInterfaces = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +000050
51 for (unsigned i = 0, e = Types.size(); i != e; ++i) {
52 Type *T = Types[i];
53 if (isa<BuiltinType>(T))
54 ++NumBuiltin;
55 else if (isa<PointerType>(T))
56 ++NumPointer;
57 else if (isa<ReferenceType>(T))
58 ++NumReference;
Chris Lattner6d87fc62007-07-18 05:50:59 +000059 else if (isa<ComplexType>(T))
60 ++NumComplex;
Reid Spencer5f016e22007-07-11 17:01:13 +000061 else if (isa<ArrayType>(T))
62 ++NumArray;
Chris Lattner6d87fc62007-07-18 05:50:59 +000063 else if (isa<VectorType>(T))
64 ++NumVector;
Reid Spencer5f016e22007-07-11 17:01:13 +000065 else if (isa<FunctionTypeNoProto>(T))
66 ++NumFunctionNP;
67 else if (isa<FunctionTypeProto>(T))
68 ++NumFunctionP;
69 else if (isa<TypedefType>(T))
70 ++NumTypeName;
71 else if (TagType *TT = dyn_cast<TagType>(T)) {
72 ++NumTagged;
73 switch (TT->getDecl()->getKind()) {
74 default: assert(0 && "Unknown tagged type!");
75 case Decl::Struct: ++NumTagStruct; break;
76 case Decl::Union: ++NumTagUnion; break;
77 case Decl::Class: ++NumTagClass; break;
78 case Decl::Enum: ++NumTagEnum; break;
79 }
Steve Naroff3f128ad2007-09-17 14:16:13 +000080 } else if (isa<ObjcInterfaceType>(T))
81 ++NumObjcInterfaces;
82 else {
Reid Spencer5f016e22007-07-11 17:01:13 +000083 assert(0 && "Unknown type!");
84 }
85 }
86
87 fprintf(stderr, " %d builtin types\n", NumBuiltin);
88 fprintf(stderr, " %d pointer types\n", NumPointer);
89 fprintf(stderr, " %d reference types\n", NumReference);
Chris Lattner6d87fc62007-07-18 05:50:59 +000090 fprintf(stderr, " %d complex types\n", NumComplex);
Reid Spencer5f016e22007-07-11 17:01:13 +000091 fprintf(stderr, " %d array types\n", NumArray);
Chris Lattner6d87fc62007-07-18 05:50:59 +000092 fprintf(stderr, " %d vector types\n", NumVector);
Reid Spencer5f016e22007-07-11 17:01:13 +000093 fprintf(stderr, " %d function types with proto\n", NumFunctionP);
94 fprintf(stderr, " %d function types with no proto\n", NumFunctionNP);
95 fprintf(stderr, " %d typename (typedef) types\n", NumTypeName);
96 fprintf(stderr, " %d tagged types\n", NumTagged);
97 fprintf(stderr, " %d struct types\n", NumTagStruct);
98 fprintf(stderr, " %d union types\n", NumTagUnion);
99 fprintf(stderr, " %d class types\n", NumTagClass);
100 fprintf(stderr, " %d enum types\n", NumTagEnum);
Steve Naroff3f128ad2007-09-17 14:16:13 +0000101 fprintf(stderr, " %d interface types\n", NumObjcInterfaces);
Reid Spencer5f016e22007-07-11 17:01:13 +0000102 fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
103 NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
Chris Lattner6d87fc62007-07-18 05:50:59 +0000104 NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
Reid Spencer5f016e22007-07-11 17:01:13 +0000105 NumFunctionP*sizeof(FunctionTypeProto)+
106 NumFunctionNP*sizeof(FunctionTypeNoProto)+
107 NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)));
108}
109
110
111void ASTContext::InitBuiltinType(QualType &R, BuiltinType::Kind K) {
112 Types.push_back((R = QualType(new BuiltinType(K),0)).getTypePtr());
113}
114
Reid Spencer5f016e22007-07-11 17:01:13 +0000115void ASTContext::InitBuiltinTypes() {
116 assert(VoidTy.isNull() && "Context reinitialized?");
117
118 // C99 6.2.5p19.
119 InitBuiltinType(VoidTy, BuiltinType::Void);
120
121 // C99 6.2.5p2.
122 InitBuiltinType(BoolTy, BuiltinType::Bool);
123 // C99 6.2.5p3.
124 if (Target.isCharSigned(SourceLocation()))
125 InitBuiltinType(CharTy, BuiltinType::Char_S);
126 else
127 InitBuiltinType(CharTy, BuiltinType::Char_U);
128 // C99 6.2.5p4.
129 InitBuiltinType(SignedCharTy, BuiltinType::SChar);
130 InitBuiltinType(ShortTy, BuiltinType::Short);
131 InitBuiltinType(IntTy, BuiltinType::Int);
132 InitBuiltinType(LongTy, BuiltinType::Long);
133 InitBuiltinType(LongLongTy, BuiltinType::LongLong);
134
135 // C99 6.2.5p6.
136 InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
137 InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
138 InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
139 InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
140 InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
141
142 // C99 6.2.5p10.
143 InitBuiltinType(FloatTy, BuiltinType::Float);
144 InitBuiltinType(DoubleTy, BuiltinType::Double);
145 InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
146
147 // C99 6.2.5p11.
148 FloatComplexTy = getComplexType(FloatTy);
149 DoubleComplexTy = getComplexType(DoubleTy);
150 LongDoubleComplexTy = getComplexType(LongDoubleTy);
Steve Naroff7e219e42007-10-15 14:41:52 +0000151
152 BuiltinVaListType = QualType();
153 ObjcIdType = QualType();
154 IdStructType = 0;
Anders Carlsson8baaca52007-10-31 02:53:19 +0000155 ObjcClassType = QualType();
156 ClassStructType = 0;
157
Steve Naroff21988912007-10-15 23:35:17 +0000158 ObjcConstantStringType = QualType();
Fariborz Jahanian33e1d642007-10-29 22:57:28 +0000159
160 // void * type
161 VoidPtrTy = getPointerType(VoidTy);
Reid Spencer5f016e22007-07-11 17:01:13 +0000162}
163
Chris Lattner464175b2007-07-18 17:52:12 +0000164//===----------------------------------------------------------------------===//
165// Type Sizing and Analysis
166//===----------------------------------------------------------------------===//
Chris Lattnera7674d82007-07-13 22:13:22 +0000167
168/// getTypeSize - Return the size of the specified type, in bits. This method
169/// does not work on incomplete types.
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000170std::pair<uint64_t, unsigned>
171ASTContext::getTypeInfo(QualType T, SourceLocation L) {
Chris Lattnera7674d82007-07-13 22:13:22 +0000172 T = T.getCanonicalType();
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000173 uint64_t Size;
174 unsigned Align;
Chris Lattnera7674d82007-07-13 22:13:22 +0000175 switch (T->getTypeClass()) {
Chris Lattner030d8842007-07-19 22:06:24 +0000176 case Type::TypeName: assert(0 && "Not a canonical type!");
Chris Lattner692233e2007-07-13 22:27:08 +0000177 case Type::FunctionNoProto:
178 case Type::FunctionProto:
Chris Lattner5d2a6302007-07-18 18:26:58 +0000179 default:
Chris Lattnerb1c2df92007-07-20 18:13:33 +0000180 assert(0 && "Incomplete types have no size!");
Steve Narofffb22d962007-08-30 01:06:46 +0000181 case Type::VariableArray:
182 assert(0 && "VLAs not implemented yet!");
183 case Type::ConstantArray: {
184 ConstantArrayType *CAT = cast<ConstantArrayType>(T);
185
Chris Lattner030d8842007-07-19 22:06:24 +0000186 std::pair<uint64_t, unsigned> EltInfo =
Steve Narofffb22d962007-08-30 01:06:46 +0000187 getTypeInfo(CAT->getElementType(), L);
188 Size = EltInfo.first*CAT->getSize().getZExtValue();
Chris Lattner030d8842007-07-19 22:06:24 +0000189 Align = EltInfo.second;
190 break;
191 }
192 case Type::Vector: {
193 std::pair<uint64_t, unsigned> EltInfo =
194 getTypeInfo(cast<VectorType>(T)->getElementType(), L);
195 Size = EltInfo.first*cast<VectorType>(T)->getNumElements();
196 // FIXME: Vector alignment is not the alignment of its elements.
197 Align = EltInfo.second;
198 break;
199 }
Chris Lattner5d2a6302007-07-18 18:26:58 +0000200
Chris Lattnera7674d82007-07-13 22:13:22 +0000201 case Type::Builtin: {
202 // FIXME: need to use TargetInfo to derive the target specific sizes. This
203 // implementation will suffice for play with vector support.
Chris Lattner525a0502007-09-22 18:29:59 +0000204 const llvm::fltSemantics *F;
Chris Lattnera7674d82007-07-13 22:13:22 +0000205 switch (cast<BuiltinType>(T)->getKind()) {
Chris Lattner692233e2007-07-13 22:27:08 +0000206 default: assert(0 && "Unknown builtin type!");
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000207 case BuiltinType::Void:
208 assert(0 && "Incomplete types have no size!");
209 case BuiltinType::Bool: Target.getBoolInfo(Size, Align, L); break;
Chris Lattner692233e2007-07-13 22:27:08 +0000210 case BuiltinType::Char_S:
211 case BuiltinType::Char_U:
212 case BuiltinType::UChar:
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000213 case BuiltinType::SChar: Target.getCharInfo(Size, Align, L); break;
Chris Lattner692233e2007-07-13 22:27:08 +0000214 case BuiltinType::UShort:
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000215 case BuiltinType::Short: Target.getShortInfo(Size, Align, L); break;
Chris Lattner692233e2007-07-13 22:27:08 +0000216 case BuiltinType::UInt:
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000217 case BuiltinType::Int: Target.getIntInfo(Size, Align, L); break;
Chris Lattner692233e2007-07-13 22:27:08 +0000218 case BuiltinType::ULong:
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000219 case BuiltinType::Long: Target.getLongInfo(Size, Align, L); break;
Chris Lattner692233e2007-07-13 22:27:08 +0000220 case BuiltinType::ULongLong:
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000221 case BuiltinType::LongLong: Target.getLongLongInfo(Size, Align, L); break;
Chris Lattner525a0502007-09-22 18:29:59 +0000222 case BuiltinType::Float: Target.getFloatInfo(Size, Align, F, L); break;
223 case BuiltinType::Double: Target.getDoubleInfo(Size, Align, F, L);break;
224 case BuiltinType::LongDouble:Target.getLongDoubleInfo(Size,Align,F,L);break;
Chris Lattnera7674d82007-07-13 22:13:22 +0000225 }
Chris Lattnerbfef6d72007-07-15 23:46:53 +0000226 break;
Chris Lattnera7674d82007-07-13 22:13:22 +0000227 }
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000228 case Type::Pointer: Target.getPointerInfo(Size, Align, L); break;
Chris Lattnera7674d82007-07-13 22:13:22 +0000229 case Type::Reference:
Chris Lattner7ab2ed82007-07-13 22:16:13 +0000230 // "When applied to a reference or a reference type, the result is the size
Chris Lattner5d2a6302007-07-18 18:26:58 +0000231 // of the referenced type." C++98 5.3.3p2: expr.sizeof.
232 // FIXME: This is wrong for struct layout!
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000233 return getTypeInfo(cast<ReferenceType>(T)->getReferenceeType(), L);
Chris Lattner5d2a6302007-07-18 18:26:58 +0000234
235 case Type::Complex: {
236 // Complex types have the same alignment as their elements, but twice the
237 // size.
238 std::pair<uint64_t, unsigned> EltInfo =
239 getTypeInfo(cast<ComplexType>(T)->getElementType(), L);
240 Size = EltInfo.first*2;
241 Align = EltInfo.second;
242 break;
243 }
244 case Type::Tagged:
Chris Lattner6cd862c2007-08-27 17:38:00 +0000245 TagType *TT = cast<TagType>(T);
246 if (RecordType *RT = dyn_cast<RecordType>(TT)) {
247 const RecordLayout &Layout = getRecordLayout(RT->getDecl(), L);
248 Size = Layout.getSize();
249 Align = Layout.getAlignment();
250 } else if (EnumDecl *ED = dyn_cast<EnumDecl>(TT->getDecl())) {
Chris Lattnere00b18c2007-08-28 18:24:31 +0000251 return getTypeInfo(ED->getIntegerType(), L);
Chris Lattner6cd862c2007-08-27 17:38:00 +0000252 } else {
Chris Lattnerdc0d73e2007-07-23 22:46:22 +0000253 assert(0 && "Unimplemented type sizes!");
Chris Lattner6cd862c2007-08-27 17:38:00 +0000254 }
Chris Lattnerdc0d73e2007-07-23 22:46:22 +0000255 break;
Chris Lattnera7674d82007-07-13 22:13:22 +0000256 }
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000257
Chris Lattner464175b2007-07-18 17:52:12 +0000258 assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000259 return std::make_pair(Size, Align);
Chris Lattnera7674d82007-07-13 22:13:22 +0000260}
261
Chris Lattner464175b2007-07-18 17:52:12 +0000262/// getRecordLayout - Get or compute information about the layout of the
263/// specified record (struct/union/class), which indicates its size and field
264/// position information.
265const RecordLayout &ASTContext::getRecordLayout(const RecordDecl *D,
266 SourceLocation L) {
267 assert(D->isDefinition() && "Cannot get layout of forward declarations!");
268
269 // Look up this layout, if already laid out, return what we have.
270 const RecordLayout *&Entry = RecordLayoutInfo[D];
271 if (Entry) return *Entry;
272
273 // Allocate and assign into RecordLayoutInfo here. The "Entry" reference can
274 // be invalidated (dangle) if the RecordLayoutInfo hashtable is inserted into.
275 RecordLayout *NewEntry = new RecordLayout();
276 Entry = NewEntry;
277
278 uint64_t *FieldOffsets = new uint64_t[D->getNumMembers()];
279 uint64_t RecordSize = 0;
280 unsigned RecordAlign = 8; // Default alignment = 1 byte = 8 bits.
281
282 if (D->getKind() != Decl::Union) {
283 // Layout each field, for now, just sequentially, respecting alignment. In
284 // the future, this will need to be tweakable by targets.
285 for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
286 const FieldDecl *FD = D->getMember(i);
287 std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
288 uint64_t FieldSize = FieldInfo.first;
289 unsigned FieldAlign = FieldInfo.second;
290
291 // Round up the current record size to the field's alignment boundary.
292 RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
293
294 // Place this field at the current location.
295 FieldOffsets[i] = RecordSize;
296
297 // Reserve space for this field.
298 RecordSize += FieldSize;
299
300 // Remember max struct/class alignment.
301 RecordAlign = std::max(RecordAlign, FieldAlign);
302 }
303
304 // Finally, round the size of the total struct up to the alignment of the
305 // struct itself.
306 RecordSize = (RecordSize+RecordAlign-1) & ~(RecordAlign-1);
307 } else {
308 // Union layout just puts each member at the start of the record.
309 for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
310 const FieldDecl *FD = D->getMember(i);
311 std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
312 uint64_t FieldSize = FieldInfo.first;
313 unsigned FieldAlign = FieldInfo.second;
314
315 // Round up the current record size to the field's alignment boundary.
316 RecordSize = std::max(RecordSize, FieldSize);
317
318 // Place this field at the start of the record.
319 FieldOffsets[i] = 0;
320
321 // Remember max struct/class alignment.
322 RecordAlign = std::max(RecordAlign, FieldAlign);
323 }
324 }
Chris Lattner5d2a6302007-07-18 18:26:58 +0000325
326 NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets);
327 return *NewEntry;
Chris Lattner464175b2007-07-18 17:52:12 +0000328}
329
Chris Lattnera7674d82007-07-13 22:13:22 +0000330//===----------------------------------------------------------------------===//
331// Type creation/memoization methods
332//===----------------------------------------------------------------------===//
333
334
Reid Spencer5f016e22007-07-11 17:01:13 +0000335/// getComplexType - Return the uniqued reference to the type for a complex
336/// number with the specified element type.
337QualType ASTContext::getComplexType(QualType T) {
338 // Unique pointers, to guarantee there is only one pointer of a particular
339 // structure.
340 llvm::FoldingSetNodeID ID;
341 ComplexType::Profile(ID, T);
342
343 void *InsertPos = 0;
344 if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
345 return QualType(CT, 0);
346
347 // If the pointee type isn't canonical, this won't be a canonical type either,
348 // so fill in the canonical type field.
349 QualType Canonical;
350 if (!T->isCanonical()) {
351 Canonical = getComplexType(T.getCanonicalType());
352
353 // Get the new insert position for the node we care about.
354 ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
355 assert(NewIP == 0 && "Shouldn't be in the map!");
356 }
357 ComplexType *New = new ComplexType(T, Canonical);
358 Types.push_back(New);
359 ComplexTypes.InsertNode(New, InsertPos);
360 return QualType(New, 0);
361}
362
363
364/// getPointerType - Return the uniqued reference to the type for a pointer to
365/// the specified type.
366QualType ASTContext::getPointerType(QualType T) {
367 // Unique pointers, to guarantee there is only one pointer of a particular
368 // structure.
369 llvm::FoldingSetNodeID ID;
370 PointerType::Profile(ID, T);
371
372 void *InsertPos = 0;
373 if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
374 return QualType(PT, 0);
375
376 // If the pointee type isn't canonical, this won't be a canonical type either,
377 // so fill in the canonical type field.
378 QualType Canonical;
379 if (!T->isCanonical()) {
380 Canonical = getPointerType(T.getCanonicalType());
381
382 // Get the new insert position for the node we care about.
383 PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
384 assert(NewIP == 0 && "Shouldn't be in the map!");
385 }
386 PointerType *New = new PointerType(T, Canonical);
387 Types.push_back(New);
388 PointerTypes.InsertNode(New, InsertPos);
389 return QualType(New, 0);
390}
391
392/// getReferenceType - Return the uniqued reference to the type for a reference
393/// to the specified type.
394QualType ASTContext::getReferenceType(QualType T) {
395 // Unique pointers, to guarantee there is only one pointer of a particular
396 // structure.
397 llvm::FoldingSetNodeID ID;
398 ReferenceType::Profile(ID, T);
399
400 void *InsertPos = 0;
401 if (ReferenceType *RT = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
402 return QualType(RT, 0);
403
404 // If the referencee type isn't canonical, this won't be a canonical type
405 // either, so fill in the canonical type field.
406 QualType Canonical;
407 if (!T->isCanonical()) {
408 Canonical = getReferenceType(T.getCanonicalType());
409
410 // Get the new insert position for the node we care about.
411 ReferenceType *NewIP = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
412 assert(NewIP == 0 && "Shouldn't be in the map!");
413 }
414
415 ReferenceType *New = new ReferenceType(T, Canonical);
416 Types.push_back(New);
417 ReferenceTypes.InsertNode(New, InsertPos);
418 return QualType(New, 0);
419}
420
Steve Narofffb22d962007-08-30 01:06:46 +0000421/// getConstantArrayType - Return the unique reference to the type for an
422/// array of the specified element type.
423QualType ASTContext::getConstantArrayType(QualType EltTy,
Steve Naroffc9406122007-08-30 18:10:14 +0000424 const llvm::APInt &ArySize,
425 ArrayType::ArraySizeModifier ASM,
426 unsigned EltTypeQuals) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000427 llvm::FoldingSetNodeID ID;
Steve Narofffb22d962007-08-30 01:06:46 +0000428 ConstantArrayType::Profile(ID, EltTy, ArySize);
Reid Spencer5f016e22007-07-11 17:01:13 +0000429
430 void *InsertPos = 0;
Steve Narofffb22d962007-08-30 01:06:46 +0000431 if (ConstantArrayType *ATP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
Reid Spencer5f016e22007-07-11 17:01:13 +0000432 return QualType(ATP, 0);
433
434 // If the element type isn't canonical, this won't be a canonical type either,
435 // so fill in the canonical type field.
436 QualType Canonical;
437 if (!EltTy->isCanonical()) {
Steve Naroffc9406122007-08-30 18:10:14 +0000438 Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize,
439 ASM, EltTypeQuals);
Reid Spencer5f016e22007-07-11 17:01:13 +0000440 // Get the new insert position for the node we care about.
Steve Narofffb22d962007-08-30 01:06:46 +0000441 ConstantArrayType *NewIP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
Reid Spencer5f016e22007-07-11 17:01:13 +0000442 assert(NewIP == 0 && "Shouldn't be in the map!");
443 }
444
Steve Naroffc9406122007-08-30 18:10:14 +0000445 ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize,
446 ASM, EltTypeQuals);
Reid Spencer5f016e22007-07-11 17:01:13 +0000447 ArrayTypes.InsertNode(New, InsertPos);
448 Types.push_back(New);
449 return QualType(New, 0);
450}
451
Steve Naroffbdbf7b02007-08-30 18:14:25 +0000452/// getVariableArrayType - Returns a non-unique reference to the type for a
453/// variable array of the specified element type.
Steve Naroffc9406122007-08-30 18:10:14 +0000454QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
455 ArrayType::ArraySizeModifier ASM,
456 unsigned EltTypeQuals) {
Ted Kremenek2bd24ba2007-10-29 23:37:31 +0000457 if (NumElts) {
458 // Since we don't unique expressions, it isn't possible to unique VLA's
459 // that have an expression provided for their size.
460
Ted Kremenek347b9f32007-10-30 16:41:53 +0000461 VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
462 ASM, EltTypeQuals);
Ted Kremenek2bd24ba2007-10-29 23:37:31 +0000463
Ted Kremenek347b9f32007-10-30 16:41:53 +0000464 CompleteVariableArrayTypes.push_back(New);
Ted Kremenek2bd24ba2007-10-29 23:37:31 +0000465 Types.push_back(New);
466 return QualType(New, 0);
467 }
468 else {
469 // No size is provided for the VLA. These we can unique.
470 llvm::FoldingSetNodeID ID;
471 VariableArrayType::Profile(ID, EltTy);
472
473 void *InsertPos = 0;
474 if (VariableArrayType *ATP =
475 IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
476 return QualType(ATP, 0);
477
478 // If the element type isn't canonical, this won't be a canonical type
479 // either, so fill in the canonical type field.
480 QualType Canonical;
481
482 if (!EltTy->isCanonical()) {
483 Canonical = getVariableArrayType(EltTy.getCanonicalType(), NumElts,
484 ASM, EltTypeQuals);
485
486 // Get the new insert position for the node we care about.
487 VariableArrayType *NewIP =
488 IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
489
490 assert(NewIP == 0 && "Shouldn't be in the map!");
491 }
492
493 VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
494 ASM, EltTypeQuals);
495
496 IncompleteVariableArrayTypes.InsertNode(New, InsertPos);
497 Types.push_back(New);
498 return QualType(New, 0);
499 }
Steve Narofffb22d962007-08-30 01:06:46 +0000500}
501
Steve Naroff73322922007-07-18 18:00:27 +0000502/// getVectorType - Return the unique reference to a vector type of
503/// the specified element type and size. VectorType must be a built-in type.
504QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000505 BuiltinType *baseType;
506
507 baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
Steve Naroff73322922007-07-18 18:00:27 +0000508 assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
Reid Spencer5f016e22007-07-11 17:01:13 +0000509
510 // Check if we've already instantiated a vector of this type.
511 llvm::FoldingSetNodeID ID;
Steve Naroff73322922007-07-18 18:00:27 +0000512 VectorType::Profile(ID, vecType, NumElts, Type::Vector);
Reid Spencer5f016e22007-07-11 17:01:13 +0000513 void *InsertPos = 0;
514 if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
515 return QualType(VTP, 0);
516
517 // If the element type isn't canonical, this won't be a canonical type either,
518 // so fill in the canonical type field.
519 QualType Canonical;
520 if (!vecType->isCanonical()) {
Steve Naroff73322922007-07-18 18:00:27 +0000521 Canonical = getVectorType(vecType.getCanonicalType(), NumElts);
Reid Spencer5f016e22007-07-11 17:01:13 +0000522
523 // Get the new insert position for the node we care about.
524 VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
525 assert(NewIP == 0 && "Shouldn't be in the map!");
526 }
527 VectorType *New = new VectorType(vecType, NumElts, Canonical);
528 VectorTypes.InsertNode(New, InsertPos);
529 Types.push_back(New);
530 return QualType(New, 0);
531}
532
Steve Naroff73322922007-07-18 18:00:27 +0000533/// getOCUVectorType - Return the unique reference to an OCU vector type of
534/// the specified element type and size. VectorType must be a built-in type.
535QualType ASTContext::getOCUVectorType(QualType vecType, unsigned NumElts) {
536 BuiltinType *baseType;
537
538 baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
539 assert(baseType != 0 && "getOCUVectorType(): Expecting a built-in type");
540
541 // Check if we've already instantiated a vector of this type.
542 llvm::FoldingSetNodeID ID;
543 VectorType::Profile(ID, vecType, NumElts, Type::OCUVector);
544 void *InsertPos = 0;
545 if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
546 return QualType(VTP, 0);
547
548 // If the element type isn't canonical, this won't be a canonical type either,
549 // so fill in the canonical type field.
550 QualType Canonical;
551 if (!vecType->isCanonical()) {
552 Canonical = getOCUVectorType(vecType.getCanonicalType(), NumElts);
553
554 // Get the new insert position for the node we care about.
555 VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
556 assert(NewIP == 0 && "Shouldn't be in the map!");
557 }
558 OCUVectorType *New = new OCUVectorType(vecType, NumElts, Canonical);
559 VectorTypes.InsertNode(New, InsertPos);
560 Types.push_back(New);
561 return QualType(New, 0);
562}
563
Reid Spencer5f016e22007-07-11 17:01:13 +0000564/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
565///
566QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {
567 // Unique functions, to guarantee there is only one function of a particular
568 // structure.
569 llvm::FoldingSetNodeID ID;
570 FunctionTypeNoProto::Profile(ID, ResultTy);
571
572 void *InsertPos = 0;
573 if (FunctionTypeNoProto *FT =
574 FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos))
575 return QualType(FT, 0);
576
577 QualType Canonical;
578 if (!ResultTy->isCanonical()) {
579 Canonical = getFunctionTypeNoProto(ResultTy.getCanonicalType());
580
581 // Get the new insert position for the node we care about.
582 FunctionTypeNoProto *NewIP =
583 FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos);
584 assert(NewIP == 0 && "Shouldn't be in the map!");
585 }
586
587 FunctionTypeNoProto *New = new FunctionTypeNoProto(ResultTy, Canonical);
588 Types.push_back(New);
589 FunctionTypeProtos.InsertNode(New, InsertPos);
590 return QualType(New, 0);
591}
592
593/// getFunctionType - Return a normal function type with a typed argument
594/// list. isVariadic indicates whether the argument list includes '...'.
595QualType ASTContext::getFunctionType(QualType ResultTy, QualType *ArgArray,
596 unsigned NumArgs, bool isVariadic) {
597 // Unique functions, to guarantee there is only one function of a particular
598 // structure.
599 llvm::FoldingSetNodeID ID;
600 FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
601
602 void *InsertPos = 0;
603 if (FunctionTypeProto *FTP =
604 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
605 return QualType(FTP, 0);
606
607 // Determine whether the type being created is already canonical or not.
608 bool isCanonical = ResultTy->isCanonical();
609 for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
610 if (!ArgArray[i]->isCanonical())
611 isCanonical = false;
612
613 // If this type isn't canonical, get the canonical version of it.
614 QualType Canonical;
615 if (!isCanonical) {
616 llvm::SmallVector<QualType, 16> CanonicalArgs;
617 CanonicalArgs.reserve(NumArgs);
618 for (unsigned i = 0; i != NumArgs; ++i)
619 CanonicalArgs.push_back(ArgArray[i].getCanonicalType());
620
621 Canonical = getFunctionType(ResultTy.getCanonicalType(),
622 &CanonicalArgs[0], NumArgs,
623 isVariadic);
624
625 // Get the new insert position for the node we care about.
626 FunctionTypeProto *NewIP =
627 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
628 assert(NewIP == 0 && "Shouldn't be in the map!");
629 }
630
631 // FunctionTypeProto objects are not allocated with new because they have a
632 // variable size array (for parameter types) at the end of them.
633 FunctionTypeProto *FTP =
634 (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
Chris Lattner942cfd32007-07-20 18:48:28 +0000635 NumArgs*sizeof(QualType));
Reid Spencer5f016e22007-07-11 17:01:13 +0000636 new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
637 Canonical);
638 Types.push_back(FTP);
639 FunctionTypeProtos.InsertNode(FTP, InsertPos);
640 return QualType(FTP, 0);
641}
642
643/// getTypedefType - Return the unique reference to the type for the
644/// specified typename decl.
645QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
646 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
647
648 QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
649 Decl->TypeForDecl = new TypedefType(Decl, Canonical);
650 Types.push_back(Decl->TypeForDecl);
651 return QualType(Decl->TypeForDecl, 0);
652}
653
Steve Naroff3536b442007-09-06 21:24:23 +0000654/// getObjcInterfaceType - Return the unique reference to the type for the
655/// specified ObjC interface decl.
656QualType ASTContext::getObjcInterfaceType(ObjcInterfaceDecl *Decl) {
657 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
658
659 Decl->TypeForDecl = new ObjcInterfaceType(Decl);
660 Types.push_back(Decl->TypeForDecl);
661 return QualType(Decl->TypeForDecl, 0);
662}
663
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000664/// getObjcQualifiedInterfaceType - Return a
665/// ObjcQualifiedInterfaceType type for the given interface decl and
666/// the conforming protocol list.
667QualType ASTContext::getObjcQualifiedInterfaceType(ObjcInterfaceDecl *Decl,
668 ObjcProtocolDecl **Protocols, unsigned NumProtocols) {
669 ObjcInterfaceType *IType =
670 cast<ObjcInterfaceType>(getObjcInterfaceType(Decl));
671
672 llvm::FoldingSetNodeID ID;
673 ObjcQualifiedInterfaceType::Profile(ID, IType, Protocols, NumProtocols);
674
675 void *InsertPos = 0;
676 if (ObjcQualifiedInterfaceType *QT =
677 ObjcQualifiedInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
678 return QualType(QT, 0);
679
680 // No Match;
Chris Lattner00bb2832007-10-11 03:36:41 +0000681 ObjcQualifiedInterfaceType *QType =
682 new ObjcQualifiedInterfaceType(IType, Protocols, NumProtocols);
Fariborz Jahanian4b6c9052007-10-11 00:55:41 +0000683 Types.push_back(QType);
684 ObjcQualifiedInterfaceTypes.InsertNode(QType, InsertPos);
685 return QualType(QType, 0);
686}
687
Steve Naroff9752f252007-08-01 18:02:17 +0000688/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
689/// TypeOfExpr AST's (since expression's are never shared). For example,
690/// multiple declarations that refer to "typeof(x)" all contain different
691/// DeclRefExpr's. This doesn't effect the type checker, since it operates
692/// on canonical type's (which are always unique).
Steve Naroff8d1a3b82007-08-01 17:20:42 +0000693QualType ASTContext::getTypeOfExpr(Expr *tofExpr) {
Steve Naroffd1861fd2007-07-31 12:34:36 +0000694 QualType Canonical = tofExpr->getType().getCanonicalType();
Steve Naroff9752f252007-08-01 18:02:17 +0000695 TypeOfExpr *toe = new TypeOfExpr(tofExpr, Canonical);
696 Types.push_back(toe);
697 return QualType(toe, 0);
Steve Naroffd1861fd2007-07-31 12:34:36 +0000698}
699
Steve Naroff9752f252007-08-01 18:02:17 +0000700/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
701/// TypeOfType AST's. The only motivation to unique these nodes would be
702/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
703/// an issue. This doesn't effect the type checker, since it operates
704/// on canonical type's (which are always unique).
Steve Naroffd1861fd2007-07-31 12:34:36 +0000705QualType ASTContext::getTypeOfType(QualType tofType) {
706 QualType Canonical = tofType.getCanonicalType();
Steve Naroff9752f252007-08-01 18:02:17 +0000707 TypeOfType *tot = new TypeOfType(tofType, Canonical);
708 Types.push_back(tot);
709 return QualType(tot, 0);
Steve Naroffd1861fd2007-07-31 12:34:36 +0000710}
711
Reid Spencer5f016e22007-07-11 17:01:13 +0000712/// getTagDeclType - Return the unique reference to the type for the
713/// specified TagDecl (struct/union/class/enum) decl.
714QualType ASTContext::getTagDeclType(TagDecl *Decl) {
715 // The decl stores the type cache.
716 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
717
718 Decl->TypeForDecl = new TagType(Decl, QualType());
719 Types.push_back(Decl->TypeForDecl);
720 return QualType(Decl->TypeForDecl, 0);
721}
722
723/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
724/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
725/// needs to agree with the definition in <stddef.h>.
726QualType ASTContext::getSizeType() const {
727 // On Darwin, size_t is defined as a "long unsigned int".
728 // FIXME: should derive from "Target".
729 return UnsignedLongTy;
730}
731
Chris Lattner8b9023b2007-07-13 03:05:23 +0000732/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
733/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
734QualType ASTContext::getPointerDiffType() const {
735 // On Darwin, ptrdiff_t is defined as a "int". This seems like a bug...
736 // FIXME: should derive from "Target".
737 return IntTy;
738}
739
Reid Spencer5f016e22007-07-11 17:01:13 +0000740/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
741/// routine will assert if passed a built-in type that isn't an integer or enum.
742static int getIntegerRank(QualType t) {
743 if (const TagType *TT = dyn_cast<TagType>(t.getCanonicalType())) {
744 assert(TT->getDecl()->getKind() == Decl::Enum && "not an int or enum");
745 return 4;
746 }
747
748 const BuiltinType *BT = cast<BuiltinType>(t.getCanonicalType());
749 switch (BT->getKind()) {
750 default:
751 assert(0 && "getIntegerRank(): not a built-in integer");
752 case BuiltinType::Bool:
753 return 1;
754 case BuiltinType::Char_S:
755 case BuiltinType::Char_U:
756 case BuiltinType::SChar:
757 case BuiltinType::UChar:
758 return 2;
759 case BuiltinType::Short:
760 case BuiltinType::UShort:
761 return 3;
762 case BuiltinType::Int:
763 case BuiltinType::UInt:
764 return 4;
765 case BuiltinType::Long:
766 case BuiltinType::ULong:
767 return 5;
768 case BuiltinType::LongLong:
769 case BuiltinType::ULongLong:
770 return 6;
771 }
772}
773
774/// getFloatingRank - Return a relative rank for floating point types.
775/// This routine will assert if passed a built-in type that isn't a float.
776static int getFloatingRank(QualType T) {
777 T = T.getCanonicalType();
778 if (ComplexType *CT = dyn_cast<ComplexType>(T))
779 return getFloatingRank(CT->getElementType());
780
781 switch (cast<BuiltinType>(T)->getKind()) {
782 default: assert(0 && "getFloatingPointRank(): not a floating type");
783 case BuiltinType::Float: return FloatRank;
784 case BuiltinType::Double: return DoubleRank;
785 case BuiltinType::LongDouble: return LongDoubleRank;
786 }
787}
788
Steve Naroff716c7302007-08-27 01:41:48 +0000789/// getFloatingTypeOfSizeWithinDomain - Returns a real floating
790/// point or a complex type (based on typeDomain/typeSize).
791/// 'typeDomain' is a real floating point or complex type.
792/// 'typeSize' is a real floating point or complex type.
Steve Narofff1448a02007-08-27 01:27:54 +0000793QualType ASTContext::getFloatingTypeOfSizeWithinDomain(
794 QualType typeSize, QualType typeDomain) const {
795 if (typeDomain->isComplexType()) {
796 switch (getFloatingRank(typeSize)) {
Steve Naroff716c7302007-08-27 01:41:48 +0000797 default: assert(0 && "getFloatingRank(): illegal value for rank");
Steve Narofff1448a02007-08-27 01:27:54 +0000798 case FloatRank: return FloatComplexTy;
799 case DoubleRank: return DoubleComplexTy;
800 case LongDoubleRank: return LongDoubleComplexTy;
801 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000802 }
Steve Narofff1448a02007-08-27 01:27:54 +0000803 if (typeDomain->isRealFloatingType()) {
804 switch (getFloatingRank(typeSize)) {
Steve Naroff716c7302007-08-27 01:41:48 +0000805 default: assert(0 && "getFloatingRank(): illegal value for rank");
Steve Narofff1448a02007-08-27 01:27:54 +0000806 case FloatRank: return FloatTy;
807 case DoubleRank: return DoubleTy;
808 case LongDoubleRank: return LongDoubleTy;
809 }
810 }
811 assert(0 && "getFloatingTypeOfSizeWithinDomain(): illegal domain");
Chris Lattnerb1776cb2007-09-16 19:23:47 +0000812 //an invalid return value, but the assert
813 //will ensure that this code is never reached.
814 return VoidTy;
Reid Spencer5f016e22007-07-11 17:01:13 +0000815}
816
Steve Narofffb0d4962007-08-27 15:30:22 +0000817/// compareFloatingType - Handles 3 different combos:
818/// float/float, float/complex, complex/complex.
819/// If lt > rt, return 1. If lt == rt, return 0. If lt < rt, return -1.
820int ASTContext::compareFloatingType(QualType lt, QualType rt) {
821 if (getFloatingRank(lt) == getFloatingRank(rt))
822 return 0;
823 if (getFloatingRank(lt) > getFloatingRank(rt))
824 return 1;
825 return -1;
Reid Spencer5f016e22007-07-11 17:01:13 +0000826}
827
828// maxIntegerType - Returns the highest ranked integer type. Handles 3 case:
829// unsigned/unsigned, signed/signed, signed/unsigned. C99 6.3.1.8p1.
830QualType ASTContext::maxIntegerType(QualType lhs, QualType rhs) {
831 if (lhs == rhs) return lhs;
832
833 bool t1Unsigned = lhs->isUnsignedIntegerType();
834 bool t2Unsigned = rhs->isUnsignedIntegerType();
835
836 if ((t1Unsigned && t2Unsigned) || (!t1Unsigned && !t2Unsigned))
837 return getIntegerRank(lhs) >= getIntegerRank(rhs) ? lhs : rhs;
838
839 // We have two integer types with differing signs
840 QualType unsignedType = t1Unsigned ? lhs : rhs;
841 QualType signedType = t1Unsigned ? rhs : lhs;
842
843 if (getIntegerRank(unsignedType) >= getIntegerRank(signedType))
844 return unsignedType;
845 else {
846 // FIXME: Need to check if the signed type can represent all values of the
847 // unsigned type. If it can, then the result is the signed type.
848 // If it can't, then the result is the unsigned version of the signed type.
849 // Should probably add a helper that returns a signed integer type from
850 // an unsigned (and vice versa). C99 6.3.1.8.
851 return signedType;
852 }
853}
Anders Carlsson71993dd2007-08-17 05:31:46 +0000854
855// getCFConstantStringType - Return the type used for constant CFStrings.
856QualType ASTContext::getCFConstantStringType() {
857 if (!CFConstantStringTypeDecl) {
858 CFConstantStringTypeDecl = new RecordDecl(Decl::Struct, SourceLocation(),
859 &Idents.get("__builtin_CFString"),
860 0);
861
862 QualType FieldTypes[4];
863
864 // const int *isa;
865 FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));
866 // int flags;
867 FieldTypes[1] = IntTy;
868 // const char *str;
869 FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));
870 // long length;
871 FieldTypes[3] = LongTy;
872 // Create fields
873 FieldDecl *FieldDecls[4];
874
875 for (unsigned i = 0; i < 4; ++i)
Steve Narofff38661e2007-09-14 02:20:46 +0000876 FieldDecls[i] = new FieldDecl(SourceLocation(), 0, FieldTypes[i]);
Anders Carlsson71993dd2007-08-17 05:31:46 +0000877
878 CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
879 }
880
881 return getTagDeclType(CFConstantStringTypeDecl);
Gabor Greif84675832007-09-11 15:32:40 +0000882}
Anders Carlssonb2cf3572007-10-11 01:00:40 +0000883
Anders Carlssone8c49532007-10-29 06:33:42 +0000884// This returns true if a type has been typedefed to BOOL:
885// typedef <type> BOOL;
Chris Lattner2d998332007-10-30 20:27:44 +0000886static bool isTypeTypedefedAsBOOL(QualType T) {
Anders Carlssone8c49532007-10-29 06:33:42 +0000887 if (const TypedefType *TT = dyn_cast<TypedefType>(T))
Chris Lattner2d998332007-10-30 20:27:44 +0000888 return !strcmp(TT->getDecl()->getName(), "BOOL");
Anders Carlsson85f9bce2007-10-29 05:01:08 +0000889
890 return false;
891}
892
Fariborz Jahanian33e1d642007-10-29 22:57:28 +0000893/// getObjcEncodingTypeSize returns size of type for objective-c encoding
894/// purpose.
895int ASTContext::getObjcEncodingTypeSize(QualType type) {
896 SourceLocation Loc;
897 uint64_t sz = getTypeSize(type, Loc);
898
899 // Make all integer and enum types at least as large as an int
900 if (sz > 0 && type->isIntegralType())
901 sz = std::max(sz, getTypeSize(IntTy, Loc));
902 // Treat arrays as pointers, since that's how they're passed in.
903 else if (type->isArrayType())
904 sz = getTypeSize(VoidPtrTy, Loc);
905 return sz / getTypeSize(CharTy, Loc);
906}
907
908/// getObjcEncodingForMethodDecl - Return the encoded type for this method
909/// declaration.
910void ASTContext::getObjcEncodingForMethodDecl(ObjcMethodDecl *Decl,
911 std::string& S)
912{
913 // TODO: First encode type qualifer, 'in', 'inout', etc. for the return type.
914 // Encode result type.
915 getObjcEncodingForType(Decl->getResultType(), S);
916 // Compute size of all parameters.
917 // Start with computing size of a pointer in number of bytes.
918 // FIXME: There might(should) be a better way of doing this computation!
919 SourceLocation Loc;
920 int PtrSize = getTypeSize(VoidPtrTy, Loc) / getTypeSize(CharTy, Loc);
921 // The first two arguments (self and _cmd) are pointers; account for
922 // their size.
923 int ParmOffset = 2 * PtrSize;
924 int NumOfParams = Decl->getNumParams();
925 for (int i = 0; i < NumOfParams; i++) {
926 QualType PType = Decl->getParamDecl(i)->getType();
927 int sz = getObjcEncodingTypeSize (PType);
928 assert (sz > 0 && "getObjcEncodingForMethodDecl - Incomplete param type");
929 ParmOffset += sz;
930 }
931 S += llvm::utostr(ParmOffset);
932 S += "@0:";
933 S += llvm::utostr(PtrSize);
934
935 // Argument types.
936 ParmOffset = 2 * PtrSize;
937 for (int i = 0; i < NumOfParams; i++) {
938 QualType PType = Decl->getParamDecl(i)->getType();
939 // TODO: Process argument qualifiers for user supplied arguments; such as,
940 // 'in', 'inout', etc.
941 getObjcEncodingForType(PType, S);
942 S += llvm::utostr(ParmOffset);
943 ParmOffset += getObjcEncodingTypeSize(PType);
944 }
945}
946
Anders Carlsson85f9bce2007-10-29 05:01:08 +0000947void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
948{
Anders Carlssone8c49532007-10-29 06:33:42 +0000949 // FIXME: This currently doesn't encode:
950 // @ An object (whether statically typed or typed id)
951 // # A class object (Class)
952 // : A method selector (SEL)
953 // {name=type...} A structure
954 // (name=type...) A union
955 // bnum A bit field of num bits
956
957 if (const BuiltinType *BT = T->getAsBuiltinType()) {
Anders Carlsson85f9bce2007-10-29 05:01:08 +0000958 char encoding;
959 switch (BT->getKind()) {
960 case BuiltinType::Void:
961 encoding = 'v';
962 break;
963 case BuiltinType::Bool:
964 encoding = 'B';
965 break;
966 case BuiltinType::Char_U:
967 case BuiltinType::UChar:
968 encoding = 'C';
969 break;
970 case BuiltinType::UShort:
971 encoding = 'S';
972 break;
973 case BuiltinType::UInt:
974 encoding = 'I';
975 break;
976 case BuiltinType::ULong:
977 encoding = 'L';
978 break;
979 case BuiltinType::ULongLong:
980 encoding = 'Q';
981 break;
982 case BuiltinType::Char_S:
983 case BuiltinType::SChar:
984 encoding = 'c';
985 break;
986 case BuiltinType::Short:
987 encoding = 's';
988 break;
989 case BuiltinType::Int:
990 encoding = 'i';
991 break;
992 case BuiltinType::Long:
993 encoding = 'l';
994 break;
995 case BuiltinType::LongLong:
996 encoding = 'q';
997 break;
998 case BuiltinType::Float:
999 encoding = 'f';
1000 break;
1001 case BuiltinType::Double:
1002 encoding = 'd';
1003 break;
1004 case BuiltinType::LongDouble:
1005 encoding = 'd';
1006 break;
1007 default:
1008 assert(0 && "Unhandled builtin type kind");
1009 }
1010
1011 S += encoding;
Anders Carlssone8c49532007-10-29 06:33:42 +00001012 } else if (const PointerType *PT = T->getAsPointerType()) {
Anders Carlsson85f9bce2007-10-29 05:01:08 +00001013 QualType PointeeTy = PT->getPointeeType();
Anders Carlsson8baaca52007-10-31 02:53:19 +00001014 if (isObjcIdType(PointeeTy) || PointeeTy->isObjcInterfaceType()) {
Fariborz Jahanianc2939bc2007-10-30 17:06:23 +00001015 S += '@';
1016 return;
Anders Carlsson8baaca52007-10-31 02:53:19 +00001017 } else if (isObjcClassType(PointeeTy)) {
1018 S += '#';
1019 return;
1020 } else if (isObjcSelType(PointeeTy)) {
1021 S += ':';
1022 return;
Fariborz Jahanianc2939bc2007-10-30 17:06:23 +00001023 }
Anders Carlsson85f9bce2007-10-29 05:01:08 +00001024
1025 if (PointeeTy->isCharType()) {
1026 // char pointer types should be encoded as '*' unless it is a
1027 // type that has been typedef'd to 'BOOL'.
Anders Carlssone8c49532007-10-29 06:33:42 +00001028 if (!isTypeTypedefedAsBOOL(PointeeTy)) {
Anders Carlsson85f9bce2007-10-29 05:01:08 +00001029 S += '*';
1030 return;
1031 }
1032 }
1033
1034 S += '^';
1035 getObjcEncodingForType(PT->getPointeeType(), S);
Anders Carlssone8c49532007-10-29 06:33:42 +00001036 } else if (const ArrayType *AT = T->getAsArrayType()) {
Anders Carlsson85f9bce2007-10-29 05:01:08 +00001037 S += '[';
1038
1039 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
1040 S += llvm::utostr(CAT->getSize().getZExtValue());
1041 else
1042 assert(0 && "Unhandled array type!");
1043
1044 getObjcEncodingForType(AT->getElementType(), S);
1045 S += ']';
Anders Carlssonc0a87b72007-10-30 00:06:20 +00001046 } else if (T->getAsFunctionType()) {
1047 S += '?';
Anders Carlsson85f9bce2007-10-29 05:01:08 +00001048 } else
Anders Carlssone8c49532007-10-29 06:33:42 +00001049 assert(0 && "@encode for type not implemented!");
Anders Carlsson85f9bce2007-10-29 05:01:08 +00001050}
1051
Anders Carlssonb2cf3572007-10-11 01:00:40 +00001052void ASTContext::setBuiltinVaListType(QualType T)
1053{
1054 assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");
1055
1056 BuiltinVaListType = T;
1057}
1058
Steve Naroff7e219e42007-10-15 14:41:52 +00001059void ASTContext::setObjcIdType(TypedefDecl *TD)
1060{
1061 assert(ObjcIdType.isNull() && "'id' type already set!");
1062
1063 ObjcIdType = getTypedefType(TD);
1064
1065 // typedef struct objc_object *id;
1066 const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1067 assert(ptr && "'id' incorrectly typed");
1068 const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1069 assert(rec && "'id' incorrectly typed");
1070 IdStructType = rec;
1071}
1072
Fariborz Jahanianb62f6812007-10-16 20:40:23 +00001073void ASTContext::setObjcSelType(TypedefDecl *TD)
1074{
1075 assert(ObjcSelType.isNull() && "'SEL' type already set!");
1076
1077 ObjcSelType = getTypedefType(TD);
1078
1079 // typedef struct objc_selector *SEL;
1080 const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1081 assert(ptr && "'SEL' incorrectly typed");
1082 const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1083 assert(rec && "'SEL' incorrectly typed");
1084 SelStructType = rec;
1085}
1086
Fariborz Jahanian390d50a2007-10-17 16:58:11 +00001087void ASTContext::setObjcProtoType(TypedefDecl *TD)
1088{
1089 assert(ObjcProtoType.isNull() && "'Protocol' type already set!");
1090
1091 // typedef struct Protocol Protocol;
1092 ObjcProtoType = TD->getUnderlyingType();
1093 // Protocol * type
1094 ObjcProtoType = getPointerType(ObjcProtoType);
1095 ProtoStructType = TD->getUnderlyingType()->getAsStructureType();
1096}
1097
Anders Carlsson8baaca52007-10-31 02:53:19 +00001098void ASTContext::setObjcClassType(TypedefDecl *TD)
1099{
1100 assert(ObjcClassType.isNull() && "'Class' type already set!");
1101
1102 ObjcClassType = getTypedefType(TD);
1103
1104 // typedef struct objc_class *Class;
1105 const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1106 assert(ptr && "'Class' incorrectly typed");
1107 const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1108 assert(rec && "'Class' incorrectly typed");
1109 ClassStructType = rec;
1110}
1111
Steve Naroff21988912007-10-15 23:35:17 +00001112void ASTContext::setObjcConstantStringInterface(ObjcInterfaceDecl *Decl) {
1113 assert(ObjcConstantStringType.isNull() &&
1114 "'NSConstantString' type already set!");
1115
1116 ObjcConstantStringType = getObjcInterfaceType(Decl);
1117}
1118
Steve Naroffec0550f2007-10-15 20:41:53 +00001119bool ASTContext::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
1120 const BuiltinType *lBuiltin = lhs->getAsBuiltinType();
1121 const BuiltinType *rBuiltin = rhs->getAsBuiltinType();
1122
1123 return lBuiltin->getKind() == rBuiltin->getKind();
1124}
1125
1126
1127bool ASTContext::objcTypesAreCompatible(QualType lhs, QualType rhs) {
1128 if (lhs->isObjcInterfaceType() && isObjcIdType(rhs))
1129 return true;
1130 else if (isObjcIdType(lhs) && rhs->isObjcInterfaceType())
1131 return true;
1132 return false;
1133}
1134
1135bool ASTContext::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
1136 return true; // FIXME: IMPLEMENT.
1137}
1138
1139// C99 6.2.7p1: If both are complete types, then the following additional
1140// requirements apply...FIXME (handle compatibility across source files).
1141bool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) {
1142 TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
1143 TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
1144
1145 if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
1146 if (ldecl->getIdentifier() == rdecl->getIdentifier())
1147 return true;
1148 }
1149 if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
1150 if (ldecl->getIdentifier() == rdecl->getIdentifier())
1151 return true;
1152 }
1153 return false;
1154}
1155
1156bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
1157 // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
1158 // identically qualified and both shall be pointers to compatible types.
1159 if (lhs.getQualifiers() != rhs.getQualifiers())
1160 return false;
1161
1162 QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
1163 QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
1164
1165 return typesAreCompatible(ltype, rtype);
1166}
1167
1168// C++ 5.17p6: When the left opperand of an assignment operator denotes a
1169// reference to T, the operation assigns to the object of type T denoted by the
1170// reference.
1171bool ASTContext::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
1172 QualType ltype = lhs;
1173
1174 if (lhs->isReferenceType())
1175 ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
1176
1177 QualType rtype = rhs;
1178
1179 if (rhs->isReferenceType())
1180 rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
1181
1182 return typesAreCompatible(ltype, rtype);
1183}
1184
1185bool ASTContext::functionTypesAreCompatible(QualType lhs, QualType rhs) {
1186 const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
1187 const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
1188 const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
1189 const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
1190
1191 // first check the return types (common between C99 and K&R).
1192 if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
1193 return false;
1194
1195 if (lproto && rproto) { // two C99 style function prototypes
1196 unsigned lproto_nargs = lproto->getNumArgs();
1197 unsigned rproto_nargs = rproto->getNumArgs();
1198
1199 if (lproto_nargs != rproto_nargs)
1200 return false;
1201
1202 // both prototypes have the same number of arguments.
1203 if ((lproto->isVariadic() && !rproto->isVariadic()) ||
1204 (rproto->isVariadic() && !lproto->isVariadic()))
1205 return false;
1206
1207 // The use of ellipsis agree...now check the argument types.
1208 for (unsigned i = 0; i < lproto_nargs; i++)
1209 if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
1210 return false;
1211 return true;
1212 }
1213 if (!lproto && !rproto) // two K&R style function decls, nothing to do.
1214 return true;
1215
1216 // we have a mixture of K&R style with C99 prototypes
1217 const FunctionTypeProto *proto = lproto ? lproto : rproto;
1218
1219 if (proto->isVariadic())
1220 return false;
1221
1222 // FIXME: Each parameter type T in the prototype must be compatible with the
1223 // type resulting from applying the usual argument conversions to T.
1224 return true;
1225}
1226
1227bool ASTContext::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
1228 QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
1229 QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
1230
1231 if (!typesAreCompatible(ltype, rtype))
1232 return false;
1233
1234 // FIXME: If both types specify constant sizes, then the sizes must also be
1235 // the same. Even if the sizes are the same, GCC produces an error.
1236 return true;
1237}
1238
1239/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
1240/// both shall have the identically qualified version of a compatible type.
1241/// C99 6.2.7p1: Two types have compatible types if their types are the
1242/// same. See 6.7.[2,3,5] for additional rules.
1243bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
1244 QualType lcanon = lhs.getCanonicalType();
1245 QualType rcanon = rhs.getCanonicalType();
1246
1247 // If two types are identical, they are are compatible
1248 if (lcanon == rcanon)
1249 return true;
1250
1251 // If the canonical type classes don't match, they can't be compatible
1252 if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
1253 // For Objective-C, it is possible for two types to be compatible
1254 // when their classes don't match (when dealing with "id"). If either type
1255 // is an interface, we defer to objcTypesAreCompatible().
1256 if (lcanon->isObjcInterfaceType() || rcanon->isObjcInterfaceType())
1257 return objcTypesAreCompatible(lcanon, rcanon);
1258 return false;
1259 }
1260 switch (lcanon->getTypeClass()) {
1261 case Type::Pointer:
1262 return pointerTypesAreCompatible(lcanon, rcanon);
1263 case Type::Reference:
1264 return referenceTypesAreCompatible(lcanon, rcanon);
1265 case Type::ConstantArray:
1266 case Type::VariableArray:
1267 return arrayTypesAreCompatible(lcanon, rcanon);
1268 case Type::FunctionNoProto:
1269 case Type::FunctionProto:
1270 return functionTypesAreCompatible(lcanon, rcanon);
1271 case Type::Tagged: // handle structures, unions
1272 return tagTypesAreCompatible(lcanon, rcanon);
1273 case Type::Builtin:
1274 return builtinTypesAreCompatible(lcanon, rcanon);
1275 case Type::ObjcInterface:
1276 return interfaceTypesAreCompatible(lcanon, rcanon);
1277 default:
1278 assert(0 && "unexpected type");
1279 }
1280 return true; // should never get here...
1281}