blob: bde4b6b45b52b6c898ccbb9fb427cf37b55b31ef [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
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 Decl class and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Decl.h"
15#include "clang/Lex/IdentifierTable.h"
16using namespace clang;
17
18// temporary statistics gathering
19static unsigned nFuncs = 0;
20static unsigned nBlockVars = 0;
21static unsigned nFileVars = 0;
22static unsigned nParmVars = 0;
23static unsigned nSUC = 0;
24static unsigned nEnumConst = 0;
25static unsigned nEnumDecls = 0;
26static unsigned nTypedef = 0;
27static unsigned nFieldDecls = 0;
Steve Naroff81f1bba2007-09-06 21:24:23 +000028static unsigned nInterfaceDecls = 0;
Steve Naroff948fd372007-09-17 14:16:13 +000029static unsigned nClassDecls = 0;
30static unsigned nMethodDecls = 0;
31static unsigned nProtocolDecls = 0;
Fariborz Jahanianc716c942007-09-21 15:40:54 +000032static unsigned nForwardProtocolDecls = 0;
Fariborz Jahanianf25220e2007-09-18 20:26:58 +000033static unsigned nCategoryDecls = 0;
Steve Naroff948fd372007-09-17 14:16:13 +000034static unsigned nIvarDecls = 0;
35
Chris Lattner4b009652007-07-25 00:24:17 +000036static bool StatSwitch = false;
37
Steve Naroff590aba82007-09-17 14:49:06 +000038const char *Decl::getDeclKindName() const {
Steve Narofff0c31dd2007-09-16 16:16:00 +000039 switch (DeclKind) {
40 default: assert(0 && "Unknown decl kind!");
41 case Typedef:
42 return "Typedef";
43 case Function:
44 return "Function";
45 case BlockVariable:
46 return "BlockVariable";
47 case FileVariable:
48 return "FileVariable";
49 case ParmVariable:
50 return "ParmVariable";
51 case EnumConstant:
52 return "EnumConstant";
53 case ObjcInterface:
54 return "ObjcInterface";
55 case ObjcClass:
56 return "ObjcClass";
57 case ObjcMethod:
58 return "ObjcMethod";
59 case ObjcProtoMethod:
60 return "ObjcProtoMethod";
61 case ObjcProtocol:
62 return "ObjcProtocol";
Fariborz Jahanianc716c942007-09-21 15:40:54 +000063 case ObjcForwardProtocol:
64 return "ObjcForwardProtocol";
Steve Narofff0c31dd2007-09-16 16:16:00 +000065 case Struct:
66 return "Struct";
67 case Union:
68 return "Union";
69 case Class:
70 return "Class";
71 case Enum:
72 return "Enum";
73 }
74}
75
Chris Lattner4b009652007-07-25 00:24:17 +000076bool Decl::CollectingStats(bool enable) {
77 if (enable) StatSwitch = true;
78 return StatSwitch;
79}
80
81void Decl::PrintStats() {
82 fprintf(stderr, "*** Decl Stats:\n");
83 fprintf(stderr, " %d decls total.\n",
84 int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
Steve Naroff948fd372007-09-17 14:16:13 +000085 nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
Fariborz Jahanianf25220e2007-09-18 20:26:58 +000086 nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls));
Chris Lattner4b009652007-07-25 00:24:17 +000087 fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
88 nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
89 fprintf(stderr, " %d block variable decls, %d each (%d bytes)\n",
90 nBlockVars, (int)sizeof(BlockVarDecl),
91 int(nBlockVars*sizeof(BlockVarDecl)));
92 fprintf(stderr, " %d file variable decls, %d each (%d bytes)\n",
93 nFileVars, (int)sizeof(FileVarDecl),
94 int(nFileVars*sizeof(FileVarDecl)));
95 fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
96 nParmVars, (int)sizeof(ParmVarDecl),
97 int(nParmVars*sizeof(ParmVarDecl)));
98 fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
99 nFieldDecls, (int)sizeof(FieldDecl),
100 int(nFieldDecls*sizeof(FieldDecl)));
101 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
102 nSUC, (int)sizeof(RecordDecl),
103 int(nSUC*sizeof(RecordDecl)));
104 fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
105 nEnumDecls, (int)sizeof(EnumDecl),
106 int(nEnumDecls*sizeof(EnumDecl)));
107 fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
108 nEnumConst, (int)sizeof(EnumConstantDecl),
109 int(nEnumConst*sizeof(EnumConstantDecl)));
110 fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
111 nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
Steve Naroff948fd372007-09-17 14:16:13 +0000112 // Objective-C decls...
113 fprintf(stderr, " %d interface decls, %d each (%d bytes)\n",
114 nInterfaceDecls, (int)sizeof(ObjcInterfaceDecl),
115 int(nInterfaceDecls*sizeof(ObjcInterfaceDecl)));
116 fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n",
117 nIvarDecls, (int)sizeof(ObjcIvarDecl),
118 int(nIvarDecls*sizeof(ObjcIvarDecl)));
119 fprintf(stderr, " %d class decls, %d each (%d bytes)\n",
120 nClassDecls, (int)sizeof(ObjcClassDecl),
121 int(nClassDecls*sizeof(ObjcClassDecl)));
122 fprintf(stderr, " %d method decls, %d each (%d bytes)\n",
123 nMethodDecls, (int)sizeof(ObjcMethodDecl),
124 int(nMethodDecls*sizeof(ObjcMethodDecl)));
125 fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n",
126 nProtocolDecls, (int)sizeof(ObjcProtocolDecl),
127 int(nProtocolDecls*sizeof(ObjcProtocolDecl)));
Fariborz Jahanianc716c942007-09-21 15:40:54 +0000128 fprintf(stderr, " %d forward protocol decls, %d each (%d bytes)\n",
129 nForwardProtocolDecls, (int)sizeof(ObjcForwardProtocolDecl),
130 int(nForwardProtocolDecls*sizeof(ObjcForwardProtocolDecl)));
Fariborz Jahanianf25220e2007-09-18 20:26:58 +0000131 fprintf(stderr, " %d category decls, %d each (%d bytes)\n",
132 nCategoryDecls, (int)sizeof(ObjcCategoryDecl),
133 int(nCategoryDecls*sizeof(ObjcCategoryDecl)));
Steve Naroff948fd372007-09-17 14:16:13 +0000134
Chris Lattner4b009652007-07-25 00:24:17 +0000135 fprintf(stderr, "Total bytes = %d\n",
136 int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
137 nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
138 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
139 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
Steve Naroff948fd372007-09-17 14:16:13 +0000140 nTypedef*sizeof(TypedefDecl)) /* FIXME: add Objc decls */);
Chris Lattner4b009652007-07-25 00:24:17 +0000141}
142
143void Decl::addDeclKind(const Kind k) {
144 switch (k) {
145 case Typedef:
146 nTypedef++;
147 break;
148 case Function:
149 nFuncs++;
150 break;
151 case BlockVariable:
152 nBlockVars++;
153 break;
154 case FileVariable:
155 nFileVars++;
156 break;
157 case ParmVariable:
158 nParmVars++;
159 break;
160 case EnumConstant:
161 nEnumConst++;
162 break;
163 case Field:
164 nFieldDecls++;
165 break;
166 case Struct:
167 case Union:
168 case Class:
169 nSUC++;
170 break;
171 case Enum:
172 nEnumDecls++;
173 break;
Steve Naroff81f1bba2007-09-06 21:24:23 +0000174 case ObjcInterface:
175 nInterfaceDecls++;
176 break;
Chris Lattnerb15b4382007-09-16 19:23:04 +0000177 case ObjcClass:
Steve Naroff948fd372007-09-17 14:16:13 +0000178 nClassDecls++;
179 break;
Chris Lattnerb15b4382007-09-16 19:23:04 +0000180 case ObjcMethod:
181 case ObjcProtoMethod:
Steve Naroff948fd372007-09-17 14:16:13 +0000182 nMethodDecls++;
183 break;
Chris Lattnerb15b4382007-09-16 19:23:04 +0000184 case ObjcProtocol:
Steve Naroff948fd372007-09-17 14:16:13 +0000185 nProtocolDecls++;
186 break;
Fariborz Jahanianc716c942007-09-21 15:40:54 +0000187 case ObjcForwardProtocol:
188 nForwardProtocolDecls++;
189 break;
Fariborz Jahanianf25220e2007-09-18 20:26:58 +0000190 case ObjcCategory:
191 nCategoryDecls++;
192 break;
Chris Lattnerb15b4382007-09-16 19:23:04 +0000193 case ObjcIvar:
Steve Naroff948fd372007-09-17 14:16:13 +0000194 nIvarDecls++;
Chris Lattnerb15b4382007-09-16 19:23:04 +0000195 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000196 }
197}
198
199// Out-of-line virtual method providing a home for Decl.
200Decl::~Decl() {
201}
202
Steve Naroffcb597472007-09-13 21:41:19 +0000203const char *FieldDecl::getName() const {
204 if (const IdentifierInfo *II = getIdentifier())
205 return II->getName();
206 return "";
207}
208
209const char *ScopedDecl::getName() const {
Chris Lattner4b009652007-07-25 00:24:17 +0000210 if (const IdentifierInfo *II = getIdentifier())
211 return II->getName();
212 return "";
213}
214
215
216FunctionDecl::~FunctionDecl() {
217 delete[] ParamInfo;
218}
219
220unsigned FunctionDecl::getNumParams() const {
221 return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
222}
223
224void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
225 assert(ParamInfo == 0 && "Already has param info!");
226 assert(NumParams == getNumParams() && "Parameter count mismatch!");
227
228 // Zero params -> null pointer.
229 if (NumParams) {
230 ParamInfo = new ParmVarDecl*[NumParams];
231 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
232 }
233}
234
235
236/// defineBody - When created, RecordDecl's correspond to a forward declared
237/// record. This method is used to mark the decl as being defined, with the
238/// specified contents.
239void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
240 assert(!isDefinition() && "Cannot redefine record!");
241 setDefinition(true);
242 NumMembers = numMembers;
243 if (numMembers) {
244 Members = new FieldDecl*[numMembers];
245 memcpy(Members, members, numMembers*sizeof(Decl*));
246 }
247}
248
249FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
250 if (Members == 0 || NumMembers < 0)
251 return 0;
252
253 // linear search. When C++ classes come along, will likely need to revisit.
254 for (int i = 0; i < NumMembers; ++i) {
255 if (Members[i]->getIdentifier() == name)
256 return Members[i];
257 }
258 return 0;
259}
Fariborz Jahanian3dc7cbc2007-09-10 20:33:04 +0000260
Fariborz Jahanian86f74a42007-09-12 18:23:47 +0000261void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
262 unsigned NumParams) {
263 assert(ParamInfo == 0 && "Already has param info!");
264
265 // Zero params -> null pointer.
266 if (NumParams) {
267 ParamInfo = new ParmVarDecl*[NumParams];
268 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
269 NumMethodParams = NumParams;
270 }
271}
272
273ObjcMethodDecl::~ObjcMethodDecl() {
274 delete[] ParamInfo;
275}
276
Fariborz Jahanianebcc9b62007-09-14 21:08:27 +0000277/// ObjcAddInstanceVariablesToClass - Inserts instance variables
278/// into ObjcInterfaceDecl's fields.
279///
280void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
281 unsigned numIvars) {
282 NumIvars = numIvars;
283 if (numIvars) {
284 Ivars = new ObjcIvarDecl*[numIvars];
285 memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
286 }
287}
288
Fariborz Jahanian3dc7cbc2007-09-10 20:33:04 +0000289/// addObjcMethods - Insert instance and methods declarations into
290/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
291///
292void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
293 unsigned numInsMembers,
294 ObjcMethodDecl **clsMethods,
295 unsigned numClsMembers) {
296 NumInsMethods = numInsMembers;
297 if (numInsMembers) {
298 InsMethods = new ObjcMethodDecl*[numInsMembers];
299 memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
300 }
301 NumClsMethods = numClsMembers;
302 if (numClsMembers) {
303 ClsMethods = new ObjcMethodDecl*[numClsMembers];
304 memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
305 }
306}
307
Fariborz Jahanian63ca8ae2007-09-17 21:07:36 +0000308/// ObjcAddProtoMethods - Insert instance and methods declarations into
309/// ObjcProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
310///
311void ObjcProtocolDecl::ObjcAddProtoMethods(ObjcMethodDecl **insMethods,
312 unsigned numInsMembers,
313 ObjcMethodDecl **clsMethods,
314 unsigned numClsMembers) {
315 NumProtoInsMethods = numInsMembers;
316 if (numInsMembers) {
Fariborz Jahanian4a2b0ac2007-09-17 22:36:42 +0000317 ProtoInsMethods = new ObjcMethodDecl*[numInsMembers];
Fariborz Jahanian63ca8ae2007-09-17 21:07:36 +0000318 memcpy(ProtoInsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
319 }
320 NumProtoClsMethods = numClsMembers;
321 if (numClsMembers) {
Fariborz Jahanian4a2b0ac2007-09-17 22:36:42 +0000322 ProtoClsMethods = new ObjcMethodDecl*[numClsMembers];
Fariborz Jahanian63ca8ae2007-09-17 21:07:36 +0000323 memcpy(ProtoClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
324 }
325}
326
Fariborz Jahanianf25220e2007-09-18 20:26:58 +0000327/// ObjcAddCat - Insert instance and methods declarations into
328/// ObjcProtocolDecl's CatInsMethods and CatClsMethods fields.
329///
330void ObjcCategoryDecl::ObjcAddCatMethods(ObjcMethodDecl **insMethods,
331 unsigned numInsMembers,
332 ObjcMethodDecl **clsMethods,
333 unsigned numClsMembers) {
334 NumCatInsMethods = numInsMembers;
335 if (numInsMembers) {
336 CatInsMethods = new ObjcMethodDecl*[numInsMembers];
337 memcpy(CatInsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
338 }
339 NumCatClsMethods = numClsMembers;
340 if (numClsMembers) {
341 CatClsMethods = new ObjcMethodDecl*[numClsMembers];
342 memcpy(CatClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
343 }
344}
345
Fariborz Jahanian63ca8ae2007-09-17 21:07:36 +0000346