blob: 7a9bc8534dad3d1a734a043411029de6648199da [file] [log] [blame]
Chris Lattnerddc135e2006-11-10 06:34:16 +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"
Chris Lattnerd0342e52006-11-20 04:02:15 +000015#include "clang/AST/Decl.h"
Chris Lattnerddc135e2006-11-10 06:34:16 +000016#include "clang/Lex/Preprocessor.h"
Chris Lattnerc6ad8132006-12-02 07:52:18 +000017#include "llvm/ADT/SmallVector.h"
Chris Lattnerddc135e2006-11-10 06:34:16 +000018using namespace llvm;
19using namespace clang;
20
21ASTContext::ASTContext(Preprocessor &pp)
22 : PP(pp), Target(pp.getTargetInfo()) {
Chris Lattner4eb445d2007-01-26 01:27:23 +000023 NumSlowLookups = 0;
Chris Lattner970e54e2006-11-12 00:37:36 +000024 InitBuiltinTypes();
25}
26
Chris Lattnerd5973eb2006-11-12 00:53:46 +000027ASTContext::~ASTContext() {
28 // Deallocate all the types.
29 while (!Types.empty()) {
Chris Lattnerc6ad8132006-12-02 07:52:18 +000030 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 }
Chris Lattnerd5973eb2006-11-12 00:53:46 +000037 Types.pop_back();
38 }
39}
40
Chris Lattner4eb445d2007-01-26 01:27:23 +000041void 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;
45 unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0;
46
47 unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
48
49 for (unsigned i = 0, e = Types.size(); i != e; ++i) {
50 Type *T = Types[i];
51 if (isa<BuiltinType>(T))
52 ++NumBuiltin;
53 else if (isa<PointerType>(T))
54 ++NumPointer;
55 else if (isa<ArrayType>(T))
56 ++NumArray;
57 else if (isa<FunctionTypeNoProto>(T))
58 ++NumFunctionNP;
59 else if (isa<FunctionTypeProto>(T))
60 ++NumFunctionP;
Chris Lattner32d920b2007-01-26 02:01:53 +000061 else if (isa<TypedefType>(T))
Chris Lattner4eb445d2007-01-26 01:27:23 +000062 ++NumTypeName;
63 else if (TaggedType *TT = dyn_cast<TaggedType>(T)) {
64 ++NumTagged;
65 switch (TT->getDecl()->getKind()) {
66 default: assert(0 && "Unknown tagged type!");
67 case Decl::Struct: ++NumTagStruct; break;
68 case Decl::Union: ++NumTagUnion; break;
69 case Decl::Class: ++NumTagClass; break;
70 case Decl::Enum: ++NumTagEnum; break;
71 }
72 } else {
73 assert(0 && "Unknown type!");
74 }
75 }
76
77 fprintf(stderr, " %d builtin types\n", NumBuiltin);
78 fprintf(stderr, " %d pointer types\n", NumPointer);
79 fprintf(stderr, " %d array types\n", NumArray);
80 fprintf(stderr, " %d function types with proto\n", NumFunctionP);
81 fprintf(stderr, " %d function types with no proto\n", NumFunctionNP);
82 fprintf(stderr, " %d typename (typedef) types\n", NumTypeName);
83 fprintf(stderr, " %d tagged types\n", NumTagged);
84 fprintf(stderr, " %d struct types\n", NumTagStruct);
85 fprintf(stderr, " %d union types\n", NumTagUnion);
86 fprintf(stderr, " %d class types\n", NumTagClass);
87 fprintf(stderr, " %d enum types\n", NumTagEnum);
88 fprintf(stderr, " %d slow type lookups\n", NumSlowLookups);
89}
90
91
Chris Lattner726f97b2006-12-03 02:57:32 +000092void ASTContext::InitBuiltinType(TypeRef &R, BuiltinType::Kind K) {
93 Types.push_back((R = new BuiltinType(K)).getTypePtr());
Chris Lattnerd5973eb2006-11-12 00:53:46 +000094}
95
96
Chris Lattner970e54e2006-11-12 00:37:36 +000097void ASTContext::InitBuiltinTypes() {
98 assert(VoidTy.isNull() && "Context reinitialized?");
99
100 // C99 6.2.5p19.
Chris Lattner726f97b2006-12-03 02:57:32 +0000101 InitBuiltinType(VoidTy, BuiltinType::Void);
Chris Lattner970e54e2006-11-12 00:37:36 +0000102
103 // C99 6.2.5p2.
Chris Lattner726f97b2006-12-03 02:57:32 +0000104 InitBuiltinType(BoolTy, BuiltinType::Bool);
Chris Lattner970e54e2006-11-12 00:37:36 +0000105 // C99 6.2.5p3.
Chris Lattner726f97b2006-12-03 02:57:32 +0000106 InitBuiltinType(CharTy, BuiltinType::Char);
Chris Lattner970e54e2006-11-12 00:37:36 +0000107 // C99 6.2.5p4.
Chris Lattner726f97b2006-12-03 02:57:32 +0000108 InitBuiltinType(SignedCharTy, BuiltinType::SChar);
109 InitBuiltinType(ShortTy, BuiltinType::Short);
110 InitBuiltinType(IntTy, BuiltinType::Int);
111 InitBuiltinType(LongTy, BuiltinType::Long);
112 InitBuiltinType(LongLongTy, BuiltinType::LongLong);
Chris Lattner970e54e2006-11-12 00:37:36 +0000113
114 // C99 6.2.5p6.
Chris Lattner726f97b2006-12-03 02:57:32 +0000115 InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
116 InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
117 InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
118 InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
119 InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
Chris Lattner970e54e2006-11-12 00:37:36 +0000120
121 // C99 6.2.5p10.
Chris Lattner726f97b2006-12-03 02:57:32 +0000122 InitBuiltinType(FloatTy, BuiltinType::Float);
123 InitBuiltinType(DoubleTy, BuiltinType::Double);
124 InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
Chris Lattner970e54e2006-11-12 00:37:36 +0000125
126 // C99 6.2.5p11.
Chris Lattner726f97b2006-12-03 02:57:32 +0000127 InitBuiltinType(FloatComplexTy, BuiltinType::FloatComplex);
128 InitBuiltinType(DoubleComplexTy, BuiltinType::DoubleComplex);
129 InitBuiltinType(LongDoubleComplexTy, BuiltinType::LongDoubleComplex);
Chris Lattner970e54e2006-11-12 00:37:36 +0000130}
131
132/// getPointerType - Return the uniqued reference to the type for a pointer to
133/// the specified type.
Chris Lattner7ccecb92006-11-12 08:50:50 +0000134TypeRef ASTContext::getPointerType(TypeRef T) {
Chris Lattnerd5973eb2006-11-12 00:53:46 +0000135 // Unique pointers, to guarantee there is only one pointer of a particular
136 // structure.
Chris Lattner67521df2007-01-27 01:29:36 +0000137 FoldingSetNodeID ID;
138 PointerType::Profile(ID, T);
139
140 void *InsertPos = 0;
141 if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
142 return PT;
Chris Lattner970e54e2006-11-12 00:37:36 +0000143
Chris Lattner7ccecb92006-11-12 08:50:50 +0000144 // If the pointee type isn't canonical, this won't be a canonical type either,
145 // so fill in the canonical type field.
Chris Lattner970e54e2006-11-12 00:37:36 +0000146 Type *Canonical = 0;
Chris Lattner67521df2007-01-27 01:29:36 +0000147 if (!T->isCanonical()) {
Chris Lattner970e54e2006-11-12 00:37:36 +0000148 Canonical = getPointerType(T.getCanonicalType()).getTypePtr();
Chris Lattner67521df2007-01-27 01:29:36 +0000149
150 // Get the new insert position for the node we care about.
151 PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
152 assert(NewIP == 0 && "Shouldn't be in the map!");
153 }
Chris Lattnerd5973eb2006-11-12 00:53:46 +0000154
Chris Lattner67521df2007-01-27 01:29:36 +0000155 PointerType *New = new PointerType(T, Canonical);
156 Types.push_back(New);
157 PointerTypes.InsertNode(New, InsertPos);
158 return New;
Chris Lattnerddc135e2006-11-10 06:34:16 +0000159}
160
Chris Lattner7ccecb92006-11-12 08:50:50 +0000161/// getArrayType - Return the unique reference to the type for an array of the
162/// specified element type.
163TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
164 unsigned EltTypeQuals, void *NumElts) {
165#warning "IGNORING SIZE"
166
Chris Lattner36f8e652007-01-27 08:31:04 +0000167 // Unique array types, to guarantee there is only one array of a particular
Chris Lattner7ccecb92006-11-12 08:50:50 +0000168 // structure.
Chris Lattner36f8e652007-01-27 08:31:04 +0000169 FoldingSetNodeID ID;
170 ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy);
171
172 void *InsertPos = 0;
173 if (ArrayType *ATP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
174 return ATP;
Chris Lattner7ccecb92006-11-12 08:50:50 +0000175
176 // If the element type isn't canonical, this won't be a canonical type either,
177 // so fill in the canonical type field.
178 Type *Canonical = 0;
Chris Lattner36f8e652007-01-27 08:31:04 +0000179 if (!EltTy->isCanonical()) {
Chris Lattner7ccecb92006-11-12 08:50:50 +0000180 Canonical = getArrayType(EltTy.getCanonicalType(), ASM, EltTypeQuals,
181 NumElts).getTypePtr();
Chris Lattner36f8e652007-01-27 08:31:04 +0000182
183 // Get the new insert position for the node we care about.
184 ArrayType *NewIP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
185 assert(NewIP == 0 && "Shouldn't be in the map!");
186 }
Chris Lattner7ccecb92006-11-12 08:50:50 +0000187
Chris Lattner36f8e652007-01-27 08:31:04 +0000188 ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical);
189 ArrayTypes.InsertNode(New, InsertPos);
190 Types.push_back(New);
191 return New;
Chris Lattner7ccecb92006-11-12 08:50:50 +0000192}
193
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000194/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
195///
196TypeRef ASTContext::getFunctionTypeNoProto(TypeRef ResultTy) {
197 // FIXME: This is obviously braindead!
198 // Unique functions, to guarantee there is only one function of a particular
199 // structure.
Chris Lattner4eb445d2007-01-26 01:27:23 +0000200 ++NumSlowLookups;
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000201 for (unsigned i = 0, e = Types.size(); i != e; ++i)
202 if (FunctionTypeNoProto *FTy = dyn_cast<FunctionTypeNoProto>(Types[i]))
203 if (FTy->getResultType() == ResultTy)
204 return Types[i];
205
206 Type *Canonical = 0;
207 if (!ResultTy->isCanonical())
208 Canonical =getFunctionTypeNoProto(ResultTy.getCanonicalType()).getTypePtr();
209
210 Types.push_back(new FunctionTypeNoProto(ResultTy, Canonical));
211 return Types.back();
212}
213
214/// getFunctionType - Return a normal function type with a typed argument
215/// list. isVariadic indicates whether the argument list includes '...'.
216TypeRef ASTContext::getFunctionType(TypeRef ResultTy, TypeRef *ArgArray,
217 unsigned NumArgs, bool isVariadic) {
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000218 // Unique functions, to guarantee there is only one function of a particular
219 // structure.
Chris Lattnerfd4de792007-01-27 01:15:32 +0000220 FoldingSetNodeID ID;
221 FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
222
223 void *InsertPos = 0;
224 if (FunctionTypeProto *FTP =
225 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
226 return FTP;
227
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000228 // Determine whether the type being created is already canonical or not.
229 bool isCanonical = ResultTy->isCanonical();
230 for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
231 if (!ArgArray[i]->isCanonical())
232 isCanonical = false;
233
234 // If this type isn't canonical, get the canonical version of it.
235 Type *Canonical = 0;
236 if (!isCanonical) {
237 SmallVector<TypeRef, 16> CanonicalArgs;
238 CanonicalArgs.reserve(NumArgs);
239 for (unsigned i = 0; i != NumArgs; ++i)
240 CanonicalArgs.push_back(ArgArray[i].getCanonicalType());
241
242 Canonical = getFunctionType(ResultTy.getCanonicalType(),
243 &CanonicalArgs[0], NumArgs,
244 isVariadic).getTypePtr();
Chris Lattnerfd4de792007-01-27 01:15:32 +0000245
246 // Get the new insert position for the node we care about.
247 FunctionTypeProto *NewIP =
248 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
249 assert(NewIP == 0 && "Shouldn't be in the map!");
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000250 }
251
252 // FunctionTypeProto objects are not allocated with new because they have a
253 // variable size array (for parameter types) at the end of them.
254 FunctionTypeProto *FTP =
255 (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
256 (NumArgs-1)*sizeof(TypeRef));
257 new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
258 Canonical);
259
260 Types.push_back(FTP);
Chris Lattnerfd4de792007-01-27 01:15:32 +0000261 FunctionTypeProtos.InsertNode(FTP, InsertPos);
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000262 return FTP;
263}
Chris Lattneref51c202006-11-10 07:17:23 +0000264
Chris Lattner32d920b2007-01-26 02:01:53 +0000265/// getTypedefType - Return the unique reference to the type for the
Chris Lattnerd0342e52006-11-20 04:02:15 +0000266/// specified typename decl.
Chris Lattner32d920b2007-01-26 02:01:53 +0000267TypeRef ASTContext::getTypedefType(TypedefDecl *Decl) {
Chris Lattner6668fc62007-01-26 02:07:07 +0000268 if (Decl->TypeForDecl) return Decl->TypeForDecl;
Chris Lattnerd0342e52006-11-20 04:02:15 +0000269
Chris Lattner6668fc62007-01-26 02:07:07 +0000270 // FIXME: does this lose qualifiers from the typedef??
Chris Lattnerd0ee4022007-01-22 07:39:30 +0000271 Type *Canonical = Decl->getUnderlyingType().getTypePtr();
Chris Lattner6668fc62007-01-26 02:07:07 +0000272 Types.push_back(Decl->TypeForDecl = new TypedefType(Decl, Canonical));
Chris Lattnerd0342e52006-11-20 04:02:15 +0000273 return Types.back();
274}
275
Chris Lattnerfb072462007-01-23 05:45:31 +0000276/// getTagDeclType - Return the unique reference to the type for the
277/// specified TagDecl (struct/union/class/enum) decl.
278TypeRef ASTContext::getTagDeclType(TagDecl *Decl) {
Chris Lattner733067d2007-01-26 01:42:24 +0000279 // The decl stores the type cache.
280 if (Decl->TypeForDecl) return Decl->TypeForDecl;
Chris Lattnerfb072462007-01-23 05:45:31 +0000281
Chris Lattner733067d2007-01-26 01:42:24 +0000282 Types.push_back(Decl->TypeForDecl = new TaggedType(Decl, 0));
Chris Lattnerfb072462007-01-23 05:45:31 +0000283 return Types.back();
284}
285
286