blob: d45780043fb0a80ecb924bf3d53f587ada73903b [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +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 Naroff3536b442007-09-06 21:24:23 +000028static unsigned nInterfaceDecls = 0;
Steve Naroff3f128ad2007-09-17 14:16:13 +000029static unsigned nClassDecls = 0;
30static unsigned nMethodDecls = 0;
31static unsigned nProtocolDecls = 0;
32static unsigned nIvarDecls = 0;
33
Reid Spencer5f016e22007-07-11 17:01:13 +000034static bool StatSwitch = false;
35
Steve Naroffe5ea3802007-09-17 14:49:06 +000036const char *Decl::getDeclKindName() const {
Steve Naroff8c9f13e2007-09-16 16:16:00 +000037 switch (DeclKind) {
38 default: assert(0 && "Unknown decl kind!");
39 case Typedef:
40 return "Typedef";
41 case Function:
42 return "Function";
43 case BlockVariable:
44 return "BlockVariable";
45 case FileVariable:
46 return "FileVariable";
47 case ParmVariable:
48 return "ParmVariable";
49 case EnumConstant:
50 return "EnumConstant";
51 case ObjcInterface:
52 return "ObjcInterface";
53 case ObjcClass:
54 return "ObjcClass";
55 case ObjcMethod:
56 return "ObjcMethod";
57 case ObjcProtoMethod:
58 return "ObjcProtoMethod";
59 case ObjcProtocol:
60 return "ObjcProtocol";
61 case Struct:
62 return "Struct";
63 case Union:
64 return "Union";
65 case Class:
66 return "Class";
67 case Enum:
68 return "Enum";
69 }
70}
71
Reid Spencer5f016e22007-07-11 17:01:13 +000072bool Decl::CollectingStats(bool enable) {
73 if (enable) StatSwitch = true;
74 return StatSwitch;
75}
76
77void Decl::PrintStats() {
78 fprintf(stderr, "*** Decl Stats:\n");
79 fprintf(stderr, " %d decls total.\n",
80 int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
Steve Naroff3f128ad2007-09-17 14:16:13 +000081 nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
82 nMethodDecls+nProtocolDecls+nIvarDecls));
Reid Spencer5f016e22007-07-11 17:01:13 +000083 fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
84 nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
85 fprintf(stderr, " %d block variable decls, %d each (%d bytes)\n",
86 nBlockVars, (int)sizeof(BlockVarDecl),
87 int(nBlockVars*sizeof(BlockVarDecl)));
88 fprintf(stderr, " %d file variable decls, %d each (%d bytes)\n",
89 nFileVars, (int)sizeof(FileVarDecl),
90 int(nFileVars*sizeof(FileVarDecl)));
91 fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
92 nParmVars, (int)sizeof(ParmVarDecl),
93 int(nParmVars*sizeof(ParmVarDecl)));
94 fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
95 nFieldDecls, (int)sizeof(FieldDecl),
96 int(nFieldDecls*sizeof(FieldDecl)));
97 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
98 nSUC, (int)sizeof(RecordDecl),
99 int(nSUC*sizeof(RecordDecl)));
100 fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
101 nEnumDecls, (int)sizeof(EnumDecl),
102 int(nEnumDecls*sizeof(EnumDecl)));
103 fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
104 nEnumConst, (int)sizeof(EnumConstantDecl),
105 int(nEnumConst*sizeof(EnumConstantDecl)));
106 fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
107 nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
Steve Naroff3f128ad2007-09-17 14:16:13 +0000108 // Objective-C decls...
109 fprintf(stderr, " %d interface decls, %d each (%d bytes)\n",
110 nInterfaceDecls, (int)sizeof(ObjcInterfaceDecl),
111 int(nInterfaceDecls*sizeof(ObjcInterfaceDecl)));
112 fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n",
113 nIvarDecls, (int)sizeof(ObjcIvarDecl),
114 int(nIvarDecls*sizeof(ObjcIvarDecl)));
115 fprintf(stderr, " %d class decls, %d each (%d bytes)\n",
116 nClassDecls, (int)sizeof(ObjcClassDecl),
117 int(nClassDecls*sizeof(ObjcClassDecl)));
118 fprintf(stderr, " %d method decls, %d each (%d bytes)\n",
119 nMethodDecls, (int)sizeof(ObjcMethodDecl),
120 int(nMethodDecls*sizeof(ObjcMethodDecl)));
121 fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n",
122 nProtocolDecls, (int)sizeof(ObjcProtocolDecl),
123 int(nProtocolDecls*sizeof(ObjcProtocolDecl)));
124
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 fprintf(stderr, "Total bytes = %d\n",
126 int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
127 nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
128 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
129 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
Steve Naroff3f128ad2007-09-17 14:16:13 +0000130 nTypedef*sizeof(TypedefDecl)) /* FIXME: add Objc decls */);
Reid Spencer5f016e22007-07-11 17:01:13 +0000131}
132
133void Decl::addDeclKind(const Kind k) {
134 switch (k) {
135 case Typedef:
136 nTypedef++;
137 break;
138 case Function:
139 nFuncs++;
140 break;
141 case BlockVariable:
142 nBlockVars++;
143 break;
144 case FileVariable:
145 nFileVars++;
146 break;
147 case ParmVariable:
148 nParmVars++;
149 break;
150 case EnumConstant:
151 nEnumConst++;
152 break;
153 case Field:
154 nFieldDecls++;
155 break;
156 case Struct:
157 case Union:
158 case Class:
159 nSUC++;
160 break;
161 case Enum:
162 nEnumDecls++;
163 break;
Steve Naroff3536b442007-09-06 21:24:23 +0000164 case ObjcInterface:
165 nInterfaceDecls++;
166 break;
Chris Lattner7341c332007-09-16 19:23:04 +0000167 case ObjcClass:
Steve Naroff3f128ad2007-09-17 14:16:13 +0000168 nClassDecls++;
169 break;
Chris Lattner7341c332007-09-16 19:23:04 +0000170 case ObjcMethod:
171 case ObjcProtoMethod:
Steve Naroff3f128ad2007-09-17 14:16:13 +0000172 nMethodDecls++;
173 break;
Chris Lattner7341c332007-09-16 19:23:04 +0000174 case ObjcProtocol:
Steve Naroff3f128ad2007-09-17 14:16:13 +0000175 nProtocolDecls++;
176 break;
Chris Lattner7341c332007-09-16 19:23:04 +0000177 case ObjcIvar:
Steve Naroff3f128ad2007-09-17 14:16:13 +0000178 nIvarDecls++;
Chris Lattner7341c332007-09-16 19:23:04 +0000179 break;
Reid Spencer5f016e22007-07-11 17:01:13 +0000180 }
181}
182
183// Out-of-line virtual method providing a home for Decl.
184Decl::~Decl() {
185}
186
Steve Naroff8e74c932007-09-13 21:41:19 +0000187const char *FieldDecl::getName() const {
188 if (const IdentifierInfo *II = getIdentifier())
189 return II->getName();
190 return "";
191}
192
193const char *ScopedDecl::getName() const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000194 if (const IdentifierInfo *II = getIdentifier())
195 return II->getName();
196 return "";
197}
198
199
200FunctionDecl::~FunctionDecl() {
201 delete[] ParamInfo;
202}
203
204unsigned FunctionDecl::getNumParams() const {
205 return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
206}
207
208void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
209 assert(ParamInfo == 0 && "Already has param info!");
210 assert(NumParams == getNumParams() && "Parameter count mismatch!");
211
212 // Zero params -> null pointer.
213 if (NumParams) {
214 ParamInfo = new ParmVarDecl*[NumParams];
215 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
216 }
217}
218
219
220/// defineBody - When created, RecordDecl's correspond to a forward declared
221/// record. This method is used to mark the decl as being defined, with the
222/// specified contents.
223void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
224 assert(!isDefinition() && "Cannot redefine record!");
225 setDefinition(true);
226 NumMembers = numMembers;
227 if (numMembers) {
228 Members = new FieldDecl*[numMembers];
229 memcpy(Members, members, numMembers*sizeof(Decl*));
230 }
231}
232
233FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
234 if (Members == 0 || NumMembers < 0)
235 return 0;
236
237 // linear search. When C++ classes come along, will likely need to revisit.
238 for (int i = 0; i < NumMembers; ++i) {
239 if (Members[i]->getIdentifier() == name)
240 return Members[i];
241 }
242 return 0;
Chris Lattner6fa5f092007-07-12 15:43:07 +0000243}
Fariborz Jahaniane3a2ca72007-09-10 20:33:04 +0000244
Fariborz Jahaniane55cd002007-09-12 18:23:47 +0000245void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
246 unsigned NumParams) {
247 assert(ParamInfo == 0 && "Already has param info!");
248
249 // Zero params -> null pointer.
250 if (NumParams) {
251 ParamInfo = new ParmVarDecl*[NumParams];
252 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
253 NumMethodParams = NumParams;
254 }
255}
256
257ObjcMethodDecl::~ObjcMethodDecl() {
258 delete[] ParamInfo;
259}
260
Fariborz Jahanianb04a0212007-09-14 21:08:27 +0000261/// ObjcAddInstanceVariablesToClass - Inserts instance variables
262/// into ObjcInterfaceDecl's fields.
263///
264void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
265 unsigned numIvars) {
266 NumIvars = numIvars;
267 if (numIvars) {
268 Ivars = new ObjcIvarDecl*[numIvars];
269 memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
270 }
271}
272
Fariborz Jahaniane3a2ca72007-09-10 20:33:04 +0000273/// addObjcMethods - Insert instance and methods declarations into
274/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
275///
276void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
277 unsigned numInsMembers,
278 ObjcMethodDecl **clsMethods,
279 unsigned numClsMembers) {
280 NumInsMethods = numInsMembers;
281 if (numInsMembers) {
282 InsMethods = new ObjcMethodDecl*[numInsMembers];
283 memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
284 }
285 NumClsMethods = numClsMembers;
286 if (numClsMembers) {
287 ClsMethods = new ObjcMethodDecl*[numClsMembers];
288 memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
289 }
290}
291