blob: 03911bbc9f04bb840c7b470f30c1bb8f9ae97e44 [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 Lattner970e54e2006-11-12 00:37:36 +000023 InitBuiltinTypes();
24}
25
Chris Lattnerd5973eb2006-11-12 00:53:46 +000026ASTContext::~ASTContext() {
27 // Deallocate all the types.
28 while (!Types.empty()) {
Chris Lattnerc6ad8132006-12-02 07:52:18 +000029 if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(Types.back())) {
30 // Destroy the object, but don't call delete. These are malloc'd.
31 FT->~FunctionTypeProto();
32 free(FT);
33 } else {
34 delete Types.back();
35 }
Chris Lattnerd5973eb2006-11-12 00:53:46 +000036 Types.pop_back();
37 }
38}
39
Chris Lattner4eb445d2007-01-26 01:27:23 +000040void ASTContext::PrintStats() const {
41 fprintf(stderr, "*** AST Context Stats:\n");
42 fprintf(stderr, " %d types total.\n", (int)Types.size());
43 unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
44 unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0;
45
46 unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
47
48 for (unsigned i = 0, e = Types.size(); i != e; ++i) {
49 Type *T = Types[i];
50 if (isa<BuiltinType>(T))
51 ++NumBuiltin;
52 else if (isa<PointerType>(T))
53 ++NumPointer;
54 else if (isa<ArrayType>(T))
55 ++NumArray;
56 else if (isa<FunctionTypeNoProto>(T))
57 ++NumFunctionNP;
58 else if (isa<FunctionTypeProto>(T))
59 ++NumFunctionP;
Chris Lattner32d920b2007-01-26 02:01:53 +000060 else if (isa<TypedefType>(T))
Chris Lattner4eb445d2007-01-26 01:27:23 +000061 ++NumTypeName;
62 else if (TaggedType *TT = dyn_cast<TaggedType>(T)) {
63 ++NumTagged;
64 switch (TT->getDecl()->getKind()) {
65 default: assert(0 && "Unknown tagged type!");
66 case Decl::Struct: ++NumTagStruct; break;
67 case Decl::Union: ++NumTagUnion; break;
68 case Decl::Class: ++NumTagClass; break;
69 case Decl::Enum: ++NumTagEnum; break;
70 }
71 } else {
72 assert(0 && "Unknown type!");
73 }
74 }
75
76 fprintf(stderr, " %d builtin types\n", NumBuiltin);
77 fprintf(stderr, " %d pointer types\n", NumPointer);
78 fprintf(stderr, " %d array types\n", NumArray);
79 fprintf(stderr, " %d function types with proto\n", NumFunctionP);
80 fprintf(stderr, " %d function types with no proto\n", NumFunctionNP);
81 fprintf(stderr, " %d typename (typedef) types\n", NumTypeName);
82 fprintf(stderr, " %d tagged types\n", NumTagged);
83 fprintf(stderr, " %d struct types\n", NumTagStruct);
84 fprintf(stderr, " %d union types\n", NumTagUnion);
85 fprintf(stderr, " %d class types\n", NumTagClass);
86 fprintf(stderr, " %d enum types\n", NumTagEnum);
Chris Lattner4eb445d2007-01-26 01:27:23 +000087}
88
89
Chris Lattner726f97b2006-12-03 02:57:32 +000090void ASTContext::InitBuiltinType(TypeRef &R, BuiltinType::Kind K) {
91 Types.push_back((R = new BuiltinType(K)).getTypePtr());
Chris Lattnerd5973eb2006-11-12 00:53:46 +000092}
93
94
Chris Lattner970e54e2006-11-12 00:37:36 +000095void ASTContext::InitBuiltinTypes() {
96 assert(VoidTy.isNull() && "Context reinitialized?");
97
98 // C99 6.2.5p19.
Chris Lattner726f97b2006-12-03 02:57:32 +000099 InitBuiltinType(VoidTy, BuiltinType::Void);
Chris Lattner970e54e2006-11-12 00:37:36 +0000100
101 // C99 6.2.5p2.
Chris Lattner726f97b2006-12-03 02:57:32 +0000102 InitBuiltinType(BoolTy, BuiltinType::Bool);
Chris Lattner970e54e2006-11-12 00:37:36 +0000103 // C99 6.2.5p3.
Chris Lattner726f97b2006-12-03 02:57:32 +0000104 InitBuiltinType(CharTy, BuiltinType::Char);
Chris Lattner970e54e2006-11-12 00:37:36 +0000105 // C99 6.2.5p4.
Chris Lattner726f97b2006-12-03 02:57:32 +0000106 InitBuiltinType(SignedCharTy, BuiltinType::SChar);
107 InitBuiltinType(ShortTy, BuiltinType::Short);
108 InitBuiltinType(IntTy, BuiltinType::Int);
109 InitBuiltinType(LongTy, BuiltinType::Long);
110 InitBuiltinType(LongLongTy, BuiltinType::LongLong);
Chris Lattner970e54e2006-11-12 00:37:36 +0000111
112 // C99 6.2.5p6.
Chris Lattner726f97b2006-12-03 02:57:32 +0000113 InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
114 InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
115 InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
116 InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
117 InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
Chris Lattner970e54e2006-11-12 00:37:36 +0000118
119 // C99 6.2.5p10.
Chris Lattner726f97b2006-12-03 02:57:32 +0000120 InitBuiltinType(FloatTy, BuiltinType::Float);
121 InitBuiltinType(DoubleTy, BuiltinType::Double);
122 InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
Chris Lattner970e54e2006-11-12 00:37:36 +0000123
124 // C99 6.2.5p11.
Chris Lattner726f97b2006-12-03 02:57:32 +0000125 InitBuiltinType(FloatComplexTy, BuiltinType::FloatComplex);
126 InitBuiltinType(DoubleComplexTy, BuiltinType::DoubleComplex);
127 InitBuiltinType(LongDoubleComplexTy, BuiltinType::LongDoubleComplex);
Chris Lattner970e54e2006-11-12 00:37:36 +0000128}
129
130/// getPointerType - Return the uniqued reference to the type for a pointer to
131/// the specified type.
Chris Lattner7ccecb92006-11-12 08:50:50 +0000132TypeRef ASTContext::getPointerType(TypeRef T) {
Chris Lattnerd5973eb2006-11-12 00:53:46 +0000133 // Unique pointers, to guarantee there is only one pointer of a particular
134 // structure.
Chris Lattner67521df2007-01-27 01:29:36 +0000135 FoldingSetNodeID ID;
136 PointerType::Profile(ID, T);
137
138 void *InsertPos = 0;
139 if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
140 return PT;
Chris Lattner970e54e2006-11-12 00:37:36 +0000141
Chris Lattner7ccecb92006-11-12 08:50:50 +0000142 // If the pointee type isn't canonical, this won't be a canonical type either,
143 // so fill in the canonical type field.
Chris Lattner970e54e2006-11-12 00:37:36 +0000144 Type *Canonical = 0;
Chris Lattner67521df2007-01-27 01:29:36 +0000145 if (!T->isCanonical()) {
Chris Lattner970e54e2006-11-12 00:37:36 +0000146 Canonical = getPointerType(T.getCanonicalType()).getTypePtr();
Chris Lattner67521df2007-01-27 01:29:36 +0000147
148 // Get the new insert position for the node we care about.
149 PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
150 assert(NewIP == 0 && "Shouldn't be in the map!");
151 }
Chris Lattnerd5973eb2006-11-12 00:53:46 +0000152
Chris Lattner67521df2007-01-27 01:29:36 +0000153 PointerType *New = new PointerType(T, Canonical);
154 Types.push_back(New);
155 PointerTypes.InsertNode(New, InsertPos);
156 return New;
Chris Lattnerddc135e2006-11-10 06:34:16 +0000157}
158
Chris Lattner7ccecb92006-11-12 08:50:50 +0000159/// getArrayType - Return the unique reference to the type for an array of the
160/// specified element type.
161TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
162 unsigned EltTypeQuals, void *NumElts) {
163#warning "IGNORING SIZE"
164
Chris Lattner36f8e652007-01-27 08:31:04 +0000165 // Unique array types, to guarantee there is only one array of a particular
Chris Lattner7ccecb92006-11-12 08:50:50 +0000166 // structure.
Chris Lattner36f8e652007-01-27 08:31:04 +0000167 FoldingSetNodeID ID;
168 ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy);
169
170 void *InsertPos = 0;
171 if (ArrayType *ATP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
172 return ATP;
Chris Lattner7ccecb92006-11-12 08:50:50 +0000173
174 // If the element type isn't canonical, this won't be a canonical type either,
175 // so fill in the canonical type field.
176 Type *Canonical = 0;
Chris Lattner36f8e652007-01-27 08:31:04 +0000177 if (!EltTy->isCanonical()) {
Chris Lattner7ccecb92006-11-12 08:50:50 +0000178 Canonical = getArrayType(EltTy.getCanonicalType(), ASM, EltTypeQuals,
179 NumElts).getTypePtr();
Chris Lattner36f8e652007-01-27 08:31:04 +0000180
181 // Get the new insert position for the node we care about.
182 ArrayType *NewIP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
183 assert(NewIP == 0 && "Shouldn't be in the map!");
184 }
Chris Lattner7ccecb92006-11-12 08:50:50 +0000185
Chris Lattner36f8e652007-01-27 08:31:04 +0000186 ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical);
187 ArrayTypes.InsertNode(New, InsertPos);
188 Types.push_back(New);
189 return New;
Chris Lattner7ccecb92006-11-12 08:50:50 +0000190}
191
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000192/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
193///
194TypeRef ASTContext::getFunctionTypeNoProto(TypeRef ResultTy) {
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000195 // Unique functions, to guarantee there is only one function of a particular
196 // structure.
Chris Lattner47955de2007-01-27 08:37:20 +0000197 FoldingSetNodeID ID;
198 FunctionTypeNoProto::Profile(ID, ResultTy);
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000199
Chris Lattner47955de2007-01-27 08:37:20 +0000200 void *InsertPos = 0;
201 if (FunctionTypeNoProto *FT =
202 FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos))
203 return FT;
204
205 Type *Canonical = 0;
206 if (!ResultTy->isCanonical()) {
207 Canonical =getFunctionTypeNoProto(ResultTy.getCanonicalType()).getTypePtr();
208
209 // Get the new insert position for the node we care about.
210 FunctionTypeNoProto *NewIP =
211 FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos);
212 assert(NewIP == 0 && "Shouldn't be in the map!");
213 }
214
215 FunctionTypeNoProto *New = new FunctionTypeNoProto(ResultTy, Canonical);
216 Types.push_back(New);
217 FunctionTypeProtos.InsertNode(New, InsertPos);
218 return New;
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000219}
220
221/// getFunctionType - Return a normal function type with a typed argument
222/// list. isVariadic indicates whether the argument list includes '...'.
223TypeRef ASTContext::getFunctionType(TypeRef ResultTy, TypeRef *ArgArray,
224 unsigned NumArgs, bool isVariadic) {
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000225 // Unique functions, to guarantee there is only one function of a particular
226 // structure.
Chris Lattnerfd4de792007-01-27 01:15:32 +0000227 FoldingSetNodeID ID;
228 FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
229
230 void *InsertPos = 0;
231 if (FunctionTypeProto *FTP =
232 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
233 return FTP;
234
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000235 // Determine whether the type being created is already canonical or not.
236 bool isCanonical = ResultTy->isCanonical();
237 for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
238 if (!ArgArray[i]->isCanonical())
239 isCanonical = false;
240
241 // If this type isn't canonical, get the canonical version of it.
242 Type *Canonical = 0;
243 if (!isCanonical) {
244 SmallVector<TypeRef, 16> CanonicalArgs;
245 CanonicalArgs.reserve(NumArgs);
246 for (unsigned i = 0; i != NumArgs; ++i)
247 CanonicalArgs.push_back(ArgArray[i].getCanonicalType());
248
249 Canonical = getFunctionType(ResultTy.getCanonicalType(),
250 &CanonicalArgs[0], NumArgs,
251 isVariadic).getTypePtr();
Chris Lattnerfd4de792007-01-27 01:15:32 +0000252
253 // Get the new insert position for the node we care about.
254 FunctionTypeProto *NewIP =
255 FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
256 assert(NewIP == 0 && "Shouldn't be in the map!");
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000257 }
258
259 // FunctionTypeProto objects are not allocated with new because they have a
260 // variable size array (for parameter types) at the end of them.
261 FunctionTypeProto *FTP =
262 (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
263 (NumArgs-1)*sizeof(TypeRef));
264 new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
265 Canonical);
266
267 Types.push_back(FTP);
Chris Lattnerfd4de792007-01-27 01:15:32 +0000268 FunctionTypeProtos.InsertNode(FTP, InsertPos);
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000269 return FTP;
270}
Chris Lattneref51c202006-11-10 07:17:23 +0000271
Chris Lattner32d920b2007-01-26 02:01:53 +0000272/// getTypedefType - Return the unique reference to the type for the
Chris Lattnerd0342e52006-11-20 04:02:15 +0000273/// specified typename decl.
Chris Lattner32d920b2007-01-26 02:01:53 +0000274TypeRef ASTContext::getTypedefType(TypedefDecl *Decl) {
Chris Lattner6668fc62007-01-26 02:07:07 +0000275 if (Decl->TypeForDecl) return Decl->TypeForDecl;
Chris Lattnerd0342e52006-11-20 04:02:15 +0000276
Chris Lattner6668fc62007-01-26 02:07:07 +0000277 // FIXME: does this lose qualifiers from the typedef??
Chris Lattnerd0ee4022007-01-22 07:39:30 +0000278 Type *Canonical = Decl->getUnderlyingType().getTypePtr();
Chris Lattner6668fc62007-01-26 02:07:07 +0000279 Types.push_back(Decl->TypeForDecl = new TypedefType(Decl, Canonical));
Chris Lattnerd0342e52006-11-20 04:02:15 +0000280 return Types.back();
281}
282
Chris Lattnerfb072462007-01-23 05:45:31 +0000283/// getTagDeclType - Return the unique reference to the type for the
284/// specified TagDecl (struct/union/class/enum) decl.
285TypeRef ASTContext::getTagDeclType(TagDecl *Decl) {
Chris Lattner733067d2007-01-26 01:42:24 +0000286 // The decl stores the type cache.
287 if (Decl->TypeForDecl) return Decl->TypeForDecl;
Chris Lattnerfb072462007-01-23 05:45:31 +0000288
Chris Lattner733067d2007-01-26 01:42:24 +0000289 Types.push_back(Decl->TypeForDecl = new TaggedType(Decl, 0));
Chris Lattnerfb072462007-01-23 05:45:31 +0000290 return Types.back();
291}
292
293