blob: b1394fe788be12e2283825cc6e5c47fcae4c5d32 [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
Douglas Gregor3e00bad2009-02-17 01:05:43 +000024CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
Douglas Gregor7d7e6722008-11-12 23:21:09 +000025 SourceLocation L, IdentifierInfo *Id)
Douglas Gregor3e00bad2009-02-17 01:05:43 +000026 : RecordDecl(K, TK, DC, L, Id),
Douglas Gregor7d7e6722008-11-12 23:21:09 +000027 UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
Sebastian Redl64b45f72009-01-05 20:52:13 +000028 UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
29 Aggregate(true), PlainOldData(true), Polymorphic(false), Bases(0),
30 NumBases(0), Conversions(DC, DeclarationName()) { }
Douglas Gregor7d7e6722008-11-12 23:21:09 +000031
Ted Kremenek4b7c9832008-09-05 17:16:31 +000032CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
33 SourceLocation L, IdentifierInfo *Id,
34 CXXRecordDecl* PrevDecl) {
Douglas Gregor3e00bad2009-02-17 01:05:43 +000035 CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id);
Ted Kremenek4b7c9832008-09-05 17:16:31 +000036 C.getTypeDeclType(R, PrevDecl);
37 return R;
38}
39
Douglas Gregorf8268ae2008-10-22 17:49:05 +000040CXXRecordDecl::~CXXRecordDecl() {
Douglas Gregorf8268ae2008-10-22 17:49:05 +000041 delete [] Bases;
42}
43
Douglas Gregor57c856b2008-10-23 18:13:27 +000044void
45CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
46 unsigned NumBases) {
Douglas Gregor64bffa92008-11-05 16:20:31 +000047 // C++ [dcl.init.aggr]p1:
48 // An aggregate is an array or a class (clause 9) with [...]
49 // no base classes [...].
50 Aggregate = false;
51
Douglas Gregor57c856b2008-10-23 18:13:27 +000052 if (this->Bases)
53 delete [] this->Bases;
54
55 this->Bases = new CXXBaseSpecifier[NumBases];
56 this->NumBases = NumBases;
57 for (unsigned i = 0; i < NumBases; ++i)
58 this->Bases[i] = *Bases[i];
59}
60
Douglas Gregor396b7cd2008-11-03 17:51:48 +000061bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
Sebastian Redl64b45f72009-01-05 20:52:13 +000062 QualType ClassType
63 = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
Douglas Gregor9e7d9de2008-12-15 21:24:18 +000064 DeclarationName ConstructorName
65 = Context.DeclarationNames.getCXXConstructorName(
66 Context.getCanonicalType(ClassType));
67 unsigned TypeQuals;
Douglas Gregorfdfab6b2008-12-23 21:31:30 +000068 DeclContext::lookup_const_iterator Con, ConEnd;
Steve Naroff0701bbb2009-01-08 17:28:14 +000069 for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
Douglas Gregorfdfab6b2008-12-23 21:31:30 +000070 Con != ConEnd; ++Con) {
Douglas Gregor396b7cd2008-11-03 17:51:48 +000071 if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
Eli Friedmane8e32052008-12-16 20:06:41 +000072 (TypeQuals & QualType::Const) != 0)
Douglas Gregor396b7cd2008-11-03 17:51:48 +000073 return true;
74 }
Douglas Gregorfdfab6b2008-12-23 21:31:30 +000075
Douglas Gregor396b7cd2008-11-03 17:51:48 +000076 return false;
77}
78
Sebastian Redl64b45f72009-01-05 20:52:13 +000079bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
80 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
81 const_cast<CXXRecordDecl*>(this)));
82 DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
83
84 DeclContext::lookup_const_iterator Op, OpEnd;
Steve Naroff0701bbb2009-01-08 17:28:14 +000085 for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
Sebastian Redl64b45f72009-01-05 20:52:13 +000086 Op != OpEnd; ++Op) {
87 // C++ [class.copy]p9:
88 // A user-declared copy assignment operator is a non-static non-template
89 // member function of class X with exactly one parameter of type X, X&,
90 // const X&, volatile X& or const volatile X&.
91 const CXXMethodDecl* Method = cast<CXXMethodDecl>(*Op);
92 if (Method->isStatic())
93 continue;
94 // TODO: Skip templates? Or is this implicitly done due to parameter types?
Douglas Gregor72564e72009-02-26 23:50:07 +000095 const FunctionProtoType *FnType =
96 Method->getType()->getAsFunctionProtoType();
Sebastian Redl64b45f72009-01-05 20:52:13 +000097 assert(FnType && "Overloaded operator has no prototype.");
98 // Don't assert on this; an invalid decl might have been left in the AST.
99 if (FnType->getNumArgs() != 1 || FnType->isVariadic())
100 continue;
101 bool AcceptsConst = true;
102 QualType ArgType = FnType->getArgType(0);
103 if (const ReferenceType *Ref = ArgType->getAsReferenceType()) {
104 ArgType = Ref->getPointeeType();
105 // Is it a non-const reference?
106 if (!ArgType.isConstQualified())
107 AcceptsConst = false;
108 }
109 if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType)
110 continue;
111
112 // We have a single argument of type cv X or cv X&, i.e. we've found the
113 // copy assignment operator. Return whether it accepts const arguments.
114 return AcceptsConst;
115 }
116 assert(isInvalidDecl() &&
117 "No copy assignment operator declared in valid code.");
118 return false;
119}
120
121void
Douglas Gregor9e7d9de2008-12-15 21:24:18 +0000122CXXRecordDecl::addedConstructor(ASTContext &Context,
123 CXXConstructorDecl *ConDecl) {
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000124 if (!ConDecl->isImplicit()) {
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000125 // Note that we have a user-declared constructor.
126 UserDeclaredConstructor = true;
127
Douglas Gregor64bffa92008-11-05 16:20:31 +0000128 // C++ [dcl.init.aggr]p1:
129 // An aggregate is an array or a class (clause 9) with no
130 // user-declared constructors (12.1) [...].
131 Aggregate = false;
132
Sebastian Redl64b45f72009-01-05 20:52:13 +0000133 // C++ [class]p4:
134 // A POD-struct is an aggregate class [...]
135 PlainOldData = false;
136
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000137 // Note when we have a user-declared copy constructor, which will
138 // suppress the implicit declaration of a copy constructor.
139 if (ConDecl->isCopyConstructor(Context))
140 UserDeclaredCopyConstructor = true;
141 }
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000142}
143
Sebastian Redl64b45f72009-01-05 20:52:13 +0000144void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
145 CXXMethodDecl *OpDecl) {
146 // We're interested specifically in copy assignment operators.
147 // Unlike addedConstructor, this method is not called for implicit
148 // declarations.
Douglas Gregor72564e72009-02-26 23:50:07 +0000149 const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType();
Sebastian Redl64b45f72009-01-05 20:52:13 +0000150 assert(FnType && "Overloaded operator has no proto function type.");
151 assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
152 QualType ArgType = FnType->getArgType(0);
153 if (const ReferenceType *Ref = ArgType->getAsReferenceType())
154 ArgType = Ref->getPointeeType();
155
156 ArgType = ArgType.getUnqualifiedType();
157 QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
158 const_cast<CXXRecordDecl*>(this)));
159
160 if (ClassType != Context.getCanonicalType(ArgType))
161 return;
162
163 // This is a copy assignment operator.
164 // Suppress the implicit declaration of a copy constructor.
165 UserDeclaredCopyAssignment = true;
166
167 // C++ [class]p4:
168 // A POD-struct is an aggregate class that [...] has no user-defined copy
169 // assignment operator [...].
170 PlainOldData = false;
171}
172
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000173void CXXRecordDecl::addConversionFunction(ASTContext &Context,
174 CXXConversionDecl *ConvDecl) {
175 Conversions.addOverload(ConvDecl);
176}
177
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000178CXXMethodDecl *
179CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor10bd3682008-11-17 22:58:34 +0000180 SourceLocation L, DeclarationName N,
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000181 QualType T, bool isStatic, bool isInline) {
Steve Naroff3e970492009-01-27 21:25:57 +0000182 return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline);
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000183}
184
185QualType CXXMethodDecl::getThisType(ASTContext &C) const {
Argyrios Kyrtzidisb0d178d2008-10-24 22:28:18 +0000186 // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
187 // If the member function is declared const, the type of this is const X*,
188 // if the member function is declared volatile, the type of this is
189 // volatile X*, and if the member function is declared const volatile,
190 // the type of this is const volatile X*.
191
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000192 assert(isInstance() && "No 'this' for static methods!");
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000193 QualType ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +0000194 ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
195 return C.getPointerType(ClassTy).withConst();
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000196}
197
Douglas Gregor7ad83902008-11-05 04:29:56 +0000198CXXBaseOrMemberInitializer::
199CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
200 : Args(0), NumArgs(0) {
201 BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
202 assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
203 BaseOrMember |= 0x01;
204
205 if (NumArgs > 0) {
206 this->NumArgs = NumArgs;
207 this->Args = new Expr*[NumArgs];
208 for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
209 this->Args[Idx] = Args[Idx];
210 }
211}
212
213CXXBaseOrMemberInitializer::
Douglas Gregor44b43212008-12-11 16:49:14 +0000214CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
Douglas Gregor7ad83902008-11-05 04:29:56 +0000215 : Args(0), NumArgs(0) {
216 BaseOrMember = reinterpret_cast<uintptr_t>(Member);
217 assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
218
219 if (NumArgs > 0) {
220 this->NumArgs = NumArgs;
221 this->Args = new Expr*[NumArgs];
222 for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
223 this->Args[Idx] = Args[Idx];
224 }
225}
226
227CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
228 delete [] Args;
229}
230
Douglas Gregorb48fe382008-10-31 09:07:45 +0000231CXXConstructorDecl *
232CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000233 SourceLocation L, DeclarationName N,
Douglas Gregorb48fe382008-10-31 09:07:45 +0000234 QualType T, bool isExplicit,
235 bool isInline, bool isImplicitlyDeclared) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000236 assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
237 "Name must refer to a constructor");
Steve Naroff3e970492009-01-27 21:25:57 +0000238 return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline,
Douglas Gregorb48fe382008-10-31 09:07:45 +0000239 isImplicitlyDeclared);
240}
241
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000242bool CXXConstructorDecl::isDefaultConstructor() const {
243 // C++ [class.ctor]p5:
Douglas Gregor64bffa92008-11-05 16:20:31 +0000244 // A default constructor for a class X is a constructor of class
245 // X that can be called without an argument.
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000246 return (getNumParams() == 0) ||
Douglas Gregorf03d7c72008-11-05 15:29:30 +0000247 (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0);
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000248}
249
250bool
251CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
252 unsigned &TypeQuals) const {
253 // C++ [class.copy]p2:
Douglas Gregor64bffa92008-11-05 16:20:31 +0000254 // A non-template constructor for class X is a copy constructor
255 // if its first parameter is of type X&, const X&, volatile X& or
256 // const volatile X&, and either there are no other parameters
257 // or else all other parameters have default arguments (8.3.6).
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000258 if ((getNumParams() < 1) ||
259 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() == 0))
260 return false;
261
262 const ParmVarDecl *Param = getParamDecl(0);
263
264 // Do we have a reference type?
265 const ReferenceType *ParamRefType = Param->getType()->getAsReferenceType();
266 if (!ParamRefType)
267 return false;
268
269 // Is it a reference to our class type?
270 QualType PointeeType
271 = Context.getCanonicalType(ParamRefType->getPointeeType());
272 QualType ClassTy
273 = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
274 if (PointeeType.getUnqualifiedType() != ClassTy)
275 return false;
276
277 // We have a copy constructor.
278 TypeQuals = PointeeType.getCVRQualifiers();
279 return true;
280}
281
Douglas Gregor60d62c22008-10-31 16:23:19 +0000282bool CXXConstructorDecl::isConvertingConstructor() const {
283 // C++ [class.conv.ctor]p1:
284 // A constructor declared without the function-specifier explicit
285 // that can be called with a single parameter specifies a
286 // conversion from the type of its first parameter to the type of
287 // its class. Such a constructor is called a converting
288 // constructor.
289 if (isExplicit())
290 return false;
291
292 return (getNumParams() == 0 &&
Douglas Gregor72564e72009-02-26 23:50:07 +0000293 getType()->getAsFunctionProtoType()->isVariadic()) ||
Douglas Gregor60d62c22008-10-31 16:23:19 +0000294 (getNumParams() == 1) ||
295 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
296}
Douglas Gregorb48fe382008-10-31 09:07:45 +0000297
Douglas Gregor42a552f2008-11-05 20:51:48 +0000298CXXDestructorDecl *
299CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000300 SourceLocation L, DeclarationName N,
Douglas Gregor42a552f2008-11-05 20:51:48 +0000301 QualType T, bool isInline,
302 bool isImplicitlyDeclared) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000303 assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
304 "Name must refer to a destructor");
Steve Naroff3e970492009-01-27 21:25:57 +0000305 return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
306 isImplicitlyDeclared);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000307}
308
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000309CXXConversionDecl *
310CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000311 SourceLocation L, DeclarationName N,
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000312 QualType T, bool isInline, bool isExplicit) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000313 assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
314 "Name must refer to a conversion function");
Steve Naroff3e970492009-01-27 21:25:57 +0000315 return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit);
Douglas Gregor2f1bc522008-11-07 20:08:42 +0000316}
317
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000318CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
319 SourceLocation L, IdentifierInfo *Id,
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000320 QualType T) {
Steve Naroff3e970492009-01-27 21:25:57 +0000321 return new (C) CXXClassVarDecl(RD, L, Id, T);
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000322}
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000323
324OverloadedFunctionDecl *
325OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000326 DeclarationName N) {
Steve Naroff3e970492009-01-27 21:25:57 +0000327 return new (C) OverloadedFunctionDecl(DC, N);
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000328}
Chris Lattner21ef7ae2008-11-04 16:51:42 +0000329
330LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
Douglas Gregor074149e2009-01-05 19:45:36 +0000331 DeclContext *DC,
Chris Lattner21ef7ae2008-11-04 16:51:42 +0000332 SourceLocation L,
Douglas Gregor074149e2009-01-05 19:45:36 +0000333 LanguageIDs Lang, bool Braces) {
Steve Naroff3e970492009-01-27 21:25:57 +0000334 return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
Douglas Gregorf44515a2008-12-16 22:23:02 +0000335}
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000336
337UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
338 SourceLocation L,
339 SourceLocation NamespaceLoc,
340 SourceLocation IdentLoc,
341 NamespaceDecl *Used,
342 DeclContext *CommonAncestor) {
343 return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, IdentLoc,
344 Used, CommonAncestor);
345}
346