blob: 5e1875ab652df47e2d39e01537a12fec5164d27c [file] [log] [blame]
Ted Kremenek4b7c9832008-09-05 17:16:31 +00001//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclCXX.h"
15#include "clang/AST/ASTContext.h"
Douglas Gregor7d7e6722008-11-12 23:21:09 +000016#include "clang/Basic/IdentifierTable.h"
Douglas Gregorfdfab6b2008-12-23 21:31:30 +000017#include "llvm/ADT/STLExtras.h"
Ted Kremenek4b7c9832008-09-05 17:16:31 +000018using namespace clang;
19
20//===----------------------------------------------------------------------===//
21// Decl Allocation/Deallocation Method Implementations
22//===----------------------------------------------------------------------===//
Douglas Gregor72c3f312008-12-05 18:15:24 +000023
24TemplateTypeParmDecl *
25TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
Nate Begemanfea86852008-12-16 19:57:09 +000026 SourceLocation L, IdentifierInfo *Id,
27 bool Typename) {
Steve Naroff3e970492009-01-27 21:25:57 +000028 return new (C) TemplateTypeParmDecl(DC, L, Id, Typename);
Douglas Gregor72c3f312008-12-05 18:15:24 +000029}
30
31NonTypeTemplateParmDecl *
32NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
Nate Begemanfea86852008-12-16 19:57:09 +000033 SourceLocation L, IdentifierInfo *Id,
34 QualType T, SourceLocation TypeSpecStartLoc) {
Steve Naroff3e970492009-01-27 21:25:57 +000035 return new (C) NonTypeTemplateParmDecl(DC, L, Id, T, TypeSpecStartLoc);
Douglas Gregor72c3f312008-12-05 18:15:24 +000036}
37
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +000038TemplateParameterList::TemplateParameterList(Decl **Params, unsigned NumParams)
39 : NumParams(NumParams) {
40 for (unsigned Idx = 0; Idx < NumParams; ++Idx)
41 begin()[Idx] = Params[Idx];
42}
43
44TemplateParameterList *
45TemplateParameterList::Create(ASTContext &C, Decl **Params,
46 unsigned NumParams) {
Steve Naroff3e970492009-01-27 21:25:57 +000047 // FIXME: how do I pass in Size to ASTContext::new?
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +000048 unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams;
49 unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
Steve Naroffc0ac4922009-01-27 23:20:32 +000050 void *Mem = C.Allocate(Size, Align);
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +000051 return new (Mem) TemplateParameterList(Params, NumParams);
52}
53
Douglas Gregor2e1cd422008-11-17 14:58:09 +000054CXXRecordDecl::CXXRecordDecl(TagKind TK, DeclContext *DC,
Douglas Gregor7d7e6722008-11-12 23:21:09 +000055 SourceLocation L, IdentifierInfo *Id)
Douglas Gregor44b43212008-12-11 16:49:14 +000056 : RecordDecl(CXXRecord, TK, DC, L, Id),
Douglas Gregor7d7e6722008-11-12 23:21:09 +000057 UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
Sebastian Redl64b45f72009-01-05 20:52:13 +000058 UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
59 Aggregate(true), PlainOldData(true), Polymorphic(false), Bases(0),
60 NumBases(0), Conversions(DC, DeclarationName()) { }
Douglas Gregor7d7e6722008-11-12 23:21:09 +000061
Ted Kremenek4b7c9832008-09-05 17:16:31 +000062CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
63 SourceLocation L, IdentifierInfo *Id,
64 CXXRecordDecl* PrevDecl) {
Steve Naroff3e970492009-01-27 21:25:57 +000065 CXXRecordDecl* R = new (C) CXXRecordDecl(TK, DC, L, Id);
Ted Kremenek4b7c9832008-09-05 17:16:31 +000066 C.getTypeDeclType(R, PrevDecl);
67 return R;
68}
69
Douglas Gregorf8268ae2008-10-22 17:49:05 +000070CXXRecordDecl::~CXXRecordDecl() {
Douglas Gregorf8268ae2008-10-22 17:49:05 +000071 delete [] Bases;
72}
73
Douglas Gregor57c856b2008-10-23 18:13:27 +000074void
75CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
76 unsigned NumBases) {
Douglas Gregor64bffa92008-11-05 16:20:31 +000077 // C++ [dcl.init.aggr]p1:
78 // An aggregate is an array or a class (clause 9) with [...]
79 // no base classes [...].
80 Aggregate = false;
81
Douglas Gregor57c856b2008-10-23 18:13:27 +000082 if (this->Bases)
83 delete [] this->Bases;
84
85 this->Bases = new CXXBaseSpecifier[NumBases];
86 this->NumBases = NumBases;
87 for (unsigned i = 0; i < NumBases; ++i)
88 this->Bases[i] = *Bases[i];
89}
90
Douglas Gregor396b7cd2008-11-03 17:51:48 +000091bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
Sebastian Redl64b45f72009-01-05 20:52:13 +000092 QualType ClassType
93 = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
Douglas Gregor9e7d9de2008-12-15 21:24:18 +000094 DeclarationName ConstructorName
95 = Context.DeclarationNames.getCXXConstructorName(
96 Context.getCanonicalType(ClassType));
97 unsigned TypeQuals;
Douglas Gregorfdfab6b2008-12-23 21:31:30 +000098 DeclContext::lookup_const_iterator Con, ConEnd;
Steve Naroff0701bbb2009-01-08 17:28:14 +000099 for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
Douglas Gregorfdfab6b2008-12-23 21:31:30 +0000100 Con != ConEnd; ++Con) {
Douglas Gregor396b7cd2008-11-03 17:51:48 +0000101 if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
Eli Friedmane8e32052008-12-16 20:06:41 +0000102 (TypeQuals & QualType::Const) != 0)
Douglas Gregor396b7cd2008-11-03 17:51:48 +0000103 return true;
104 }
Douglas Gregorfdfab6b2008-12-23 21:31:30 +0000105
Douglas Gregor396b7cd2008-11-03 17:51:48 +0000106 return false;
107}
108
Sebastian Redl64b45f72009-01-05 20:52:13 +0000109bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
110 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
111 const_cast<CXXRecordDecl*>(this)));
112 DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
113
114 DeclContext::lookup_const_iterator Op, OpEnd;
Steve Naroff0701bbb2009-01-08 17:28:14 +0000115 for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
Sebastian Redl64b45f72009-01-05 20:52:13 +0000116 Op != OpEnd; ++Op) {
117 // C++ [class.copy]p9:
118 // A user-declared copy assignment operator is a non-static non-template
119 // member function of class X with exactly one parameter of type X, X&,
120 // const X&, volatile X& or const volatile X&.
121 const CXXMethodDecl* Method = cast<CXXMethodDecl>(*Op);
122 if (Method->isStatic())
123 continue;
124 // TODO: Skip templates? Or is this implicitly done due to parameter types?
125 const FunctionTypeProto *FnType =
126 Method->getType()->getAsFunctionTypeProto();
127 assert(FnType && "Overloaded operator has no prototype.");
128 // Don't assert on this; an invalid decl might have been left in the AST.
129 if (FnType->getNumArgs() != 1 || FnType->isVariadic())
130 continue;
131 bool AcceptsConst = true;
132 QualType ArgType = FnType->getArgType(0);
133 if (const ReferenceType *Ref = ArgType->getAsReferenceType()) {
134 ArgType = Ref->getPointeeType();
135 // Is it a non-const reference?
136 if (!ArgType.isConstQualified())
137 AcceptsConst = false;
138 }
139 if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType)
140 continue;
141
142 // We have a single argument of type cv X or cv X&, i.e. we've found the
143 // copy assignment operator. Return whether it accepts const arguments.
144 return AcceptsConst;
145 }
146 assert(isInvalidDecl() &&
147 "No copy assignment operator declared in valid code.");
148 return false;
149}
150
151void
Douglas Gregor9e7d9de2008-12-15 21:24:18 +0000152CXXRecordDecl::addedConstructor(ASTContext &Context,
153 CXXConstructorDecl *ConDecl) {
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000154 if (!ConDecl->isImplicit()) {
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000155 // Note that we have a user-declared constructor.
156 UserDeclaredConstructor = true;
157
Douglas Gregor64bffa92008-11-05 16:20:31 +0000158 // C++ [dcl.init.aggr]p1:
159 // An aggregate is an array or a class (clause 9) with no
160 // user-declared constructors (12.1) [...].
161 Aggregate = false;
162
Sebastian Redl64b45f72009-01-05 20:52:13 +0000163 // C++ [class]p4:
164 // A POD-struct is an aggregate class [...]
165 PlainOldData = false;
166
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000167 // Note when we have a user-declared copy constructor, which will
168 // suppress the implicit declaration of a copy constructor.
169 if (ConDecl->isCopyConstructor(Context))
170 UserDeclaredCopyConstructor = true;
171 }
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000172}
173
Sebastian Redl64b45f72009-01-05 20:52:13 +0000174void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
175 CXXMethodDecl *OpDecl) {
176 // We're interested specifically in copy assignment operators.
177 // Unlike addedConstructor, this method is not called for implicit
178 // declarations.
179 const FunctionTypeProto *FnType = OpDecl->getType()->getAsFunctionTypeProto();
180 assert(FnType && "Overloaded operator has no proto function type.");
181 assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
182 QualType ArgType = FnType->getArgType(0);
183 if (const ReferenceType *Ref = ArgType->getAsReferenceType())
184 ArgType = Ref->getPointeeType();
185
186 ArgType = ArgType.getUnqualifiedType();
187 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
188 const_cast<CXXRecordDecl*>(this)));
189
190 if (ClassType != Context.getCanonicalType(ArgType))
191 return;
192
193 // This is a copy assignment operator.
194 // Suppress the implicit declaration of a copy constructor.
195 UserDeclaredCopyAssignment = true;
196
197 // C++ [class]p4:
198 // A POD-struct is an aggregate class that [...] has no user-defined copy
199 // assignment operator [...].
200 PlainOldData = false;
201}
202
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000203void CXXRecordDecl::addConversionFunction(ASTContext &Context,
204 CXXConversionDecl *ConvDecl) {
205 Conversions.addOverload(ConvDecl);
206}
207
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000208CXXMethodDecl *
209CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor10bd3682008-11-17 22:58:34 +0000210 SourceLocation L, DeclarationName N,
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000211 QualType T, bool isStatic, bool isInline) {
Steve Naroff3e970492009-01-27 21:25:57 +0000212 return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline);
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000213}
214
215QualType CXXMethodDecl::getThisType(ASTContext &C) const {
Argyrios Kyrtzidisb0d178d2008-10-24 22:28:18 +0000216 // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
217 // If the member function is declared const, the type of this is const X*,
218 // if the member function is declared volatile, the type of this is
219 // volatile X*, and if the member function is declared const volatile,
220 // the type of this is const volatile X*.
221
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000222 assert(isInstance() && "No 'this' for static methods!");
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000223 QualType ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +0000224 ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
225 return C.getPointerType(ClassTy).withConst();
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000226}
227
Douglas Gregor7ad83902008-11-05 04:29:56 +0000228CXXBaseOrMemberInitializer::
229CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
230 : Args(0), NumArgs(0) {
231 BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
232 assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
233 BaseOrMember |= 0x01;
234
235 if (NumArgs > 0) {
236 this->NumArgs = NumArgs;
237 this->Args = new Expr*[NumArgs];
238 for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
239 this->Args[Idx] = Args[Idx];
240 }
241}
242
243CXXBaseOrMemberInitializer::
Douglas Gregor44b43212008-12-11 16:49:14 +0000244CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
Douglas Gregor7ad83902008-11-05 04:29:56 +0000245 : Args(0), NumArgs(0) {
246 BaseOrMember = reinterpret_cast<uintptr_t>(Member);
247 assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
248
249 if (NumArgs > 0) {
250 this->NumArgs = NumArgs;
251 this->Args = new Expr*[NumArgs];
252 for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
253 this->Args[Idx] = Args[Idx];
254 }
255}
256
257CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
258 delete [] Args;
259}
260
Douglas Gregorb48fe382008-10-31 09:07:45 +0000261CXXConstructorDecl *
262CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000263 SourceLocation L, DeclarationName N,
Douglas Gregorb48fe382008-10-31 09:07:45 +0000264 QualType T, bool isExplicit,
265 bool isInline, bool isImplicitlyDeclared) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000266 assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
267 "Name must refer to a constructor");
Steve Naroff3e970492009-01-27 21:25:57 +0000268 return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline,
Douglas Gregorb48fe382008-10-31 09:07:45 +0000269 isImplicitlyDeclared);
270}
271
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000272bool CXXConstructorDecl::isDefaultConstructor() const {
273 // C++ [class.ctor]p5:
Douglas Gregor64bffa92008-11-05 16:20:31 +0000274 // A default constructor for a class X is a constructor of class
275 // X that can be called without an argument.
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000276 return (getNumParams() == 0) ||
Douglas Gregorf03d7c72008-11-05 15:29:30 +0000277 (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0);
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000278}
279
280bool
281CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
282 unsigned &TypeQuals) const {
283 // C++ [class.copy]p2:
Douglas Gregor64bffa92008-11-05 16:20:31 +0000284 // A non-template constructor for class X is a copy constructor
285 // if its first parameter is of type X&, const X&, volatile X& or
286 // const volatile X&, and either there are no other parameters
287 // or else all other parameters have default arguments (8.3.6).
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000288 if ((getNumParams() < 1) ||
289 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() == 0))
290 return false;
291
292 const ParmVarDecl *Param = getParamDecl(0);
293
294 // Do we have a reference type?
295 const ReferenceType *ParamRefType = Param->getType()->getAsReferenceType();
296 if (!ParamRefType)
297 return false;
298
299 // Is it a reference to our class type?
300 QualType PointeeType
301 = Context.getCanonicalType(ParamRefType->getPointeeType());
302 QualType ClassTy
303 = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
304 if (PointeeType.getUnqualifiedType() != ClassTy)
305 return false;
306
307 // We have a copy constructor.
308 TypeQuals = PointeeType.getCVRQualifiers();
309 return true;
310}
311
Douglas Gregor60d62c22008-10-31 16:23:19 +0000312bool CXXConstructorDecl::isConvertingConstructor() const {
313 // C++ [class.conv.ctor]p1:
314 // A constructor declared without the function-specifier explicit
315 // that can be called with a single parameter specifies a
316 // conversion from the type of its first parameter to the type of
317 // its class. Such a constructor is called a converting
318 // constructor.
319 if (isExplicit())
320 return false;
321
322 return (getNumParams() == 0 &&
323 getType()->getAsFunctionTypeProto()->isVariadic()) ||
324 (getNumParams() == 1) ||
325 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
326}
Douglas Gregorb48fe382008-10-31 09:07:45 +0000327
Douglas Gregor42a552f2008-11-05 20:51:48 +0000328CXXDestructorDecl *
329CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000330 SourceLocation L, DeclarationName N,
Douglas Gregor42a552f2008-11-05 20:51:48 +0000331 QualType T, bool isInline,
332 bool isImplicitlyDeclared) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000333 assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
334 "Name must refer to a destructor");
Steve Naroff3e970492009-01-27 21:25:57 +0000335 return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
336 isImplicitlyDeclared);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000337}
338
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000339CXXConversionDecl *
340CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000341 SourceLocation L, DeclarationName N,
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000342 QualType T, bool isInline, bool isExplicit) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000343 assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
344 "Name must refer to a conversion function");
Steve Naroff3e970492009-01-27 21:25:57 +0000345 return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit);
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000346}
347
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000348CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
349 SourceLocation L, IdentifierInfo *Id,
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000350 QualType T) {
Steve Naroff3e970492009-01-27 21:25:57 +0000351 return new (C) CXXClassVarDecl(RD, L, Id, T);
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000352}
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000353
354OverloadedFunctionDecl *
355OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000356 DeclarationName N) {
Steve Naroff3e970492009-01-27 21:25:57 +0000357 return new (C) OverloadedFunctionDecl(DC, N);
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000358}
Chris Lattner21ef7ae2008-11-04 16:51:42 +0000359
360LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
Douglas Gregor074149e2009-01-05 19:45:36 +0000361 DeclContext *DC,
Chris Lattner21ef7ae2008-11-04 16:51:42 +0000362 SourceLocation L,
Douglas Gregor074149e2009-01-05 19:45:36 +0000363 LanguageIDs Lang, bool Braces) {
Steve Naroff3e970492009-01-27 21:25:57 +0000364 return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
Douglas Gregorf44515a2008-12-16 22:23:02 +0000365}
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000366
367UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
368 SourceLocation L,
369 SourceLocation NamespaceLoc,
370 SourceLocation IdentLoc,
371 NamespaceDecl *Used,
372 DeclContext *CommonAncestor) {
373 return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, IdentLoc,
374 Used, CommonAncestor);
375}
376