blob: 965ba2180a46b6dd5f7d2b70a29ba938b6cbea2b [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;
Chris Lattner4b009652007-07-25 00:24:17 +000029static bool StatSwitch = false;
30
31bool Decl::CollectingStats(bool enable) {
32 if (enable) StatSwitch = true;
33 return StatSwitch;
34}
35
36void Decl::PrintStats() {
37 fprintf(stderr, "*** Decl Stats:\n");
38 fprintf(stderr, " %d decls total.\n",
39 int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
40 nEnumDecls+nEnumConst+nTypedef));
41 fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
42 nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
43 fprintf(stderr, " %d block variable decls, %d each (%d bytes)\n",
44 nBlockVars, (int)sizeof(BlockVarDecl),
45 int(nBlockVars*sizeof(BlockVarDecl)));
46 fprintf(stderr, " %d file variable decls, %d each (%d bytes)\n",
47 nFileVars, (int)sizeof(FileVarDecl),
48 int(nFileVars*sizeof(FileVarDecl)));
49 fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
50 nParmVars, (int)sizeof(ParmVarDecl),
51 int(nParmVars*sizeof(ParmVarDecl)));
52 fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
53 nFieldDecls, (int)sizeof(FieldDecl),
54 int(nFieldDecls*sizeof(FieldDecl)));
55 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
56 nSUC, (int)sizeof(RecordDecl),
57 int(nSUC*sizeof(RecordDecl)));
58 fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
59 nEnumDecls, (int)sizeof(EnumDecl),
60 int(nEnumDecls*sizeof(EnumDecl)));
61 fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
62 nEnumConst, (int)sizeof(EnumConstantDecl),
63 int(nEnumConst*sizeof(EnumConstantDecl)));
64 fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
65 nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
66 fprintf(stderr, "Total bytes = %d\n",
67 int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
68 nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
69 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
70 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
71 nTypedef*sizeof(TypedefDecl)));
72}
73
74void Decl::addDeclKind(const Kind k) {
75 switch (k) {
76 case Typedef:
77 nTypedef++;
78 break;
79 case Function:
80 nFuncs++;
81 break;
82 case BlockVariable:
83 nBlockVars++;
84 break;
85 case FileVariable:
86 nFileVars++;
87 break;
88 case ParmVariable:
89 nParmVars++;
90 break;
91 case EnumConstant:
92 nEnumConst++;
93 break;
94 case Field:
95 nFieldDecls++;
96 break;
97 case Struct:
98 case Union:
99 case Class:
100 nSUC++;
101 break;
102 case Enum:
103 nEnumDecls++;
104 break;
Steve Naroff81f1bba2007-09-06 21:24:23 +0000105 case ObjcInterface:
106 nInterfaceDecls++;
107 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000108 }
109}
110
111// Out-of-line virtual method providing a home for Decl.
112Decl::~Decl() {
113}
114
Steve Naroffcb597472007-09-13 21:41:19 +0000115const char *FieldDecl::getName() const {
116 if (const IdentifierInfo *II = getIdentifier())
117 return II->getName();
118 return "";
119}
120
121const char *ScopedDecl::getName() const {
Chris Lattner4b009652007-07-25 00:24:17 +0000122 if (const IdentifierInfo *II = getIdentifier())
123 return II->getName();
124 return "";
125}
126
127
128FunctionDecl::~FunctionDecl() {
129 delete[] ParamInfo;
130}
131
132unsigned FunctionDecl::getNumParams() const {
133 return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
134}
135
136void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
137 assert(ParamInfo == 0 && "Already has param info!");
138 assert(NumParams == getNumParams() && "Parameter count mismatch!");
139
140 // Zero params -> null pointer.
141 if (NumParams) {
142 ParamInfo = new ParmVarDecl*[NumParams];
143 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
144 }
145}
146
147
148/// defineBody - When created, RecordDecl's correspond to a forward declared
149/// record. This method is used to mark the decl as being defined, with the
150/// specified contents.
151void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
152 assert(!isDefinition() && "Cannot redefine record!");
153 setDefinition(true);
154 NumMembers = numMembers;
155 if (numMembers) {
156 Members = new FieldDecl*[numMembers];
157 memcpy(Members, members, numMembers*sizeof(Decl*));
158 }
159}
160
161FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
162 if (Members == 0 || NumMembers < 0)
163 return 0;
164
165 // linear search. When C++ classes come along, will likely need to revisit.
166 for (int i = 0; i < NumMembers; ++i) {
167 if (Members[i]->getIdentifier() == name)
168 return Members[i];
169 }
170 return 0;
171}
Fariborz Jahanian3dc7cbc2007-09-10 20:33:04 +0000172
Fariborz Jahanian86f74a42007-09-12 18:23:47 +0000173void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
174 unsigned NumParams) {
175 assert(ParamInfo == 0 && "Already has param info!");
176
177 // Zero params -> null pointer.
178 if (NumParams) {
179 ParamInfo = new ParmVarDecl*[NumParams];
180 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
181 NumMethodParams = NumParams;
182 }
183}
184
185ObjcMethodDecl::~ObjcMethodDecl() {
186 delete[] ParamInfo;
187}
188
Fariborz Jahanianebcc9b62007-09-14 21:08:27 +0000189/// ObjcAddInstanceVariablesToClass - Inserts instance variables
190/// into ObjcInterfaceDecl's fields.
191///
192void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
193 unsigned numIvars) {
194 NumIvars = numIvars;
195 if (numIvars) {
196 Ivars = new ObjcIvarDecl*[numIvars];
197 memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
198 }
199}
200
Fariborz Jahanian3dc7cbc2007-09-10 20:33:04 +0000201/// addObjcMethods - Insert instance and methods declarations into
202/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
203///
204void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
205 unsigned numInsMembers,
206 ObjcMethodDecl **clsMethods,
207 unsigned numClsMembers) {
208 NumInsMethods = numInsMembers;
209 if (numInsMembers) {
210 InsMethods = new ObjcMethodDecl*[numInsMembers];
211 memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
212 }
213 NumClsMethods = numClsMembers;
214 if (numClsMembers) {
215 ClsMethods = new ObjcMethodDecl*[numClsMembers];
216 memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
217 }
218}
219