blob: 92b691ee9017a69eb89852c79a6310d3c0ddf141 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +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 Naroff3fafa102007-10-01 19:00:59 +000016#include "clang/AST/DeclObjC.h"
Chris Lattner4b009652007-07-25 00:24:17 +000017#include "clang/Basic/TargetInfo.h"
18#include "llvm/ADT/SmallVector.h"
Anders Carlsson36f07d82007-10-29 05:01:08 +000019#include "llvm/ADT/StringExtras.h"
Ted Kremenek738e6c02007-10-31 17:10:13 +000020#include "llvm/Bitcode/Serialize.h"
21#include "llvm/Bitcode/Deserialize.h"
Anders Carlsson36f07d82007-10-29 05:01:08 +000022
Chris Lattner4b009652007-07-25 00:24:17 +000023using namespace clang;
24
25enum FloatingRank {
26 FloatRank, DoubleRank, LongDoubleRank
27};
28
29ASTContext::~ASTContext() {
30 // Deallocate all the types.
31 while (!Types.empty()) {
32 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(Types.back())) {
33 // Destroy the object, but don't call delete. These are malloc'd.
34 FT->~FunctionTypeProto();
35 free(FT);
36 } else {
37 delete Types.back();
38 }
39 Types.pop_back();
40 }
41}
42
43void ASTContext::PrintStats() const {
44 fprintf(stderr, "*** AST Context Stats:\n");
45 fprintf(stderr, " %d types total.\n", (int)Types.size());
46 unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
47 unsigned NumVector = 0, NumComplex = 0;
48 unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
49
50 unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
Chris Lattner8a35b462007-12-12 06:43:05 +000051 unsigned NumObjcInterfaces = 0, NumObjcQualifiedInterfaces = 0;
Fariborz Jahaniane76e8412007-12-17 21:03:50 +000052 unsigned NumObjcQualifiedIds = 0;
Chris Lattner4b009652007-07-25 00:24:17 +000053
54 for (unsigned i = 0, e = Types.size(); i != e; ++i) {
55 Type *T = Types[i];
56 if (isa<BuiltinType>(T))
57 ++NumBuiltin;
58 else if (isa<PointerType>(T))
59 ++NumPointer;
60 else if (isa<ReferenceType>(T))
61 ++NumReference;
62 else if (isa<ComplexType>(T))
63 ++NumComplex;
64 else if (isa<ArrayType>(T))
65 ++NumArray;
66 else if (isa<VectorType>(T))
67 ++NumVector;
68 else if (isa<FunctionTypeNoProto>(T))
69 ++NumFunctionNP;
70 else if (isa<FunctionTypeProto>(T))
71 ++NumFunctionP;
72 else if (isa<TypedefType>(T))
73 ++NumTypeName;
74 else if (TagType *TT = dyn_cast<TagType>(T)) {
75 ++NumTagged;
76 switch (TT->getDecl()->getKind()) {
77 default: assert(0 && "Unknown tagged type!");
78 case Decl::Struct: ++NumTagStruct; break;
79 case Decl::Union: ++NumTagUnion; break;
80 case Decl::Class: ++NumTagClass; break;
81 case Decl::Enum: ++NumTagEnum; break;
82 }
Steve Naroff948fd372007-09-17 14:16:13 +000083 } else if (isa<ObjcInterfaceType>(T))
84 ++NumObjcInterfaces;
Chris Lattner8a35b462007-12-12 06:43:05 +000085 else if (isa<ObjcQualifiedInterfaceType>(T))
86 ++NumObjcQualifiedInterfaces;
Fariborz Jahaniane76e8412007-12-17 21:03:50 +000087 else if (isa<ObjcQualifiedIdType>(T))
88 ++NumObjcQualifiedIds;
Steve Naroff948fd372007-09-17 14:16:13 +000089 else {
Chris Lattner8a35b462007-12-12 06:43:05 +000090 QualType(T, 0).dump();
Chris Lattner4b009652007-07-25 00:24:17 +000091 assert(0 && "Unknown type!");
92 }
93 }
94
95 fprintf(stderr, " %d builtin types\n", NumBuiltin);
96 fprintf(stderr, " %d pointer types\n", NumPointer);
97 fprintf(stderr, " %d reference types\n", NumReference);
98 fprintf(stderr, " %d complex types\n", NumComplex);
99 fprintf(stderr, " %d array types\n", NumArray);
100 fprintf(stderr, " %d vector types\n", NumVector);
101 fprintf(stderr, " %d function types with proto\n", NumFunctionP);
102 fprintf(stderr, " %d function types with no proto\n", NumFunctionNP);
103 fprintf(stderr, " %d typename (typedef) types\n", NumTypeName);
104 fprintf(stderr, " %d tagged types\n", NumTagged);
105 fprintf(stderr, " %d struct types\n", NumTagStruct);
106 fprintf(stderr, " %d union types\n", NumTagUnion);
107 fprintf(stderr, " %d class types\n", NumTagClass);
108 fprintf(stderr, " %d enum types\n", NumTagEnum);
Steve Naroff948fd372007-09-17 14:16:13 +0000109 fprintf(stderr, " %d interface types\n", NumObjcInterfaces);
Chris Lattner8a35b462007-12-12 06:43:05 +0000110 fprintf(stderr, " %d protocol qualified interface types\n",
111 NumObjcQualifiedInterfaces);
Fariborz Jahaniane76e8412007-12-17 21:03:50 +0000112 fprintf(stderr, " %d protocol qualified id types\n",
113 NumObjcQualifiedIds);
Chris Lattner4b009652007-07-25 00:24:17 +0000114 fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
115 NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
116 NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
117 NumFunctionP*sizeof(FunctionTypeProto)+
118 NumFunctionNP*sizeof(FunctionTypeNoProto)+
119 NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)));
120}
121
122
123void ASTContext::InitBuiltinType(QualType &R, BuiltinType::Kind K) {
124 Types.push_back((R = QualType(new BuiltinType(K),0)).getTypePtr());
125}
126
Chris Lattner4b009652007-07-25 00:24:17 +0000127void ASTContext::InitBuiltinTypes() {
128 assert(VoidTy.isNull() && "Context reinitialized?");
129
130 // C99 6.2.5p19.
131 InitBuiltinType(VoidTy, BuiltinType::Void);
132
133 // C99 6.2.5p2.
134 InitBuiltinType(BoolTy, BuiltinType::Bool);
135 // C99 6.2.5p3.
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000136 if (Target.isCharSigned(FullSourceLoc()))
Chris Lattner4b009652007-07-25 00:24:17 +0000137 InitBuiltinType(CharTy, BuiltinType::Char_S);
138 else
139 InitBuiltinType(CharTy, BuiltinType::Char_U);
140 // C99 6.2.5p4.
141 InitBuiltinType(SignedCharTy, BuiltinType::SChar);
142 InitBuiltinType(ShortTy, BuiltinType::Short);
143 InitBuiltinType(IntTy, BuiltinType::Int);
144 InitBuiltinType(LongTy, BuiltinType::Long);
145 InitBuiltinType(LongLongTy, BuiltinType::LongLong);
146
147 // C99 6.2.5p6.
148 InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
149 InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
150 InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
151 InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
152 InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
153
154 // C99 6.2.5p10.
155 InitBuiltinType(FloatTy, BuiltinType::Float);
156 InitBuiltinType(DoubleTy, BuiltinType::Double);
157 InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
158
159 // C99 6.2.5p11.
160 FloatComplexTy = getComplexType(FloatTy);
161 DoubleComplexTy = getComplexType(DoubleTy);
162 LongDoubleComplexTy = getComplexType(LongDoubleTy);
Steve Naroff9d12c902007-10-15 14:41:52 +0000163
164 BuiltinVaListType = QualType();
165 ObjcIdType = QualType();
166 IdStructType = 0;
Anders Carlsson7f23e3d2007-10-31 02:53:19 +0000167 ObjcClassType = QualType();
168 ClassStructType = 0;
169
Steve Narofff2e30312007-10-15 23:35:17 +0000170 ObjcConstantStringType = QualType();
Fariborz Jahanianc81f3162007-10-29 22:57:28 +0000171
172 // void * type
173 VoidPtrTy = getPointerType(VoidTy);
Chris Lattner4b009652007-07-25 00:24:17 +0000174}
175
176//===----------------------------------------------------------------------===//
177// Type Sizing and Analysis
178//===----------------------------------------------------------------------===//
179
180/// getTypeSize - Return the size of the specified type, in bits. This method
181/// does not work on incomplete types.
182std::pair<uint64_t, unsigned>
183ASTContext::getTypeInfo(QualType T, SourceLocation L) {
184 T = T.getCanonicalType();
185 uint64_t Size;
186 unsigned Align;
187 switch (T->getTypeClass()) {
188 case Type::TypeName: assert(0 && "Not a canonical type!");
189 case Type::FunctionNoProto:
190 case Type::FunctionProto:
191 default:
192 assert(0 && "Incomplete types have no size!");
Steve Naroff83c13012007-08-30 01:06:46 +0000193 case Type::VariableArray:
194 assert(0 && "VLAs not implemented yet!");
195 case Type::ConstantArray: {
196 ConstantArrayType *CAT = cast<ConstantArrayType>(T);
197
Chris Lattner4b009652007-07-25 00:24:17 +0000198 std::pair<uint64_t, unsigned> EltInfo =
Steve Naroff83c13012007-08-30 01:06:46 +0000199 getTypeInfo(CAT->getElementType(), L);
200 Size = EltInfo.first*CAT->getSize().getZExtValue();
Chris Lattner4b009652007-07-25 00:24:17 +0000201 Align = EltInfo.second;
202 break;
203 }
204 case Type::Vector: {
205 std::pair<uint64_t, unsigned> EltInfo =
206 getTypeInfo(cast<VectorType>(T)->getElementType(), L);
207 Size = EltInfo.first*cast<VectorType>(T)->getNumElements();
208 // FIXME: Vector alignment is not the alignment of its elements.
209 Align = EltInfo.second;
210 break;
211 }
212
213 case Type::Builtin: {
214 // FIXME: need to use TargetInfo to derive the target specific sizes. This
215 // implementation will suffice for play with vector support.
Chris Lattner858eece2007-09-22 18:29:59 +0000216 const llvm::fltSemantics *F;
Chris Lattner4b009652007-07-25 00:24:17 +0000217 switch (cast<BuiltinType>(T)->getKind()) {
218 default: assert(0 && "Unknown builtin type!");
219 case BuiltinType::Void:
220 assert(0 && "Incomplete types have no size!");
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000221 case BuiltinType::Bool: Target.getBoolInfo(Size,Align,getFullLoc(L));
222 break;
223
Chris Lattner4b009652007-07-25 00:24:17 +0000224 case BuiltinType::Char_S:
225 case BuiltinType::Char_U:
226 case BuiltinType::UChar:
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000227 case BuiltinType::SChar: Target.getCharInfo(Size,Align,getFullLoc(L));
228 break;
229
Chris Lattner4b009652007-07-25 00:24:17 +0000230 case BuiltinType::UShort:
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000231 case BuiltinType::Short: Target.getShortInfo(Size,Align,getFullLoc(L));
232 break;
233
Chris Lattner4b009652007-07-25 00:24:17 +0000234 case BuiltinType::UInt:
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000235 case BuiltinType::Int: Target.getIntInfo(Size,Align,getFullLoc(L));
236 break;
237
Chris Lattner4b009652007-07-25 00:24:17 +0000238 case BuiltinType::ULong:
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000239 case BuiltinType::Long: Target.getLongInfo(Size,Align,getFullLoc(L));
240 break;
241
Chris Lattner4b009652007-07-25 00:24:17 +0000242 case BuiltinType::ULongLong:
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000243 case BuiltinType::LongLong: Target.getLongLongInfo(Size,Align,
244 getFullLoc(L));
245 break;
246
247 case BuiltinType::Float: Target.getFloatInfo(Size,Align,F,
248 getFullLoc(L));
249 break;
250
251 case BuiltinType::Double: Target.getDoubleInfo(Size,Align,F,
252 getFullLoc(L));
253 break;
254
255 case BuiltinType::LongDouble: Target.getLongDoubleInfo(Size,Align,F,
256 getFullLoc(L));
257 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000258 }
259 break;
260 }
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000261 case Type::Pointer: Target.getPointerInfo(Size, Align, getFullLoc(L)); break;
Chris Lattner4b009652007-07-25 00:24:17 +0000262 case Type::Reference:
263 // "When applied to a reference or a reference type, the result is the size
264 // of the referenced type." C++98 5.3.3p2: expr.sizeof.
265 // FIXME: This is wrong for struct layout!
266 return getTypeInfo(cast<ReferenceType>(T)->getReferenceeType(), L);
267
268 case Type::Complex: {
269 // Complex types have the same alignment as their elements, but twice the
270 // size.
271 std::pair<uint64_t, unsigned> EltInfo =
272 getTypeInfo(cast<ComplexType>(T)->getElementType(), L);
273 Size = EltInfo.first*2;
274 Align = EltInfo.second;
275 break;
276 }
277 case Type::Tagged:
Chris Lattnereb56d292007-08-27 17:38:00 +0000278 TagType *TT = cast<TagType>(T);
279 if (RecordType *RT = dyn_cast<RecordType>(TT)) {
Devang Patel7a78e432007-11-01 19:11:01 +0000280 const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl(), L);
Chris Lattnereb56d292007-08-27 17:38:00 +0000281 Size = Layout.getSize();
282 Align = Layout.getAlignment();
283 } else if (EnumDecl *ED = dyn_cast<EnumDecl>(TT->getDecl())) {
Chris Lattner90a018d2007-08-28 18:24:31 +0000284 return getTypeInfo(ED->getIntegerType(), L);
Chris Lattnereb56d292007-08-27 17:38:00 +0000285 } else {
Chris Lattner4b009652007-07-25 00:24:17 +0000286 assert(0 && "Unimplemented type sizes!");
Chris Lattnereb56d292007-08-27 17:38:00 +0000287 }
Chris Lattner4b009652007-07-25 00:24:17 +0000288 break;
289 }
290
291 assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
292 return std::make_pair(Size, Align);
293}
294
Devang Patel7a78e432007-11-01 19:11:01 +0000295/// getASTRecordLayout - Get or compute information about the layout of the
Chris Lattner4b009652007-07-25 00:24:17 +0000296/// specified record (struct/union/class), which indicates its size and field
297/// position information.
Devang Patel7a78e432007-11-01 19:11:01 +0000298const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D,
299 SourceLocation L) {
Chris Lattner4b009652007-07-25 00:24:17 +0000300 assert(D->isDefinition() && "Cannot get layout of forward declarations!");
301
302 // Look up this layout, if already laid out, return what we have.
Devang Patel7a78e432007-11-01 19:11:01 +0000303 const ASTRecordLayout *&Entry = ASTRecordLayouts[D];
Chris Lattner4b009652007-07-25 00:24:17 +0000304 if (Entry) return *Entry;
305
Devang Patel7a78e432007-11-01 19:11:01 +0000306 // Allocate and assign into ASTRecordLayouts here. The "Entry" reference can
307 // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
308 ASTRecordLayout *NewEntry = new ASTRecordLayout();
Chris Lattner4b009652007-07-25 00:24:17 +0000309 Entry = NewEntry;
310
311 uint64_t *FieldOffsets = new uint64_t[D->getNumMembers()];
312 uint64_t RecordSize = 0;
313 unsigned RecordAlign = 8; // Default alignment = 1 byte = 8 bits.
314
315 if (D->getKind() != Decl::Union) {
316 // Layout each field, for now, just sequentially, respecting alignment. In
317 // the future, this will need to be tweakable by targets.
318 for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
319 const FieldDecl *FD = D->getMember(i);
320 std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
321 uint64_t FieldSize = FieldInfo.first;
322 unsigned FieldAlign = FieldInfo.second;
323
324 // Round up the current record size to the field's alignment boundary.
325 RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
326
327 // Place this field at the current location.
328 FieldOffsets[i] = RecordSize;
329
330 // Reserve space for this field.
331 RecordSize += FieldSize;
332
333 // Remember max struct/class alignment.
334 RecordAlign = std::max(RecordAlign, FieldAlign);
335 }
336
337 // Finally, round the size of the total struct up to the alignment of the
338 // struct itself.
339 RecordSize = (RecordSize+RecordAlign-1) & ~(RecordAlign-1);
340 } else {
341 // Union layout just puts each member at the start of the record.
342 for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
343 const FieldDecl *FD = D->getMember(i);
344 std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
345 uint64_t FieldSize = FieldInfo.first;
346 unsigned FieldAlign = FieldInfo.second;
347
348 // Round up the current record size to the field's alignment boundary.
349 RecordSize = std::max(RecordSize, FieldSize);
350
351 // Place this field at the start of the record.
352 FieldOffsets[i] = 0;
353
354 // Remember max struct/class alignment.
355 RecordAlign = std::max(RecordAlign, FieldAlign);
356 }
357 }
358
359 NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets);
360 return *NewEntry;
361}
362
Chris Lattner4b009652007-07-25 00:24:17 +0000363//===----------------------------------------------------------------------===//
364// Type creation/memoization methods
365//===----------------------------------------------------------------------===//
366
367
368/// getComplexType - Return the uniqued reference to the type for a complex
369/// number with the specified element type.
370QualType ASTContext::getComplexType(QualType T) {
371 // Unique pointers, to guarantee there is only one pointer of a particular
372 // structure.
373 llvm::FoldingSetNodeID ID;
374 ComplexType::Profile(ID, T);
375
376 void *InsertPos = 0;
377 if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
378 return QualType(CT, 0);
379
380 // If the pointee type isn't canonical, this won't be a canonical type either,
381 // so fill in the canonical type field.
382 QualType Canonical;
383 if (!T->isCanonical()) {
384 Canonical = getComplexType(T.getCanonicalType());
385
386 // Get the new insert position for the node we care about.
387 ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
388 assert(NewIP == 0 && "Shouldn't be in the map!");
389 }
390 ComplexType *New = new ComplexType(T, Canonical);
391 Types.push_back(New);
392 ComplexTypes.InsertNode(New, InsertPos);
393 return QualType(New, 0);
394}
395
396
397/// getPointerType - Return the uniqued reference to the type for a pointer to
398/// the specified type.
399QualType ASTContext::getPointerType(QualType T) {
400 // Unique pointers, to guarantee there is only one pointer of a particular
401 // structure.
402 llvm::FoldingSetNodeID ID;
403 PointerType::Profile(ID, T);
404
405 void *InsertPos = 0;
406 if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
407 return QualType(PT, 0);
408
409 // If the pointee type isn't canonical, this won't be a canonical type either,
410 // so fill in the canonical type field.
411 QualType Canonical;
412 if (!T->isCanonical()) {
413 Canonical = getPointerType(T.getCanonicalType());
414
415 // Get the new insert position for the node we care about.
416 PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
417 assert(NewIP == 0 && "Shouldn't be in the map!");
418 }
419 PointerType *New = new PointerType(T, Canonical);
420 Types.push_back(New);
421 PointerTypes.InsertNode(New, InsertPos);
422 return QualType(New, 0);
423}
424
425/// getReferenceType - Return the uniqued reference to the type for a reference
426/// to the specified type.
427QualType ASTContext::getReferenceType(QualType T) {
428 // Unique pointers, to guarantee there is only one pointer of a particular
429 // structure.
430 llvm::FoldingSetNodeID ID;
431 ReferenceType::Profile(ID, T);
432
433 void *InsertPos = 0;
434 if (ReferenceType *RT = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
435 return QualType(RT, 0);
436
437 // If the referencee type isn't canonical, this won't be a canonical type
438 // either, so fill in the canonical type field.
439 QualType Canonical;
440 if (!T->isCanonical()) {
441 Canonical = getReferenceType(T.getCanonicalType());
442
443 // Get the new insert position for the node we care about.
444 ReferenceType *NewIP = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
445 assert(NewIP == 0 && "Shouldn't be in the map!");
446 }
447
448 ReferenceType *New = new ReferenceType(T, Canonical);
449 Types.push_back(New);
450 ReferenceTypes.InsertNode(New, InsertPos);
451 return QualType(New, 0);
452}
453
Steve Naroff83c13012007-08-30 01:06:46 +0000454/// getConstantArrayType - Return the unique reference to the type for an
455/// array of the specified element type.
456QualType ASTContext::getConstantArrayType(QualType EltTy,
Steve Naroff24c9b982007-08-30 18:10:14 +0000457 const llvm::APInt &ArySize,
458 ArrayType::ArraySizeModifier ASM,
459 unsigned EltTypeQuals) {
Chris Lattner4b009652007-07-25 00:24:17 +0000460 llvm::FoldingSetNodeID ID;
Steve Naroff83c13012007-08-30 01:06:46 +0000461 ConstantArrayType::Profile(ID, EltTy, ArySize);
Chris Lattner4b009652007-07-25 00:24:17 +0000462
463 void *InsertPos = 0;
Ted Kremenek738e6c02007-10-31 17:10:13 +0000464 if (ConstantArrayType *ATP =
465 ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
Chris Lattner4b009652007-07-25 00:24:17 +0000466 return QualType(ATP, 0);
467
468 // If the element type isn't canonical, this won't be a canonical type either,
469 // so fill in the canonical type field.
470 QualType Canonical;
471 if (!EltTy->isCanonical()) {
Steve Naroff24c9b982007-08-30 18:10:14 +0000472 Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize,
473 ASM, EltTypeQuals);
Chris Lattner4b009652007-07-25 00:24:17 +0000474 // Get the new insert position for the node we care about.
Ted Kremenek738e6c02007-10-31 17:10:13 +0000475 ConstantArrayType *NewIP =
476 ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
477
Chris Lattner4b009652007-07-25 00:24:17 +0000478 assert(NewIP == 0 && "Shouldn't be in the map!");
479 }
480
Steve Naroff24c9b982007-08-30 18:10:14 +0000481 ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize,
482 ASM, EltTypeQuals);
Ted Kremenek738e6c02007-10-31 17:10:13 +0000483 ConstantArrayTypes.InsertNode(New, InsertPos);
Chris Lattner4b009652007-07-25 00:24:17 +0000484 Types.push_back(New);
485 return QualType(New, 0);
486}
487
Steve Naroffe2579e32007-08-30 18:14:25 +0000488/// getVariableArrayType - Returns a non-unique reference to the type for a
489/// variable array of the specified element type.
Steve Naroff24c9b982007-08-30 18:10:14 +0000490QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
491 ArrayType::ArraySizeModifier ASM,
492 unsigned EltTypeQuals) {
Ted Kremenek3793e1a2007-10-29 23:37:31 +0000493 if (NumElts) {
494 // Since we don't unique expressions, it isn't possible to unique VLA's
495 // that have an expression provided for their size.
496
Ted Kremenek2058dc42007-10-30 16:41:53 +0000497 VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
498 ASM, EltTypeQuals);
Ted Kremenek3793e1a2007-10-29 23:37:31 +0000499
Ted Kremenek2058dc42007-10-30 16:41:53 +0000500 CompleteVariableArrayTypes.push_back(New);
Ted Kremenek3793e1a2007-10-29 23:37:31 +0000501 Types.push_back(New);
502 return QualType(New, 0);
503 }
504 else {
505 // No size is provided for the VLA. These we can unique.
506 llvm::FoldingSetNodeID ID;
507 VariableArrayType::Profile(ID, EltTy);
508
509 void *InsertPos = 0;
510 if (VariableArrayType *ATP =
511 IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
512 return QualType(ATP, 0);
513
514 // If the element type isn't canonical, this won't be a canonical type
515 // either, so fill in the canonical type field.
516 QualType Canonical;
517
518 if (!EltTy->isCanonical()) {
519 Canonical = getVariableArrayType(EltTy.getCanonicalType(), NumElts,
520 ASM, EltTypeQuals);
521
522 // Get the new insert position for the node we care about.
523 VariableArrayType *NewIP =
524 IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
525
526 assert(NewIP == 0 && "Shouldn't be in the map!");
527 }
528
529 VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
530 ASM, EltTypeQuals);
531
532 IncompleteVariableArrayTypes.InsertNode(New, InsertPos);
533 Types.push_back(New);
534 return QualType(New, 0);
535 }
Steve Naroff83c13012007-08-30 01:06:46 +0000536}
537
Chris Lattner4b009652007-07-25 00:24:17 +0000538/// getVectorType - Return the unique reference to a vector type of
539/// the specified element type and size. VectorType must be a built-in type.
540QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
541 BuiltinType *baseType;
542
543 baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
544 assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
545
546 // Check if we've already instantiated a vector of this type.
547 llvm::FoldingSetNodeID ID;
548 VectorType::Profile(ID, vecType, NumElts, Type::Vector);
549 void *InsertPos = 0;
550 if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
551 return QualType(VTP, 0);
552
553 // If the element type isn't canonical, this won't be a canonical type either,
554 // so fill in the canonical type field.
555 QualType Canonical;
556 if (!vecType->isCanonical()) {
557 Canonical = getVectorType(vecType.getCanonicalType(), NumElts);
558
559 // Get the new insert position for the node we care about.
560 VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
561 assert(NewIP == 0 && "Shouldn't be in the map!");
562 }
563 VectorType *New = new VectorType(vecType, NumElts, Canonical);
564 VectorTypes.InsertNode(New, InsertPos);
565 Types.push_back(New);
566 return QualType(New, 0);
567}
568
569/// getOCUVectorType - Return the unique reference to an OCU vector type of
570/// the specified element type and size. VectorType must be a built-in type.
571QualType ASTContext::getOCUVectorType(QualType vecType, unsigned NumElts) {
572 BuiltinType *baseType;
573
574 baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
575 assert(baseType != 0 && "getOCUVectorType(): Expecting a built-in type");
576
577 // Check if we've already instantiated a vector of this type.
578 llvm::FoldingSetNodeID ID;
579 VectorType::Profile(ID, vecType, NumElts, Type::OCUVector);
580 void *InsertPos = 0;
581 if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
582 return QualType(VTP, 0);
583
584 // If the element type isn't canonical, this won't be a canonical type either,
585 // so fill in the canonical type field.
586 QualType Canonical;
587 if (!vecType->isCanonical()) {
588 Canonical = getOCUVectorType(vecType.getCanonicalType(), NumElts);
589
590 // Get the new insert position for the node we care about.
591 VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
592 assert(NewIP == 0 && "Shouldn't be in the map!");
593 }
594 OCUVectorType *New = new OCUVectorType(vecType, NumElts, Canonical);
595 VectorTypes.InsertNode(New, InsertPos);
596 Types.push_back(New);
597 return QualType(New, 0);
598}
599
600/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
601///
602QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {
603 // Unique functions, to guarantee there is only one function of a particular
604 // structure.
605 llvm::FoldingSetNodeID ID;
606 FunctionTypeNoProto::Profile(ID, ResultTy);
607
608 void *InsertPos = 0;
609 if (FunctionTypeNoProto *FT =
610 FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos))
611 return QualType(FT, 0);
612
613 QualType Canonical;
614 if (!ResultTy->isCanonical()) {
615 Canonical = getFunctionTypeNoProto(ResultTy.getCanonicalType());
616
617 // Get the new insert position for the node we care about.
618 FunctionTypeNoProto *NewIP =
619 FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos);
620 assert(NewIP == 0 && "Shouldn't be in the map!");
621 }
622
623 FunctionTypeNoProto *New = new FunctionTypeNoProto(ResultTy, Canonical);
624 Types.push_back(New);
625 FunctionTypeProtos.InsertNode(New, InsertPos);
626 return QualType(New, 0);
627}
628
629/// getFunctionType - Return a normal function type with a typed argument
630/// list. isVariadic indicates whether the argument list includes '...'.
631QualType ASTContext::getFunctionType(QualType ResultTy, QualType *ArgArray,
632 unsigned NumArgs, bool isVariadic) {
633 // Unique functions, to guarantee there is only one function of a particular
634 // structure.
635 llvm::FoldingSetNodeID ID;
636 FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
637
638 void *InsertPos = 0;
639 if (FunctionTypeProto *FTP =
640 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
641 return QualType(FTP, 0);
642
643 // Determine whether the type being created is already canonical or not.
644 bool isCanonical = ResultTy->isCanonical();
645 for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
646 if (!ArgArray[i]->isCanonical())
647 isCanonical = false;
648
649 // If this type isn't canonical, get the canonical version of it.
650 QualType Canonical;
651 if (!isCanonical) {
652 llvm::SmallVector<QualType, 16> CanonicalArgs;
653 CanonicalArgs.reserve(NumArgs);
654 for (unsigned i = 0; i != NumArgs; ++i)
655 CanonicalArgs.push_back(ArgArray[i].getCanonicalType());
656
657 Canonical = getFunctionType(ResultTy.getCanonicalType(),
658 &CanonicalArgs[0], NumArgs,
659 isVariadic);
660
661 // Get the new insert position for the node we care about.
662 FunctionTypeProto *NewIP =
663 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
664 assert(NewIP == 0 && "Shouldn't be in the map!");
665 }
666
667 // FunctionTypeProto objects are not allocated with new because they have a
668 // variable size array (for parameter types) at the end of them.
669 FunctionTypeProto *FTP =
670 (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
671 NumArgs*sizeof(QualType));
672 new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
673 Canonical);
674 Types.push_back(FTP);
675 FunctionTypeProtos.InsertNode(FTP, InsertPos);
676 return QualType(FTP, 0);
677}
678
679/// getTypedefType - Return the unique reference to the type for the
680/// specified typename decl.
681QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
682 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
683
684 QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
Fariborz Jahaniane76e8412007-12-17 21:03:50 +0000685 Decl->TypeForDecl = new TypedefType(Type::TypeName, Decl, Canonical);
Chris Lattner4b009652007-07-25 00:24:17 +0000686 Types.push_back(Decl->TypeForDecl);
687 return QualType(Decl->TypeForDecl, 0);
688}
689
Steve Naroff81f1bba2007-09-06 21:24:23 +0000690/// getObjcInterfaceType - Return the unique reference to the type for the
691/// specified ObjC interface decl.
692QualType ASTContext::getObjcInterfaceType(ObjcInterfaceDecl *Decl) {
693 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
694
Fariborz Jahanian0c2f2142007-12-13 20:47:42 +0000695 Decl->TypeForDecl = new ObjcInterfaceType(Type::ObjcInterface, Decl);
Steve Naroff81f1bba2007-09-06 21:24:23 +0000696 Types.push_back(Decl->TypeForDecl);
697 return QualType(Decl->TypeForDecl, 0);
698}
699
Fariborz Jahanian91193f62007-10-11 00:55:41 +0000700/// getObjcQualifiedInterfaceType - Return a
701/// ObjcQualifiedInterfaceType type for the given interface decl and
702/// the conforming protocol list.
703QualType ASTContext::getObjcQualifiedInterfaceType(ObjcInterfaceDecl *Decl,
704 ObjcProtocolDecl **Protocols, unsigned NumProtocols) {
Fariborz Jahanian91193f62007-10-11 00:55:41 +0000705 llvm::FoldingSetNodeID ID;
Fariborz Jahanian0c2f2142007-12-13 20:47:42 +0000706 ObjcQualifiedInterfaceType::Profile(ID, Protocols, NumProtocols);
Fariborz Jahanian91193f62007-10-11 00:55:41 +0000707
708 void *InsertPos = 0;
709 if (ObjcQualifiedInterfaceType *QT =
710 ObjcQualifiedInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
711 return QualType(QT, 0);
712
713 // No Match;
Chris Lattnerd855a6e2007-10-11 03:36:41 +0000714 ObjcQualifiedInterfaceType *QType =
Fariborz Jahanian0c2f2142007-12-13 20:47:42 +0000715 new ObjcQualifiedInterfaceType(Decl, Protocols, NumProtocols);
Fariborz Jahanian91193f62007-10-11 00:55:41 +0000716 Types.push_back(QType);
717 ObjcQualifiedInterfaceTypes.InsertNode(QType, InsertPos);
718 return QualType(QType, 0);
719}
720
Fariborz Jahaniane76e8412007-12-17 21:03:50 +0000721/// getObjcQualifiedIdType - Return a
722/// getObjcQualifiedIdType type for the given interface decl and
723/// the conforming protocol list.
724QualType ASTContext::getObjcQualifiedIdType(TypedefDecl *Decl,
725 ObjcProtocolDecl **Protocols,
726 unsigned NumProtocols) {
727 llvm::FoldingSetNodeID ID;
728 ObjcQualifiedIdType::Profile(ID, Protocols, NumProtocols);
729
730 void *InsertPos = 0;
731 if (ObjcQualifiedIdType *QT =
732 ObjcQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
733 return QualType(QT, 0);
734
735 // No Match;
736 QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
737 ObjcQualifiedIdType *QType =
738 new ObjcQualifiedIdType(Decl, Canonical, Protocols, NumProtocols);
739 Types.push_back(QType);
740 ObjcQualifiedIdTypes.InsertNode(QType, InsertPos);
741 return QualType(QType, 0);
742}
743
Steve Naroff0604dd92007-08-01 18:02:17 +0000744/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
745/// TypeOfExpr AST's (since expression's are never shared). For example,
746/// multiple declarations that refer to "typeof(x)" all contain different
747/// DeclRefExpr's. This doesn't effect the type checker, since it operates
748/// on canonical type's (which are always unique).
Steve Naroff11b649c2007-08-01 17:20:42 +0000749QualType ASTContext::getTypeOfExpr(Expr *tofExpr) {
Steve Naroff7cbb1462007-07-31 12:34:36 +0000750 QualType Canonical = tofExpr->getType().getCanonicalType();
Steve Naroff0604dd92007-08-01 18:02:17 +0000751 TypeOfExpr *toe = new TypeOfExpr(tofExpr, Canonical);
752 Types.push_back(toe);
753 return QualType(toe, 0);
Steve Naroff7cbb1462007-07-31 12:34:36 +0000754}
755
Steve Naroff0604dd92007-08-01 18:02:17 +0000756/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
757/// TypeOfType AST's. The only motivation to unique these nodes would be
758/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
759/// an issue. This doesn't effect the type checker, since it operates
760/// on canonical type's (which are always unique).
Steve Naroff7cbb1462007-07-31 12:34:36 +0000761QualType ASTContext::getTypeOfType(QualType tofType) {
762 QualType Canonical = tofType.getCanonicalType();
Steve Naroff0604dd92007-08-01 18:02:17 +0000763 TypeOfType *tot = new TypeOfType(tofType, Canonical);
764 Types.push_back(tot);
765 return QualType(tot, 0);
Steve Naroff7cbb1462007-07-31 12:34:36 +0000766}
767
Chris Lattner4b009652007-07-25 00:24:17 +0000768/// getTagDeclType - Return the unique reference to the type for the
769/// specified TagDecl (struct/union/class/enum) decl.
770QualType ASTContext::getTagDeclType(TagDecl *Decl) {
Ted Kremenekae8fa032007-11-26 21:16:01 +0000771 assert (Decl);
772
Ted Kremenekf05026d2007-11-14 00:03:20 +0000773 // The decl stores the type cache.
Ted Kremenekae8fa032007-11-26 21:16:01 +0000774 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
Ted Kremenekf05026d2007-11-14 00:03:20 +0000775
776 TagType* T = new TagType(Decl, QualType());
Ted Kremenekae8fa032007-11-26 21:16:01 +0000777 Types.push_back(T);
778 Decl->TypeForDecl = T;
Ted Kremenekf05026d2007-11-14 00:03:20 +0000779
780 return QualType(T, 0);
Chris Lattner4b009652007-07-25 00:24:17 +0000781}
782
783/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
784/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
785/// needs to agree with the definition in <stddef.h>.
786QualType ASTContext::getSizeType() const {
787 // On Darwin, size_t is defined as a "long unsigned int".
788 // FIXME: should derive from "Target".
789 return UnsignedLongTy;
790}
791
792/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
793/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
794QualType ASTContext::getPointerDiffType() const {
795 // On Darwin, ptrdiff_t is defined as a "int". This seems like a bug...
796 // FIXME: should derive from "Target".
797 return IntTy;
798}
799
800/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
801/// routine will assert if passed a built-in type that isn't an integer or enum.
802static int getIntegerRank(QualType t) {
803 if (const TagType *TT = dyn_cast<TagType>(t.getCanonicalType())) {
804 assert(TT->getDecl()->getKind() == Decl::Enum && "not an int or enum");
805 return 4;
806 }
807
808 const BuiltinType *BT = cast<BuiltinType>(t.getCanonicalType());
809 switch (BT->getKind()) {
810 default:
811 assert(0 && "getIntegerRank(): not a built-in integer");
812 case BuiltinType::Bool:
813 return 1;
814 case BuiltinType::Char_S:
815 case BuiltinType::Char_U:
816 case BuiltinType::SChar:
817 case BuiltinType::UChar:
818 return 2;
819 case BuiltinType::Short:
820 case BuiltinType::UShort:
821 return 3;
822 case BuiltinType::Int:
823 case BuiltinType::UInt:
824 return 4;
825 case BuiltinType::Long:
826 case BuiltinType::ULong:
827 return 5;
828 case BuiltinType::LongLong:
829 case BuiltinType::ULongLong:
830 return 6;
831 }
832}
833
834/// getFloatingRank - Return a relative rank for floating point types.
835/// This routine will assert if passed a built-in type that isn't a float.
836static int getFloatingRank(QualType T) {
837 T = T.getCanonicalType();
838 if (ComplexType *CT = dyn_cast<ComplexType>(T))
839 return getFloatingRank(CT->getElementType());
840
841 switch (cast<BuiltinType>(T)->getKind()) {
Chris Lattner5003e8b2007-11-01 05:03:41 +0000842 default: assert(0 && "getFloatingRank(): not a floating type");
Chris Lattner4b009652007-07-25 00:24:17 +0000843 case BuiltinType::Float: return FloatRank;
844 case BuiltinType::Double: return DoubleRank;
845 case BuiltinType::LongDouble: return LongDoubleRank;
846 }
847}
848
Steve Narofffa0c4532007-08-27 01:41:48 +0000849/// getFloatingTypeOfSizeWithinDomain - Returns a real floating
850/// point or a complex type (based on typeDomain/typeSize).
851/// 'typeDomain' is a real floating point or complex type.
852/// 'typeSize' is a real floating point or complex type.
Steve Naroff3cf497f2007-08-27 01:27:54 +0000853QualType ASTContext::getFloatingTypeOfSizeWithinDomain(
854 QualType typeSize, QualType typeDomain) const {
855 if (typeDomain->isComplexType()) {
856 switch (getFloatingRank(typeSize)) {
Steve Narofffa0c4532007-08-27 01:41:48 +0000857 default: assert(0 && "getFloatingRank(): illegal value for rank");
Steve Naroff3cf497f2007-08-27 01:27:54 +0000858 case FloatRank: return FloatComplexTy;
859 case DoubleRank: return DoubleComplexTy;
860 case LongDoubleRank: return LongDoubleComplexTy;
861 }
Chris Lattner4b009652007-07-25 00:24:17 +0000862 }
Steve Naroff3cf497f2007-08-27 01:27:54 +0000863 if (typeDomain->isRealFloatingType()) {
864 switch (getFloatingRank(typeSize)) {
Steve Narofffa0c4532007-08-27 01:41:48 +0000865 default: assert(0 && "getFloatingRank(): illegal value for rank");
Steve Naroff3cf497f2007-08-27 01:27:54 +0000866 case FloatRank: return FloatTy;
867 case DoubleRank: return DoubleTy;
868 case LongDoubleRank: return LongDoubleTy;
869 }
870 }
871 assert(0 && "getFloatingTypeOfSizeWithinDomain(): illegal domain");
Chris Lattner1d2b4612007-09-16 19:23:47 +0000872 //an invalid return value, but the assert
873 //will ensure that this code is never reached.
874 return VoidTy;
Chris Lattner4b009652007-07-25 00:24:17 +0000875}
876
Steve Naroff45fc9822007-08-27 15:30:22 +0000877/// compareFloatingType - Handles 3 different combos:
878/// float/float, float/complex, complex/complex.
879/// If lt > rt, return 1. If lt == rt, return 0. If lt < rt, return -1.
880int ASTContext::compareFloatingType(QualType lt, QualType rt) {
881 if (getFloatingRank(lt) == getFloatingRank(rt))
882 return 0;
883 if (getFloatingRank(lt) > getFloatingRank(rt))
884 return 1;
885 return -1;
Chris Lattner4b009652007-07-25 00:24:17 +0000886}
887
888// maxIntegerType - Returns the highest ranked integer type. Handles 3 case:
889// unsigned/unsigned, signed/signed, signed/unsigned. C99 6.3.1.8p1.
890QualType ASTContext::maxIntegerType(QualType lhs, QualType rhs) {
891 if (lhs == rhs) return lhs;
892
893 bool t1Unsigned = lhs->isUnsignedIntegerType();
894 bool t2Unsigned = rhs->isUnsignedIntegerType();
895
896 if ((t1Unsigned && t2Unsigned) || (!t1Unsigned && !t2Unsigned))
897 return getIntegerRank(lhs) >= getIntegerRank(rhs) ? lhs : rhs;
898
899 // We have two integer types with differing signs
900 QualType unsignedType = t1Unsigned ? lhs : rhs;
901 QualType signedType = t1Unsigned ? rhs : lhs;
902
903 if (getIntegerRank(unsignedType) >= getIntegerRank(signedType))
904 return unsignedType;
905 else {
906 // FIXME: Need to check if the signed type can represent all values of the
907 // unsigned type. If it can, then the result is the signed type.
908 // If it can't, then the result is the unsigned version of the signed type.
909 // Should probably add a helper that returns a signed integer type from
910 // an unsigned (and vice versa). C99 6.3.1.8.
911 return signedType;
912 }
913}
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000914
915// getCFConstantStringType - Return the type used for constant CFStrings.
916QualType ASTContext::getCFConstantStringType() {
917 if (!CFConstantStringTypeDecl) {
918 CFConstantStringTypeDecl = new RecordDecl(Decl::Struct, SourceLocation(),
Steve Naroff0add5d22007-11-03 11:27:19 +0000919 &Idents.get("NSConstantString"),
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000920 0);
Anders Carlssonbb2cf512007-11-19 00:25:30 +0000921 QualType FieldTypes[4];
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000922
923 // const int *isa;
924 FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));
Anders Carlssonbb2cf512007-11-19 00:25:30 +0000925 // int flags;
926 FieldTypes[1] = IntTy;
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000927 // const char *str;
Anders Carlssonbb2cf512007-11-19 00:25:30 +0000928 FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000929 // long length;
Anders Carlssonbb2cf512007-11-19 00:25:30 +0000930 FieldTypes[3] = LongTy;
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000931 // Create fields
Anders Carlssonbb2cf512007-11-19 00:25:30 +0000932 FieldDecl *FieldDecls[4];
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000933
Anders Carlssonbb2cf512007-11-19 00:25:30 +0000934 for (unsigned i = 0; i < 4; ++i)
Steve Naroffdc1ad762007-09-14 02:20:46 +0000935 FieldDecls[i] = new FieldDecl(SourceLocation(), 0, FieldTypes[i]);
Anders Carlssone7e7aa22007-08-17 05:31:46 +0000936
937 CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
938 }
939
940 return getTagDeclType(CFConstantStringTypeDecl);
Gabor Greif61ce98c2007-09-11 15:32:40 +0000941}
Anders Carlssonfb5b1e82007-10-11 01:00:40 +0000942
Anders Carlssone3f02572007-10-29 06:33:42 +0000943// This returns true if a type has been typedefed to BOOL:
944// typedef <type> BOOL;
Chris Lattnercb034cb2007-10-30 20:27:44 +0000945static bool isTypeTypedefedAsBOOL(QualType T) {
Anders Carlssone3f02572007-10-29 06:33:42 +0000946 if (const TypedefType *TT = dyn_cast<TypedefType>(T))
Chris Lattnercb034cb2007-10-30 20:27:44 +0000947 return !strcmp(TT->getDecl()->getName(), "BOOL");
Anders Carlsson36f07d82007-10-29 05:01:08 +0000948
949 return false;
950}
951
Fariborz Jahanianc81f3162007-10-29 22:57:28 +0000952/// getObjcEncodingTypeSize returns size of type for objective-c encoding
953/// purpose.
954int ASTContext::getObjcEncodingTypeSize(QualType type) {
955 SourceLocation Loc;
956 uint64_t sz = getTypeSize(type, Loc);
957
958 // Make all integer and enum types at least as large as an int
959 if (sz > 0 && type->isIntegralType())
960 sz = std::max(sz, getTypeSize(IntTy, Loc));
961 // Treat arrays as pointers, since that's how they're passed in.
962 else if (type->isArrayType())
963 sz = getTypeSize(VoidPtrTy, Loc);
964 return sz / getTypeSize(CharTy, Loc);
965}
966
967/// getObjcEncodingForMethodDecl - Return the encoded type for this method
968/// declaration.
969void ASTContext::getObjcEncodingForMethodDecl(ObjcMethodDecl *Decl,
970 std::string& S)
971{
Fariborz Jahanian65e7eb52007-11-01 17:18:37 +0000972 // Encode type qualifer, 'in', 'inout', etc. for the return type.
973 getObjcEncodingForTypeQualifier(Decl->getObjcDeclQualifier(), S);
Fariborz Jahanianc81f3162007-10-29 22:57:28 +0000974 // Encode result type.
975 getObjcEncodingForType(Decl->getResultType(), S);
976 // Compute size of all parameters.
977 // Start with computing size of a pointer in number of bytes.
978 // FIXME: There might(should) be a better way of doing this computation!
979 SourceLocation Loc;
980 int PtrSize = getTypeSize(VoidPtrTy, Loc) / getTypeSize(CharTy, Loc);
981 // The first two arguments (self and _cmd) are pointers; account for
982 // their size.
983 int ParmOffset = 2 * PtrSize;
984 int NumOfParams = Decl->getNumParams();
985 for (int i = 0; i < NumOfParams; i++) {
986 QualType PType = Decl->getParamDecl(i)->getType();
987 int sz = getObjcEncodingTypeSize (PType);
988 assert (sz > 0 && "getObjcEncodingForMethodDecl - Incomplete param type");
989 ParmOffset += sz;
990 }
991 S += llvm::utostr(ParmOffset);
992 S += "@0:";
993 S += llvm::utostr(PtrSize);
994
995 // Argument types.
996 ParmOffset = 2 * PtrSize;
997 for (int i = 0; i < NumOfParams; i++) {
998 QualType PType = Decl->getParamDecl(i)->getType();
Fariborz Jahanian65e7eb52007-11-01 17:18:37 +0000999 // Process argument qualifiers for user supplied arguments; such as,
Fariborz Jahanianc81f3162007-10-29 22:57:28 +00001000 // 'in', 'inout', etc.
Fariborz Jahanian65e7eb52007-11-01 17:18:37 +00001001 getObjcEncodingForTypeQualifier(
1002 Decl->getParamDecl(i)->getObjcDeclQualifier(), S);
Fariborz Jahanianc81f3162007-10-29 22:57:28 +00001003 getObjcEncodingForType(PType, S);
1004 S += llvm::utostr(ParmOffset);
1005 ParmOffset += getObjcEncodingTypeSize(PType);
1006 }
1007}
1008
Anders Carlsson36f07d82007-10-29 05:01:08 +00001009void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
1010{
Anders Carlssone3f02572007-10-29 06:33:42 +00001011 // FIXME: This currently doesn't encode:
1012 // @ An object (whether statically typed or typed id)
1013 // # A class object (Class)
1014 // : A method selector (SEL)
1015 // {name=type...} A structure
1016 // (name=type...) A union
1017 // bnum A bit field of num bits
1018
1019 if (const BuiltinType *BT = T->getAsBuiltinType()) {
Anders Carlsson36f07d82007-10-29 05:01:08 +00001020 char encoding;
1021 switch (BT->getKind()) {
1022 case BuiltinType::Void:
1023 encoding = 'v';
1024 break;
1025 case BuiltinType::Bool:
1026 encoding = 'B';
1027 break;
1028 case BuiltinType::Char_U:
1029 case BuiltinType::UChar:
1030 encoding = 'C';
1031 break;
1032 case BuiltinType::UShort:
1033 encoding = 'S';
1034 break;
1035 case BuiltinType::UInt:
1036 encoding = 'I';
1037 break;
1038 case BuiltinType::ULong:
1039 encoding = 'L';
1040 break;
1041 case BuiltinType::ULongLong:
1042 encoding = 'Q';
1043 break;
1044 case BuiltinType::Char_S:
1045 case BuiltinType::SChar:
1046 encoding = 'c';
1047 break;
1048 case BuiltinType::Short:
1049 encoding = 's';
1050 break;
1051 case BuiltinType::Int:
1052 encoding = 'i';
1053 break;
1054 case BuiltinType::Long:
1055 encoding = 'l';
1056 break;
1057 case BuiltinType::LongLong:
1058 encoding = 'q';
1059 break;
1060 case BuiltinType::Float:
1061 encoding = 'f';
1062 break;
1063 case BuiltinType::Double:
1064 encoding = 'd';
1065 break;
1066 case BuiltinType::LongDouble:
1067 encoding = 'd';
1068 break;
1069 default:
1070 assert(0 && "Unhandled builtin type kind");
1071 }
1072
1073 S += encoding;
Fariborz Jahaniane76e8412007-12-17 21:03:50 +00001074 }
1075 else if (const ObjcQualifiedIdType *QIT = dyn_cast<ObjcQualifiedIdType>(T)) {
1076 // Treat id<P...> same as 'id' for encoding purposes.
1077 return getObjcEncodingForType(QIT->getDecl()->getUnderlyingType(), S);
1078
1079 }
1080 else if (const PointerType *PT = T->getAsPointerType()) {
Anders Carlsson36f07d82007-10-29 05:01:08 +00001081 QualType PointeeTy = PT->getPointeeType();
Anders Carlsson7f23e3d2007-10-31 02:53:19 +00001082 if (isObjcIdType(PointeeTy) || PointeeTy->isObjcInterfaceType()) {
Fariborz Jahanian80faffa2007-10-30 17:06:23 +00001083 S += '@';
1084 return;
Anders Carlsson7f23e3d2007-10-31 02:53:19 +00001085 } else if (isObjcClassType(PointeeTy)) {
1086 S += '#';
1087 return;
1088 } else if (isObjcSelType(PointeeTy)) {
1089 S += ':';
1090 return;
Fariborz Jahanian80faffa2007-10-30 17:06:23 +00001091 }
Anders Carlsson36f07d82007-10-29 05:01:08 +00001092
1093 if (PointeeTy->isCharType()) {
1094 // char pointer types should be encoded as '*' unless it is a
1095 // type that has been typedef'd to 'BOOL'.
Anders Carlssone3f02572007-10-29 06:33:42 +00001096 if (!isTypeTypedefedAsBOOL(PointeeTy)) {
Anders Carlsson36f07d82007-10-29 05:01:08 +00001097 S += '*';
1098 return;
1099 }
1100 }
1101
1102 S += '^';
1103 getObjcEncodingForType(PT->getPointeeType(), S);
Anders Carlssone3f02572007-10-29 06:33:42 +00001104 } else if (const ArrayType *AT = T->getAsArrayType()) {
Anders Carlsson36f07d82007-10-29 05:01:08 +00001105 S += '[';
1106
1107 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
1108 S += llvm::utostr(CAT->getSize().getZExtValue());
1109 else
1110 assert(0 && "Unhandled array type!");
1111
1112 getObjcEncodingForType(AT->getElementType(), S);
1113 S += ']';
Anders Carlsson5695bb72007-10-30 00:06:20 +00001114 } else if (T->getAsFunctionType()) {
1115 S += '?';
Fariborz Jahanianc8ba2bd2007-11-13 23:21:38 +00001116 } else if (const RecordType *RTy = T->getAsRecordType()) {
1117 RecordDecl *RDecl= RTy->getDecl();
1118 S += '{';
1119 S += RDecl->getName();
1120 S += '=';
1121 for (int i = 0; i < RDecl->getNumMembers(); i++) {
1122 FieldDecl *field = RDecl->getMember(i);
1123 getObjcEncodingForType(field->getType(), S);
1124 }
1125 S += '}';
Steve Naroff49af3f32007-12-12 22:30:11 +00001126 } else if (T->isEnumeralType()) {
1127 S += 'i';
Anders Carlsson36f07d82007-10-29 05:01:08 +00001128 } else
Steve Naroff49af3f32007-12-12 22:30:11 +00001129 assert(0 && "@encode for type not implemented!");
Anders Carlsson36f07d82007-10-29 05:01:08 +00001130}
1131
Fariborz Jahanian65e7eb52007-11-01 17:18:37 +00001132void ASTContext::getObjcEncodingForTypeQualifier(Decl::ObjcDeclQualifier QT,
1133 std::string& S) const {
1134 if (QT & Decl::OBJC_TQ_In)
1135 S += 'n';
1136 if (QT & Decl::OBJC_TQ_Inout)
1137 S += 'N';
1138 if (QT & Decl::OBJC_TQ_Out)
1139 S += 'o';
1140 if (QT & Decl::OBJC_TQ_Bycopy)
1141 S += 'O';
1142 if (QT & Decl::OBJC_TQ_Byref)
1143 S += 'R';
1144 if (QT & Decl::OBJC_TQ_Oneway)
1145 S += 'V';
1146}
1147
Anders Carlssonfb5b1e82007-10-11 01:00:40 +00001148void ASTContext::setBuiltinVaListType(QualType T)
1149{
1150 assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");
1151
1152 BuiltinVaListType = T;
1153}
1154
Steve Naroff9d12c902007-10-15 14:41:52 +00001155void ASTContext::setObjcIdType(TypedefDecl *TD)
1156{
1157 assert(ObjcIdType.isNull() && "'id' type already set!");
1158
1159 ObjcIdType = getTypedefType(TD);
1160
1161 // typedef struct objc_object *id;
1162 const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1163 assert(ptr && "'id' incorrectly typed");
1164 const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1165 assert(rec && "'id' incorrectly typed");
1166 IdStructType = rec;
1167}
1168
Fariborz Jahanianf807c202007-10-16 20:40:23 +00001169void ASTContext::setObjcSelType(TypedefDecl *TD)
1170{
1171 assert(ObjcSelType.isNull() && "'SEL' type already set!");
1172
1173 ObjcSelType = getTypedefType(TD);
1174
1175 // typedef struct objc_selector *SEL;
1176 const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1177 assert(ptr && "'SEL' incorrectly typed");
1178 const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1179 assert(rec && "'SEL' incorrectly typed");
1180 SelStructType = rec;
1181}
1182
Fariborz Jahanianb4452ed2007-12-07 00:18:54 +00001183void ASTContext::setObjcProtoType(QualType QT)
Fariborz Jahanianb391e6e2007-10-17 16:58:11 +00001184{
1185 assert(ObjcProtoType.isNull() && "'Protocol' type already set!");
Fariborz Jahanianb4452ed2007-12-07 00:18:54 +00001186 ObjcProtoType = QT;
Fariborz Jahanianb391e6e2007-10-17 16:58:11 +00001187}
1188
Anders Carlsson7f23e3d2007-10-31 02:53:19 +00001189void ASTContext::setObjcClassType(TypedefDecl *TD)
1190{
1191 assert(ObjcClassType.isNull() && "'Class' type already set!");
1192
1193 ObjcClassType = getTypedefType(TD);
1194
1195 // typedef struct objc_class *Class;
1196 const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
1197 assert(ptr && "'Class' incorrectly typed");
1198 const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
1199 assert(rec && "'Class' incorrectly typed");
1200 ClassStructType = rec;
1201}
1202
Steve Narofff2e30312007-10-15 23:35:17 +00001203void ASTContext::setObjcConstantStringInterface(ObjcInterfaceDecl *Decl) {
1204 assert(ObjcConstantStringType.isNull() &&
1205 "'NSConstantString' type already set!");
1206
1207 ObjcConstantStringType = getObjcInterfaceType(Decl);
1208}
1209
Steve Naroff85f0dc52007-10-15 20:41:53 +00001210bool ASTContext::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
1211 const BuiltinType *lBuiltin = lhs->getAsBuiltinType();
1212 const BuiltinType *rBuiltin = rhs->getAsBuiltinType();
1213
1214 return lBuiltin->getKind() == rBuiltin->getKind();
1215}
1216
1217
1218bool ASTContext::objcTypesAreCompatible(QualType lhs, QualType rhs) {
1219 if (lhs->isObjcInterfaceType() && isObjcIdType(rhs))
1220 return true;
1221 else if (isObjcIdType(lhs) && rhs->isObjcInterfaceType())
1222 return true;
1223 return false;
1224}
1225
1226bool ASTContext::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
1227 return true; // FIXME: IMPLEMENT.
1228}
1229
Fariborz Jahanian12519d42007-12-12 01:00:23 +00001230bool ASTContext::QualifiedInterfaceTypesAreCompatible(QualType lhs,
1231 QualType rhs) {
1232 ObjcQualifiedInterfaceType *lhsQI =
1233 dyn_cast<ObjcQualifiedInterfaceType>(lhs.getCanonicalType().getTypePtr());
1234 assert(lhsQI && "QualifiedInterfaceTypesAreCompatible - bad lhs type");
1235 ObjcQualifiedInterfaceType *rhsQI =
1236 dyn_cast<ObjcQualifiedInterfaceType>(rhs.getCanonicalType().getTypePtr());
1237 assert(rhsQI && "QualifiedInterfaceTypesAreCompatible - bad rhs type");
Fariborz Jahanian0c2f2142007-12-13 20:47:42 +00001238 if (!interfaceTypesAreCompatible(getObjcInterfaceType(lhsQI->getDecl()),
1239 getObjcInterfaceType(rhsQI->getDecl())))
Fariborz Jahanian12519d42007-12-12 01:00:23 +00001240 return false;
1241 /* All protocols in lhs must have a presense in rhs. */
1242 for (unsigned i =0; i < lhsQI->getNumProtocols(); i++) {
1243 bool match = false;
1244 ObjcProtocolDecl *lhsProto = lhsQI->getProtocols(i);
1245 for (unsigned j = 0; j < rhsQI->getNumProtocols(); j++) {
1246 ObjcProtocolDecl *rhsProto = rhsQI->getProtocols(j);
1247 if (lhsProto == rhsProto) {
1248 match = true;
1249 break;
1250 }
1251 }
1252 if (!match)
1253 return false;
1254 }
1255 return true;
1256}
1257
Fariborz Jahaniane76e8412007-12-17 21:03:50 +00001258// TODO: id<P1,...> vs. id<P,...>
1259#if 0
1260bool ASTContext::QualifiedIdTypesAreCompatible(QualType lhs,
1261 QualType rhs) {
1262}
1263#endif
1264
Chris Lattner5003e8b2007-11-01 05:03:41 +00001265bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
1266 const VectorType *lVector = lhs->getAsVectorType();
1267 const VectorType *rVector = rhs->getAsVectorType();
1268
1269 if ((lVector->getElementType().getCanonicalType() ==
1270 rVector->getElementType().getCanonicalType()) &&
1271 (lVector->getNumElements() == rVector->getNumElements()))
1272 return true;
1273 return false;
1274}
1275
Steve Naroff85f0dc52007-10-15 20:41:53 +00001276// C99 6.2.7p1: If both are complete types, then the following additional
1277// requirements apply...FIXME (handle compatibility across source files).
1278bool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) {
1279 TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
1280 TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
1281
1282 if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
1283 if (ldecl->getIdentifier() == rdecl->getIdentifier())
1284 return true;
1285 }
1286 if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
1287 if (ldecl->getIdentifier() == rdecl->getIdentifier())
1288 return true;
1289 }
Steve Naroff4a5e2072007-11-07 06:03:51 +00001290 // "Class" and "id" are compatible built-in structure types.
1291 if (isObjcIdType(lhs) && isObjcClassType(rhs) ||
1292 isObjcClassType(lhs) && isObjcIdType(rhs))
1293 return true;
Steve Naroff85f0dc52007-10-15 20:41:53 +00001294 return false;
1295}
1296
1297bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
1298 // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
1299 // identically qualified and both shall be pointers to compatible types.
1300 if (lhs.getQualifiers() != rhs.getQualifiers())
1301 return false;
1302
1303 QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
1304 QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
1305
1306 return typesAreCompatible(ltype, rtype);
1307}
1308
Bill Wendling6a9d8542007-12-03 07:33:35 +00001309// C++ 5.17p6: When the left operand of an assignment operator denotes a
Steve Naroff85f0dc52007-10-15 20:41:53 +00001310// reference to T, the operation assigns to the object of type T denoted by the
1311// reference.
1312bool ASTContext::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
1313 QualType ltype = lhs;
1314
1315 if (lhs->isReferenceType())
1316 ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
1317
1318 QualType rtype = rhs;
1319
1320 if (rhs->isReferenceType())
1321 rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
1322
1323 return typesAreCompatible(ltype, rtype);
1324}
1325
1326bool ASTContext::functionTypesAreCompatible(QualType lhs, QualType rhs) {
1327 const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
1328 const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
1329 const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
1330 const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
1331
1332 // first check the return types (common between C99 and K&R).
1333 if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
1334 return false;
1335
1336 if (lproto && rproto) { // two C99 style function prototypes
1337 unsigned lproto_nargs = lproto->getNumArgs();
1338 unsigned rproto_nargs = rproto->getNumArgs();
1339
1340 if (lproto_nargs != rproto_nargs)
1341 return false;
1342
1343 // both prototypes have the same number of arguments.
1344 if ((lproto->isVariadic() && !rproto->isVariadic()) ||
1345 (rproto->isVariadic() && !lproto->isVariadic()))
1346 return false;
1347
1348 // The use of ellipsis agree...now check the argument types.
1349 for (unsigned i = 0; i < lproto_nargs; i++)
1350 if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
1351 return false;
1352 return true;
1353 }
1354 if (!lproto && !rproto) // two K&R style function decls, nothing to do.
1355 return true;
1356
1357 // we have a mixture of K&R style with C99 prototypes
1358 const FunctionTypeProto *proto = lproto ? lproto : rproto;
1359
1360 if (proto->isVariadic())
1361 return false;
1362
1363 // FIXME: Each parameter type T in the prototype must be compatible with the
1364 // type resulting from applying the usual argument conversions to T.
1365 return true;
1366}
1367
1368bool ASTContext::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
1369 QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
1370 QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
1371
1372 if (!typesAreCompatible(ltype, rtype))
1373 return false;
1374
1375 // FIXME: If both types specify constant sizes, then the sizes must also be
1376 // the same. Even if the sizes are the same, GCC produces an error.
1377 return true;
1378}
1379
1380/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
1381/// both shall have the identically qualified version of a compatible type.
1382/// C99 6.2.7p1: Two types have compatible types if their types are the
1383/// same. See 6.7.[2,3,5] for additional rules.
1384bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
1385 QualType lcanon = lhs.getCanonicalType();
1386 QualType rcanon = rhs.getCanonicalType();
1387
1388 // If two types are identical, they are are compatible
1389 if (lcanon == rcanon)
1390 return true;
Bill Wendling6a9d8542007-12-03 07:33:35 +00001391
1392 // C++ [expr]: If an expression initially has the type "reference to T", the
1393 // type is adjusted to "T" prior to any further analysis, the expression
1394 // designates the object or function denoted by the reference, and the
1395 // expression is an lvalue.
1396 if (lcanon->getTypeClass() == Type::Reference)
1397 lcanon = cast<ReferenceType>(lcanon)->getReferenceeType();
1398 if (rcanon->getTypeClass() == Type::Reference)
1399 rcanon = cast<ReferenceType>(rcanon)->getReferenceeType();
Steve Naroff85f0dc52007-10-15 20:41:53 +00001400
1401 // If the canonical type classes don't match, they can't be compatible
1402 if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
1403 // For Objective-C, it is possible for two types to be compatible
1404 // when their classes don't match (when dealing with "id"). If either type
1405 // is an interface, we defer to objcTypesAreCompatible().
1406 if (lcanon->isObjcInterfaceType() || rcanon->isObjcInterfaceType())
1407 return objcTypesAreCompatible(lcanon, rcanon);
1408 return false;
1409 }
1410 switch (lcanon->getTypeClass()) {
1411 case Type::Pointer:
1412 return pointerTypesAreCompatible(lcanon, rcanon);
Steve Naroff85f0dc52007-10-15 20:41:53 +00001413 case Type::ConstantArray:
1414 case Type::VariableArray:
1415 return arrayTypesAreCompatible(lcanon, rcanon);
1416 case Type::FunctionNoProto:
1417 case Type::FunctionProto:
1418 return functionTypesAreCompatible(lcanon, rcanon);
1419 case Type::Tagged: // handle structures, unions
1420 return tagTypesAreCompatible(lcanon, rcanon);
1421 case Type::Builtin:
1422 return builtinTypesAreCompatible(lcanon, rcanon);
1423 case Type::ObjcInterface:
1424 return interfaceTypesAreCompatible(lcanon, rcanon);
Chris Lattner5003e8b2007-11-01 05:03:41 +00001425 case Type::Vector:
1426 case Type::OCUVector:
1427 return vectorTypesAreCompatible(lcanon, rcanon);
Fariborz Jahanian12519d42007-12-12 01:00:23 +00001428 case Type::ObjcQualifiedInterface:
1429 return QualifiedInterfaceTypesAreCompatible(lcanon, rcanon);
Steve Naroff85f0dc52007-10-15 20:41:53 +00001430 default:
1431 assert(0 && "unexpected type");
1432 }
1433 return true; // should never get here...
1434}
Ted Kremenek738e6c02007-10-31 17:10:13 +00001435
Ted Kremenek738e6c02007-10-31 17:10:13 +00001436/// Emit - Serialize an ASTContext object to Bitcode.
1437void ASTContext::Emit(llvm::Serializer& S) const {
Ted Kremenek9af4d5c2007-10-31 20:00:03 +00001438 S.EmitRef(SourceMgr);
1439 S.EmitRef(Target);
1440 S.EmitRef(Idents);
1441 S.EmitRef(Selectors);
Ted Kremenek738e6c02007-10-31 17:10:13 +00001442
Ted Kremenek68228a92007-10-31 22:44:07 +00001443 // Emit the size of the type vector so that we can reserve that size
1444 // when we reconstitute the ASTContext object.
Ted Kremenek0199d9f2007-11-06 22:26:16 +00001445 S.EmitInt(Types.size());
1446
Ted Kremenek034a78c2007-11-13 22:02:55 +00001447 for (std::vector<Type*>::const_iterator I=Types.begin(), E=Types.end();
1448 I!=E;++I)
1449 (*I)->Emit(S);
Ted Kremenek0199d9f2007-11-06 22:26:16 +00001450
Ted Kremeneke1fed7a2007-11-01 18:11:32 +00001451 // FIXME: S.EmitOwnedPtr(CFConstantStringTypeDecl);
Ted Kremenek738e6c02007-10-31 17:10:13 +00001452}
1453
Ted Kremenekacba3612007-11-13 00:25:37 +00001454ASTContext* ASTContext::Create(llvm::Deserializer& D) {
Ted Kremenek68228a92007-10-31 22:44:07 +00001455 SourceManager &SM = D.ReadRef<SourceManager>();
1456 TargetInfo &t = D.ReadRef<TargetInfo>();
1457 IdentifierTable &idents = D.ReadRef<IdentifierTable>();
1458 SelectorTable &sels = D.ReadRef<SelectorTable>();
1459
1460 unsigned size_reserve = D.ReadInt();
1461
1462 ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve);
1463
Ted Kremenek034a78c2007-11-13 22:02:55 +00001464 for (unsigned i = 0; i < size_reserve; ++i)
1465 Type::Create(*A,i,D);
Ted Kremenek0199d9f2007-11-06 22:26:16 +00001466
Ted Kremeneke1fed7a2007-11-01 18:11:32 +00001467 // FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
Ted Kremenek68228a92007-10-31 22:44:07 +00001468
1469 return A;
1470}