blob: f7301181d720b66ead0525f9f2da922d29559cfc [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 llvm;
17using namespace clang;
Chris Lattnera11999d2006-10-15 22:34:45 +000018
Steve Narofff84d11f2007-05-23 21:48:04 +000019// temporary statistics gathering
20static unsigned nFuncs = 0;
21static unsigned nBlockVars = 0;
22static unsigned nFileVars = 0;
23static unsigned nParmVars = 0;
Chris Lattnera5490952007-05-24 01:09:39 +000024static unsigned nSUC = 0;
Steve Narofff84d11f2007-05-23 21:48:04 +000025static unsigned nEnumConst = 0;
26static unsigned nEnumDecls = 0;
27static unsigned nTypedef = 0;
28static unsigned nFieldDecls = 0;
29static bool StatSwitch = false;
30
31bool Decl::CollectingStats(bool enable) {
32 if (enable) StatSwitch = true;
33 return StatSwitch;
34}
35
36void Decl::PrintStats() {
Chris Lattnerfc234de2007-05-24 00:40:54 +000037 fprintf(stderr, "*** Decl Stats:\n");
38 fprintf(stderr, " %d decls total.\n",
Chris Lattnera5490952007-05-24 01:09:39 +000039 int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
Chris Lattnerfc234de2007-05-24 00:40:54 +000040 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)));
Chris Lattnera5490952007-05-24 01:09:39 +000055 fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
56 nSUC, (int)sizeof(RecordDecl),
57 int(nSUC*sizeof(RecordDecl)));
Chris Lattnerfc234de2007-05-24 00:40:54 +000058 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)+
Chris Lattnera5490952007-05-24 01:09:39 +000069 nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
Chris Lattnerfc234de2007-05-24 00:40:54 +000070 nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
71 nTypedef*sizeof(TypedefDecl)));
Steve Narofff84d11f2007-05-23 21:48:04 +000072}
73
74void Decl::addDeclKind(const Kind k) {
Chris Lattnerfc234de2007-05-24 00:40:54 +000075 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:
Chris Lattnera5490952007-05-24 01:09:39 +0000100 nSUC++;
Chris Lattnerfc234de2007-05-24 00:40:54 +0000101 break;
102 case Enum:
103 nEnumDecls++;
104 break;
105 }
Steve Narofff84d11f2007-05-23 21:48:04 +0000106}
107
Chris Lattner6d9a6852006-10-25 05:11:20 +0000108// Out-of-line virtual method providing a home for Decl.
109Decl::~Decl() {
110}
Chris Lattner17ed4872006-11-20 04:58:19 +0000111
112const char *Decl::getName() const {
Chris Lattnerec040b12007-01-21 23:09:50 +0000113 if (const IdentifierInfo *II = getIdentifier())
114 return II->getName();
115 return "";
Chris Lattner17ed4872006-11-20 04:58:19 +0000116}
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +0000117
118
119FunctionDecl::~FunctionDecl() {
120 delete[] ParamInfo;
121}
122
123unsigned FunctionDecl::getNumParams() const {
124 return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
125}
126
Chris Lattner53621a52007-06-13 20:44:40 +0000127void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +0000128 assert(ParamInfo == 0 && "Already has param info!");
129 assert(NumParams == getNumParams() && "Parameter count mismatch!");
130
Chris Lattner8f5bf2f2007-01-21 19:04:10 +0000131 // Zero params -> null pointer.
132 if (NumParams) {
Chris Lattner53621a52007-06-13 20:44:40 +0000133 ParamInfo = new ParmVarDecl*[NumParams];
134 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
Chris Lattner8f5bf2f2007-01-21 19:04:10 +0000135 }
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +0000136}
Chris Lattner41943152007-01-25 04:52:46 +0000137
138
139/// defineBody - When created, RecordDecl's correspond to a forward declared
140/// record. This method is used to mark the decl as being defined, with the
141/// specified contents.
Steve Naroffcc321422007-03-26 23:09:51 +0000142void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
Chris Lattner41943152007-01-25 04:52:46 +0000143 assert(!isDefinition() && "Cannot redefine record!");
144 setDefinition(true);
Chris Lattner5f521502007-01-25 06:27:24 +0000145 NumMembers = numMembers;
146 if (numMembers) {
Steve Naroffcc321422007-03-26 23:09:51 +0000147 Members = new FieldDecl*[numMembers];
Chris Lattner5f521502007-01-25 06:27:24 +0000148 memcpy(Members, members, numMembers*sizeof(Decl*));
Chris Lattner41943152007-01-25 04:52:46 +0000149 }
150}
Steve Naroffcc321422007-03-26 23:09:51 +0000151
152FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
153 if (Members == 0 || NumMembers < 0)
154 return 0;
155
156 // linear search. When C++ classes come along, will likely need to revisit.
157 for (int i = 0; i < NumMembers; ++i) {
158 if (Members[i]->getIdentifier() == name)
159 return Members[i];
160 }
161 return 0;
Steve Naroff6a0675f2007-06-01 21:54:34 +0000162}