blob: 285b184217386f807a274f59c000880ceee19045 [file] [log] [blame]
Chris Lattnera11999d2006-10-15 22:34:45 +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"
Chris Lattner17ed4872006-11-20 04:58:19 +000015#include "clang/Lex/IdentifierTable.h"
Chris Lattner6d9a6852006-10-25 05:11:20 +000016using namespace clang;
Chris Lattnera11999d2006-10-15 22:34:45 +000017
Steve Narofff84d11f2007-05-23 21:48:04 +000018// temporary statistics gathering
19static unsigned nFuncs = 0;
20static unsigned nBlockVars = 0;
21static unsigned nFileVars = 0;
22static unsigned nParmVars = 0;
Chris Lattnera5490952007-05-24 01:09:39 +000023static unsigned nSUC = 0;
Steve Narofff84d11f2007-05-23 21:48:04 +000024static unsigned nEnumConst = 0;
25static unsigned nEnumDecls = 0;
26static unsigned nTypedef = 0;
27static unsigned nFieldDecls = 0;
Steve Naroff09bf8152007-09-06 21:24:23 +000028static unsigned nInterfaceDecls = 0;
Steve Narofff84d11f2007-05-23 21:48:04 +000029static bool StatSwitch = false;
30
Steve Naroff2f742082007-09-16 16:16:00 +000031const char *Decl::getDeclKindName() {
32 switch (DeclKind) {
33 default: assert(0 && "Unknown decl kind!");
34 case Typedef:
35 return "Typedef";
36 case Function:
37 return "Function";
38 case BlockVariable:
39 return "BlockVariable";
40 case FileVariable:
41 return "FileVariable";
42 case ParmVariable:
43 return "ParmVariable";
44 case EnumConstant:
45 return "EnumConstant";
46 case ObjcInterface:
47 return "ObjcInterface";
48 case ObjcClass:
49 return "ObjcClass";
50 case ObjcMethod:
51 return "ObjcMethod";
52 case ObjcProtoMethod:
53 return "ObjcProtoMethod";
54 case ObjcProtocol:
55 return "ObjcProtocol";
56 case Struct:
57 return "Struct";
58 case Union:
59 return "Union";
60 case Class:
61 return "Class";
62 case Enum:
63 return "Enum";
64 }
65}
66
Steve Narofff84d11f2007-05-23 21:48:04 +000067bool Decl::CollectingStats(bool enable) {
68 if (enable) StatSwitch = true;
69 return StatSwitch;
70}
71
72void Decl::PrintStats() {
Chris Lattnerfc234de2007-05-24 00:40:54 +000073 fprintf(stderr, "*** Decl Stats:\n");
74 fprintf(stderr, " %d decls total.\n",
Chris Lattnera5490952007-05-24 01:09:39 +000075 int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
Chris Lattnerfc234de2007-05-24 00:40:54 +000076 nEnumDecls+nEnumConst+nTypedef));
77 fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
78 nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
79 fprintf(stderr, " %d block variable decls, %d each (%d bytes)\n",
80 nBlockVars, (int)sizeof(BlockVarDecl),
81 int(nBlockVars*sizeof(BlockVarDecl)));
82 fprintf(stderr, " %d file variable decls, %d each (%d bytes)\n",
83 nFileVars, (int)sizeof(FileVarDecl),
84 int(nFileVars*sizeof(FileVarDecl)));
85 fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
86 nParmVars, (int)sizeof(ParmVarDecl),
87 int(nParmVars*sizeof(ParmVarDecl)));
88 fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
89 nFieldDecls, (int)sizeof(FieldDecl),
90 int(nFieldDecls*sizeof(FieldDecl)));
Chris Lattnera5490952007-05-24 01:09:39 +000091 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
92 nSUC, (int)sizeof(RecordDecl),
93 int(nSUC*sizeof(RecordDecl)));
Chris Lattnerfc234de2007-05-24 00:40:54 +000094 fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
95 nEnumDecls, (int)sizeof(EnumDecl),
96 int(nEnumDecls*sizeof(EnumDecl)));
97 fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
98 nEnumConst, (int)sizeof(EnumConstantDecl),
99 int(nEnumConst*sizeof(EnumConstantDecl)));
100 fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
101 nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
102 fprintf(stderr, "Total bytes = %d\n",
103 int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
104 nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
Chris Lattnera5490952007-05-24 01:09:39 +0000105 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
Chris Lattnerfc234de2007-05-24 00:40:54 +0000106 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
107 nTypedef*sizeof(TypedefDecl)));
Steve Narofff84d11f2007-05-23 21:48:04 +0000108}
109
110void Decl::addDeclKind(const Kind k) {
Chris Lattnerfc234de2007-05-24 00:40:54 +0000111 switch (k) {
112 case Typedef:
113 nTypedef++;
114 break;
115 case Function:
116 nFuncs++;
117 break;
118 case BlockVariable:
119 nBlockVars++;
120 break;
121 case FileVariable:
122 nFileVars++;
123 break;
124 case ParmVariable:
125 nParmVars++;
126 break;
127 case EnumConstant:
128 nEnumConst++;
129 break;
130 case Field:
131 nFieldDecls++;
132 break;
133 case Struct:
134 case Union:
135 case Class:
Chris Lattnera5490952007-05-24 01:09:39 +0000136 nSUC++;
Chris Lattnerfc234de2007-05-24 00:40:54 +0000137 break;
138 case Enum:
139 nEnumDecls++;
140 break;
Steve Naroff09bf8152007-09-06 21:24:23 +0000141 case ObjcInterface:
142 nInterfaceDecls++;
143 break;
Chris Lattner81b76242007-09-16 19:23:04 +0000144 case ObjcClass:
145 case ObjcMethod:
146 case ObjcProtoMethod:
147 case ObjcProtocol:
148 case ObjcIvar:
149 assert(0 && "FIXME: Count these decls!");
150 break;
Chris Lattnerfc234de2007-05-24 00:40:54 +0000151 }
Steve Narofff84d11f2007-05-23 21:48:04 +0000152}
153
Chris Lattner6d9a6852006-10-25 05:11:20 +0000154// Out-of-line virtual method providing a home for Decl.
155Decl::~Decl() {
156}
Chris Lattner17ed4872006-11-20 04:58:19 +0000157
Steve Naroff9def2b12007-09-13 21:41:19 +0000158const char *FieldDecl::getName() const {
159 if (const IdentifierInfo *II = getIdentifier())
160 return II->getName();
161 return "";
162}
163
164const char *ScopedDecl::getName() const {
Chris Lattnerec040b12007-01-21 23:09:50 +0000165 if (const IdentifierInfo *II = getIdentifier())
166 return II->getName();
167 return "";
Chris Lattner17ed4872006-11-20 04:58:19 +0000168}
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +0000169
170
171FunctionDecl::~FunctionDecl() {
172 delete[] ParamInfo;
173}
174
175unsigned FunctionDecl::getNumParams() const {
176 return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
177}
178
Chris Lattner53621a52007-06-13 20:44:40 +0000179void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +0000180 assert(ParamInfo == 0 && "Already has param info!");
181 assert(NumParams == getNumParams() && "Parameter count mismatch!");
182
Chris Lattner8f5bf2f2007-01-21 19:04:10 +0000183 // Zero params -> null pointer.
184 if (NumParams) {
Chris Lattner53621a52007-06-13 20:44:40 +0000185 ParamInfo = new ParmVarDecl*[NumParams];
186 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
Chris Lattner8f5bf2f2007-01-21 19:04:10 +0000187 }
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +0000188}
Chris Lattner41943152007-01-25 04:52:46 +0000189
190
191/// defineBody - When created, RecordDecl's correspond to a forward declared
192/// record. This method is used to mark the decl as being defined, with the
193/// specified contents.
Steve Naroffcc321422007-03-26 23:09:51 +0000194void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
Chris Lattner41943152007-01-25 04:52:46 +0000195 assert(!isDefinition() && "Cannot redefine record!");
196 setDefinition(true);
Chris Lattner5f521502007-01-25 06:27:24 +0000197 NumMembers = numMembers;
198 if (numMembers) {
Steve Naroffcc321422007-03-26 23:09:51 +0000199 Members = new FieldDecl*[numMembers];
Chris Lattner5f521502007-01-25 06:27:24 +0000200 memcpy(Members, members, numMembers*sizeof(Decl*));
Chris Lattner41943152007-01-25 04:52:46 +0000201 }
202}
Steve Naroffcc321422007-03-26 23:09:51 +0000203
204FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
205 if (Members == 0 || NumMembers < 0)
206 return 0;
207
208 // linear search. When C++ classes come along, will likely need to revisit.
209 for (int i = 0; i < NumMembers; ++i) {
210 if (Members[i]->getIdentifier() == name)
211 return Members[i];
212 }
213 return 0;
Chris Lattnerbd4de5df2007-07-12 15:43:07 +0000214}
Fariborz Jahanian33d03742007-09-10 20:33:04 +0000215
Fariborz Jahaniancfb31fa2007-09-12 18:23:47 +0000216void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
217 unsigned NumParams) {
218 assert(ParamInfo == 0 && "Already has param info!");
219
220 // Zero params -> null pointer.
221 if (NumParams) {
222 ParamInfo = new ParmVarDecl*[NumParams];
223 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
224 NumMethodParams = NumParams;
225 }
226}
227
228ObjcMethodDecl::~ObjcMethodDecl() {
229 delete[] ParamInfo;
230}
231
Fariborz Jahanianf3287bf2007-09-14 21:08:27 +0000232/// ObjcAddInstanceVariablesToClass - Inserts instance variables
233/// into ObjcInterfaceDecl's fields.
234///
235void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
236 unsigned numIvars) {
237 NumIvars = numIvars;
238 if (numIvars) {
239 Ivars = new ObjcIvarDecl*[numIvars];
240 memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
241 }
242}
243
Fariborz Jahanian33d03742007-09-10 20:33:04 +0000244/// addObjcMethods - Insert instance and methods declarations into
245/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
246///
247void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
248 unsigned numInsMembers,
249 ObjcMethodDecl **clsMethods,
250 unsigned numClsMembers) {
251 NumInsMethods = numInsMembers;
252 if (numInsMembers) {
253 InsMethods = new ObjcMethodDecl*[numInsMembers];
254 memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
255 }
256 NumClsMethods = numClsMembers;
257 if (numClsMembers) {
258 ClsMethods = new ObjcMethodDecl*[numClsMembers];
259 memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
260 }
261}
262