blob: 21701461e617efd8fa275d8fb88f04ffb063a5df [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"
16using namespace clang;
17
18//===----------------------------------------------------------------------===//
19// Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
22CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
23 SourceLocation L, IdentifierInfo *Id,
24 QualType T, Expr *BW) {
25 void *Mem = C.getAllocator().Allocate<CXXFieldDecl>();
26 return new (Mem) CXXFieldDecl(RD, L, Id, T, BW);
27}
28
29CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
30 SourceLocation L, IdentifierInfo *Id,
31 CXXRecordDecl* PrevDecl) {
Ted Kremenek4b7c9832008-09-05 17:16:31 +000032 void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +000033 CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id);
Ted Kremenek4b7c9832008-09-05 17:16:31 +000034 C.getTypeDeclType(R, PrevDecl);
35 return R;
36}
37
Douglas Gregorf8268ae2008-10-22 17:49:05 +000038CXXRecordDecl::~CXXRecordDecl() {
Douglas Gregorf8268ae2008-10-22 17:49:05 +000039 delete [] Bases;
40}
41
Douglas Gregorb48fe382008-10-31 09:07:45 +000042void CXXRecordDecl::Destroy(ASTContext &C) {
43 for (OverloadedFunctionDecl::function_iterator func
44 = Constructors.function_begin();
45 func != Constructors.function_end(); ++func)
46 (*func)->Destroy(C);
47 RecordDecl::Destroy(C);
48}
49
Douglas Gregor57c856b2008-10-23 18:13:27 +000050void
51CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
52 unsigned NumBases) {
53 if (this->Bases)
54 delete [] this->Bases;
55
56 this->Bases = new CXXBaseSpecifier[NumBases];
57 this->NumBases = NumBases;
58 for (unsigned i = 0; i < NumBases; ++i)
59 this->Bases[i] = *Bases[i];
60}
61
Douglas Gregor396b7cd2008-11-03 17:51:48 +000062bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
63 for (OverloadedFunctionDecl::function_const_iterator Con
64 = Constructors.function_begin();
65 Con != Constructors.function_end(); ++Con) {
66 unsigned TypeQuals;
67 if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
68 (TypeQuals & QualType::Const != 0))
69 return true;
70 }
71 return false;
72}
73
Douglas Gregor030ff0c2008-10-31 20:25:05 +000074void
75CXXRecordDecl::addConstructor(ASTContext &Context,
76 CXXConstructorDecl *ConDecl) {
77 if (!ConDecl->isImplicitlyDeclared()) {
78 // Note that we have a user-declared constructor.
79 UserDeclaredConstructor = true;
80
81 // Note when we have a user-declared copy constructor, which will
82 // suppress the implicit declaration of a copy constructor.
83 if (ConDecl->isCopyConstructor(Context))
84 UserDeclaredCopyConstructor = true;
85 }
86
87 Constructors.addOverload(ConDecl);
88}
89
Ted Kremenek4b7c9832008-09-05 17:16:31 +000090CXXMethodDecl *
91CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
92 SourceLocation L, IdentifierInfo *Id,
93 QualType T, bool isStatic, bool isInline,
94 ScopedDecl *PrevDecl) {
95 void *Mem = C.getAllocator().Allocate<CXXMethodDecl>();
96 return new (Mem) CXXMethodDecl(RD, L, Id, T, isStatic, isInline, PrevDecl);
97}
98
99QualType CXXMethodDecl::getThisType(ASTContext &C) const {
Argyrios Kyrtzidisb0d178d2008-10-24 22:28:18 +0000100 // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
101 // If the member function is declared const, the type of this is const X*,
102 // if the member function is declared volatile, the type of this is
103 // volatile X*, and if the member function is declared const volatile,
104 // the type of this is const volatile X*.
105
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000106 assert(isInstance() && "No 'this' for static methods!");
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000107 QualType ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +0000108 ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
109 return C.getPointerType(ClassTy).withConst();
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000110}
111
Douglas Gregorb48fe382008-10-31 09:07:45 +0000112CXXConstructorDecl *
113CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
114 SourceLocation L, IdentifierInfo *Id,
115 QualType T, bool isExplicit,
116 bool isInline, bool isImplicitlyDeclared) {
117 void *Mem = C.getAllocator().Allocate<CXXConstructorDecl>();
118 return new (Mem) CXXConstructorDecl(RD, L, Id, T, isExplicit, isInline,
119 isImplicitlyDeclared);
120}
121
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000122bool CXXConstructorDecl::isDefaultConstructor() const {
123 // C++ [class.ctor]p5:
124 //
125 // A default constructor for a class X is a constructor of class
126 // X that can be called without an argument.
127 return (getNumParams() == 0) ||
128 (getNumParams() > 0 & getParamDecl(1)->getDefaultArg() != 0);
129}
130
131bool
132CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
133 unsigned &TypeQuals) const {
134 // C++ [class.copy]p2:
135 // A non-template constructor for class X is a copy constructor
136 // if its first parameter is of type X&, const X&, volatile X& or
137 // const volatile X&, and either there are no other parameters
138 // or else all other parameters have default arguments (8.3.6).
139 if ((getNumParams() < 1) ||
140 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() == 0))
141 return false;
142
143 const ParmVarDecl *Param = getParamDecl(0);
144
145 // Do we have a reference type?
146 const ReferenceType *ParamRefType = Param->getType()->getAsReferenceType();
147 if (!ParamRefType)
148 return false;
149
150 // Is it a reference to our class type?
151 QualType PointeeType
152 = Context.getCanonicalType(ParamRefType->getPointeeType());
153 QualType ClassTy
154 = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
155 if (PointeeType.getUnqualifiedType() != ClassTy)
156 return false;
157
158 // We have a copy constructor.
159 TypeQuals = PointeeType.getCVRQualifiers();
160 return true;
161}
162
Douglas Gregor60d62c22008-10-31 16:23:19 +0000163bool CXXConstructorDecl::isConvertingConstructor() const {
164 // C++ [class.conv.ctor]p1:
165 // A constructor declared without the function-specifier explicit
166 // that can be called with a single parameter specifies a
167 // conversion from the type of its first parameter to the type of
168 // its class. Such a constructor is called a converting
169 // constructor.
170 if (isExplicit())
171 return false;
172
173 return (getNumParams() == 0 &&
174 getType()->getAsFunctionTypeProto()->isVariadic()) ||
175 (getNumParams() == 1) ||
176 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
177}
Douglas Gregorb48fe382008-10-31 09:07:45 +0000178
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000179CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
180 SourceLocation L, IdentifierInfo *Id,
181 QualType T, ScopedDecl *PrevDecl) {
182 void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();
183 return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);
184}
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000185
186OverloadedFunctionDecl *
187OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
188 IdentifierInfo *Id) {
189 void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
190 return new (Mem) OverloadedFunctionDecl(DC, Id);
191}
Chris Lattner21ef7ae2008-11-04 16:51:42 +0000192
193LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
194 SourceLocation L,
195 LanguageIDs Lang, Decl *D) {
196 void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
197 return new (Mem) LinkageSpecDecl(L, Lang, D);
198}
199