blob: 5ff6322825610fe01c3deb6b807de364e51b2c83 [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 Lattner726f97b2006-12-03 02:57:32 +000040void ASTContext::InitBuiltinType(TypeRef &R, BuiltinType::Kind K) {
41 Types.push_back((R = new BuiltinType(K)).getTypePtr());
Chris Lattnerd5973eb2006-11-12 00:53:46 +000042}
43
44
Chris Lattner970e54e2006-11-12 00:37:36 +000045void ASTContext::InitBuiltinTypes() {
46 assert(VoidTy.isNull() && "Context reinitialized?");
47
48 // C99 6.2.5p19.
Chris Lattner726f97b2006-12-03 02:57:32 +000049 InitBuiltinType(VoidTy, BuiltinType::Void);
Chris Lattner970e54e2006-11-12 00:37:36 +000050
51 // C99 6.2.5p2.
Chris Lattner726f97b2006-12-03 02:57:32 +000052 InitBuiltinType(BoolTy, BuiltinType::Bool);
Chris Lattner970e54e2006-11-12 00:37:36 +000053 // C99 6.2.5p3.
Chris Lattner726f97b2006-12-03 02:57:32 +000054 InitBuiltinType(CharTy, BuiltinType::Char);
Chris Lattner970e54e2006-11-12 00:37:36 +000055 // C99 6.2.5p4.
Chris Lattner726f97b2006-12-03 02:57:32 +000056 InitBuiltinType(SignedCharTy, BuiltinType::SChar);
57 InitBuiltinType(ShortTy, BuiltinType::Short);
58 InitBuiltinType(IntTy, BuiltinType::Int);
59 InitBuiltinType(LongTy, BuiltinType::Long);
60 InitBuiltinType(LongLongTy, BuiltinType::LongLong);
Chris Lattner970e54e2006-11-12 00:37:36 +000061
62 // C99 6.2.5p6.
Chris Lattner726f97b2006-12-03 02:57:32 +000063 InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
64 InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
65 InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
66 InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
67 InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
Chris Lattner970e54e2006-11-12 00:37:36 +000068
69 // C99 6.2.5p10.
Chris Lattner726f97b2006-12-03 02:57:32 +000070 InitBuiltinType(FloatTy, BuiltinType::Float);
71 InitBuiltinType(DoubleTy, BuiltinType::Double);
72 InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
Chris Lattner970e54e2006-11-12 00:37:36 +000073
74 // C99 6.2.5p11.
Chris Lattner726f97b2006-12-03 02:57:32 +000075 InitBuiltinType(FloatComplexTy, BuiltinType::FloatComplex);
76 InitBuiltinType(DoubleComplexTy, BuiltinType::DoubleComplex);
77 InitBuiltinType(LongDoubleComplexTy, BuiltinType::LongDoubleComplex);
Chris Lattner970e54e2006-11-12 00:37:36 +000078}
79
80/// getPointerType - Return the uniqued reference to the type for a pointer to
81/// the specified type.
Chris Lattner7ccecb92006-11-12 08:50:50 +000082TypeRef ASTContext::getPointerType(TypeRef T) {
Chris Lattnerd5973eb2006-11-12 00:53:46 +000083 // FIXME: This is obviously braindead!
84 // Unique pointers, to guarantee there is only one pointer of a particular
85 // structure.
86 for (unsigned i = 0, e = Types.size(); i != e; ++i)
Chris Lattner47814662006-11-12 00:56:20 +000087 if (PointerType *PTy = dyn_cast<PointerType>(Types[i]))
Chris Lattner7ccecb92006-11-12 08:50:50 +000088 if (PTy->getPointeeType() == T)
Chris Lattnerd5973eb2006-11-12 00:53:46 +000089 return Types[i];
Chris Lattner970e54e2006-11-12 00:37:36 +000090
Chris Lattner7ccecb92006-11-12 08:50:50 +000091 // If the pointee type isn't canonical, this won't be a canonical type either,
92 // so fill in the canonical type field.
Chris Lattner970e54e2006-11-12 00:37:36 +000093 Type *Canonical = 0;
94 if (!T->isCanonical())
95 Canonical = getPointerType(T.getCanonicalType()).getTypePtr();
Chris Lattnerd5973eb2006-11-12 00:53:46 +000096
97 Types.push_back(new PointerType(T, Canonical));
98 return Types.back();
Chris Lattnerddc135e2006-11-10 06:34:16 +000099}
100
Chris Lattner7ccecb92006-11-12 08:50:50 +0000101/// getArrayType - Return the unique reference to the type for an array of the
102/// specified element type.
103TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
104 unsigned EltTypeQuals, void *NumElts) {
105#warning "IGNORING SIZE"
106
107 // FIXME: This is obviously braindead!
108 // Unique array, to guarantee there is only one array of a particular
109 // structure.
110 for (unsigned i = 0, e = Types.size(); i != e; ++i)
111 if (ArrayType *ATy = dyn_cast<ArrayType>(Types[i]))
112 if (ATy->getElementType() == EltTy &&
113 ATy->getSizeModifier() == ASM &&
114 ATy->getIndexTypeQualifier() == EltTypeQuals)
115 return Types[i];
116
117 // If the element type isn't canonical, this won't be a canonical type either,
118 // so fill in the canonical type field.
119 Type *Canonical = 0;
120 if (!EltTy->isCanonical())
121 Canonical = getArrayType(EltTy.getCanonicalType(), ASM, EltTypeQuals,
122 NumElts).getTypePtr();
123
124 Types.push_back(new ArrayType(EltTy, ASM, EltTypeQuals, Canonical));
125 return Types.back();
126}
127
Chris Lattnerc6ad8132006-12-02 07:52:18 +0000128/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
129///
130TypeRef ASTContext::getFunctionTypeNoProto(TypeRef ResultTy) {
131 // FIXME: This is obviously braindead!
132 // Unique functions, to guarantee there is only one function of a particular
133 // structure.
134 for (unsigned i = 0, e = Types.size(); i != e; ++i)
135 if (FunctionTypeNoProto *FTy = dyn_cast<FunctionTypeNoProto>(Types[i]))
136 if (FTy->getResultType() == ResultTy)
137 return Types[i];
138
139 Type *Canonical = 0;
140 if (!ResultTy->isCanonical())
141 Canonical =getFunctionTypeNoProto(ResultTy.getCanonicalType()).getTypePtr();
142
143 Types.push_back(new FunctionTypeNoProto(ResultTy, Canonical));
144 return Types.back();
145}
146
147/// getFunctionType - Return a normal function type with a typed argument
148/// list. isVariadic indicates whether the argument list includes '...'.
149TypeRef ASTContext::getFunctionType(TypeRef ResultTy, TypeRef *ArgArray,
150 unsigned NumArgs, bool isVariadic) {
151 // FIXME: This is obviously braindead!
152 // Unique functions, to guarantee there is only one function of a particular
153 // structure.
154 for (unsigned i = 0, e = Types.size(); i != e; ++i) {
155 if (FunctionTypeProto *FTy = dyn_cast<FunctionTypeProto>(Types[i]))
156 if (FTy->getResultType() == ResultTy &&
157 FTy->getNumArgs() == NumArgs &&
158 FTy->isVariadic() == isVariadic) {
159 bool Match = true;
160 for (unsigned arg = 0; arg != NumArgs; ++arg) {
161 if (FTy->getArgType(arg) != ArgArray[arg]) {
162 Match = false;
163 break;
164 }
165 }
166 if (Match)
167 return Types[i];
168 }
169 }
170
171 // Determine whether the type being created is already canonical or not.
172 bool isCanonical = ResultTy->isCanonical();
173 for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
174 if (!ArgArray[i]->isCanonical())
175 isCanonical = false;
176
177 // If this type isn't canonical, get the canonical version of it.
178 Type *Canonical = 0;
179 if (!isCanonical) {
180 SmallVector<TypeRef, 16> CanonicalArgs;
181 CanonicalArgs.reserve(NumArgs);
182 for (unsigned i = 0; i != NumArgs; ++i)
183 CanonicalArgs.push_back(ArgArray[i].getCanonicalType());
184
185 Canonical = getFunctionType(ResultTy.getCanonicalType(),
186 &CanonicalArgs[0], NumArgs,
187 isVariadic).getTypePtr();
188 }
189
190 // FunctionTypeProto objects are not allocated with new because they have a
191 // variable size array (for parameter types) at the end of them.
192 FunctionTypeProto *FTP =
193 (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
194 (NumArgs-1)*sizeof(TypeRef));
195 new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
196 Canonical);
197
198 Types.push_back(FTP);
199 return FTP;
200}
Chris Lattneref51c202006-11-10 07:17:23 +0000201
Chris Lattnerd0342e52006-11-20 04:02:15 +0000202/// getTypeDeclType - Return the unique reference to the type for the
203/// specified typename decl.
204TypeRef ASTContext::getTypeDeclType(TypeDecl *Decl) {
205 // FIXME: This is obviously braindead!
206 // Unique TypeDecl, to guarantee there is only one TypeDeclType.
207 for (unsigned i = 0, e = Types.size(); i != e; ++i)
208 if (TypeNameType *Ty = dyn_cast<TypeNameType>(Types[i]))
209 if (Ty->getDecl() == Decl)
210 return Types[i];
211
212 // FIXME: does this lose qualifiers from the typedef??
213
Chris Lattnerd0ee4022007-01-22 07:39:30 +0000214 Type *Canonical = Decl->getUnderlyingType().getTypePtr();
Chris Lattnerd0342e52006-11-20 04:02:15 +0000215 Types.push_back(new TypeNameType(Decl, Canonical));
216 return Types.back();
217}
218
Chris Lattnerfb072462007-01-23 05:45:31 +0000219/// getTagDeclType - Return the unique reference to the type for the
220/// specified TagDecl (struct/union/class/enum) decl.
221TypeRef ASTContext::getTagDeclType(TagDecl *Decl) {
222 // FIXME: This is obviously braindead!
223 // Unique TypeDecl, to guarantee there is only one TaggedType.
224 for (unsigned i = 0, e = Types.size(); i != e; ++i)
225 if (TaggedType *Ty = dyn_cast<TaggedType>(Types[i]))
226 if (Ty->getDecl() == Decl)
227 return Types[i];
228
229 // FIXME: does this lose qualifiers from the typedef??
230
231 Types.push_back(new TaggedType(Decl, 0));
232 return Types.back();
233}
234
235