blob: fb47904e01245190c00ccfbe3422768fc6be683b [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 Gregor030ff0c2008-10-31 20:25:05 +000062void
63CXXRecordDecl::addConstructor(ASTContext &Context,
64 CXXConstructorDecl *ConDecl) {
65 if (!ConDecl->isImplicitlyDeclared()) {
66 // Note that we have a user-declared constructor.
67 UserDeclaredConstructor = true;
68
69 // Note when we have a user-declared copy constructor, which will
70 // suppress the implicit declaration of a copy constructor.
71 if (ConDecl->isCopyConstructor(Context))
72 UserDeclaredCopyConstructor = true;
73 }
74
75 Constructors.addOverload(ConDecl);
76}
77
Ted Kremenek4b7c9832008-09-05 17:16:31 +000078CXXMethodDecl *
79CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
80 SourceLocation L, IdentifierInfo *Id,
81 QualType T, bool isStatic, bool isInline,
82 ScopedDecl *PrevDecl) {
83 void *Mem = C.getAllocator().Allocate<CXXMethodDecl>();
84 return new (Mem) CXXMethodDecl(RD, L, Id, T, isStatic, isInline, PrevDecl);
85}
86
87QualType CXXMethodDecl::getThisType(ASTContext &C) const {
Argyrios Kyrtzidisb0d178d2008-10-24 22:28:18 +000088 // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
89 // If the member function is declared const, the type of this is const X*,
90 // if the member function is declared volatile, the type of this is
91 // volatile X*, and if the member function is declared const volatile,
92 // the type of this is const volatile X*.
93
Ted Kremenek4b7c9832008-09-05 17:16:31 +000094 assert(isInstance() && "No 'this' for static methods!");
Douglas Gregor030ff0c2008-10-31 20:25:05 +000095 QualType ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +000096 ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
97 return C.getPointerType(ClassTy).withConst();
Ted Kremenek4b7c9832008-09-05 17:16:31 +000098}
99
Douglas Gregorb48fe382008-10-31 09:07:45 +0000100CXXConstructorDecl *
101CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
102 SourceLocation L, IdentifierInfo *Id,
103 QualType T, bool isExplicit,
104 bool isInline, bool isImplicitlyDeclared) {
105 void *Mem = C.getAllocator().Allocate<CXXConstructorDecl>();
106 return new (Mem) CXXConstructorDecl(RD, L, Id, T, isExplicit, isInline,
107 isImplicitlyDeclared);
108}
109
Douglas Gregor030ff0c2008-10-31 20:25:05 +0000110bool CXXConstructorDecl::isDefaultConstructor() const {
111 // C++ [class.ctor]p5:
112 //
113 // A default constructor for a class X is a constructor of class
114 // X that can be called without an argument.
115 return (getNumParams() == 0) ||
116 (getNumParams() > 0 & getParamDecl(1)->getDefaultArg() != 0);
117}
118
119bool
120CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
121 unsigned &TypeQuals) const {
122 // C++ [class.copy]p2:
123 // A non-template constructor for class X is a copy constructor
124 // if its first parameter is of type X&, const X&, volatile X& or
125 // const volatile X&, and either there are no other parameters
126 // or else all other parameters have default arguments (8.3.6).
127 if ((getNumParams() < 1) ||
128 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() == 0))
129 return false;
130
131 const ParmVarDecl *Param = getParamDecl(0);
132
133 // Do we have a reference type?
134 const ReferenceType *ParamRefType = Param->getType()->getAsReferenceType();
135 if (!ParamRefType)
136 return false;
137
138 // Is it a reference to our class type?
139 QualType PointeeType
140 = Context.getCanonicalType(ParamRefType->getPointeeType());
141 QualType ClassTy
142 = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
143 if (PointeeType.getUnqualifiedType() != ClassTy)
144 return false;
145
146 // We have a copy constructor.
147 TypeQuals = PointeeType.getCVRQualifiers();
148 return true;
149}
150
Douglas Gregor60d62c22008-10-31 16:23:19 +0000151bool CXXConstructorDecl::isConvertingConstructor() const {
152 // C++ [class.conv.ctor]p1:
153 // A constructor declared without the function-specifier explicit
154 // that can be called with a single parameter specifies a
155 // conversion from the type of its first parameter to the type of
156 // its class. Such a constructor is called a converting
157 // constructor.
158 if (isExplicit())
159 return false;
160
161 return (getNumParams() == 0 &&
162 getType()->getAsFunctionTypeProto()->isVariadic()) ||
163 (getNumParams() == 1) ||
164 (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
165}
Douglas Gregorb48fe382008-10-31 09:07:45 +0000166
Ted Kremenek4b7c9832008-09-05 17:16:31 +0000167CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
168 SourceLocation L, IdentifierInfo *Id,
169 QualType T, ScopedDecl *PrevDecl) {
170 void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();
171 return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);
172}
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000173
174OverloadedFunctionDecl *
175OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
176 IdentifierInfo *Id) {
177 void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
178 return new (Mem) OverloadedFunctionDecl(DC, Id);
179}