blob: f4a346ff97239dccd9b5b92115fd197dc470cc5e [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;
28static bool StatSwitch = false;
29
30bool Decl::CollectingStats(bool enable) {
31 if (enable) StatSwitch = true;
32 return StatSwitch;
33}
34
35void Decl::PrintStats() {
36 fprintf(stderr, "*** Decl Stats:\n");
37 fprintf(stderr, " %d decls total.\n",
38 int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
39 nEnumDecls+nEnumConst+nTypedef));
40 fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
41 nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
42 fprintf(stderr, " %d block variable decls, %d each (%d bytes)\n",
43 nBlockVars, (int)sizeof(BlockVarDecl),
44 int(nBlockVars*sizeof(BlockVarDecl)));
45 fprintf(stderr, " %d file variable decls, %d each (%d bytes)\n",
46 nFileVars, (int)sizeof(FileVarDecl),
47 int(nFileVars*sizeof(FileVarDecl)));
48 fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
49 nParmVars, (int)sizeof(ParmVarDecl),
50 int(nParmVars*sizeof(ParmVarDecl)));
51 fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
52 nFieldDecls, (int)sizeof(FieldDecl),
53 int(nFieldDecls*sizeof(FieldDecl)));
54 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
55 nSUC, (int)sizeof(RecordDecl),
56 int(nSUC*sizeof(RecordDecl)));
57 fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
58 nEnumDecls, (int)sizeof(EnumDecl),
59 int(nEnumDecls*sizeof(EnumDecl)));
60 fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
61 nEnumConst, (int)sizeof(EnumConstantDecl),
62 int(nEnumConst*sizeof(EnumConstantDecl)));
63 fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
64 nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
65 fprintf(stderr, "Total bytes = %d\n",
66 int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
67 nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
68 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
69 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
70 nTypedef*sizeof(TypedefDecl)));
71}
72
73void Decl::addDeclKind(const Kind k) {
74 switch (k) {
75 case Typedef:
76 nTypedef++;
77 break;
78 case Function:
79 nFuncs++;
80 break;
81 case BlockVariable:
82 nBlockVars++;
83 break;
84 case FileVariable:
85 nFileVars++;
86 break;
87 case ParmVariable:
88 nParmVars++;
89 break;
90 case EnumConstant:
91 nEnumConst++;
92 break;
93 case Field:
94 nFieldDecls++;
95 break;
96 case Struct:
97 case Union:
98 case Class:
99 nSUC++;
100 break;
101 case Enum:
102 nEnumDecls++;
103 break;
104 }
105}
106
107// Out-of-line virtual method providing a home for Decl.
108Decl::~Decl() {
109}
110
111const char *Decl::getName() const {
112 if (const IdentifierInfo *II = getIdentifier())
113 return II->getName();
114 return "";
115}
116
117
118FunctionDecl::~FunctionDecl() {
119 delete[] ParamInfo;
120}
121
122unsigned FunctionDecl::getNumParams() const {
123 return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
124}
125
126void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
127 assert(ParamInfo == 0 && "Already has param info!");
128 assert(NumParams == getNumParams() && "Parameter count mismatch!");
129
130 // Zero params -> null pointer.
131 if (NumParams) {
132 ParamInfo = new ParmVarDecl*[NumParams];
133 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
134 }
135}
136
137
138/// defineBody - When created, RecordDecl's correspond to a forward declared
139/// record. This method is used to mark the decl as being defined, with the
140/// specified contents.
141void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
142 assert(!isDefinition() && "Cannot redefine record!");
143 setDefinition(true);
144 NumMembers = numMembers;
145 if (numMembers) {
146 Members = new FieldDecl*[numMembers];
147 memcpy(Members, members, numMembers*sizeof(Decl*));
148 }
149}
150
151FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
152 if (Members == 0 || NumMembers < 0)
153 return 0;
154
155 // linear search. When C++ classes come along, will likely need to revisit.
156 for (int i = 0; i < NumMembers; ++i) {
157 if (Members[i]->getIdentifier() == name)
158 return Members[i];
159 }
160 return 0;
Chris Lattner6fa5f092007-07-12 15:43:07 +0000161}