1f4a2713aSLionel Sambuc //===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the C++ related Decl classes.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
14f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
15f4a2713aSLionel Sambuc #include "clang/AST/ASTLambda.h"
16f4a2713aSLionel Sambuc #include "clang/AST/ASTMutationListener.h"
17f4a2713aSLionel Sambuc #include "clang/AST/CXXInheritance.h"
18f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
19f4a2713aSLionel Sambuc #include "clang/AST/Expr.h"
20f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h"
21f4a2713aSLionel Sambuc #include "clang/AST/TypeLoc.h"
22f4a2713aSLionel Sambuc #include "clang/Basic/IdentifierTable.h"
23f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
24f4a2713aSLionel Sambuc #include "llvm/ADT/SmallPtrSet.h"
25f4a2713aSLionel Sambuc using namespace clang;
26f4a2713aSLionel Sambuc
27f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
28f4a2713aSLionel Sambuc // Decl Allocation/Deallocation Method Implementations
29f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
30f4a2713aSLionel Sambuc
anchor()31f4a2713aSLionel Sambuc void AccessSpecDecl::anchor() { }
32f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)33f4a2713aSLionel Sambuc AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
34*0a6a1f1dSLionel Sambuc return new (C, ID) AccessSpecDecl(EmptyShell());
35f4a2713aSLionel Sambuc }
36f4a2713aSLionel Sambuc
getFromExternalSource(ASTContext & C) const37f4a2713aSLionel Sambuc void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
38f4a2713aSLionel Sambuc ExternalASTSource *Source = C.getExternalSource();
39f4a2713aSLionel Sambuc assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set");
40f4a2713aSLionel Sambuc assert(Source && "getFromExternalSource with no external source");
41f4a2713aSLionel Sambuc
42f4a2713aSLionel Sambuc for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I)
43f4a2713aSLionel Sambuc I.setDecl(cast<NamedDecl>(Source->GetExternalDecl(
44f4a2713aSLionel Sambuc reinterpret_cast<uintptr_t>(I.getDecl()) >> 2)));
45f4a2713aSLionel Sambuc Impl.Decls.setLazy(false);
46f4a2713aSLionel Sambuc }
47f4a2713aSLionel Sambuc
DefinitionData(CXXRecordDecl * D)48f4a2713aSLionel Sambuc CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
49f4a2713aSLionel Sambuc : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
50f4a2713aSLionel Sambuc Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
51f4a2713aSLionel Sambuc Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
52f4a2713aSLionel Sambuc HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
53*0a6a1f1dSLionel Sambuc HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true),
54f4a2713aSLionel Sambuc HasInClassInitializer(false), HasUninitializedReferenceMember(false),
55f4a2713aSLionel Sambuc NeedOverloadResolutionForMoveConstructor(false),
56f4a2713aSLionel Sambuc NeedOverloadResolutionForMoveAssignment(false),
57f4a2713aSLionel Sambuc NeedOverloadResolutionForDestructor(false),
58f4a2713aSLionel Sambuc DefaultedMoveConstructorIsDeleted(false),
59f4a2713aSLionel Sambuc DefaultedMoveAssignmentIsDeleted(false),
60f4a2713aSLionel Sambuc DefaultedDestructorIsDeleted(false),
61f4a2713aSLionel Sambuc HasTrivialSpecialMembers(SMF_All),
62f4a2713aSLionel Sambuc DeclaredNonTrivialSpecialMembers(0),
63f4a2713aSLionel Sambuc HasIrrelevantDestructor(true),
64f4a2713aSLionel Sambuc HasConstexprNonCopyMoveConstructor(false),
65f4a2713aSLionel Sambuc DefaultedDefaultConstructorIsConstexpr(true),
66f4a2713aSLionel Sambuc HasConstexprDefaultConstructor(false),
67f4a2713aSLionel Sambuc HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
68f4a2713aSLionel Sambuc UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0),
69f4a2713aSLionel Sambuc ImplicitCopyConstructorHasConstParam(true),
70f4a2713aSLionel Sambuc ImplicitCopyAssignmentHasConstParam(true),
71f4a2713aSLionel Sambuc HasDeclaredCopyConstructorWithConstParam(false),
72f4a2713aSLionel Sambuc HasDeclaredCopyAssignmentWithConstParam(false),
73*0a6a1f1dSLionel Sambuc IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
74*0a6a1f1dSLionel Sambuc Bases(), VBases(),
75f4a2713aSLionel Sambuc Definition(D), FirstFriend() {
76f4a2713aSLionel Sambuc }
77f4a2713aSLionel Sambuc
getBasesSlowCase() const78f4a2713aSLionel Sambuc CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
79f4a2713aSLionel Sambuc return Bases.get(Definition->getASTContext().getExternalSource());
80f4a2713aSLionel Sambuc }
81f4a2713aSLionel Sambuc
getVBasesSlowCase() const82f4a2713aSLionel Sambuc CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const {
83f4a2713aSLionel Sambuc return VBases.get(Definition->getASTContext().getExternalSource());
84f4a2713aSLionel Sambuc }
85f4a2713aSLionel Sambuc
CXXRecordDecl(Kind K,TagKind TK,const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,CXXRecordDecl * PrevDecl)86*0a6a1f1dSLionel Sambuc CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
87*0a6a1f1dSLionel Sambuc DeclContext *DC, SourceLocation StartLoc,
88*0a6a1f1dSLionel Sambuc SourceLocation IdLoc, IdentifierInfo *Id,
89*0a6a1f1dSLionel Sambuc CXXRecordDecl *PrevDecl)
90*0a6a1f1dSLionel Sambuc : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
91*0a6a1f1dSLionel Sambuc DefinitionData(PrevDecl ? PrevDecl->DefinitionData
92*0a6a1f1dSLionel Sambuc : DefinitionDataPtr(this)),
93f4a2713aSLionel Sambuc TemplateOrInstantiation() {}
94f4a2713aSLionel Sambuc
Create(const ASTContext & C,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,CXXRecordDecl * PrevDecl,bool DelayTypeCreation)95f4a2713aSLionel Sambuc CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
96f4a2713aSLionel Sambuc DeclContext *DC, SourceLocation StartLoc,
97f4a2713aSLionel Sambuc SourceLocation IdLoc, IdentifierInfo *Id,
98f4a2713aSLionel Sambuc CXXRecordDecl* PrevDecl,
99f4a2713aSLionel Sambuc bool DelayTypeCreation) {
100*0a6a1f1dSLionel Sambuc CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
101*0a6a1f1dSLionel Sambuc IdLoc, Id, PrevDecl);
102f4a2713aSLionel Sambuc R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
103f4a2713aSLionel Sambuc
104f4a2713aSLionel Sambuc // FIXME: DelayTypeCreation seems like such a hack
105f4a2713aSLionel Sambuc if (!DelayTypeCreation)
106f4a2713aSLionel Sambuc C.getTypeDeclType(R, PrevDecl);
107f4a2713aSLionel Sambuc return R;
108f4a2713aSLionel Sambuc }
109f4a2713aSLionel Sambuc
110*0a6a1f1dSLionel Sambuc CXXRecordDecl *
CreateLambda(const ASTContext & C,DeclContext * DC,TypeSourceInfo * Info,SourceLocation Loc,bool Dependent,bool IsGeneric,LambdaCaptureDefault CaptureDefault)111*0a6a1f1dSLionel Sambuc CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
112f4a2713aSLionel Sambuc TypeSourceInfo *Info, SourceLocation Loc,
113f4a2713aSLionel Sambuc bool Dependent, bool IsGeneric,
114f4a2713aSLionel Sambuc LambdaCaptureDefault CaptureDefault) {
115*0a6a1f1dSLionel Sambuc CXXRecordDecl *R =
116*0a6a1f1dSLionel Sambuc new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
117*0a6a1f1dSLionel Sambuc nullptr, nullptr);
118f4a2713aSLionel Sambuc R->IsBeingDefined = true;
119*0a6a1f1dSLionel Sambuc R->DefinitionData =
120*0a6a1f1dSLionel Sambuc new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
121f4a2713aSLionel Sambuc CaptureDefault);
122f4a2713aSLionel Sambuc R->MayHaveOutOfDateDef = false;
123f4a2713aSLionel Sambuc R->setImplicit(true);
124*0a6a1f1dSLionel Sambuc C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
125f4a2713aSLionel Sambuc return R;
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc
128f4a2713aSLionel Sambuc CXXRecordDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)129f4a2713aSLionel Sambuc CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
130*0a6a1f1dSLionel Sambuc CXXRecordDecl *R = new (C, ID) CXXRecordDecl(
131*0a6a1f1dSLionel Sambuc CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(),
132*0a6a1f1dSLionel Sambuc nullptr, nullptr);
133f4a2713aSLionel Sambuc R->MayHaveOutOfDateDef = false;
134f4a2713aSLionel Sambuc return R;
135f4a2713aSLionel Sambuc }
136f4a2713aSLionel Sambuc
137f4a2713aSLionel Sambuc void
setBases(CXXBaseSpecifier const * const * Bases,unsigned NumBases)138f4a2713aSLionel Sambuc CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
139f4a2713aSLionel Sambuc unsigned NumBases) {
140f4a2713aSLionel Sambuc ASTContext &C = getASTContext();
141f4a2713aSLionel Sambuc
142f4a2713aSLionel Sambuc if (!data().Bases.isOffset() && data().NumBases > 0)
143f4a2713aSLionel Sambuc C.Deallocate(data().getBases());
144f4a2713aSLionel Sambuc
145f4a2713aSLionel Sambuc if (NumBases) {
146f4a2713aSLionel Sambuc // C++ [dcl.init.aggr]p1:
147f4a2713aSLionel Sambuc // An aggregate is [...] a class with [...] no base classes [...].
148f4a2713aSLionel Sambuc data().Aggregate = false;
149f4a2713aSLionel Sambuc
150f4a2713aSLionel Sambuc // C++ [class]p4:
151f4a2713aSLionel Sambuc // A POD-struct is an aggregate class...
152f4a2713aSLionel Sambuc data().PlainOldData = false;
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc
155f4a2713aSLionel Sambuc // The set of seen virtual base types.
156f4a2713aSLionel Sambuc llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
157f4a2713aSLionel Sambuc
158f4a2713aSLionel Sambuc // The virtual bases of this class.
159f4a2713aSLionel Sambuc SmallVector<const CXXBaseSpecifier *, 8> VBases;
160f4a2713aSLionel Sambuc
161f4a2713aSLionel Sambuc data().Bases = new(C) CXXBaseSpecifier [NumBases];
162f4a2713aSLionel Sambuc data().NumBases = NumBases;
163f4a2713aSLionel Sambuc for (unsigned i = 0; i < NumBases; ++i) {
164f4a2713aSLionel Sambuc data().getBases()[i] = *Bases[i];
165f4a2713aSLionel Sambuc // Keep track of inherited vbases for this base class.
166f4a2713aSLionel Sambuc const CXXBaseSpecifier *Base = Bases[i];
167f4a2713aSLionel Sambuc QualType BaseType = Base->getType();
168f4a2713aSLionel Sambuc // Skip dependent types; we can't do any checking on them now.
169f4a2713aSLionel Sambuc if (BaseType->isDependentType())
170f4a2713aSLionel Sambuc continue;
171f4a2713aSLionel Sambuc CXXRecordDecl *BaseClassDecl
172f4a2713aSLionel Sambuc = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
173f4a2713aSLionel Sambuc
174f4a2713aSLionel Sambuc // A class with a non-empty base class is not empty.
175f4a2713aSLionel Sambuc // FIXME: Standard ref?
176f4a2713aSLionel Sambuc if (!BaseClassDecl->isEmpty()) {
177f4a2713aSLionel Sambuc if (!data().Empty) {
178f4a2713aSLionel Sambuc // C++0x [class]p7:
179f4a2713aSLionel Sambuc // A standard-layout class is a class that:
180f4a2713aSLionel Sambuc // [...]
181f4a2713aSLionel Sambuc // -- either has no non-static data members in the most derived
182f4a2713aSLionel Sambuc // class and at most one base class with non-static data members,
183f4a2713aSLionel Sambuc // or has no base classes with non-static data members, and
184f4a2713aSLionel Sambuc // If this is the second non-empty base, then neither of these two
185f4a2713aSLionel Sambuc // clauses can be true.
186f4a2713aSLionel Sambuc data().IsStandardLayout = false;
187f4a2713aSLionel Sambuc }
188f4a2713aSLionel Sambuc
189f4a2713aSLionel Sambuc data().Empty = false;
190f4a2713aSLionel Sambuc data().HasNoNonEmptyBases = false;
191f4a2713aSLionel Sambuc }
192f4a2713aSLionel Sambuc
193f4a2713aSLionel Sambuc // C++ [class.virtual]p1:
194f4a2713aSLionel Sambuc // A class that declares or inherits a virtual function is called a
195f4a2713aSLionel Sambuc // polymorphic class.
196f4a2713aSLionel Sambuc if (BaseClassDecl->isPolymorphic())
197f4a2713aSLionel Sambuc data().Polymorphic = true;
198f4a2713aSLionel Sambuc
199f4a2713aSLionel Sambuc // C++0x [class]p7:
200f4a2713aSLionel Sambuc // A standard-layout class is a class that: [...]
201f4a2713aSLionel Sambuc // -- has no non-standard-layout base classes
202f4a2713aSLionel Sambuc if (!BaseClassDecl->isStandardLayout())
203f4a2713aSLionel Sambuc data().IsStandardLayout = false;
204f4a2713aSLionel Sambuc
205f4a2713aSLionel Sambuc // Record if this base is the first non-literal field or base.
206f4a2713aSLionel Sambuc if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C))
207f4a2713aSLionel Sambuc data().HasNonLiteralTypeFieldsOrBases = true;
208f4a2713aSLionel Sambuc
209f4a2713aSLionel Sambuc // Now go through all virtual bases of this base and add them.
210*0a6a1f1dSLionel Sambuc for (const auto &VBase : BaseClassDecl->vbases()) {
211f4a2713aSLionel Sambuc // Add this base if it's not already in the list.
212*0a6a1f1dSLionel Sambuc if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType())).second) {
213*0a6a1f1dSLionel Sambuc VBases.push_back(&VBase);
214f4a2713aSLionel Sambuc
215f4a2713aSLionel Sambuc // C++11 [class.copy]p8:
216f4a2713aSLionel Sambuc // The implicitly-declared copy constructor for a class X will have
217f4a2713aSLionel Sambuc // the form 'X::X(const X&)' if each [...] virtual base class B of X
218f4a2713aSLionel Sambuc // has a copy constructor whose first parameter is of type
219f4a2713aSLionel Sambuc // 'const B&' or 'const volatile B&' [...]
220*0a6a1f1dSLionel Sambuc if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl())
221f4a2713aSLionel Sambuc if (!VBaseDecl->hasCopyConstructorWithConstParam())
222f4a2713aSLionel Sambuc data().ImplicitCopyConstructorHasConstParam = false;
223f4a2713aSLionel Sambuc }
224f4a2713aSLionel Sambuc }
225f4a2713aSLionel Sambuc
226f4a2713aSLionel Sambuc if (Base->isVirtual()) {
227f4a2713aSLionel Sambuc // Add this base if it's not already in the list.
228*0a6a1f1dSLionel Sambuc if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)).second)
229f4a2713aSLionel Sambuc VBases.push_back(Base);
230f4a2713aSLionel Sambuc
231f4a2713aSLionel Sambuc // C++0x [meta.unary.prop] is_empty:
232f4a2713aSLionel Sambuc // T is a class type, but not a union type, with ... no virtual base
233f4a2713aSLionel Sambuc // classes
234f4a2713aSLionel Sambuc data().Empty = false;
235f4a2713aSLionel Sambuc
236f4a2713aSLionel Sambuc // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
237f4a2713aSLionel Sambuc // A [default constructor, copy/move constructor, or copy/move assignment
238f4a2713aSLionel Sambuc // operator for a class X] is trivial [...] if:
239f4a2713aSLionel Sambuc // -- class X has [...] no virtual base classes
240f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= SMF_Destructor;
241f4a2713aSLionel Sambuc
242f4a2713aSLionel Sambuc // C++0x [class]p7:
243f4a2713aSLionel Sambuc // A standard-layout class is a class that: [...]
244f4a2713aSLionel Sambuc // -- has [...] no virtual base classes
245f4a2713aSLionel Sambuc data().IsStandardLayout = false;
246f4a2713aSLionel Sambuc
247f4a2713aSLionel Sambuc // C++11 [dcl.constexpr]p4:
248f4a2713aSLionel Sambuc // In the definition of a constexpr constructor [...]
249f4a2713aSLionel Sambuc // -- the class shall not have any virtual base classes
250f4a2713aSLionel Sambuc data().DefaultedDefaultConstructorIsConstexpr = false;
251f4a2713aSLionel Sambuc } else {
252f4a2713aSLionel Sambuc // C++ [class.ctor]p5:
253f4a2713aSLionel Sambuc // A default constructor is trivial [...] if:
254f4a2713aSLionel Sambuc // -- all the direct base classes of its class have trivial default
255f4a2713aSLionel Sambuc // constructors.
256f4a2713aSLionel Sambuc if (!BaseClassDecl->hasTrivialDefaultConstructor())
257f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
258f4a2713aSLionel Sambuc
259f4a2713aSLionel Sambuc // C++0x [class.copy]p13:
260f4a2713aSLionel Sambuc // A copy/move constructor for class X is trivial if [...]
261f4a2713aSLionel Sambuc // [...]
262f4a2713aSLionel Sambuc // -- the constructor selected to copy/move each direct base class
263f4a2713aSLionel Sambuc // subobject is trivial, and
264f4a2713aSLionel Sambuc if (!BaseClassDecl->hasTrivialCopyConstructor())
265f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor;
266f4a2713aSLionel Sambuc // If the base class doesn't have a simple move constructor, we'll eagerly
267f4a2713aSLionel Sambuc // declare it and perform overload resolution to determine which function
268f4a2713aSLionel Sambuc // it actually calls. If it does have a simple move constructor, this
269f4a2713aSLionel Sambuc // check is correct.
270f4a2713aSLionel Sambuc if (!BaseClassDecl->hasTrivialMoveConstructor())
271f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor;
272f4a2713aSLionel Sambuc
273f4a2713aSLionel Sambuc // C++0x [class.copy]p27:
274f4a2713aSLionel Sambuc // A copy/move assignment operator for class X is trivial if [...]
275f4a2713aSLionel Sambuc // [...]
276f4a2713aSLionel Sambuc // -- the assignment operator selected to copy/move each direct base
277f4a2713aSLionel Sambuc // class subobject is trivial, and
278f4a2713aSLionel Sambuc if (!BaseClassDecl->hasTrivialCopyAssignment())
279f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment;
280f4a2713aSLionel Sambuc // If the base class doesn't have a simple move assignment, we'll eagerly
281f4a2713aSLionel Sambuc // declare it and perform overload resolution to determine which function
282f4a2713aSLionel Sambuc // it actually calls. If it does have a simple move assignment, this
283f4a2713aSLionel Sambuc // check is correct.
284f4a2713aSLionel Sambuc if (!BaseClassDecl->hasTrivialMoveAssignment())
285f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment;
286f4a2713aSLionel Sambuc
287f4a2713aSLionel Sambuc // C++11 [class.ctor]p6:
288f4a2713aSLionel Sambuc // If that user-written default constructor would satisfy the
289f4a2713aSLionel Sambuc // requirements of a constexpr constructor, the implicitly-defined
290f4a2713aSLionel Sambuc // default constructor is constexpr.
291f4a2713aSLionel Sambuc if (!BaseClassDecl->hasConstexprDefaultConstructor())
292f4a2713aSLionel Sambuc data().DefaultedDefaultConstructorIsConstexpr = false;
293f4a2713aSLionel Sambuc }
294f4a2713aSLionel Sambuc
295f4a2713aSLionel Sambuc // C++ [class.ctor]p3:
296f4a2713aSLionel Sambuc // A destructor is trivial if all the direct base classes of its class
297f4a2713aSLionel Sambuc // have trivial destructors.
298f4a2713aSLionel Sambuc if (!BaseClassDecl->hasTrivialDestructor())
299f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_Destructor;
300f4a2713aSLionel Sambuc
301f4a2713aSLionel Sambuc if (!BaseClassDecl->hasIrrelevantDestructor())
302f4a2713aSLionel Sambuc data().HasIrrelevantDestructor = false;
303f4a2713aSLionel Sambuc
304f4a2713aSLionel Sambuc // C++11 [class.copy]p18:
305f4a2713aSLionel Sambuc // The implicitly-declared copy assignment oeprator for a class X will
306f4a2713aSLionel Sambuc // have the form 'X& X::operator=(const X&)' if each direct base class B
307f4a2713aSLionel Sambuc // of X has a copy assignment operator whose parameter is of type 'const
308f4a2713aSLionel Sambuc // B&', 'const volatile B&', or 'B' [...]
309f4a2713aSLionel Sambuc if (!BaseClassDecl->hasCopyAssignmentWithConstParam())
310f4a2713aSLionel Sambuc data().ImplicitCopyAssignmentHasConstParam = false;
311f4a2713aSLionel Sambuc
312f4a2713aSLionel Sambuc // C++11 [class.copy]p8:
313f4a2713aSLionel Sambuc // The implicitly-declared copy constructor for a class X will have
314f4a2713aSLionel Sambuc // the form 'X::X(const X&)' if each direct [...] base class B of X
315f4a2713aSLionel Sambuc // has a copy constructor whose first parameter is of type
316f4a2713aSLionel Sambuc // 'const B&' or 'const volatile B&' [...]
317f4a2713aSLionel Sambuc if (!BaseClassDecl->hasCopyConstructorWithConstParam())
318f4a2713aSLionel Sambuc data().ImplicitCopyConstructorHasConstParam = false;
319f4a2713aSLionel Sambuc
320f4a2713aSLionel Sambuc // A class has an Objective-C object member if... or any of its bases
321f4a2713aSLionel Sambuc // has an Objective-C object member.
322f4a2713aSLionel Sambuc if (BaseClassDecl->hasObjectMember())
323f4a2713aSLionel Sambuc setHasObjectMember(true);
324f4a2713aSLionel Sambuc
325f4a2713aSLionel Sambuc if (BaseClassDecl->hasVolatileMember())
326f4a2713aSLionel Sambuc setHasVolatileMember(true);
327f4a2713aSLionel Sambuc
328f4a2713aSLionel Sambuc // Keep track of the presence of mutable fields.
329f4a2713aSLionel Sambuc if (BaseClassDecl->hasMutableFields())
330f4a2713aSLionel Sambuc data().HasMutableFields = true;
331f4a2713aSLionel Sambuc
332f4a2713aSLionel Sambuc if (BaseClassDecl->hasUninitializedReferenceMember())
333f4a2713aSLionel Sambuc data().HasUninitializedReferenceMember = true;
334f4a2713aSLionel Sambuc
335f4a2713aSLionel Sambuc addedClassSubobject(BaseClassDecl);
336f4a2713aSLionel Sambuc }
337f4a2713aSLionel Sambuc
338*0a6a1f1dSLionel Sambuc if (VBases.empty()) {
339*0a6a1f1dSLionel Sambuc data().IsParsingBaseSpecifiers = false;
340f4a2713aSLionel Sambuc return;
341*0a6a1f1dSLionel Sambuc }
342f4a2713aSLionel Sambuc
343f4a2713aSLionel Sambuc // Create base specifier for any direct or indirect virtual bases.
344f4a2713aSLionel Sambuc data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
345f4a2713aSLionel Sambuc data().NumVBases = VBases.size();
346f4a2713aSLionel Sambuc for (int I = 0, E = VBases.size(); I != E; ++I) {
347f4a2713aSLionel Sambuc QualType Type = VBases[I]->getType();
348f4a2713aSLionel Sambuc if (!Type->isDependentType())
349f4a2713aSLionel Sambuc addedClassSubobject(Type->getAsCXXRecordDecl());
350f4a2713aSLionel Sambuc data().getVBases()[I] = *VBases[I];
351f4a2713aSLionel Sambuc }
352*0a6a1f1dSLionel Sambuc
353*0a6a1f1dSLionel Sambuc data().IsParsingBaseSpecifiers = false;
354f4a2713aSLionel Sambuc }
355f4a2713aSLionel Sambuc
addedClassSubobject(CXXRecordDecl * Subobj)356f4a2713aSLionel Sambuc void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
357f4a2713aSLionel Sambuc // C++11 [class.copy]p11:
358f4a2713aSLionel Sambuc // A defaulted copy/move constructor for a class X is defined as
359f4a2713aSLionel Sambuc // deleted if X has:
360f4a2713aSLionel Sambuc // -- a direct or virtual base class B that cannot be copied/moved [...]
361f4a2713aSLionel Sambuc // -- a non-static data member of class type M (or array thereof)
362f4a2713aSLionel Sambuc // that cannot be copied or moved [...]
363f4a2713aSLionel Sambuc if (!Subobj->hasSimpleMoveConstructor())
364f4a2713aSLionel Sambuc data().NeedOverloadResolutionForMoveConstructor = true;
365f4a2713aSLionel Sambuc
366f4a2713aSLionel Sambuc // C++11 [class.copy]p23:
367f4a2713aSLionel Sambuc // A defaulted copy/move assignment operator for a class X is defined as
368f4a2713aSLionel Sambuc // deleted if X has:
369f4a2713aSLionel Sambuc // -- a direct or virtual base class B that cannot be copied/moved [...]
370f4a2713aSLionel Sambuc // -- a non-static data member of class type M (or array thereof)
371f4a2713aSLionel Sambuc // that cannot be copied or moved [...]
372f4a2713aSLionel Sambuc if (!Subobj->hasSimpleMoveAssignment())
373f4a2713aSLionel Sambuc data().NeedOverloadResolutionForMoveAssignment = true;
374f4a2713aSLionel Sambuc
375f4a2713aSLionel Sambuc // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5:
376f4a2713aSLionel Sambuc // A defaulted [ctor or dtor] for a class X is defined as
377f4a2713aSLionel Sambuc // deleted if X has:
378f4a2713aSLionel Sambuc // -- any direct or virtual base class [...] has a type with a destructor
379f4a2713aSLionel Sambuc // that is deleted or inaccessible from the defaulted [ctor or dtor].
380f4a2713aSLionel Sambuc // -- any non-static data member has a type with a destructor
381f4a2713aSLionel Sambuc // that is deleted or inaccessible from the defaulted [ctor or dtor].
382f4a2713aSLionel Sambuc if (!Subobj->hasSimpleDestructor()) {
383f4a2713aSLionel Sambuc data().NeedOverloadResolutionForMoveConstructor = true;
384f4a2713aSLionel Sambuc data().NeedOverloadResolutionForDestructor = true;
385f4a2713aSLionel Sambuc }
386f4a2713aSLionel Sambuc }
387f4a2713aSLionel Sambuc
388f4a2713aSLionel Sambuc /// Callback function for CXXRecordDecl::forallBases that acknowledges
389f4a2713aSLionel Sambuc /// that it saw a base class.
SawBase(const CXXRecordDecl *,void *)390f4a2713aSLionel Sambuc static bool SawBase(const CXXRecordDecl *, void *) {
391f4a2713aSLionel Sambuc return true;
392f4a2713aSLionel Sambuc }
393f4a2713aSLionel Sambuc
hasAnyDependentBases() const394f4a2713aSLionel Sambuc bool CXXRecordDecl::hasAnyDependentBases() const {
395f4a2713aSLionel Sambuc if (!isDependentContext())
396f4a2713aSLionel Sambuc return false;
397f4a2713aSLionel Sambuc
398*0a6a1f1dSLionel Sambuc return !forallBases(SawBase, nullptr);
399f4a2713aSLionel Sambuc }
400f4a2713aSLionel Sambuc
isTriviallyCopyable() const401f4a2713aSLionel Sambuc bool CXXRecordDecl::isTriviallyCopyable() const {
402f4a2713aSLionel Sambuc // C++0x [class]p5:
403f4a2713aSLionel Sambuc // A trivially copyable class is a class that:
404f4a2713aSLionel Sambuc // -- has no non-trivial copy constructors,
405f4a2713aSLionel Sambuc if (hasNonTrivialCopyConstructor()) return false;
406f4a2713aSLionel Sambuc // -- has no non-trivial move constructors,
407f4a2713aSLionel Sambuc if (hasNonTrivialMoveConstructor()) return false;
408f4a2713aSLionel Sambuc // -- has no non-trivial copy assignment operators,
409f4a2713aSLionel Sambuc if (hasNonTrivialCopyAssignment()) return false;
410f4a2713aSLionel Sambuc // -- has no non-trivial move assignment operators, and
411f4a2713aSLionel Sambuc if (hasNonTrivialMoveAssignment()) return false;
412f4a2713aSLionel Sambuc // -- has a trivial destructor.
413f4a2713aSLionel Sambuc if (!hasTrivialDestructor()) return false;
414f4a2713aSLionel Sambuc
415f4a2713aSLionel Sambuc return true;
416f4a2713aSLionel Sambuc }
417f4a2713aSLionel Sambuc
markedVirtualFunctionPure()418f4a2713aSLionel Sambuc void CXXRecordDecl::markedVirtualFunctionPure() {
419f4a2713aSLionel Sambuc // C++ [class.abstract]p2:
420f4a2713aSLionel Sambuc // A class is abstract if it has at least one pure virtual function.
421f4a2713aSLionel Sambuc data().Abstract = true;
422f4a2713aSLionel Sambuc }
423f4a2713aSLionel Sambuc
addedMember(Decl * D)424f4a2713aSLionel Sambuc void CXXRecordDecl::addedMember(Decl *D) {
425f4a2713aSLionel Sambuc if (!D->isImplicit() &&
426f4a2713aSLionel Sambuc !isa<FieldDecl>(D) &&
427f4a2713aSLionel Sambuc !isa<IndirectFieldDecl>(D) &&
428f4a2713aSLionel Sambuc (!isa<TagDecl>(D) || cast<TagDecl>(D)->getTagKind() == TTK_Class ||
429f4a2713aSLionel Sambuc cast<TagDecl>(D)->getTagKind() == TTK_Interface))
430f4a2713aSLionel Sambuc data().HasOnlyCMembers = false;
431f4a2713aSLionel Sambuc
432f4a2713aSLionel Sambuc // Ignore friends and invalid declarations.
433f4a2713aSLionel Sambuc if (D->getFriendObjectKind() || D->isInvalidDecl())
434f4a2713aSLionel Sambuc return;
435f4a2713aSLionel Sambuc
436f4a2713aSLionel Sambuc FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D);
437f4a2713aSLionel Sambuc if (FunTmpl)
438f4a2713aSLionel Sambuc D = FunTmpl->getTemplatedDecl();
439f4a2713aSLionel Sambuc
440f4a2713aSLionel Sambuc if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
441f4a2713aSLionel Sambuc if (Method->isVirtual()) {
442f4a2713aSLionel Sambuc // C++ [dcl.init.aggr]p1:
443f4a2713aSLionel Sambuc // An aggregate is an array or a class with [...] no virtual functions.
444f4a2713aSLionel Sambuc data().Aggregate = false;
445f4a2713aSLionel Sambuc
446f4a2713aSLionel Sambuc // C++ [class]p4:
447f4a2713aSLionel Sambuc // A POD-struct is an aggregate class...
448f4a2713aSLionel Sambuc data().PlainOldData = false;
449f4a2713aSLionel Sambuc
450f4a2713aSLionel Sambuc // Virtual functions make the class non-empty.
451f4a2713aSLionel Sambuc // FIXME: Standard ref?
452f4a2713aSLionel Sambuc data().Empty = false;
453f4a2713aSLionel Sambuc
454f4a2713aSLionel Sambuc // C++ [class.virtual]p1:
455f4a2713aSLionel Sambuc // A class that declares or inherits a virtual function is called a
456f4a2713aSLionel Sambuc // polymorphic class.
457f4a2713aSLionel Sambuc data().Polymorphic = true;
458f4a2713aSLionel Sambuc
459f4a2713aSLionel Sambuc // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
460f4a2713aSLionel Sambuc // A [default constructor, copy/move constructor, or copy/move
461f4a2713aSLionel Sambuc // assignment operator for a class X] is trivial [...] if:
462f4a2713aSLionel Sambuc // -- class X has no virtual functions [...]
463f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= SMF_Destructor;
464f4a2713aSLionel Sambuc
465f4a2713aSLionel Sambuc // C++0x [class]p7:
466f4a2713aSLionel Sambuc // A standard-layout class is a class that: [...]
467f4a2713aSLionel Sambuc // -- has no virtual functions
468f4a2713aSLionel Sambuc data().IsStandardLayout = false;
469f4a2713aSLionel Sambuc }
470f4a2713aSLionel Sambuc }
471f4a2713aSLionel Sambuc
472f4a2713aSLionel Sambuc // Notify the listener if an implicit member was added after the definition
473f4a2713aSLionel Sambuc // was completed.
474f4a2713aSLionel Sambuc if (!isBeingDefined() && D->isImplicit())
475f4a2713aSLionel Sambuc if (ASTMutationListener *L = getASTMutationListener())
476f4a2713aSLionel Sambuc L->AddedCXXImplicitMember(data().Definition, D);
477f4a2713aSLionel Sambuc
478f4a2713aSLionel Sambuc // The kind of special member this declaration is, if any.
479f4a2713aSLionel Sambuc unsigned SMKind = 0;
480f4a2713aSLionel Sambuc
481f4a2713aSLionel Sambuc // Handle constructors.
482f4a2713aSLionel Sambuc if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
483f4a2713aSLionel Sambuc if (!Constructor->isImplicit()) {
484f4a2713aSLionel Sambuc // Note that we have a user-declared constructor.
485f4a2713aSLionel Sambuc data().UserDeclaredConstructor = true;
486f4a2713aSLionel Sambuc
487f4a2713aSLionel Sambuc // C++ [class]p4:
488f4a2713aSLionel Sambuc // A POD-struct is an aggregate class [...]
489f4a2713aSLionel Sambuc // Since the POD bit is meant to be C++03 POD-ness, clear it even if the
490f4a2713aSLionel Sambuc // type is technically an aggregate in C++0x since it wouldn't be in 03.
491f4a2713aSLionel Sambuc data().PlainOldData = false;
492f4a2713aSLionel Sambuc }
493f4a2713aSLionel Sambuc
494f4a2713aSLionel Sambuc // Technically, "user-provided" is only defined for special member
495f4a2713aSLionel Sambuc // functions, but the intent of the standard is clearly that it should apply
496f4a2713aSLionel Sambuc // to all functions.
497f4a2713aSLionel Sambuc bool UserProvided = Constructor->isUserProvided();
498f4a2713aSLionel Sambuc
499f4a2713aSLionel Sambuc if (Constructor->isDefaultConstructor()) {
500f4a2713aSLionel Sambuc SMKind |= SMF_DefaultConstructor;
501f4a2713aSLionel Sambuc
502f4a2713aSLionel Sambuc if (UserProvided)
503f4a2713aSLionel Sambuc data().UserProvidedDefaultConstructor = true;
504f4a2713aSLionel Sambuc if (Constructor->isConstexpr())
505f4a2713aSLionel Sambuc data().HasConstexprDefaultConstructor = true;
506f4a2713aSLionel Sambuc }
507f4a2713aSLionel Sambuc
508f4a2713aSLionel Sambuc if (!FunTmpl) {
509f4a2713aSLionel Sambuc unsigned Quals;
510f4a2713aSLionel Sambuc if (Constructor->isCopyConstructor(Quals)) {
511f4a2713aSLionel Sambuc SMKind |= SMF_CopyConstructor;
512f4a2713aSLionel Sambuc
513f4a2713aSLionel Sambuc if (Quals & Qualifiers::Const)
514f4a2713aSLionel Sambuc data().HasDeclaredCopyConstructorWithConstParam = true;
515f4a2713aSLionel Sambuc } else if (Constructor->isMoveConstructor())
516f4a2713aSLionel Sambuc SMKind |= SMF_MoveConstructor;
517f4a2713aSLionel Sambuc }
518f4a2713aSLionel Sambuc
519f4a2713aSLionel Sambuc // Record if we see any constexpr constructors which are neither copy
520f4a2713aSLionel Sambuc // nor move constructors.
521f4a2713aSLionel Sambuc if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor())
522f4a2713aSLionel Sambuc data().HasConstexprNonCopyMoveConstructor = true;
523f4a2713aSLionel Sambuc
524f4a2713aSLionel Sambuc // C++ [dcl.init.aggr]p1:
525f4a2713aSLionel Sambuc // An aggregate is an array or a class with no user-declared
526f4a2713aSLionel Sambuc // constructors [...].
527f4a2713aSLionel Sambuc // C++11 [dcl.init.aggr]p1:
528f4a2713aSLionel Sambuc // An aggregate is an array or a class with no user-provided
529f4a2713aSLionel Sambuc // constructors [...].
530f4a2713aSLionel Sambuc if (getASTContext().getLangOpts().CPlusPlus11
531f4a2713aSLionel Sambuc ? UserProvided : !Constructor->isImplicit())
532f4a2713aSLionel Sambuc data().Aggregate = false;
533f4a2713aSLionel Sambuc }
534f4a2713aSLionel Sambuc
535f4a2713aSLionel Sambuc // Handle destructors.
536f4a2713aSLionel Sambuc if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) {
537f4a2713aSLionel Sambuc SMKind |= SMF_Destructor;
538f4a2713aSLionel Sambuc
539*0a6a1f1dSLionel Sambuc if (DD->isUserProvided())
540f4a2713aSLionel Sambuc data().HasIrrelevantDestructor = false;
541*0a6a1f1dSLionel Sambuc // If the destructor is explicitly defaulted and not trivial or not public
542*0a6a1f1dSLionel Sambuc // or if the destructor is deleted, we clear HasIrrelevantDestructor in
543*0a6a1f1dSLionel Sambuc // finishedDefaultedOrDeletedMember.
544f4a2713aSLionel Sambuc
545f4a2713aSLionel Sambuc // C++11 [class.dtor]p5:
546f4a2713aSLionel Sambuc // A destructor is trivial if [...] the destructor is not virtual.
547f4a2713aSLionel Sambuc if (DD->isVirtual())
548f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_Destructor;
549f4a2713aSLionel Sambuc }
550f4a2713aSLionel Sambuc
551f4a2713aSLionel Sambuc // Handle member functions.
552f4a2713aSLionel Sambuc if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
553f4a2713aSLionel Sambuc if (Method->isCopyAssignmentOperator()) {
554f4a2713aSLionel Sambuc SMKind |= SMF_CopyAssignment;
555f4a2713aSLionel Sambuc
556f4a2713aSLionel Sambuc const ReferenceType *ParamTy =
557f4a2713aSLionel Sambuc Method->getParamDecl(0)->getType()->getAs<ReferenceType>();
558f4a2713aSLionel Sambuc if (!ParamTy || ParamTy->getPointeeType().isConstQualified())
559f4a2713aSLionel Sambuc data().HasDeclaredCopyAssignmentWithConstParam = true;
560f4a2713aSLionel Sambuc }
561f4a2713aSLionel Sambuc
562f4a2713aSLionel Sambuc if (Method->isMoveAssignmentOperator())
563f4a2713aSLionel Sambuc SMKind |= SMF_MoveAssignment;
564f4a2713aSLionel Sambuc
565f4a2713aSLionel Sambuc // Keep the list of conversion functions up-to-date.
566f4a2713aSLionel Sambuc if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
567f4a2713aSLionel Sambuc // FIXME: We use the 'unsafe' accessor for the access specifier here,
568f4a2713aSLionel Sambuc // because Sema may not have set it yet. That's really just a misdesign
569f4a2713aSLionel Sambuc // in Sema. However, LLDB *will* have set the access specifier correctly,
570f4a2713aSLionel Sambuc // and adds declarations after the class is technically completed,
571f4a2713aSLionel Sambuc // so completeDefinition()'s overriding of the access specifiers doesn't
572f4a2713aSLionel Sambuc // work.
573f4a2713aSLionel Sambuc AccessSpecifier AS = Conversion->getAccessUnsafe();
574f4a2713aSLionel Sambuc
575f4a2713aSLionel Sambuc if (Conversion->getPrimaryTemplate()) {
576f4a2713aSLionel Sambuc // We don't record specializations.
577f4a2713aSLionel Sambuc } else {
578f4a2713aSLionel Sambuc ASTContext &Ctx = getASTContext();
579f4a2713aSLionel Sambuc ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx);
580f4a2713aSLionel Sambuc NamedDecl *Primary =
581f4a2713aSLionel Sambuc FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion);
582f4a2713aSLionel Sambuc if (Primary->getPreviousDecl())
583f4a2713aSLionel Sambuc Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()),
584f4a2713aSLionel Sambuc Primary, AS);
585f4a2713aSLionel Sambuc else
586f4a2713aSLionel Sambuc Conversions.addDecl(Ctx, Primary, AS);
587f4a2713aSLionel Sambuc }
588f4a2713aSLionel Sambuc }
589f4a2713aSLionel Sambuc
590f4a2713aSLionel Sambuc if (SMKind) {
591f4a2713aSLionel Sambuc // If this is the first declaration of a special member, we no longer have
592f4a2713aSLionel Sambuc // an implicit trivial special member.
593f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &=
594f4a2713aSLionel Sambuc data().DeclaredSpecialMembers | ~SMKind;
595f4a2713aSLionel Sambuc
596f4a2713aSLionel Sambuc if (!Method->isImplicit() && !Method->isUserProvided()) {
597f4a2713aSLionel Sambuc // This method is user-declared but not user-provided. We can't work out
598f4a2713aSLionel Sambuc // whether it's trivial yet (not until we get to the end of the class).
599f4a2713aSLionel Sambuc // We'll handle this method in finishedDefaultedOrDeletedMember.
600f4a2713aSLionel Sambuc } else if (Method->isTrivial())
601f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers |= SMKind;
602f4a2713aSLionel Sambuc else
603f4a2713aSLionel Sambuc data().DeclaredNonTrivialSpecialMembers |= SMKind;
604f4a2713aSLionel Sambuc
605f4a2713aSLionel Sambuc // Note when we have declared a declared special member, and suppress the
606f4a2713aSLionel Sambuc // implicit declaration of this special member.
607f4a2713aSLionel Sambuc data().DeclaredSpecialMembers |= SMKind;
608f4a2713aSLionel Sambuc
609f4a2713aSLionel Sambuc if (!Method->isImplicit()) {
610f4a2713aSLionel Sambuc data().UserDeclaredSpecialMembers |= SMKind;
611f4a2713aSLionel Sambuc
612f4a2713aSLionel Sambuc // C++03 [class]p4:
613f4a2713aSLionel Sambuc // A POD-struct is an aggregate class that has [...] no user-defined
614f4a2713aSLionel Sambuc // copy assignment operator and no user-defined destructor.
615f4a2713aSLionel Sambuc //
616f4a2713aSLionel Sambuc // Since the POD bit is meant to be C++03 POD-ness, and in C++03,
617f4a2713aSLionel Sambuc // aggregates could not have any constructors, clear it even for an
618f4a2713aSLionel Sambuc // explicitly defaulted or deleted constructor.
619f4a2713aSLionel Sambuc // type is technically an aggregate in C++0x since it wouldn't be in 03.
620f4a2713aSLionel Sambuc //
621f4a2713aSLionel Sambuc // Also, a user-declared move assignment operator makes a class non-POD.
622f4a2713aSLionel Sambuc // This is an extension in C++03.
623f4a2713aSLionel Sambuc data().PlainOldData = false;
624f4a2713aSLionel Sambuc }
625f4a2713aSLionel Sambuc }
626f4a2713aSLionel Sambuc
627f4a2713aSLionel Sambuc return;
628f4a2713aSLionel Sambuc }
629f4a2713aSLionel Sambuc
630f4a2713aSLionel Sambuc // Handle non-static data members.
631f4a2713aSLionel Sambuc if (FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
632f4a2713aSLionel Sambuc // C++ [class.bit]p2:
633f4a2713aSLionel Sambuc // A declaration for a bit-field that omits the identifier declares an
634f4a2713aSLionel Sambuc // unnamed bit-field. Unnamed bit-fields are not members and cannot be
635f4a2713aSLionel Sambuc // initialized.
636f4a2713aSLionel Sambuc if (Field->isUnnamedBitfield())
637f4a2713aSLionel Sambuc return;
638f4a2713aSLionel Sambuc
639f4a2713aSLionel Sambuc // C++ [dcl.init.aggr]p1:
640f4a2713aSLionel Sambuc // An aggregate is an array or a class (clause 9) with [...] no
641f4a2713aSLionel Sambuc // private or protected non-static data members (clause 11).
642f4a2713aSLionel Sambuc //
643f4a2713aSLionel Sambuc // A POD must be an aggregate.
644f4a2713aSLionel Sambuc if (D->getAccess() == AS_private || D->getAccess() == AS_protected) {
645f4a2713aSLionel Sambuc data().Aggregate = false;
646f4a2713aSLionel Sambuc data().PlainOldData = false;
647f4a2713aSLionel Sambuc }
648f4a2713aSLionel Sambuc
649f4a2713aSLionel Sambuc // C++0x [class]p7:
650f4a2713aSLionel Sambuc // A standard-layout class is a class that:
651f4a2713aSLionel Sambuc // [...]
652f4a2713aSLionel Sambuc // -- has the same access control for all non-static data members,
653f4a2713aSLionel Sambuc switch (D->getAccess()) {
654f4a2713aSLionel Sambuc case AS_private: data().HasPrivateFields = true; break;
655f4a2713aSLionel Sambuc case AS_protected: data().HasProtectedFields = true; break;
656f4a2713aSLionel Sambuc case AS_public: data().HasPublicFields = true; break;
657f4a2713aSLionel Sambuc case AS_none: llvm_unreachable("Invalid access specifier");
658f4a2713aSLionel Sambuc };
659f4a2713aSLionel Sambuc if ((data().HasPrivateFields + data().HasProtectedFields +
660f4a2713aSLionel Sambuc data().HasPublicFields) > 1)
661f4a2713aSLionel Sambuc data().IsStandardLayout = false;
662f4a2713aSLionel Sambuc
663f4a2713aSLionel Sambuc // Keep track of the presence of mutable fields.
664f4a2713aSLionel Sambuc if (Field->isMutable())
665f4a2713aSLionel Sambuc data().HasMutableFields = true;
666f4a2713aSLionel Sambuc
667*0a6a1f1dSLionel Sambuc // C++11 [class.union]p8, DR1460:
668*0a6a1f1dSLionel Sambuc // If X is a union, a non-static data member of X that is not an anonymous
669*0a6a1f1dSLionel Sambuc // union is a variant member of X.
670*0a6a1f1dSLionel Sambuc if (isUnion() && !Field->isAnonymousStructOrUnion())
671*0a6a1f1dSLionel Sambuc data().HasVariantMembers = true;
672*0a6a1f1dSLionel Sambuc
673f4a2713aSLionel Sambuc // C++0x [class]p9:
674f4a2713aSLionel Sambuc // A POD struct is a class that is both a trivial class and a
675f4a2713aSLionel Sambuc // standard-layout class, and has no non-static data members of type
676f4a2713aSLionel Sambuc // non-POD struct, non-POD union (or array of such types).
677f4a2713aSLionel Sambuc //
678f4a2713aSLionel Sambuc // Automatic Reference Counting: the presence of a member of Objective-C pointer type
679f4a2713aSLionel Sambuc // that does not explicitly have no lifetime makes the class a non-POD.
680f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
681f4a2713aSLionel Sambuc QualType T = Context.getBaseElementType(Field->getType());
682f4a2713aSLionel Sambuc if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
683*0a6a1f1dSLionel Sambuc if (!Context.getLangOpts().ObjCAutoRefCount) {
684f4a2713aSLionel Sambuc setHasObjectMember(true);
685*0a6a1f1dSLionel Sambuc } else if (T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
686*0a6a1f1dSLionel Sambuc // Objective-C Automatic Reference Counting:
687*0a6a1f1dSLionel Sambuc // If a class has a non-static data member of Objective-C pointer
688*0a6a1f1dSLionel Sambuc // type (or array thereof), it is a non-POD type and its
689*0a6a1f1dSLionel Sambuc // default constructor (if any), copy constructor, move constructor,
690*0a6a1f1dSLionel Sambuc // copy assignment operator, move assignment operator, and destructor are
691*0a6a1f1dSLionel Sambuc // non-trivial.
692*0a6a1f1dSLionel Sambuc setHasObjectMember(true);
693*0a6a1f1dSLionel Sambuc struct DefinitionData &Data = data();
694*0a6a1f1dSLionel Sambuc Data.PlainOldData = false;
695*0a6a1f1dSLionel Sambuc Data.HasTrivialSpecialMembers = 0;
696*0a6a1f1dSLionel Sambuc Data.HasIrrelevantDestructor = false;
697*0a6a1f1dSLionel Sambuc }
698f4a2713aSLionel Sambuc } else if (!T.isCXX98PODType(Context))
699f4a2713aSLionel Sambuc data().PlainOldData = false;
700f4a2713aSLionel Sambuc
701f4a2713aSLionel Sambuc if (T->isReferenceType()) {
702f4a2713aSLionel Sambuc if (!Field->hasInClassInitializer())
703f4a2713aSLionel Sambuc data().HasUninitializedReferenceMember = true;
704f4a2713aSLionel Sambuc
705f4a2713aSLionel Sambuc // C++0x [class]p7:
706f4a2713aSLionel Sambuc // A standard-layout class is a class that:
707f4a2713aSLionel Sambuc // -- has no non-static data members of type [...] reference,
708f4a2713aSLionel Sambuc data().IsStandardLayout = false;
709f4a2713aSLionel Sambuc }
710f4a2713aSLionel Sambuc
711f4a2713aSLionel Sambuc // Record if this field is the first non-literal or volatile field or base.
712f4a2713aSLionel Sambuc if (!T->isLiteralType(Context) || T.isVolatileQualified())
713f4a2713aSLionel Sambuc data().HasNonLiteralTypeFieldsOrBases = true;
714f4a2713aSLionel Sambuc
715*0a6a1f1dSLionel Sambuc if (Field->hasInClassInitializer() ||
716*0a6a1f1dSLionel Sambuc (Field->isAnonymousStructOrUnion() &&
717*0a6a1f1dSLionel Sambuc Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
718f4a2713aSLionel Sambuc data().HasInClassInitializer = true;
719f4a2713aSLionel Sambuc
720f4a2713aSLionel Sambuc // C++11 [class]p5:
721f4a2713aSLionel Sambuc // A default constructor is trivial if [...] no non-static data member
722f4a2713aSLionel Sambuc // of its class has a brace-or-equal-initializer.
723f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
724f4a2713aSLionel Sambuc
725f4a2713aSLionel Sambuc // C++11 [dcl.init.aggr]p1:
726f4a2713aSLionel Sambuc // An aggregate is a [...] class with [...] no
727f4a2713aSLionel Sambuc // brace-or-equal-initializers for non-static data members.
728f4a2713aSLionel Sambuc //
729f4a2713aSLionel Sambuc // This rule was removed in C++1y.
730*0a6a1f1dSLionel Sambuc if (!getASTContext().getLangOpts().CPlusPlus14)
731f4a2713aSLionel Sambuc data().Aggregate = false;
732f4a2713aSLionel Sambuc
733f4a2713aSLionel Sambuc // C++11 [class]p10:
734f4a2713aSLionel Sambuc // A POD struct is [...] a trivial class.
735f4a2713aSLionel Sambuc data().PlainOldData = false;
736f4a2713aSLionel Sambuc }
737f4a2713aSLionel Sambuc
738f4a2713aSLionel Sambuc // C++11 [class.copy]p23:
739f4a2713aSLionel Sambuc // A defaulted copy/move assignment operator for a class X is defined
740f4a2713aSLionel Sambuc // as deleted if X has:
741f4a2713aSLionel Sambuc // -- a non-static data member of reference type
742f4a2713aSLionel Sambuc if (T->isReferenceType())
743f4a2713aSLionel Sambuc data().DefaultedMoveAssignmentIsDeleted = true;
744f4a2713aSLionel Sambuc
745f4a2713aSLionel Sambuc if (const RecordType *RecordTy = T->getAs<RecordType>()) {
746f4a2713aSLionel Sambuc CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
747f4a2713aSLionel Sambuc if (FieldRec->getDefinition()) {
748f4a2713aSLionel Sambuc addedClassSubobject(FieldRec);
749f4a2713aSLionel Sambuc
750f4a2713aSLionel Sambuc // We may need to perform overload resolution to determine whether a
751f4a2713aSLionel Sambuc // field can be moved if it's const or volatile qualified.
752f4a2713aSLionel Sambuc if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
753f4a2713aSLionel Sambuc data().NeedOverloadResolutionForMoveConstructor = true;
754f4a2713aSLionel Sambuc data().NeedOverloadResolutionForMoveAssignment = true;
755f4a2713aSLionel Sambuc }
756f4a2713aSLionel Sambuc
757f4a2713aSLionel Sambuc // C++11 [class.ctor]p5, C++11 [class.copy]p11:
758f4a2713aSLionel Sambuc // A defaulted [special member] for a class X is defined as
759f4a2713aSLionel Sambuc // deleted if:
760f4a2713aSLionel Sambuc // -- X is a union-like class that has a variant member with a
761f4a2713aSLionel Sambuc // non-trivial [corresponding special member]
762f4a2713aSLionel Sambuc if (isUnion()) {
763f4a2713aSLionel Sambuc if (FieldRec->hasNonTrivialMoveConstructor())
764f4a2713aSLionel Sambuc data().DefaultedMoveConstructorIsDeleted = true;
765f4a2713aSLionel Sambuc if (FieldRec->hasNonTrivialMoveAssignment())
766f4a2713aSLionel Sambuc data().DefaultedMoveAssignmentIsDeleted = true;
767f4a2713aSLionel Sambuc if (FieldRec->hasNonTrivialDestructor())
768f4a2713aSLionel Sambuc data().DefaultedDestructorIsDeleted = true;
769f4a2713aSLionel Sambuc }
770f4a2713aSLionel Sambuc
771f4a2713aSLionel Sambuc // C++0x [class.ctor]p5:
772f4a2713aSLionel Sambuc // A default constructor is trivial [...] if:
773f4a2713aSLionel Sambuc // -- for all the non-static data members of its class that are of
774f4a2713aSLionel Sambuc // class type (or array thereof), each such class has a trivial
775f4a2713aSLionel Sambuc // default constructor.
776f4a2713aSLionel Sambuc if (!FieldRec->hasTrivialDefaultConstructor())
777f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
778f4a2713aSLionel Sambuc
779f4a2713aSLionel Sambuc // C++0x [class.copy]p13:
780f4a2713aSLionel Sambuc // A copy/move constructor for class X is trivial if [...]
781f4a2713aSLionel Sambuc // [...]
782f4a2713aSLionel Sambuc // -- for each non-static data member of X that is of class type (or
783f4a2713aSLionel Sambuc // an array thereof), the constructor selected to copy/move that
784f4a2713aSLionel Sambuc // member is trivial;
785f4a2713aSLionel Sambuc if (!FieldRec->hasTrivialCopyConstructor())
786f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor;
787f4a2713aSLionel Sambuc // If the field doesn't have a simple move constructor, we'll eagerly
788f4a2713aSLionel Sambuc // declare the move constructor for this class and we'll decide whether
789f4a2713aSLionel Sambuc // it's trivial then.
790f4a2713aSLionel Sambuc if (!FieldRec->hasTrivialMoveConstructor())
791f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor;
792f4a2713aSLionel Sambuc
793f4a2713aSLionel Sambuc // C++0x [class.copy]p27:
794f4a2713aSLionel Sambuc // A copy/move assignment operator for class X is trivial if [...]
795f4a2713aSLionel Sambuc // [...]
796f4a2713aSLionel Sambuc // -- for each non-static data member of X that is of class type (or
797f4a2713aSLionel Sambuc // an array thereof), the assignment operator selected to
798f4a2713aSLionel Sambuc // copy/move that member is trivial;
799f4a2713aSLionel Sambuc if (!FieldRec->hasTrivialCopyAssignment())
800f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment;
801f4a2713aSLionel Sambuc // If the field doesn't have a simple move assignment, we'll eagerly
802f4a2713aSLionel Sambuc // declare the move assignment for this class and we'll decide whether
803f4a2713aSLionel Sambuc // it's trivial then.
804f4a2713aSLionel Sambuc if (!FieldRec->hasTrivialMoveAssignment())
805f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment;
806f4a2713aSLionel Sambuc
807f4a2713aSLionel Sambuc if (!FieldRec->hasTrivialDestructor())
808f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers &= ~SMF_Destructor;
809f4a2713aSLionel Sambuc if (!FieldRec->hasIrrelevantDestructor())
810f4a2713aSLionel Sambuc data().HasIrrelevantDestructor = false;
811f4a2713aSLionel Sambuc if (FieldRec->hasObjectMember())
812f4a2713aSLionel Sambuc setHasObjectMember(true);
813f4a2713aSLionel Sambuc if (FieldRec->hasVolatileMember())
814f4a2713aSLionel Sambuc setHasVolatileMember(true);
815f4a2713aSLionel Sambuc
816f4a2713aSLionel Sambuc // C++0x [class]p7:
817f4a2713aSLionel Sambuc // A standard-layout class is a class that:
818f4a2713aSLionel Sambuc // -- has no non-static data members of type non-standard-layout
819f4a2713aSLionel Sambuc // class (or array of such types) [...]
820f4a2713aSLionel Sambuc if (!FieldRec->isStandardLayout())
821f4a2713aSLionel Sambuc data().IsStandardLayout = false;
822f4a2713aSLionel Sambuc
823f4a2713aSLionel Sambuc // C++0x [class]p7:
824f4a2713aSLionel Sambuc // A standard-layout class is a class that:
825f4a2713aSLionel Sambuc // [...]
826f4a2713aSLionel Sambuc // -- has no base classes of the same type as the first non-static
827f4a2713aSLionel Sambuc // data member.
828f4a2713aSLionel Sambuc // We don't want to expend bits in the state of the record decl
829f4a2713aSLionel Sambuc // tracking whether this is the first non-static data member so we
830f4a2713aSLionel Sambuc // cheat a bit and use some of the existing state: the empty bit.
831f4a2713aSLionel Sambuc // Virtual bases and virtual methods make a class non-empty, but they
832f4a2713aSLionel Sambuc // also make it non-standard-layout so we needn't check here.
833f4a2713aSLionel Sambuc // A non-empty base class may leave the class standard-layout, but not
834*0a6a1f1dSLionel Sambuc // if we have arrived here, and have at least one non-static data
835f4a2713aSLionel Sambuc // member. If IsStandardLayout remains true, then the first non-static
836f4a2713aSLionel Sambuc // data member must come through here with Empty still true, and Empty
837f4a2713aSLionel Sambuc // will subsequently be set to false below.
838f4a2713aSLionel Sambuc if (data().IsStandardLayout && data().Empty) {
839*0a6a1f1dSLionel Sambuc for (const auto &BI : bases()) {
840*0a6a1f1dSLionel Sambuc if (Context.hasSameUnqualifiedType(BI.getType(), T)) {
841f4a2713aSLionel Sambuc data().IsStandardLayout = false;
842f4a2713aSLionel Sambuc break;
843f4a2713aSLionel Sambuc }
844f4a2713aSLionel Sambuc }
845f4a2713aSLionel Sambuc }
846f4a2713aSLionel Sambuc
847f4a2713aSLionel Sambuc // Keep track of the presence of mutable fields.
848f4a2713aSLionel Sambuc if (FieldRec->hasMutableFields())
849f4a2713aSLionel Sambuc data().HasMutableFields = true;
850f4a2713aSLionel Sambuc
851f4a2713aSLionel Sambuc // C++11 [class.copy]p13:
852f4a2713aSLionel Sambuc // If the implicitly-defined constructor would satisfy the
853f4a2713aSLionel Sambuc // requirements of a constexpr constructor, the implicitly-defined
854f4a2713aSLionel Sambuc // constructor is constexpr.
855f4a2713aSLionel Sambuc // C++11 [dcl.constexpr]p4:
856f4a2713aSLionel Sambuc // -- every constructor involved in initializing non-static data
857f4a2713aSLionel Sambuc // members [...] shall be a constexpr constructor
858f4a2713aSLionel Sambuc if (!Field->hasInClassInitializer() &&
859f4a2713aSLionel Sambuc !FieldRec->hasConstexprDefaultConstructor() && !isUnion())
860f4a2713aSLionel Sambuc // The standard requires any in-class initializer to be a constant
861f4a2713aSLionel Sambuc // expression. We consider this to be a defect.
862f4a2713aSLionel Sambuc data().DefaultedDefaultConstructorIsConstexpr = false;
863f4a2713aSLionel Sambuc
864f4a2713aSLionel Sambuc // C++11 [class.copy]p8:
865f4a2713aSLionel Sambuc // The implicitly-declared copy constructor for a class X will have
866f4a2713aSLionel Sambuc // the form 'X::X(const X&)' if [...] for all the non-static data
867f4a2713aSLionel Sambuc // members of X that are of a class type M (or array thereof), each
868f4a2713aSLionel Sambuc // such class type has a copy constructor whose first parameter is
869f4a2713aSLionel Sambuc // of type 'const M&' or 'const volatile M&'.
870f4a2713aSLionel Sambuc if (!FieldRec->hasCopyConstructorWithConstParam())
871f4a2713aSLionel Sambuc data().ImplicitCopyConstructorHasConstParam = false;
872f4a2713aSLionel Sambuc
873f4a2713aSLionel Sambuc // C++11 [class.copy]p18:
874f4a2713aSLionel Sambuc // The implicitly-declared copy assignment oeprator for a class X will
875f4a2713aSLionel Sambuc // have the form 'X& X::operator=(const X&)' if [...] for all the
876f4a2713aSLionel Sambuc // non-static data members of X that are of a class type M (or array
877f4a2713aSLionel Sambuc // thereof), each such class type has a copy assignment operator whose
878f4a2713aSLionel Sambuc // parameter is of type 'const M&', 'const volatile M&' or 'M'.
879f4a2713aSLionel Sambuc if (!FieldRec->hasCopyAssignmentWithConstParam())
880f4a2713aSLionel Sambuc data().ImplicitCopyAssignmentHasConstParam = false;
881f4a2713aSLionel Sambuc
882f4a2713aSLionel Sambuc if (FieldRec->hasUninitializedReferenceMember() &&
883f4a2713aSLionel Sambuc !Field->hasInClassInitializer())
884f4a2713aSLionel Sambuc data().HasUninitializedReferenceMember = true;
885*0a6a1f1dSLionel Sambuc
886*0a6a1f1dSLionel Sambuc // C++11 [class.union]p8, DR1460:
887*0a6a1f1dSLionel Sambuc // a non-static data member of an anonymous union that is a member of
888*0a6a1f1dSLionel Sambuc // X is also a variant member of X.
889*0a6a1f1dSLionel Sambuc if (FieldRec->hasVariantMembers() &&
890*0a6a1f1dSLionel Sambuc Field->isAnonymousStructOrUnion())
891*0a6a1f1dSLionel Sambuc data().HasVariantMembers = true;
892f4a2713aSLionel Sambuc }
893f4a2713aSLionel Sambuc } else {
894f4a2713aSLionel Sambuc // Base element type of field is a non-class type.
895f4a2713aSLionel Sambuc if (!T->isLiteralType(Context) ||
896f4a2713aSLionel Sambuc (!Field->hasInClassInitializer() && !isUnion()))
897f4a2713aSLionel Sambuc data().DefaultedDefaultConstructorIsConstexpr = false;
898f4a2713aSLionel Sambuc
899f4a2713aSLionel Sambuc // C++11 [class.copy]p23:
900f4a2713aSLionel Sambuc // A defaulted copy/move assignment operator for a class X is defined
901f4a2713aSLionel Sambuc // as deleted if X has:
902f4a2713aSLionel Sambuc // -- a non-static data member of const non-class type (or array
903f4a2713aSLionel Sambuc // thereof)
904f4a2713aSLionel Sambuc if (T.isConstQualified())
905f4a2713aSLionel Sambuc data().DefaultedMoveAssignmentIsDeleted = true;
906f4a2713aSLionel Sambuc }
907f4a2713aSLionel Sambuc
908f4a2713aSLionel Sambuc // C++0x [class]p7:
909f4a2713aSLionel Sambuc // A standard-layout class is a class that:
910f4a2713aSLionel Sambuc // [...]
911f4a2713aSLionel Sambuc // -- either has no non-static data members in the most derived
912f4a2713aSLionel Sambuc // class and at most one base class with non-static data members,
913f4a2713aSLionel Sambuc // or has no base classes with non-static data members, and
914f4a2713aSLionel Sambuc // At this point we know that we have a non-static data member, so the last
915f4a2713aSLionel Sambuc // clause holds.
916f4a2713aSLionel Sambuc if (!data().HasNoNonEmptyBases)
917f4a2713aSLionel Sambuc data().IsStandardLayout = false;
918f4a2713aSLionel Sambuc
919f4a2713aSLionel Sambuc // If this is not a zero-length bit-field, then the class is not empty.
920f4a2713aSLionel Sambuc if (data().Empty) {
921f4a2713aSLionel Sambuc if (!Field->isBitField() ||
922f4a2713aSLionel Sambuc (!Field->getBitWidth()->isTypeDependent() &&
923f4a2713aSLionel Sambuc !Field->getBitWidth()->isValueDependent() &&
924f4a2713aSLionel Sambuc Field->getBitWidthValue(Context) != 0))
925f4a2713aSLionel Sambuc data().Empty = false;
926f4a2713aSLionel Sambuc }
927f4a2713aSLionel Sambuc }
928f4a2713aSLionel Sambuc
929f4a2713aSLionel Sambuc // Handle using declarations of conversion functions.
930f4a2713aSLionel Sambuc if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D)) {
931f4a2713aSLionel Sambuc if (Shadow->getDeclName().getNameKind()
932f4a2713aSLionel Sambuc == DeclarationName::CXXConversionFunctionName) {
933f4a2713aSLionel Sambuc ASTContext &Ctx = getASTContext();
934f4a2713aSLionel Sambuc data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess());
935f4a2713aSLionel Sambuc }
936f4a2713aSLionel Sambuc }
937f4a2713aSLionel Sambuc }
938f4a2713aSLionel Sambuc
finishedDefaultedOrDeletedMember(CXXMethodDecl * D)939f4a2713aSLionel Sambuc void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
940f4a2713aSLionel Sambuc assert(!D->isImplicit() && !D->isUserProvided());
941f4a2713aSLionel Sambuc
942f4a2713aSLionel Sambuc // The kind of special member this declaration is, if any.
943f4a2713aSLionel Sambuc unsigned SMKind = 0;
944f4a2713aSLionel Sambuc
945f4a2713aSLionel Sambuc if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
946f4a2713aSLionel Sambuc if (Constructor->isDefaultConstructor()) {
947f4a2713aSLionel Sambuc SMKind |= SMF_DefaultConstructor;
948f4a2713aSLionel Sambuc if (Constructor->isConstexpr())
949f4a2713aSLionel Sambuc data().HasConstexprDefaultConstructor = true;
950f4a2713aSLionel Sambuc }
951f4a2713aSLionel Sambuc if (Constructor->isCopyConstructor())
952f4a2713aSLionel Sambuc SMKind |= SMF_CopyConstructor;
953f4a2713aSLionel Sambuc else if (Constructor->isMoveConstructor())
954f4a2713aSLionel Sambuc SMKind |= SMF_MoveConstructor;
955f4a2713aSLionel Sambuc else if (Constructor->isConstexpr())
956f4a2713aSLionel Sambuc // We may now know that the constructor is constexpr.
957f4a2713aSLionel Sambuc data().HasConstexprNonCopyMoveConstructor = true;
958*0a6a1f1dSLionel Sambuc } else if (isa<CXXDestructorDecl>(D)) {
959f4a2713aSLionel Sambuc SMKind |= SMF_Destructor;
960*0a6a1f1dSLionel Sambuc if (!D->isTrivial() || D->getAccess() != AS_public || D->isDeleted())
961*0a6a1f1dSLionel Sambuc data().HasIrrelevantDestructor = false;
962*0a6a1f1dSLionel Sambuc } else if (D->isCopyAssignmentOperator())
963f4a2713aSLionel Sambuc SMKind |= SMF_CopyAssignment;
964f4a2713aSLionel Sambuc else if (D->isMoveAssignmentOperator())
965f4a2713aSLionel Sambuc SMKind |= SMF_MoveAssignment;
966f4a2713aSLionel Sambuc
967f4a2713aSLionel Sambuc // Update which trivial / non-trivial special members we have.
968f4a2713aSLionel Sambuc // addedMember will have skipped this step for this member.
969f4a2713aSLionel Sambuc if (D->isTrivial())
970f4a2713aSLionel Sambuc data().HasTrivialSpecialMembers |= SMKind;
971f4a2713aSLionel Sambuc else
972f4a2713aSLionel Sambuc data().DeclaredNonTrivialSpecialMembers |= SMKind;
973f4a2713aSLionel Sambuc }
974f4a2713aSLionel Sambuc
isCLike() const975f4a2713aSLionel Sambuc bool CXXRecordDecl::isCLike() const {
976f4a2713aSLionel Sambuc if (getTagKind() == TTK_Class || getTagKind() == TTK_Interface ||
977f4a2713aSLionel Sambuc !TemplateOrInstantiation.isNull())
978f4a2713aSLionel Sambuc return false;
979f4a2713aSLionel Sambuc if (!hasDefinition())
980f4a2713aSLionel Sambuc return true;
981f4a2713aSLionel Sambuc
982f4a2713aSLionel Sambuc return isPOD() && data().HasOnlyCMembers;
983f4a2713aSLionel Sambuc }
984f4a2713aSLionel Sambuc
isGenericLambda() const985f4a2713aSLionel Sambuc bool CXXRecordDecl::isGenericLambda() const {
986f4a2713aSLionel Sambuc if (!isLambda()) return false;
987f4a2713aSLionel Sambuc return getLambdaData().IsGenericLambda;
988f4a2713aSLionel Sambuc }
989f4a2713aSLionel Sambuc
getLambdaCallOperator() const990f4a2713aSLionel Sambuc CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
991*0a6a1f1dSLionel Sambuc if (!isLambda()) return nullptr;
992f4a2713aSLionel Sambuc DeclarationName Name =
993f4a2713aSLionel Sambuc getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
994f4a2713aSLionel Sambuc DeclContext::lookup_const_result Calls = lookup(Name);
995f4a2713aSLionel Sambuc
996f4a2713aSLionel Sambuc assert(!Calls.empty() && "Missing lambda call operator!");
997f4a2713aSLionel Sambuc assert(Calls.size() == 1 && "More than one lambda call operator!");
998f4a2713aSLionel Sambuc
999f4a2713aSLionel Sambuc NamedDecl *CallOp = Calls.front();
1000f4a2713aSLionel Sambuc if (FunctionTemplateDecl *CallOpTmpl =
1001f4a2713aSLionel Sambuc dyn_cast<FunctionTemplateDecl>(CallOp))
1002f4a2713aSLionel Sambuc return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl());
1003f4a2713aSLionel Sambuc
1004f4a2713aSLionel Sambuc return cast<CXXMethodDecl>(CallOp);
1005f4a2713aSLionel Sambuc }
1006f4a2713aSLionel Sambuc
getLambdaStaticInvoker() const1007f4a2713aSLionel Sambuc CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
1008*0a6a1f1dSLionel Sambuc if (!isLambda()) return nullptr;
1009f4a2713aSLionel Sambuc DeclarationName Name =
1010f4a2713aSLionel Sambuc &getASTContext().Idents.get(getLambdaStaticInvokerName());
1011f4a2713aSLionel Sambuc DeclContext::lookup_const_result Invoker = lookup(Name);
1012*0a6a1f1dSLionel Sambuc if (Invoker.empty()) return nullptr;
1013f4a2713aSLionel Sambuc assert(Invoker.size() == 1 && "More than one static invoker operator!");
1014f4a2713aSLionel Sambuc NamedDecl *InvokerFun = Invoker.front();
1015f4a2713aSLionel Sambuc if (FunctionTemplateDecl *InvokerTemplate =
1016f4a2713aSLionel Sambuc dyn_cast<FunctionTemplateDecl>(InvokerFun))
1017f4a2713aSLionel Sambuc return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl());
1018f4a2713aSLionel Sambuc
1019f4a2713aSLionel Sambuc return cast<CXXMethodDecl>(InvokerFun);
1020f4a2713aSLionel Sambuc }
1021f4a2713aSLionel Sambuc
getCaptureFields(llvm::DenseMap<const VarDecl *,FieldDecl * > & Captures,FieldDecl * & ThisCapture) const1022f4a2713aSLionel Sambuc void CXXRecordDecl::getCaptureFields(
1023f4a2713aSLionel Sambuc llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
1024f4a2713aSLionel Sambuc FieldDecl *&ThisCapture) const {
1025f4a2713aSLionel Sambuc Captures.clear();
1026*0a6a1f1dSLionel Sambuc ThisCapture = nullptr;
1027f4a2713aSLionel Sambuc
1028f4a2713aSLionel Sambuc LambdaDefinitionData &Lambda = getLambdaData();
1029f4a2713aSLionel Sambuc RecordDecl::field_iterator Field = field_begin();
1030*0a6a1f1dSLionel Sambuc for (const LambdaCapture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
1031f4a2713aSLionel Sambuc C != CEnd; ++C, ++Field) {
1032f4a2713aSLionel Sambuc if (C->capturesThis())
1033f4a2713aSLionel Sambuc ThisCapture = *Field;
1034f4a2713aSLionel Sambuc else if (C->capturesVariable())
1035f4a2713aSLionel Sambuc Captures[C->getCapturedVar()] = *Field;
1036f4a2713aSLionel Sambuc }
1037f4a2713aSLionel Sambuc assert(Field == field_end());
1038f4a2713aSLionel Sambuc }
1039f4a2713aSLionel Sambuc
1040f4a2713aSLionel Sambuc TemplateParameterList *
getGenericLambdaTemplateParameterList() const1041f4a2713aSLionel Sambuc CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
1042*0a6a1f1dSLionel Sambuc if (!isLambda()) return nullptr;
1043f4a2713aSLionel Sambuc CXXMethodDecl *CallOp = getLambdaCallOperator();
1044f4a2713aSLionel Sambuc if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
1045f4a2713aSLionel Sambuc return Tmpl->getTemplateParameters();
1046*0a6a1f1dSLionel Sambuc return nullptr;
1047f4a2713aSLionel Sambuc }
1048f4a2713aSLionel Sambuc
GetConversionType(ASTContext & Context,NamedDecl * Conv)1049f4a2713aSLionel Sambuc static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
1050*0a6a1f1dSLionel Sambuc QualType T =
1051*0a6a1f1dSLionel Sambuc cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction())
1052*0a6a1f1dSLionel Sambuc ->getConversionType();
1053f4a2713aSLionel Sambuc return Context.getCanonicalType(T);
1054f4a2713aSLionel Sambuc }
1055f4a2713aSLionel Sambuc
1056f4a2713aSLionel Sambuc /// Collect the visible conversions of a base class.
1057f4a2713aSLionel Sambuc ///
1058f4a2713aSLionel Sambuc /// \param Record a base class of the class we're considering
1059f4a2713aSLionel Sambuc /// \param InVirtual whether this base class is a virtual base (or a base
1060f4a2713aSLionel Sambuc /// of a virtual base)
1061f4a2713aSLionel Sambuc /// \param Access the access along the inheritance path to this base
1062f4a2713aSLionel Sambuc /// \param ParentHiddenTypes the conversions provided by the inheritors
1063f4a2713aSLionel Sambuc /// of this base
1064f4a2713aSLionel Sambuc /// \param Output the set to which to add conversions from non-virtual bases
1065f4a2713aSLionel Sambuc /// \param VOutput the set to which to add conversions from virtual bases
1066f4a2713aSLionel Sambuc /// \param HiddenVBaseCs the set of conversions which were hidden in a
1067f4a2713aSLionel Sambuc /// virtual base along some inheritance path
CollectVisibleConversions(ASTContext & Context,CXXRecordDecl * Record,bool InVirtual,AccessSpecifier Access,const llvm::SmallPtrSet<CanQualType,8> & ParentHiddenTypes,ASTUnresolvedSet & Output,UnresolvedSetImpl & VOutput,llvm::SmallPtrSet<NamedDecl *,8> & HiddenVBaseCs)1068f4a2713aSLionel Sambuc static void CollectVisibleConversions(ASTContext &Context,
1069f4a2713aSLionel Sambuc CXXRecordDecl *Record,
1070f4a2713aSLionel Sambuc bool InVirtual,
1071f4a2713aSLionel Sambuc AccessSpecifier Access,
1072f4a2713aSLionel Sambuc const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes,
1073f4a2713aSLionel Sambuc ASTUnresolvedSet &Output,
1074f4a2713aSLionel Sambuc UnresolvedSetImpl &VOutput,
1075f4a2713aSLionel Sambuc llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) {
1076f4a2713aSLionel Sambuc // The set of types which have conversions in this class or its
1077f4a2713aSLionel Sambuc // subclasses. As an optimization, we don't copy the derived set
1078f4a2713aSLionel Sambuc // unless it might change.
1079f4a2713aSLionel Sambuc const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes;
1080f4a2713aSLionel Sambuc llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer;
1081f4a2713aSLionel Sambuc
1082f4a2713aSLionel Sambuc // Collect the direct conversions and figure out which conversions
1083f4a2713aSLionel Sambuc // will be hidden in the subclasses.
1084f4a2713aSLionel Sambuc CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin();
1085f4a2713aSLionel Sambuc CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end();
1086f4a2713aSLionel Sambuc if (ConvI != ConvE) {
1087f4a2713aSLionel Sambuc HiddenTypesBuffer = ParentHiddenTypes;
1088f4a2713aSLionel Sambuc HiddenTypes = &HiddenTypesBuffer;
1089f4a2713aSLionel Sambuc
1090f4a2713aSLionel Sambuc for (CXXRecordDecl::conversion_iterator I = ConvI; I != ConvE; ++I) {
1091f4a2713aSLionel Sambuc CanQualType ConvType(GetConversionType(Context, I.getDecl()));
1092f4a2713aSLionel Sambuc bool Hidden = ParentHiddenTypes.count(ConvType);
1093f4a2713aSLionel Sambuc if (!Hidden)
1094f4a2713aSLionel Sambuc HiddenTypesBuffer.insert(ConvType);
1095f4a2713aSLionel Sambuc
1096f4a2713aSLionel Sambuc // If this conversion is hidden and we're in a virtual base,
1097f4a2713aSLionel Sambuc // remember that it's hidden along some inheritance path.
1098f4a2713aSLionel Sambuc if (Hidden && InVirtual)
1099f4a2713aSLionel Sambuc HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()));
1100f4a2713aSLionel Sambuc
1101f4a2713aSLionel Sambuc // If this conversion isn't hidden, add it to the appropriate output.
1102f4a2713aSLionel Sambuc else if (!Hidden) {
1103f4a2713aSLionel Sambuc AccessSpecifier IAccess
1104f4a2713aSLionel Sambuc = CXXRecordDecl::MergeAccess(Access, I.getAccess());
1105f4a2713aSLionel Sambuc
1106f4a2713aSLionel Sambuc if (InVirtual)
1107f4a2713aSLionel Sambuc VOutput.addDecl(I.getDecl(), IAccess);
1108f4a2713aSLionel Sambuc else
1109f4a2713aSLionel Sambuc Output.addDecl(Context, I.getDecl(), IAccess);
1110f4a2713aSLionel Sambuc }
1111f4a2713aSLionel Sambuc }
1112f4a2713aSLionel Sambuc }
1113f4a2713aSLionel Sambuc
1114f4a2713aSLionel Sambuc // Collect information recursively from any base classes.
1115*0a6a1f1dSLionel Sambuc for (const auto &I : Record->bases()) {
1116*0a6a1f1dSLionel Sambuc const RecordType *RT = I.getType()->getAs<RecordType>();
1117f4a2713aSLionel Sambuc if (!RT) continue;
1118f4a2713aSLionel Sambuc
1119f4a2713aSLionel Sambuc AccessSpecifier BaseAccess
1120*0a6a1f1dSLionel Sambuc = CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier());
1121*0a6a1f1dSLionel Sambuc bool BaseInVirtual = InVirtual || I.isVirtual();
1122f4a2713aSLionel Sambuc
1123f4a2713aSLionel Sambuc CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
1124f4a2713aSLionel Sambuc CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
1125f4a2713aSLionel Sambuc *HiddenTypes, Output, VOutput, HiddenVBaseCs);
1126f4a2713aSLionel Sambuc }
1127f4a2713aSLionel Sambuc }
1128f4a2713aSLionel Sambuc
1129f4a2713aSLionel Sambuc /// Collect the visible conversions of a class.
1130f4a2713aSLionel Sambuc ///
1131f4a2713aSLionel Sambuc /// This would be extremely straightforward if it weren't for virtual
1132f4a2713aSLionel Sambuc /// bases. It might be worth special-casing that, really.
CollectVisibleConversions(ASTContext & Context,CXXRecordDecl * Record,ASTUnresolvedSet & Output)1133f4a2713aSLionel Sambuc static void CollectVisibleConversions(ASTContext &Context,
1134f4a2713aSLionel Sambuc CXXRecordDecl *Record,
1135f4a2713aSLionel Sambuc ASTUnresolvedSet &Output) {
1136f4a2713aSLionel Sambuc // The collection of all conversions in virtual bases that we've
1137f4a2713aSLionel Sambuc // found. These will be added to the output as long as they don't
1138f4a2713aSLionel Sambuc // appear in the hidden-conversions set.
1139f4a2713aSLionel Sambuc UnresolvedSet<8> VBaseCs;
1140f4a2713aSLionel Sambuc
1141f4a2713aSLionel Sambuc // The set of conversions in virtual bases that we've determined to
1142f4a2713aSLionel Sambuc // be hidden.
1143f4a2713aSLionel Sambuc llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs;
1144f4a2713aSLionel Sambuc
1145f4a2713aSLionel Sambuc // The set of types hidden by classes derived from this one.
1146f4a2713aSLionel Sambuc llvm::SmallPtrSet<CanQualType, 8> HiddenTypes;
1147f4a2713aSLionel Sambuc
1148f4a2713aSLionel Sambuc // Go ahead and collect the direct conversions and add them to the
1149f4a2713aSLionel Sambuc // hidden-types set.
1150f4a2713aSLionel Sambuc CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin();
1151f4a2713aSLionel Sambuc CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end();
1152f4a2713aSLionel Sambuc Output.append(Context, ConvI, ConvE);
1153f4a2713aSLionel Sambuc for (; ConvI != ConvE; ++ConvI)
1154f4a2713aSLionel Sambuc HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl()));
1155f4a2713aSLionel Sambuc
1156f4a2713aSLionel Sambuc // Recursively collect conversions from base classes.
1157*0a6a1f1dSLionel Sambuc for (const auto &I : Record->bases()) {
1158*0a6a1f1dSLionel Sambuc const RecordType *RT = I.getType()->getAs<RecordType>();
1159f4a2713aSLionel Sambuc if (!RT) continue;
1160f4a2713aSLionel Sambuc
1161f4a2713aSLionel Sambuc CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
1162*0a6a1f1dSLionel Sambuc I.isVirtual(), I.getAccessSpecifier(),
1163f4a2713aSLionel Sambuc HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
1164f4a2713aSLionel Sambuc }
1165f4a2713aSLionel Sambuc
1166f4a2713aSLionel Sambuc // Add any unhidden conversions provided by virtual bases.
1167f4a2713aSLionel Sambuc for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end();
1168f4a2713aSLionel Sambuc I != E; ++I) {
1169f4a2713aSLionel Sambuc if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())))
1170f4a2713aSLionel Sambuc Output.addDecl(Context, I.getDecl(), I.getAccess());
1171f4a2713aSLionel Sambuc }
1172f4a2713aSLionel Sambuc }
1173f4a2713aSLionel Sambuc
1174f4a2713aSLionel Sambuc /// getVisibleConversionFunctions - get all conversion functions visible
1175f4a2713aSLionel Sambuc /// in current class; including conversion function templates.
1176f4a2713aSLionel Sambuc std::pair<CXXRecordDecl::conversion_iterator,CXXRecordDecl::conversion_iterator>
getVisibleConversionFunctions()1177f4a2713aSLionel Sambuc CXXRecordDecl::getVisibleConversionFunctions() {
1178f4a2713aSLionel Sambuc ASTContext &Ctx = getASTContext();
1179f4a2713aSLionel Sambuc
1180f4a2713aSLionel Sambuc ASTUnresolvedSet *Set;
1181f4a2713aSLionel Sambuc if (bases_begin() == bases_end()) {
1182f4a2713aSLionel Sambuc // If root class, all conversions are visible.
1183f4a2713aSLionel Sambuc Set = &data().Conversions.get(Ctx);
1184f4a2713aSLionel Sambuc } else {
1185f4a2713aSLionel Sambuc Set = &data().VisibleConversions.get(Ctx);
1186f4a2713aSLionel Sambuc // If visible conversion list is not evaluated, evaluate it.
1187f4a2713aSLionel Sambuc if (!data().ComputedVisibleConversions) {
1188f4a2713aSLionel Sambuc CollectVisibleConversions(Ctx, this, *Set);
1189f4a2713aSLionel Sambuc data().ComputedVisibleConversions = true;
1190f4a2713aSLionel Sambuc }
1191f4a2713aSLionel Sambuc }
1192f4a2713aSLionel Sambuc return std::make_pair(Set->begin(), Set->end());
1193f4a2713aSLionel Sambuc }
1194f4a2713aSLionel Sambuc
removeConversion(const NamedDecl * ConvDecl)1195f4a2713aSLionel Sambuc void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
1196f4a2713aSLionel Sambuc // This operation is O(N) but extremely rare. Sema only uses it to
1197f4a2713aSLionel Sambuc // remove UsingShadowDecls in a class that were followed by a direct
1198f4a2713aSLionel Sambuc // declaration, e.g.:
1199f4a2713aSLionel Sambuc // class A : B {
1200f4a2713aSLionel Sambuc // using B::operator int;
1201f4a2713aSLionel Sambuc // operator int();
1202f4a2713aSLionel Sambuc // };
1203f4a2713aSLionel Sambuc // This is uncommon by itself and even more uncommon in conjunction
1204f4a2713aSLionel Sambuc // with sufficiently large numbers of directly-declared conversions
1205f4a2713aSLionel Sambuc // that asymptotic behavior matters.
1206f4a2713aSLionel Sambuc
1207f4a2713aSLionel Sambuc ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext());
1208f4a2713aSLionel Sambuc for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
1209f4a2713aSLionel Sambuc if (Convs[I].getDecl() == ConvDecl) {
1210f4a2713aSLionel Sambuc Convs.erase(I);
1211f4a2713aSLionel Sambuc assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end()
1212f4a2713aSLionel Sambuc && "conversion was found multiple times in unresolved set");
1213f4a2713aSLionel Sambuc return;
1214f4a2713aSLionel Sambuc }
1215f4a2713aSLionel Sambuc }
1216f4a2713aSLionel Sambuc
1217f4a2713aSLionel Sambuc llvm_unreachable("conversion not found in set!");
1218f4a2713aSLionel Sambuc }
1219f4a2713aSLionel Sambuc
getInstantiatedFromMemberClass() const1220f4a2713aSLionel Sambuc CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
1221f4a2713aSLionel Sambuc if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
1222f4a2713aSLionel Sambuc return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
1223f4a2713aSLionel Sambuc
1224*0a6a1f1dSLionel Sambuc return nullptr;
1225f4a2713aSLionel Sambuc }
1226f4a2713aSLionel Sambuc
1227f4a2713aSLionel Sambuc void
setInstantiationOfMemberClass(CXXRecordDecl * RD,TemplateSpecializationKind TSK)1228f4a2713aSLionel Sambuc CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
1229f4a2713aSLionel Sambuc TemplateSpecializationKind TSK) {
1230f4a2713aSLionel Sambuc assert(TemplateOrInstantiation.isNull() &&
1231f4a2713aSLionel Sambuc "Previous template or instantiation?");
1232*0a6a1f1dSLionel Sambuc assert(!isa<ClassTemplatePartialSpecializationDecl>(this));
1233f4a2713aSLionel Sambuc TemplateOrInstantiation
1234f4a2713aSLionel Sambuc = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
1235f4a2713aSLionel Sambuc }
1236f4a2713aSLionel Sambuc
getTemplateSpecializationKind() const1237f4a2713aSLionel Sambuc TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
1238f4a2713aSLionel Sambuc if (const ClassTemplateSpecializationDecl *Spec
1239f4a2713aSLionel Sambuc = dyn_cast<ClassTemplateSpecializationDecl>(this))
1240f4a2713aSLionel Sambuc return Spec->getSpecializationKind();
1241f4a2713aSLionel Sambuc
1242f4a2713aSLionel Sambuc if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
1243f4a2713aSLionel Sambuc return MSInfo->getTemplateSpecializationKind();
1244f4a2713aSLionel Sambuc
1245f4a2713aSLionel Sambuc return TSK_Undeclared;
1246f4a2713aSLionel Sambuc }
1247f4a2713aSLionel Sambuc
1248f4a2713aSLionel Sambuc void
setTemplateSpecializationKind(TemplateSpecializationKind TSK)1249f4a2713aSLionel Sambuc CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
1250f4a2713aSLionel Sambuc if (ClassTemplateSpecializationDecl *Spec
1251f4a2713aSLionel Sambuc = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
1252f4a2713aSLionel Sambuc Spec->setSpecializationKind(TSK);
1253f4a2713aSLionel Sambuc return;
1254f4a2713aSLionel Sambuc }
1255f4a2713aSLionel Sambuc
1256f4a2713aSLionel Sambuc if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
1257f4a2713aSLionel Sambuc MSInfo->setTemplateSpecializationKind(TSK);
1258f4a2713aSLionel Sambuc return;
1259f4a2713aSLionel Sambuc }
1260f4a2713aSLionel Sambuc
1261f4a2713aSLionel Sambuc llvm_unreachable("Not a class template or member class specialization");
1262f4a2713aSLionel Sambuc }
1263f4a2713aSLionel Sambuc
getTemplateInstantiationPattern() const1264*0a6a1f1dSLionel Sambuc const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
1265*0a6a1f1dSLionel Sambuc // If it's a class template specialization, find the template or partial
1266*0a6a1f1dSLionel Sambuc // specialization from which it was instantiated.
1267*0a6a1f1dSLionel Sambuc if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
1268*0a6a1f1dSLionel Sambuc auto From = TD->getInstantiatedFrom();
1269*0a6a1f1dSLionel Sambuc if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
1270*0a6a1f1dSLionel Sambuc while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
1271*0a6a1f1dSLionel Sambuc if (NewCTD->isMemberSpecialization())
1272*0a6a1f1dSLionel Sambuc break;
1273*0a6a1f1dSLionel Sambuc CTD = NewCTD;
1274*0a6a1f1dSLionel Sambuc }
1275*0a6a1f1dSLionel Sambuc return CTD->getTemplatedDecl();
1276*0a6a1f1dSLionel Sambuc }
1277*0a6a1f1dSLionel Sambuc if (auto *CTPSD =
1278*0a6a1f1dSLionel Sambuc From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
1279*0a6a1f1dSLionel Sambuc while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
1280*0a6a1f1dSLionel Sambuc if (NewCTPSD->isMemberSpecialization())
1281*0a6a1f1dSLionel Sambuc break;
1282*0a6a1f1dSLionel Sambuc CTPSD = NewCTPSD;
1283*0a6a1f1dSLionel Sambuc }
1284*0a6a1f1dSLionel Sambuc return CTPSD;
1285*0a6a1f1dSLionel Sambuc }
1286*0a6a1f1dSLionel Sambuc }
1287*0a6a1f1dSLionel Sambuc
1288*0a6a1f1dSLionel Sambuc if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
1289*0a6a1f1dSLionel Sambuc if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
1290*0a6a1f1dSLionel Sambuc const CXXRecordDecl *RD = this;
1291*0a6a1f1dSLionel Sambuc while (auto *NewRD = RD->getInstantiatedFromMemberClass())
1292*0a6a1f1dSLionel Sambuc RD = NewRD;
1293*0a6a1f1dSLionel Sambuc return RD;
1294*0a6a1f1dSLionel Sambuc }
1295*0a6a1f1dSLionel Sambuc }
1296*0a6a1f1dSLionel Sambuc
1297*0a6a1f1dSLionel Sambuc assert(!isTemplateInstantiation(this->getTemplateSpecializationKind()) &&
1298*0a6a1f1dSLionel Sambuc "couldn't find pattern for class template instantiation");
1299*0a6a1f1dSLionel Sambuc return nullptr;
1300*0a6a1f1dSLionel Sambuc }
1301*0a6a1f1dSLionel Sambuc
getDestructor() const1302f4a2713aSLionel Sambuc CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
1303f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
1304f4a2713aSLionel Sambuc QualType ClassType = Context.getTypeDeclType(this);
1305f4a2713aSLionel Sambuc
1306f4a2713aSLionel Sambuc DeclarationName Name
1307f4a2713aSLionel Sambuc = Context.DeclarationNames.getCXXDestructorName(
1308f4a2713aSLionel Sambuc Context.getCanonicalType(ClassType));
1309f4a2713aSLionel Sambuc
1310f4a2713aSLionel Sambuc DeclContext::lookup_const_result R = lookup(Name);
1311f4a2713aSLionel Sambuc if (R.empty())
1312*0a6a1f1dSLionel Sambuc return nullptr;
1313f4a2713aSLionel Sambuc
1314f4a2713aSLionel Sambuc CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(R.front());
1315f4a2713aSLionel Sambuc return Dtor;
1316f4a2713aSLionel Sambuc }
1317f4a2713aSLionel Sambuc
completeDefinition()1318f4a2713aSLionel Sambuc void CXXRecordDecl::completeDefinition() {
1319*0a6a1f1dSLionel Sambuc completeDefinition(nullptr);
1320f4a2713aSLionel Sambuc }
1321f4a2713aSLionel Sambuc
completeDefinition(CXXFinalOverriderMap * FinalOverriders)1322f4a2713aSLionel Sambuc void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
1323f4a2713aSLionel Sambuc RecordDecl::completeDefinition();
1324f4a2713aSLionel Sambuc
1325f4a2713aSLionel Sambuc // If the class may be abstract (but hasn't been marked as such), check for
1326f4a2713aSLionel Sambuc // any pure final overriders.
1327f4a2713aSLionel Sambuc if (mayBeAbstract()) {
1328f4a2713aSLionel Sambuc CXXFinalOverriderMap MyFinalOverriders;
1329f4a2713aSLionel Sambuc if (!FinalOverriders) {
1330f4a2713aSLionel Sambuc getFinalOverriders(MyFinalOverriders);
1331f4a2713aSLionel Sambuc FinalOverriders = &MyFinalOverriders;
1332f4a2713aSLionel Sambuc }
1333f4a2713aSLionel Sambuc
1334f4a2713aSLionel Sambuc bool Done = false;
1335f4a2713aSLionel Sambuc for (CXXFinalOverriderMap::iterator M = FinalOverriders->begin(),
1336f4a2713aSLionel Sambuc MEnd = FinalOverriders->end();
1337f4a2713aSLionel Sambuc M != MEnd && !Done; ++M) {
1338f4a2713aSLionel Sambuc for (OverridingMethods::iterator SO = M->second.begin(),
1339f4a2713aSLionel Sambuc SOEnd = M->second.end();
1340f4a2713aSLionel Sambuc SO != SOEnd && !Done; ++SO) {
1341f4a2713aSLionel Sambuc assert(SO->second.size() > 0 &&
1342f4a2713aSLionel Sambuc "All virtual functions have overridding virtual functions");
1343f4a2713aSLionel Sambuc
1344f4a2713aSLionel Sambuc // C++ [class.abstract]p4:
1345f4a2713aSLionel Sambuc // A class is abstract if it contains or inherits at least one
1346f4a2713aSLionel Sambuc // pure virtual function for which the final overrider is pure
1347f4a2713aSLionel Sambuc // virtual.
1348f4a2713aSLionel Sambuc if (SO->second.front().Method->isPure()) {
1349f4a2713aSLionel Sambuc data().Abstract = true;
1350f4a2713aSLionel Sambuc Done = true;
1351f4a2713aSLionel Sambuc break;
1352f4a2713aSLionel Sambuc }
1353f4a2713aSLionel Sambuc }
1354f4a2713aSLionel Sambuc }
1355f4a2713aSLionel Sambuc }
1356f4a2713aSLionel Sambuc
1357f4a2713aSLionel Sambuc // Set access bits correctly on the directly-declared conversions.
1358f4a2713aSLionel Sambuc for (conversion_iterator I = conversion_begin(), E = conversion_end();
1359f4a2713aSLionel Sambuc I != E; ++I)
1360f4a2713aSLionel Sambuc I.setAccess((*I)->getAccess());
1361f4a2713aSLionel Sambuc }
1362f4a2713aSLionel Sambuc
mayBeAbstract() const1363f4a2713aSLionel Sambuc bool CXXRecordDecl::mayBeAbstract() const {
1364f4a2713aSLionel Sambuc if (data().Abstract || isInvalidDecl() || !data().Polymorphic ||
1365f4a2713aSLionel Sambuc isDependentContext())
1366f4a2713aSLionel Sambuc return false;
1367f4a2713aSLionel Sambuc
1368*0a6a1f1dSLionel Sambuc for (const auto &B : bases()) {
1369f4a2713aSLionel Sambuc CXXRecordDecl *BaseDecl
1370*0a6a1f1dSLionel Sambuc = cast<CXXRecordDecl>(B.getType()->getAs<RecordType>()->getDecl());
1371f4a2713aSLionel Sambuc if (BaseDecl->isAbstract())
1372f4a2713aSLionel Sambuc return true;
1373f4a2713aSLionel Sambuc }
1374f4a2713aSLionel Sambuc
1375f4a2713aSLionel Sambuc return false;
1376f4a2713aSLionel Sambuc }
1377f4a2713aSLionel Sambuc
anchor()1378f4a2713aSLionel Sambuc void CXXMethodDecl::anchor() { }
1379f4a2713aSLionel Sambuc
isStatic() const1380f4a2713aSLionel Sambuc bool CXXMethodDecl::isStatic() const {
1381f4a2713aSLionel Sambuc const CXXMethodDecl *MD = getCanonicalDecl();
1382f4a2713aSLionel Sambuc
1383f4a2713aSLionel Sambuc if (MD->getStorageClass() == SC_Static)
1384f4a2713aSLionel Sambuc return true;
1385f4a2713aSLionel Sambuc
1386f4a2713aSLionel Sambuc OverloadedOperatorKind OOK = getDeclName().getCXXOverloadedOperator();
1387f4a2713aSLionel Sambuc return isStaticOverloadedOperator(OOK);
1388f4a2713aSLionel Sambuc }
1389f4a2713aSLionel Sambuc
recursivelyOverrides(const CXXMethodDecl * DerivedMD,const CXXMethodDecl * BaseMD)1390f4a2713aSLionel Sambuc static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
1391f4a2713aSLionel Sambuc const CXXMethodDecl *BaseMD) {
1392f4a2713aSLionel Sambuc for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(),
1393f4a2713aSLionel Sambuc E = DerivedMD->end_overridden_methods(); I != E; ++I) {
1394f4a2713aSLionel Sambuc const CXXMethodDecl *MD = *I;
1395f4a2713aSLionel Sambuc if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl())
1396f4a2713aSLionel Sambuc return true;
1397f4a2713aSLionel Sambuc if (recursivelyOverrides(MD, BaseMD))
1398f4a2713aSLionel Sambuc return true;
1399f4a2713aSLionel Sambuc }
1400f4a2713aSLionel Sambuc return false;
1401f4a2713aSLionel Sambuc }
1402f4a2713aSLionel Sambuc
1403f4a2713aSLionel Sambuc CXXMethodDecl *
getCorrespondingMethodInClass(const CXXRecordDecl * RD,bool MayBeBase)1404f4a2713aSLionel Sambuc CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
1405f4a2713aSLionel Sambuc bool MayBeBase) {
1406f4a2713aSLionel Sambuc if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl())
1407f4a2713aSLionel Sambuc return this;
1408f4a2713aSLionel Sambuc
1409f4a2713aSLionel Sambuc // Lookup doesn't work for destructors, so handle them separately.
1410f4a2713aSLionel Sambuc if (isa<CXXDestructorDecl>(this)) {
1411f4a2713aSLionel Sambuc CXXMethodDecl *MD = RD->getDestructor();
1412f4a2713aSLionel Sambuc if (MD) {
1413f4a2713aSLionel Sambuc if (recursivelyOverrides(MD, this))
1414f4a2713aSLionel Sambuc return MD;
1415f4a2713aSLionel Sambuc if (MayBeBase && recursivelyOverrides(this, MD))
1416f4a2713aSLionel Sambuc return MD;
1417f4a2713aSLionel Sambuc }
1418*0a6a1f1dSLionel Sambuc return nullptr;
1419f4a2713aSLionel Sambuc }
1420f4a2713aSLionel Sambuc
1421f4a2713aSLionel Sambuc lookup_const_result Candidates = RD->lookup(getDeclName());
1422f4a2713aSLionel Sambuc for (NamedDecl * const * I = Candidates.begin(); I != Candidates.end(); ++I) {
1423f4a2713aSLionel Sambuc CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*I);
1424f4a2713aSLionel Sambuc if (!MD)
1425f4a2713aSLionel Sambuc continue;
1426f4a2713aSLionel Sambuc if (recursivelyOverrides(MD, this))
1427f4a2713aSLionel Sambuc return MD;
1428f4a2713aSLionel Sambuc if (MayBeBase && recursivelyOverrides(this, MD))
1429f4a2713aSLionel Sambuc return MD;
1430f4a2713aSLionel Sambuc }
1431f4a2713aSLionel Sambuc
1432*0a6a1f1dSLionel Sambuc for (const auto &I : RD->bases()) {
1433*0a6a1f1dSLionel Sambuc const RecordType *RT = I.getType()->getAs<RecordType>();
1434f4a2713aSLionel Sambuc if (!RT)
1435f4a2713aSLionel Sambuc continue;
1436f4a2713aSLionel Sambuc const CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
1437f4a2713aSLionel Sambuc CXXMethodDecl *T = this->getCorrespondingMethodInClass(Base);
1438f4a2713aSLionel Sambuc if (T)
1439f4a2713aSLionel Sambuc return T;
1440f4a2713aSLionel Sambuc }
1441f4a2713aSLionel Sambuc
1442*0a6a1f1dSLionel Sambuc return nullptr;
1443f4a2713aSLionel Sambuc }
1444f4a2713aSLionel Sambuc
1445f4a2713aSLionel Sambuc CXXMethodDecl *
Create(ASTContext & C,CXXRecordDecl * RD,SourceLocation StartLoc,const DeclarationNameInfo & NameInfo,QualType T,TypeSourceInfo * TInfo,StorageClass SC,bool isInline,bool isConstexpr,SourceLocation EndLocation)1446f4a2713aSLionel Sambuc CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1447f4a2713aSLionel Sambuc SourceLocation StartLoc,
1448f4a2713aSLionel Sambuc const DeclarationNameInfo &NameInfo,
1449f4a2713aSLionel Sambuc QualType T, TypeSourceInfo *TInfo,
1450f4a2713aSLionel Sambuc StorageClass SC, bool isInline,
1451f4a2713aSLionel Sambuc bool isConstexpr, SourceLocation EndLocation) {
1452*0a6a1f1dSLionel Sambuc return new (C, RD) CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo,
1453*0a6a1f1dSLionel Sambuc T, TInfo, SC, isInline, isConstexpr,
1454f4a2713aSLionel Sambuc EndLocation);
1455f4a2713aSLionel Sambuc }
1456f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)1457f4a2713aSLionel Sambuc CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1458*0a6a1f1dSLionel Sambuc return new (C, ID) CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(),
1459*0a6a1f1dSLionel Sambuc DeclarationNameInfo(), QualType(), nullptr,
1460*0a6a1f1dSLionel Sambuc SC_None, false, false, SourceLocation());
1461f4a2713aSLionel Sambuc }
1462f4a2713aSLionel Sambuc
isUsualDeallocationFunction() const1463f4a2713aSLionel Sambuc bool CXXMethodDecl::isUsualDeallocationFunction() const {
1464f4a2713aSLionel Sambuc if (getOverloadedOperator() != OO_Delete &&
1465f4a2713aSLionel Sambuc getOverloadedOperator() != OO_Array_Delete)
1466f4a2713aSLionel Sambuc return false;
1467f4a2713aSLionel Sambuc
1468f4a2713aSLionel Sambuc // C++ [basic.stc.dynamic.deallocation]p2:
1469f4a2713aSLionel Sambuc // A template instance is never a usual deallocation function,
1470f4a2713aSLionel Sambuc // regardless of its signature.
1471f4a2713aSLionel Sambuc if (getPrimaryTemplate())
1472f4a2713aSLionel Sambuc return false;
1473f4a2713aSLionel Sambuc
1474f4a2713aSLionel Sambuc // C++ [basic.stc.dynamic.deallocation]p2:
1475f4a2713aSLionel Sambuc // If a class T has a member deallocation function named operator delete
1476f4a2713aSLionel Sambuc // with exactly one parameter, then that function is a usual (non-placement)
1477f4a2713aSLionel Sambuc // deallocation function. [...]
1478f4a2713aSLionel Sambuc if (getNumParams() == 1)
1479f4a2713aSLionel Sambuc return true;
1480f4a2713aSLionel Sambuc
1481f4a2713aSLionel Sambuc // C++ [basic.stc.dynamic.deallocation]p2:
1482f4a2713aSLionel Sambuc // [...] If class T does not declare such an operator delete but does
1483f4a2713aSLionel Sambuc // declare a member deallocation function named operator delete with
1484f4a2713aSLionel Sambuc // exactly two parameters, the second of which has type std::size_t (18.1),
1485f4a2713aSLionel Sambuc // then this function is a usual deallocation function.
1486f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
1487f4a2713aSLionel Sambuc if (getNumParams() != 2 ||
1488f4a2713aSLionel Sambuc !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(),
1489f4a2713aSLionel Sambuc Context.getSizeType()))
1490f4a2713aSLionel Sambuc return false;
1491f4a2713aSLionel Sambuc
1492f4a2713aSLionel Sambuc // This function is a usual deallocation function if there are no
1493f4a2713aSLionel Sambuc // single-parameter deallocation functions of the same kind.
1494f4a2713aSLionel Sambuc DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName());
1495f4a2713aSLionel Sambuc for (DeclContext::lookup_const_result::iterator I = R.begin(), E = R.end();
1496f4a2713aSLionel Sambuc I != E; ++I) {
1497f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I))
1498f4a2713aSLionel Sambuc if (FD->getNumParams() == 1)
1499f4a2713aSLionel Sambuc return false;
1500f4a2713aSLionel Sambuc }
1501f4a2713aSLionel Sambuc
1502f4a2713aSLionel Sambuc return true;
1503f4a2713aSLionel Sambuc }
1504f4a2713aSLionel Sambuc
isCopyAssignmentOperator() const1505f4a2713aSLionel Sambuc bool CXXMethodDecl::isCopyAssignmentOperator() const {
1506f4a2713aSLionel Sambuc // C++0x [class.copy]p17:
1507f4a2713aSLionel Sambuc // A user-declared copy assignment operator X::operator= is a non-static
1508f4a2713aSLionel Sambuc // non-template member function of class X with exactly one parameter of
1509f4a2713aSLionel Sambuc // type X, X&, const X&, volatile X& or const volatile X&.
1510f4a2713aSLionel Sambuc if (/*operator=*/getOverloadedOperator() != OO_Equal ||
1511f4a2713aSLionel Sambuc /*non-static*/ isStatic() ||
1512f4a2713aSLionel Sambuc /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() ||
1513f4a2713aSLionel Sambuc getNumParams() != 1)
1514f4a2713aSLionel Sambuc return false;
1515f4a2713aSLionel Sambuc
1516f4a2713aSLionel Sambuc QualType ParamType = getParamDecl(0)->getType();
1517f4a2713aSLionel Sambuc if (const LValueReferenceType *Ref = ParamType->getAs<LValueReferenceType>())
1518f4a2713aSLionel Sambuc ParamType = Ref->getPointeeType();
1519f4a2713aSLionel Sambuc
1520f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
1521f4a2713aSLionel Sambuc QualType ClassType
1522f4a2713aSLionel Sambuc = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
1523f4a2713aSLionel Sambuc return Context.hasSameUnqualifiedType(ClassType, ParamType);
1524f4a2713aSLionel Sambuc }
1525f4a2713aSLionel Sambuc
isMoveAssignmentOperator() const1526f4a2713aSLionel Sambuc bool CXXMethodDecl::isMoveAssignmentOperator() const {
1527f4a2713aSLionel Sambuc // C++0x [class.copy]p19:
1528f4a2713aSLionel Sambuc // A user-declared move assignment operator X::operator= is a non-static
1529f4a2713aSLionel Sambuc // non-template member function of class X with exactly one parameter of type
1530f4a2713aSLionel Sambuc // X&&, const X&&, volatile X&&, or const volatile X&&.
1531f4a2713aSLionel Sambuc if (getOverloadedOperator() != OO_Equal || isStatic() ||
1532f4a2713aSLionel Sambuc getPrimaryTemplate() || getDescribedFunctionTemplate() ||
1533f4a2713aSLionel Sambuc getNumParams() != 1)
1534f4a2713aSLionel Sambuc return false;
1535f4a2713aSLionel Sambuc
1536f4a2713aSLionel Sambuc QualType ParamType = getParamDecl(0)->getType();
1537f4a2713aSLionel Sambuc if (!isa<RValueReferenceType>(ParamType))
1538f4a2713aSLionel Sambuc return false;
1539f4a2713aSLionel Sambuc ParamType = ParamType->getPointeeType();
1540f4a2713aSLionel Sambuc
1541f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
1542f4a2713aSLionel Sambuc QualType ClassType
1543f4a2713aSLionel Sambuc = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
1544f4a2713aSLionel Sambuc return Context.hasSameUnqualifiedType(ClassType, ParamType);
1545f4a2713aSLionel Sambuc }
1546f4a2713aSLionel Sambuc
addOverriddenMethod(const CXXMethodDecl * MD)1547f4a2713aSLionel Sambuc void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
1548f4a2713aSLionel Sambuc assert(MD->isCanonicalDecl() && "Method is not canonical!");
1549f4a2713aSLionel Sambuc assert(!MD->getParent()->isDependentContext() &&
1550f4a2713aSLionel Sambuc "Can't add an overridden method to a class template!");
1551f4a2713aSLionel Sambuc assert(MD->isVirtual() && "Method is not virtual!");
1552f4a2713aSLionel Sambuc
1553f4a2713aSLionel Sambuc getASTContext().addOverriddenMethod(this, MD);
1554f4a2713aSLionel Sambuc }
1555f4a2713aSLionel Sambuc
begin_overridden_methods() const1556f4a2713aSLionel Sambuc CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
1557*0a6a1f1dSLionel Sambuc if (isa<CXXConstructorDecl>(this)) return nullptr;
1558f4a2713aSLionel Sambuc return getASTContext().overridden_methods_begin(this);
1559f4a2713aSLionel Sambuc }
1560f4a2713aSLionel Sambuc
end_overridden_methods() const1561f4a2713aSLionel Sambuc CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
1562*0a6a1f1dSLionel Sambuc if (isa<CXXConstructorDecl>(this)) return nullptr;
1563f4a2713aSLionel Sambuc return getASTContext().overridden_methods_end(this);
1564f4a2713aSLionel Sambuc }
1565f4a2713aSLionel Sambuc
size_overridden_methods() const1566f4a2713aSLionel Sambuc unsigned CXXMethodDecl::size_overridden_methods() const {
1567f4a2713aSLionel Sambuc if (isa<CXXConstructorDecl>(this)) return 0;
1568f4a2713aSLionel Sambuc return getASTContext().overridden_methods_size(this);
1569f4a2713aSLionel Sambuc }
1570f4a2713aSLionel Sambuc
getThisType(ASTContext & C) const1571f4a2713aSLionel Sambuc QualType CXXMethodDecl::getThisType(ASTContext &C) const {
1572f4a2713aSLionel Sambuc // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
1573f4a2713aSLionel Sambuc // If the member function is declared const, the type of this is const X*,
1574f4a2713aSLionel Sambuc // if the member function is declared volatile, the type of this is
1575f4a2713aSLionel Sambuc // volatile X*, and if the member function is declared const volatile,
1576f4a2713aSLionel Sambuc // the type of this is const volatile X*.
1577f4a2713aSLionel Sambuc
1578f4a2713aSLionel Sambuc assert(isInstance() && "No 'this' for static methods!");
1579f4a2713aSLionel Sambuc
1580f4a2713aSLionel Sambuc QualType ClassTy = C.getTypeDeclType(getParent());
1581f4a2713aSLionel Sambuc ClassTy = C.getQualifiedType(ClassTy,
1582f4a2713aSLionel Sambuc Qualifiers::fromCVRMask(getTypeQualifiers()));
1583f4a2713aSLionel Sambuc return C.getPointerType(ClassTy);
1584f4a2713aSLionel Sambuc }
1585f4a2713aSLionel Sambuc
hasInlineBody() const1586f4a2713aSLionel Sambuc bool CXXMethodDecl::hasInlineBody() const {
1587f4a2713aSLionel Sambuc // If this function is a template instantiation, look at the template from
1588f4a2713aSLionel Sambuc // which it was instantiated.
1589f4a2713aSLionel Sambuc const FunctionDecl *CheckFn = getTemplateInstantiationPattern();
1590f4a2713aSLionel Sambuc if (!CheckFn)
1591f4a2713aSLionel Sambuc CheckFn = this;
1592f4a2713aSLionel Sambuc
1593f4a2713aSLionel Sambuc const FunctionDecl *fn;
1594f4a2713aSLionel Sambuc return CheckFn->hasBody(fn) && !fn->isOutOfLine();
1595f4a2713aSLionel Sambuc }
1596f4a2713aSLionel Sambuc
isLambdaStaticInvoker() const1597f4a2713aSLionel Sambuc bool CXXMethodDecl::isLambdaStaticInvoker() const {
1598f4a2713aSLionel Sambuc const CXXRecordDecl *P = getParent();
1599f4a2713aSLionel Sambuc if (P->isLambda()) {
1600f4a2713aSLionel Sambuc if (const CXXMethodDecl *StaticInvoker = P->getLambdaStaticInvoker()) {
1601f4a2713aSLionel Sambuc if (StaticInvoker == this) return true;
1602f4a2713aSLionel Sambuc if (P->isGenericLambda() && this->isFunctionTemplateSpecialization())
1603f4a2713aSLionel Sambuc return StaticInvoker == this->getPrimaryTemplate()->getTemplatedDecl();
1604f4a2713aSLionel Sambuc }
1605f4a2713aSLionel Sambuc }
1606f4a2713aSLionel Sambuc return false;
1607f4a2713aSLionel Sambuc }
1608f4a2713aSLionel Sambuc
CXXCtorInitializer(ASTContext & Context,TypeSourceInfo * TInfo,bool IsVirtual,SourceLocation L,Expr * Init,SourceLocation R,SourceLocation EllipsisLoc)1609f4a2713aSLionel Sambuc CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1610f4a2713aSLionel Sambuc TypeSourceInfo *TInfo, bool IsVirtual,
1611f4a2713aSLionel Sambuc SourceLocation L, Expr *Init,
1612f4a2713aSLionel Sambuc SourceLocation R,
1613f4a2713aSLionel Sambuc SourceLocation EllipsisLoc)
1614f4a2713aSLionel Sambuc : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init),
1615f4a2713aSLionel Sambuc LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual),
1616f4a2713aSLionel Sambuc IsWritten(false), SourceOrderOrNumArrayIndices(0)
1617f4a2713aSLionel Sambuc {
1618f4a2713aSLionel Sambuc }
1619f4a2713aSLionel Sambuc
CXXCtorInitializer(ASTContext & Context,FieldDecl * Member,SourceLocation MemberLoc,SourceLocation L,Expr * Init,SourceLocation R)1620f4a2713aSLionel Sambuc CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1621f4a2713aSLionel Sambuc FieldDecl *Member,
1622f4a2713aSLionel Sambuc SourceLocation MemberLoc,
1623f4a2713aSLionel Sambuc SourceLocation L, Expr *Init,
1624f4a2713aSLionel Sambuc SourceLocation R)
1625f4a2713aSLionel Sambuc : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
1626f4a2713aSLionel Sambuc LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
1627f4a2713aSLionel Sambuc IsWritten(false), SourceOrderOrNumArrayIndices(0)
1628f4a2713aSLionel Sambuc {
1629f4a2713aSLionel Sambuc }
1630f4a2713aSLionel Sambuc
CXXCtorInitializer(ASTContext & Context,IndirectFieldDecl * Member,SourceLocation MemberLoc,SourceLocation L,Expr * Init,SourceLocation R)1631f4a2713aSLionel Sambuc CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1632f4a2713aSLionel Sambuc IndirectFieldDecl *Member,
1633f4a2713aSLionel Sambuc SourceLocation MemberLoc,
1634f4a2713aSLionel Sambuc SourceLocation L, Expr *Init,
1635f4a2713aSLionel Sambuc SourceLocation R)
1636f4a2713aSLionel Sambuc : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
1637f4a2713aSLionel Sambuc LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
1638f4a2713aSLionel Sambuc IsWritten(false), SourceOrderOrNumArrayIndices(0)
1639f4a2713aSLionel Sambuc {
1640f4a2713aSLionel Sambuc }
1641f4a2713aSLionel Sambuc
CXXCtorInitializer(ASTContext & Context,TypeSourceInfo * TInfo,SourceLocation L,Expr * Init,SourceLocation R)1642f4a2713aSLionel Sambuc CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1643f4a2713aSLionel Sambuc TypeSourceInfo *TInfo,
1644f4a2713aSLionel Sambuc SourceLocation L, Expr *Init,
1645f4a2713aSLionel Sambuc SourceLocation R)
1646f4a2713aSLionel Sambuc : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init),
1647f4a2713aSLionel Sambuc LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false),
1648f4a2713aSLionel Sambuc IsWritten(false), SourceOrderOrNumArrayIndices(0)
1649f4a2713aSLionel Sambuc {
1650f4a2713aSLionel Sambuc }
1651f4a2713aSLionel Sambuc
CXXCtorInitializer(ASTContext & Context,FieldDecl * Member,SourceLocation MemberLoc,SourceLocation L,Expr * Init,SourceLocation R,VarDecl ** Indices,unsigned NumIndices)1652f4a2713aSLionel Sambuc CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1653f4a2713aSLionel Sambuc FieldDecl *Member,
1654f4a2713aSLionel Sambuc SourceLocation MemberLoc,
1655f4a2713aSLionel Sambuc SourceLocation L, Expr *Init,
1656f4a2713aSLionel Sambuc SourceLocation R,
1657f4a2713aSLionel Sambuc VarDecl **Indices,
1658f4a2713aSLionel Sambuc unsigned NumIndices)
1659f4a2713aSLionel Sambuc : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
1660*0a6a1f1dSLionel Sambuc LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
1661f4a2713aSLionel Sambuc IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
1662f4a2713aSLionel Sambuc {
1663f4a2713aSLionel Sambuc VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
1664f4a2713aSLionel Sambuc memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
1665f4a2713aSLionel Sambuc }
1666f4a2713aSLionel Sambuc
Create(ASTContext & Context,FieldDecl * Member,SourceLocation MemberLoc,SourceLocation L,Expr * Init,SourceLocation R,VarDecl ** Indices,unsigned NumIndices)1667f4a2713aSLionel Sambuc CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
1668f4a2713aSLionel Sambuc FieldDecl *Member,
1669f4a2713aSLionel Sambuc SourceLocation MemberLoc,
1670f4a2713aSLionel Sambuc SourceLocation L, Expr *Init,
1671f4a2713aSLionel Sambuc SourceLocation R,
1672f4a2713aSLionel Sambuc VarDecl **Indices,
1673f4a2713aSLionel Sambuc unsigned NumIndices) {
1674f4a2713aSLionel Sambuc void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) +
1675f4a2713aSLionel Sambuc sizeof(VarDecl *) * NumIndices,
1676f4a2713aSLionel Sambuc llvm::alignOf<CXXCtorInitializer>());
1677f4a2713aSLionel Sambuc return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,
1678f4a2713aSLionel Sambuc Indices, NumIndices);
1679f4a2713aSLionel Sambuc }
1680f4a2713aSLionel Sambuc
getBaseClassLoc() const1681f4a2713aSLionel Sambuc TypeLoc CXXCtorInitializer::getBaseClassLoc() const {
1682f4a2713aSLionel Sambuc if (isBaseInitializer())
1683f4a2713aSLionel Sambuc return Initializee.get<TypeSourceInfo*>()->getTypeLoc();
1684f4a2713aSLionel Sambuc else
1685f4a2713aSLionel Sambuc return TypeLoc();
1686f4a2713aSLionel Sambuc }
1687f4a2713aSLionel Sambuc
getBaseClass() const1688f4a2713aSLionel Sambuc const Type *CXXCtorInitializer::getBaseClass() const {
1689f4a2713aSLionel Sambuc if (isBaseInitializer())
1690f4a2713aSLionel Sambuc return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr();
1691f4a2713aSLionel Sambuc else
1692*0a6a1f1dSLionel Sambuc return nullptr;
1693f4a2713aSLionel Sambuc }
1694f4a2713aSLionel Sambuc
getSourceLocation() const1695f4a2713aSLionel Sambuc SourceLocation CXXCtorInitializer::getSourceLocation() const {
1696f4a2713aSLionel Sambuc if (isInClassMemberInitializer())
1697f4a2713aSLionel Sambuc return getAnyMember()->getLocation();
1698f4a2713aSLionel Sambuc
1699*0a6a1f1dSLionel Sambuc if (isAnyMemberInitializer())
1700*0a6a1f1dSLionel Sambuc return getMemberLocation();
1701*0a6a1f1dSLionel Sambuc
1702f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = Initializee.get<TypeSourceInfo*>())
1703f4a2713aSLionel Sambuc return TSInfo->getTypeLoc().getLocalSourceRange().getBegin();
1704f4a2713aSLionel Sambuc
1705f4a2713aSLionel Sambuc return SourceLocation();
1706f4a2713aSLionel Sambuc }
1707f4a2713aSLionel Sambuc
getSourceRange() const1708f4a2713aSLionel Sambuc SourceRange CXXCtorInitializer::getSourceRange() const {
1709f4a2713aSLionel Sambuc if (isInClassMemberInitializer()) {
1710f4a2713aSLionel Sambuc FieldDecl *D = getAnyMember();
1711f4a2713aSLionel Sambuc if (Expr *I = D->getInClassInitializer())
1712f4a2713aSLionel Sambuc return I->getSourceRange();
1713f4a2713aSLionel Sambuc return SourceRange();
1714f4a2713aSLionel Sambuc }
1715f4a2713aSLionel Sambuc
1716f4a2713aSLionel Sambuc return SourceRange(getSourceLocation(), getRParenLoc());
1717f4a2713aSLionel Sambuc }
1718f4a2713aSLionel Sambuc
anchor()1719f4a2713aSLionel Sambuc void CXXConstructorDecl::anchor() { }
1720f4a2713aSLionel Sambuc
1721f4a2713aSLionel Sambuc CXXConstructorDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1722f4a2713aSLionel Sambuc CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1723*0a6a1f1dSLionel Sambuc return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(),
1724*0a6a1f1dSLionel Sambuc DeclarationNameInfo(), QualType(),
1725*0a6a1f1dSLionel Sambuc nullptr, false, false, false, false);
1726f4a2713aSLionel Sambuc }
1727f4a2713aSLionel Sambuc
1728f4a2713aSLionel Sambuc CXXConstructorDecl *
Create(ASTContext & C,CXXRecordDecl * RD,SourceLocation StartLoc,const DeclarationNameInfo & NameInfo,QualType T,TypeSourceInfo * TInfo,bool isExplicit,bool isInline,bool isImplicitlyDeclared,bool isConstexpr)1729f4a2713aSLionel Sambuc CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1730f4a2713aSLionel Sambuc SourceLocation StartLoc,
1731f4a2713aSLionel Sambuc const DeclarationNameInfo &NameInfo,
1732f4a2713aSLionel Sambuc QualType T, TypeSourceInfo *TInfo,
1733f4a2713aSLionel Sambuc bool isExplicit, bool isInline,
1734f4a2713aSLionel Sambuc bool isImplicitlyDeclared, bool isConstexpr) {
1735f4a2713aSLionel Sambuc assert(NameInfo.getName().getNameKind()
1736f4a2713aSLionel Sambuc == DeclarationName::CXXConstructorName &&
1737f4a2713aSLionel Sambuc "Name must refer to a constructor");
1738*0a6a1f1dSLionel Sambuc return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
1739*0a6a1f1dSLionel Sambuc isExplicit, isInline,
1740*0a6a1f1dSLionel Sambuc isImplicitlyDeclared, isConstexpr);
1741f4a2713aSLionel Sambuc }
1742f4a2713aSLionel Sambuc
getTargetConstructor() const1743f4a2713aSLionel Sambuc CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
1744f4a2713aSLionel Sambuc assert(isDelegatingConstructor() && "Not a delegating constructor!");
1745f4a2713aSLionel Sambuc Expr *E = (*init_begin())->getInit()->IgnoreImplicit();
1746f4a2713aSLionel Sambuc if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(E))
1747f4a2713aSLionel Sambuc return Construct->getConstructor();
1748f4a2713aSLionel Sambuc
1749*0a6a1f1dSLionel Sambuc return nullptr;
1750f4a2713aSLionel Sambuc }
1751f4a2713aSLionel Sambuc
isDefaultConstructor() const1752f4a2713aSLionel Sambuc bool CXXConstructorDecl::isDefaultConstructor() const {
1753f4a2713aSLionel Sambuc // C++ [class.ctor]p5:
1754f4a2713aSLionel Sambuc // A default constructor for a class X is a constructor of class
1755f4a2713aSLionel Sambuc // X that can be called without an argument.
1756f4a2713aSLionel Sambuc return (getNumParams() == 0) ||
1757f4a2713aSLionel Sambuc (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg());
1758f4a2713aSLionel Sambuc }
1759f4a2713aSLionel Sambuc
1760f4a2713aSLionel Sambuc bool
isCopyConstructor(unsigned & TypeQuals) const1761f4a2713aSLionel Sambuc CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
1762f4a2713aSLionel Sambuc return isCopyOrMoveConstructor(TypeQuals) &&
1763f4a2713aSLionel Sambuc getParamDecl(0)->getType()->isLValueReferenceType();
1764f4a2713aSLionel Sambuc }
1765f4a2713aSLionel Sambuc
isMoveConstructor(unsigned & TypeQuals) const1766f4a2713aSLionel Sambuc bool CXXConstructorDecl::isMoveConstructor(unsigned &TypeQuals) const {
1767f4a2713aSLionel Sambuc return isCopyOrMoveConstructor(TypeQuals) &&
1768f4a2713aSLionel Sambuc getParamDecl(0)->getType()->isRValueReferenceType();
1769f4a2713aSLionel Sambuc }
1770f4a2713aSLionel Sambuc
1771f4a2713aSLionel Sambuc /// \brief Determine whether this is a copy or move constructor.
isCopyOrMoveConstructor(unsigned & TypeQuals) const1772f4a2713aSLionel Sambuc bool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const {
1773f4a2713aSLionel Sambuc // C++ [class.copy]p2:
1774f4a2713aSLionel Sambuc // A non-template constructor for class X is a copy constructor
1775f4a2713aSLionel Sambuc // if its first parameter is of type X&, const X&, volatile X& or
1776f4a2713aSLionel Sambuc // const volatile X&, and either there are no other parameters
1777f4a2713aSLionel Sambuc // or else all other parameters have default arguments (8.3.6).
1778f4a2713aSLionel Sambuc // C++0x [class.copy]p3:
1779f4a2713aSLionel Sambuc // A non-template constructor for class X is a move constructor if its
1780f4a2713aSLionel Sambuc // first parameter is of type X&&, const X&&, volatile X&&, or
1781f4a2713aSLionel Sambuc // const volatile X&&, and either there are no other parameters or else
1782f4a2713aSLionel Sambuc // all other parameters have default arguments.
1783f4a2713aSLionel Sambuc if ((getNumParams() < 1) ||
1784f4a2713aSLionel Sambuc (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
1785*0a6a1f1dSLionel Sambuc (getPrimaryTemplate() != nullptr) ||
1786*0a6a1f1dSLionel Sambuc (getDescribedFunctionTemplate() != nullptr))
1787f4a2713aSLionel Sambuc return false;
1788f4a2713aSLionel Sambuc
1789f4a2713aSLionel Sambuc const ParmVarDecl *Param = getParamDecl(0);
1790f4a2713aSLionel Sambuc
1791f4a2713aSLionel Sambuc // Do we have a reference type?
1792f4a2713aSLionel Sambuc const ReferenceType *ParamRefType = Param->getType()->getAs<ReferenceType>();
1793f4a2713aSLionel Sambuc if (!ParamRefType)
1794f4a2713aSLionel Sambuc return false;
1795f4a2713aSLionel Sambuc
1796f4a2713aSLionel Sambuc // Is it a reference to our class type?
1797f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
1798f4a2713aSLionel Sambuc
1799f4a2713aSLionel Sambuc CanQualType PointeeType
1800f4a2713aSLionel Sambuc = Context.getCanonicalType(ParamRefType->getPointeeType());
1801f4a2713aSLionel Sambuc CanQualType ClassTy
1802f4a2713aSLionel Sambuc = Context.getCanonicalType(Context.getTagDeclType(getParent()));
1803f4a2713aSLionel Sambuc if (PointeeType.getUnqualifiedType() != ClassTy)
1804f4a2713aSLionel Sambuc return false;
1805f4a2713aSLionel Sambuc
1806f4a2713aSLionel Sambuc // FIXME: other qualifiers?
1807f4a2713aSLionel Sambuc
1808f4a2713aSLionel Sambuc // We have a copy or move constructor.
1809f4a2713aSLionel Sambuc TypeQuals = PointeeType.getCVRQualifiers();
1810f4a2713aSLionel Sambuc return true;
1811f4a2713aSLionel Sambuc }
1812f4a2713aSLionel Sambuc
isConvertingConstructor(bool AllowExplicit) const1813f4a2713aSLionel Sambuc bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
1814f4a2713aSLionel Sambuc // C++ [class.conv.ctor]p1:
1815f4a2713aSLionel Sambuc // A constructor declared without the function-specifier explicit
1816f4a2713aSLionel Sambuc // that can be called with a single parameter specifies a
1817f4a2713aSLionel Sambuc // conversion from the type of its first parameter to the type of
1818f4a2713aSLionel Sambuc // its class. Such a constructor is called a converting
1819f4a2713aSLionel Sambuc // constructor.
1820f4a2713aSLionel Sambuc if (isExplicit() && !AllowExplicit)
1821f4a2713aSLionel Sambuc return false;
1822f4a2713aSLionel Sambuc
1823f4a2713aSLionel Sambuc return (getNumParams() == 0 &&
1824f4a2713aSLionel Sambuc getType()->getAs<FunctionProtoType>()->isVariadic()) ||
1825f4a2713aSLionel Sambuc (getNumParams() == 1) ||
1826f4a2713aSLionel Sambuc (getNumParams() > 1 &&
1827f4a2713aSLionel Sambuc (getParamDecl(1)->hasDefaultArg() ||
1828f4a2713aSLionel Sambuc getParamDecl(1)->isParameterPack()));
1829f4a2713aSLionel Sambuc }
1830f4a2713aSLionel Sambuc
isSpecializationCopyingObject() const1831f4a2713aSLionel Sambuc bool CXXConstructorDecl::isSpecializationCopyingObject() const {
1832f4a2713aSLionel Sambuc if ((getNumParams() < 1) ||
1833f4a2713aSLionel Sambuc (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
1834*0a6a1f1dSLionel Sambuc (getDescribedFunctionTemplate() != nullptr))
1835f4a2713aSLionel Sambuc return false;
1836f4a2713aSLionel Sambuc
1837f4a2713aSLionel Sambuc const ParmVarDecl *Param = getParamDecl(0);
1838f4a2713aSLionel Sambuc
1839f4a2713aSLionel Sambuc ASTContext &Context = getASTContext();
1840f4a2713aSLionel Sambuc CanQualType ParamType = Context.getCanonicalType(Param->getType());
1841f4a2713aSLionel Sambuc
1842f4a2713aSLionel Sambuc // Is it the same as our our class type?
1843f4a2713aSLionel Sambuc CanQualType ClassTy
1844f4a2713aSLionel Sambuc = Context.getCanonicalType(Context.getTagDeclType(getParent()));
1845f4a2713aSLionel Sambuc if (ParamType.getUnqualifiedType() != ClassTy)
1846f4a2713aSLionel Sambuc return false;
1847f4a2713aSLionel Sambuc
1848f4a2713aSLionel Sambuc return true;
1849f4a2713aSLionel Sambuc }
1850f4a2713aSLionel Sambuc
getInheritedConstructor() const1851f4a2713aSLionel Sambuc const CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const {
1852f4a2713aSLionel Sambuc // Hack: we store the inherited constructor in the overridden method table
1853f4a2713aSLionel Sambuc method_iterator It = getASTContext().overridden_methods_begin(this);
1854f4a2713aSLionel Sambuc if (It == getASTContext().overridden_methods_end(this))
1855*0a6a1f1dSLionel Sambuc return nullptr;
1856f4a2713aSLionel Sambuc
1857f4a2713aSLionel Sambuc return cast<CXXConstructorDecl>(*It);
1858f4a2713aSLionel Sambuc }
1859f4a2713aSLionel Sambuc
1860f4a2713aSLionel Sambuc void
setInheritedConstructor(const CXXConstructorDecl * BaseCtor)1861f4a2713aSLionel Sambuc CXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl *BaseCtor){
1862f4a2713aSLionel Sambuc // Hack: we store the inherited constructor in the overridden method table
1863f4a2713aSLionel Sambuc assert(getASTContext().overridden_methods_size(this) == 0 &&
1864f4a2713aSLionel Sambuc "Base ctor already set.");
1865f4a2713aSLionel Sambuc getASTContext().addOverriddenMethod(this, BaseCtor);
1866f4a2713aSLionel Sambuc }
1867f4a2713aSLionel Sambuc
anchor()1868f4a2713aSLionel Sambuc void CXXDestructorDecl::anchor() { }
1869f4a2713aSLionel Sambuc
1870f4a2713aSLionel Sambuc CXXDestructorDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1871f4a2713aSLionel Sambuc CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1872*0a6a1f1dSLionel Sambuc return new (C, ID)
1873*0a6a1f1dSLionel Sambuc CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
1874*0a6a1f1dSLionel Sambuc QualType(), nullptr, false, false);
1875f4a2713aSLionel Sambuc }
1876f4a2713aSLionel Sambuc
1877f4a2713aSLionel Sambuc CXXDestructorDecl *
Create(ASTContext & C,CXXRecordDecl * RD,SourceLocation StartLoc,const DeclarationNameInfo & NameInfo,QualType T,TypeSourceInfo * TInfo,bool isInline,bool isImplicitlyDeclared)1878f4a2713aSLionel Sambuc CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1879f4a2713aSLionel Sambuc SourceLocation StartLoc,
1880f4a2713aSLionel Sambuc const DeclarationNameInfo &NameInfo,
1881f4a2713aSLionel Sambuc QualType T, TypeSourceInfo *TInfo,
1882f4a2713aSLionel Sambuc bool isInline, bool isImplicitlyDeclared) {
1883f4a2713aSLionel Sambuc assert(NameInfo.getName().getNameKind()
1884f4a2713aSLionel Sambuc == DeclarationName::CXXDestructorName &&
1885f4a2713aSLionel Sambuc "Name must refer to a destructor");
1886*0a6a1f1dSLionel Sambuc return new (C, RD) CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
1887*0a6a1f1dSLionel Sambuc isInline, isImplicitlyDeclared);
1888f4a2713aSLionel Sambuc }
1889f4a2713aSLionel Sambuc
anchor()1890f4a2713aSLionel Sambuc void CXXConversionDecl::anchor() { }
1891f4a2713aSLionel Sambuc
1892f4a2713aSLionel Sambuc CXXConversionDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1893f4a2713aSLionel Sambuc CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1894*0a6a1f1dSLionel Sambuc return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(),
1895*0a6a1f1dSLionel Sambuc DeclarationNameInfo(), QualType(),
1896*0a6a1f1dSLionel Sambuc nullptr, false, false, false,
1897f4a2713aSLionel Sambuc SourceLocation());
1898f4a2713aSLionel Sambuc }
1899f4a2713aSLionel Sambuc
1900f4a2713aSLionel Sambuc CXXConversionDecl *
Create(ASTContext & C,CXXRecordDecl * RD,SourceLocation StartLoc,const DeclarationNameInfo & NameInfo,QualType T,TypeSourceInfo * TInfo,bool isInline,bool isExplicit,bool isConstexpr,SourceLocation EndLocation)1901f4a2713aSLionel Sambuc CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1902f4a2713aSLionel Sambuc SourceLocation StartLoc,
1903f4a2713aSLionel Sambuc const DeclarationNameInfo &NameInfo,
1904f4a2713aSLionel Sambuc QualType T, TypeSourceInfo *TInfo,
1905f4a2713aSLionel Sambuc bool isInline, bool isExplicit,
1906f4a2713aSLionel Sambuc bool isConstexpr, SourceLocation EndLocation) {
1907f4a2713aSLionel Sambuc assert(NameInfo.getName().getNameKind()
1908f4a2713aSLionel Sambuc == DeclarationName::CXXConversionFunctionName &&
1909f4a2713aSLionel Sambuc "Name must refer to a conversion function");
1910*0a6a1f1dSLionel Sambuc return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo,
1911f4a2713aSLionel Sambuc isInline, isExplicit, isConstexpr,
1912f4a2713aSLionel Sambuc EndLocation);
1913f4a2713aSLionel Sambuc }
1914f4a2713aSLionel Sambuc
isLambdaToBlockPointerConversion() const1915f4a2713aSLionel Sambuc bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
1916f4a2713aSLionel Sambuc return isImplicit() && getParent()->isLambda() &&
1917f4a2713aSLionel Sambuc getConversionType()->isBlockPointerType();
1918f4a2713aSLionel Sambuc }
1919f4a2713aSLionel Sambuc
anchor()1920f4a2713aSLionel Sambuc void LinkageSpecDecl::anchor() { }
1921f4a2713aSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,SourceLocation ExternLoc,SourceLocation LangLoc,LanguageIDs Lang,bool HasBraces)1922f4a2713aSLionel Sambuc LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
1923f4a2713aSLionel Sambuc DeclContext *DC,
1924f4a2713aSLionel Sambuc SourceLocation ExternLoc,
1925f4a2713aSLionel Sambuc SourceLocation LangLoc,
1926f4a2713aSLionel Sambuc LanguageIDs Lang,
1927f4a2713aSLionel Sambuc bool HasBraces) {
1928*0a6a1f1dSLionel Sambuc return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
1929f4a2713aSLionel Sambuc }
1930f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)1931*0a6a1f1dSLionel Sambuc LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C,
1932*0a6a1f1dSLionel Sambuc unsigned ID) {
1933*0a6a1f1dSLionel Sambuc return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(),
1934*0a6a1f1dSLionel Sambuc SourceLocation(), lang_c, false);
1935f4a2713aSLionel Sambuc }
1936f4a2713aSLionel Sambuc
anchor()1937f4a2713aSLionel Sambuc void UsingDirectiveDecl::anchor() { }
1938f4a2713aSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,SourceLocation L,SourceLocation NamespaceLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation IdentLoc,NamedDecl * Used,DeclContext * CommonAncestor)1939f4a2713aSLionel Sambuc UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
1940f4a2713aSLionel Sambuc SourceLocation L,
1941f4a2713aSLionel Sambuc SourceLocation NamespaceLoc,
1942f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc,
1943f4a2713aSLionel Sambuc SourceLocation IdentLoc,
1944f4a2713aSLionel Sambuc NamedDecl *Used,
1945f4a2713aSLionel Sambuc DeclContext *CommonAncestor) {
1946f4a2713aSLionel Sambuc if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
1947f4a2713aSLionel Sambuc Used = NS->getOriginalNamespace();
1948*0a6a1f1dSLionel Sambuc return new (C, DC) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
1949f4a2713aSLionel Sambuc IdentLoc, Used, CommonAncestor);
1950f4a2713aSLionel Sambuc }
1951f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)1952*0a6a1f1dSLionel Sambuc UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C,
1953*0a6a1f1dSLionel Sambuc unsigned ID) {
1954*0a6a1f1dSLionel Sambuc return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(),
1955*0a6a1f1dSLionel Sambuc SourceLocation(),
1956f4a2713aSLionel Sambuc NestedNameSpecifierLoc(),
1957*0a6a1f1dSLionel Sambuc SourceLocation(), nullptr, nullptr);
1958f4a2713aSLionel Sambuc }
1959f4a2713aSLionel Sambuc
getNominatedNamespace()1960f4a2713aSLionel Sambuc NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
1961f4a2713aSLionel Sambuc if (NamespaceAliasDecl *NA =
1962f4a2713aSLionel Sambuc dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
1963f4a2713aSLionel Sambuc return NA->getNamespace();
1964f4a2713aSLionel Sambuc return cast_or_null<NamespaceDecl>(NominatedNamespace);
1965f4a2713aSLionel Sambuc }
1966f4a2713aSLionel Sambuc
NamespaceDecl(ASTContext & C,DeclContext * DC,bool Inline,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,NamespaceDecl * PrevDecl)1967*0a6a1f1dSLionel Sambuc NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
1968*0a6a1f1dSLionel Sambuc SourceLocation StartLoc, SourceLocation IdLoc,
1969*0a6a1f1dSLionel Sambuc IdentifierInfo *Id, NamespaceDecl *PrevDecl)
1970f4a2713aSLionel Sambuc : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
1971*0a6a1f1dSLionel Sambuc redeclarable_base(C), LocStart(StartLoc), RBraceLoc(),
1972*0a6a1f1dSLionel Sambuc AnonOrFirstNamespaceAndInline(nullptr, Inline) {
1973f4a2713aSLionel Sambuc setPreviousDecl(PrevDecl);
1974f4a2713aSLionel Sambuc
1975f4a2713aSLionel Sambuc if (PrevDecl)
1976f4a2713aSLionel Sambuc AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
1977f4a2713aSLionel Sambuc }
1978f4a2713aSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,bool Inline,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,NamespaceDecl * PrevDecl)1979f4a2713aSLionel Sambuc NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
1980f4a2713aSLionel Sambuc bool Inline, SourceLocation StartLoc,
1981f4a2713aSLionel Sambuc SourceLocation IdLoc, IdentifierInfo *Id,
1982f4a2713aSLionel Sambuc NamespaceDecl *PrevDecl) {
1983*0a6a1f1dSLionel Sambuc return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id,
1984*0a6a1f1dSLionel Sambuc PrevDecl);
1985f4a2713aSLionel Sambuc }
1986f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)1987f4a2713aSLionel Sambuc NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1988*0a6a1f1dSLionel Sambuc return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(),
1989*0a6a1f1dSLionel Sambuc SourceLocation(), nullptr, nullptr);
1990*0a6a1f1dSLionel Sambuc }
1991*0a6a1f1dSLionel Sambuc
getNextRedeclarationImpl()1992*0a6a1f1dSLionel Sambuc NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
1993*0a6a1f1dSLionel Sambuc return getNextRedeclaration();
1994*0a6a1f1dSLionel Sambuc }
getPreviousDeclImpl()1995*0a6a1f1dSLionel Sambuc NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() {
1996*0a6a1f1dSLionel Sambuc return getPreviousDecl();
1997*0a6a1f1dSLionel Sambuc }
getMostRecentDeclImpl()1998*0a6a1f1dSLionel Sambuc NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() {
1999*0a6a1f1dSLionel Sambuc return getMostRecentDecl();
2000f4a2713aSLionel Sambuc }
2001f4a2713aSLionel Sambuc
anchor()2002f4a2713aSLionel Sambuc void NamespaceAliasDecl::anchor() { }
2003f4a2713aSLionel Sambuc
getNextRedeclarationImpl()2004*0a6a1f1dSLionel Sambuc NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() {
2005*0a6a1f1dSLionel Sambuc return getNextRedeclaration();
2006*0a6a1f1dSLionel Sambuc }
getPreviousDeclImpl()2007*0a6a1f1dSLionel Sambuc NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() {
2008*0a6a1f1dSLionel Sambuc return getPreviousDecl();
2009*0a6a1f1dSLionel Sambuc }
getMostRecentDeclImpl()2010*0a6a1f1dSLionel Sambuc NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() {
2011*0a6a1f1dSLionel Sambuc return getMostRecentDecl();
2012*0a6a1f1dSLionel Sambuc }
2013*0a6a1f1dSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,SourceLocation UsingLoc,SourceLocation AliasLoc,IdentifierInfo * Alias,NestedNameSpecifierLoc QualifierLoc,SourceLocation IdentLoc,NamedDecl * Namespace)2014f4a2713aSLionel Sambuc NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
2015f4a2713aSLionel Sambuc SourceLocation UsingLoc,
2016f4a2713aSLionel Sambuc SourceLocation AliasLoc,
2017f4a2713aSLionel Sambuc IdentifierInfo *Alias,
2018f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc,
2019f4a2713aSLionel Sambuc SourceLocation IdentLoc,
2020f4a2713aSLionel Sambuc NamedDecl *Namespace) {
2021*0a6a1f1dSLionel Sambuc // FIXME: Preserve the aliased namespace as written.
2022f4a2713aSLionel Sambuc if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
2023f4a2713aSLionel Sambuc Namespace = NS->getOriginalNamespace();
2024*0a6a1f1dSLionel Sambuc return new (C, DC) NamespaceAliasDecl(C, DC, UsingLoc, AliasLoc, Alias,
2025f4a2713aSLionel Sambuc QualifierLoc, IdentLoc, Namespace);
2026f4a2713aSLionel Sambuc }
2027f4a2713aSLionel Sambuc
2028f4a2713aSLionel Sambuc NamespaceAliasDecl *
CreateDeserialized(ASTContext & C,unsigned ID)2029f4a2713aSLionel Sambuc NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2030*0a6a1f1dSLionel Sambuc return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(),
2031*0a6a1f1dSLionel Sambuc SourceLocation(), nullptr,
2032f4a2713aSLionel Sambuc NestedNameSpecifierLoc(),
2033*0a6a1f1dSLionel Sambuc SourceLocation(), nullptr);
2034f4a2713aSLionel Sambuc }
2035f4a2713aSLionel Sambuc
anchor()2036f4a2713aSLionel Sambuc void UsingShadowDecl::anchor() { }
2037f4a2713aSLionel Sambuc
2038f4a2713aSLionel Sambuc UsingShadowDecl *
CreateDeserialized(ASTContext & C,unsigned ID)2039f4a2713aSLionel Sambuc UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2040*0a6a1f1dSLionel Sambuc return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(),
2041*0a6a1f1dSLionel Sambuc nullptr, nullptr);
2042f4a2713aSLionel Sambuc }
2043f4a2713aSLionel Sambuc
getUsingDecl() const2044f4a2713aSLionel Sambuc UsingDecl *UsingShadowDecl::getUsingDecl() const {
2045f4a2713aSLionel Sambuc const UsingShadowDecl *Shadow = this;
2046f4a2713aSLionel Sambuc while (const UsingShadowDecl *NextShadow =
2047f4a2713aSLionel Sambuc dyn_cast<UsingShadowDecl>(Shadow->UsingOrNextShadow))
2048f4a2713aSLionel Sambuc Shadow = NextShadow;
2049f4a2713aSLionel Sambuc return cast<UsingDecl>(Shadow->UsingOrNextShadow);
2050f4a2713aSLionel Sambuc }
2051f4a2713aSLionel Sambuc
anchor()2052f4a2713aSLionel Sambuc void UsingDecl::anchor() { }
2053f4a2713aSLionel Sambuc
addShadowDecl(UsingShadowDecl * S)2054f4a2713aSLionel Sambuc void UsingDecl::addShadowDecl(UsingShadowDecl *S) {
2055f4a2713aSLionel Sambuc assert(std::find(shadow_begin(), shadow_end(), S) == shadow_end() &&
2056f4a2713aSLionel Sambuc "declaration already in set");
2057f4a2713aSLionel Sambuc assert(S->getUsingDecl() == this);
2058f4a2713aSLionel Sambuc
2059f4a2713aSLionel Sambuc if (FirstUsingShadow.getPointer())
2060f4a2713aSLionel Sambuc S->UsingOrNextShadow = FirstUsingShadow.getPointer();
2061f4a2713aSLionel Sambuc FirstUsingShadow.setPointer(S);
2062f4a2713aSLionel Sambuc }
2063f4a2713aSLionel Sambuc
removeShadowDecl(UsingShadowDecl * S)2064f4a2713aSLionel Sambuc void UsingDecl::removeShadowDecl(UsingShadowDecl *S) {
2065f4a2713aSLionel Sambuc assert(std::find(shadow_begin(), shadow_end(), S) != shadow_end() &&
2066f4a2713aSLionel Sambuc "declaration not in set");
2067f4a2713aSLionel Sambuc assert(S->getUsingDecl() == this);
2068f4a2713aSLionel Sambuc
2069f4a2713aSLionel Sambuc // Remove S from the shadow decl chain. This is O(n) but hopefully rare.
2070f4a2713aSLionel Sambuc
2071f4a2713aSLionel Sambuc if (FirstUsingShadow.getPointer() == S) {
2072f4a2713aSLionel Sambuc FirstUsingShadow.setPointer(
2073f4a2713aSLionel Sambuc dyn_cast<UsingShadowDecl>(S->UsingOrNextShadow));
2074f4a2713aSLionel Sambuc S->UsingOrNextShadow = this;
2075f4a2713aSLionel Sambuc return;
2076f4a2713aSLionel Sambuc }
2077f4a2713aSLionel Sambuc
2078f4a2713aSLionel Sambuc UsingShadowDecl *Prev = FirstUsingShadow.getPointer();
2079f4a2713aSLionel Sambuc while (Prev->UsingOrNextShadow != S)
2080f4a2713aSLionel Sambuc Prev = cast<UsingShadowDecl>(Prev->UsingOrNextShadow);
2081f4a2713aSLionel Sambuc Prev->UsingOrNextShadow = S->UsingOrNextShadow;
2082f4a2713aSLionel Sambuc S->UsingOrNextShadow = this;
2083f4a2713aSLionel Sambuc }
2084f4a2713aSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,SourceLocation UL,NestedNameSpecifierLoc QualifierLoc,const DeclarationNameInfo & NameInfo,bool HasTypename)2085f4a2713aSLionel Sambuc UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
2086f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc,
2087f4a2713aSLionel Sambuc const DeclarationNameInfo &NameInfo,
2088f4a2713aSLionel Sambuc bool HasTypename) {
2089*0a6a1f1dSLionel Sambuc return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
2090f4a2713aSLionel Sambuc }
2091f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)2092f4a2713aSLionel Sambuc UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2093*0a6a1f1dSLionel Sambuc return new (C, ID) UsingDecl(nullptr, SourceLocation(),
2094*0a6a1f1dSLionel Sambuc NestedNameSpecifierLoc(), DeclarationNameInfo(),
2095*0a6a1f1dSLionel Sambuc false);
2096f4a2713aSLionel Sambuc }
2097f4a2713aSLionel Sambuc
getSourceRange() const2098f4a2713aSLionel Sambuc SourceRange UsingDecl::getSourceRange() const {
2099f4a2713aSLionel Sambuc SourceLocation Begin = isAccessDeclaration()
2100f4a2713aSLionel Sambuc ? getQualifierLoc().getBeginLoc() : UsingLocation;
2101f4a2713aSLionel Sambuc return SourceRange(Begin, getNameInfo().getEndLoc());
2102f4a2713aSLionel Sambuc }
2103f4a2713aSLionel Sambuc
anchor()2104f4a2713aSLionel Sambuc void UnresolvedUsingValueDecl::anchor() { }
2105f4a2713aSLionel Sambuc
2106f4a2713aSLionel Sambuc UnresolvedUsingValueDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation UsingLoc,NestedNameSpecifierLoc QualifierLoc,const DeclarationNameInfo & NameInfo)2107f4a2713aSLionel Sambuc UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
2108f4a2713aSLionel Sambuc SourceLocation UsingLoc,
2109f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc,
2110f4a2713aSLionel Sambuc const DeclarationNameInfo &NameInfo) {
2111*0a6a1f1dSLionel Sambuc return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
2112f4a2713aSLionel Sambuc QualifierLoc, NameInfo);
2113f4a2713aSLionel Sambuc }
2114f4a2713aSLionel Sambuc
2115f4a2713aSLionel Sambuc UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext & C,unsigned ID)2116f4a2713aSLionel Sambuc UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2117*0a6a1f1dSLionel Sambuc return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(),
2118*0a6a1f1dSLionel Sambuc SourceLocation(),
2119f4a2713aSLionel Sambuc NestedNameSpecifierLoc(),
2120f4a2713aSLionel Sambuc DeclarationNameInfo());
2121f4a2713aSLionel Sambuc }
2122f4a2713aSLionel Sambuc
getSourceRange() const2123f4a2713aSLionel Sambuc SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
2124f4a2713aSLionel Sambuc SourceLocation Begin = isAccessDeclaration()
2125f4a2713aSLionel Sambuc ? getQualifierLoc().getBeginLoc() : UsingLocation;
2126f4a2713aSLionel Sambuc return SourceRange(Begin, getNameInfo().getEndLoc());
2127f4a2713aSLionel Sambuc }
2128f4a2713aSLionel Sambuc
anchor()2129f4a2713aSLionel Sambuc void UnresolvedUsingTypenameDecl::anchor() { }
2130f4a2713aSLionel Sambuc
2131f4a2713aSLionel Sambuc UnresolvedUsingTypenameDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation UsingLoc,SourceLocation TypenameLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TargetNameLoc,DeclarationName TargetName)2132f4a2713aSLionel Sambuc UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
2133f4a2713aSLionel Sambuc SourceLocation UsingLoc,
2134f4a2713aSLionel Sambuc SourceLocation TypenameLoc,
2135f4a2713aSLionel Sambuc NestedNameSpecifierLoc QualifierLoc,
2136f4a2713aSLionel Sambuc SourceLocation TargetNameLoc,
2137f4a2713aSLionel Sambuc DeclarationName TargetName) {
2138*0a6a1f1dSLionel Sambuc return new (C, DC) UnresolvedUsingTypenameDecl(
2139*0a6a1f1dSLionel Sambuc DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc,
2140f4a2713aSLionel Sambuc TargetName.getAsIdentifierInfo());
2141f4a2713aSLionel Sambuc }
2142f4a2713aSLionel Sambuc
2143f4a2713aSLionel Sambuc UnresolvedUsingTypenameDecl *
CreateDeserialized(ASTContext & C,unsigned ID)2144f4a2713aSLionel Sambuc UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2145*0a6a1f1dSLionel Sambuc return new (C, ID) UnresolvedUsingTypenameDecl(
2146*0a6a1f1dSLionel Sambuc nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(),
2147*0a6a1f1dSLionel Sambuc SourceLocation(), nullptr);
2148f4a2713aSLionel Sambuc }
2149f4a2713aSLionel Sambuc
anchor()2150f4a2713aSLionel Sambuc void StaticAssertDecl::anchor() { }
2151f4a2713aSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,SourceLocation StaticAssertLoc,Expr * AssertExpr,StringLiteral * Message,SourceLocation RParenLoc,bool Failed)2152f4a2713aSLionel Sambuc StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
2153f4a2713aSLionel Sambuc SourceLocation StaticAssertLoc,
2154f4a2713aSLionel Sambuc Expr *AssertExpr,
2155f4a2713aSLionel Sambuc StringLiteral *Message,
2156f4a2713aSLionel Sambuc SourceLocation RParenLoc,
2157f4a2713aSLionel Sambuc bool Failed) {
2158*0a6a1f1dSLionel Sambuc return new (C, DC) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
2159f4a2713aSLionel Sambuc RParenLoc, Failed);
2160f4a2713aSLionel Sambuc }
2161f4a2713aSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)2162f4a2713aSLionel Sambuc StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C,
2163f4a2713aSLionel Sambuc unsigned ID) {
2164*0a6a1f1dSLionel Sambuc return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr,
2165*0a6a1f1dSLionel Sambuc nullptr, SourceLocation(), false);
2166*0a6a1f1dSLionel Sambuc }
2167*0a6a1f1dSLionel Sambuc
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName N,QualType T,TypeSourceInfo * TInfo,SourceLocation StartL,IdentifierInfo * Getter,IdentifierInfo * Setter)2168*0a6a1f1dSLionel Sambuc MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC,
2169*0a6a1f1dSLionel Sambuc SourceLocation L, DeclarationName N,
2170*0a6a1f1dSLionel Sambuc QualType T, TypeSourceInfo *TInfo,
2171*0a6a1f1dSLionel Sambuc SourceLocation StartL,
2172*0a6a1f1dSLionel Sambuc IdentifierInfo *Getter,
2173*0a6a1f1dSLionel Sambuc IdentifierInfo *Setter) {
2174*0a6a1f1dSLionel Sambuc return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter);
2175*0a6a1f1dSLionel Sambuc }
2176*0a6a1f1dSLionel Sambuc
CreateDeserialized(ASTContext & C,unsigned ID)2177*0a6a1f1dSLionel Sambuc MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
2178*0a6a1f1dSLionel Sambuc unsigned ID) {
2179*0a6a1f1dSLionel Sambuc return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(),
2180*0a6a1f1dSLionel Sambuc DeclarationName(), QualType(), nullptr,
2181*0a6a1f1dSLionel Sambuc SourceLocation(), nullptr, nullptr);
2182f4a2713aSLionel Sambuc }
2183f4a2713aSLionel Sambuc
getAccessName(AccessSpecifier AS)2184f4a2713aSLionel Sambuc static const char *getAccessName(AccessSpecifier AS) {
2185f4a2713aSLionel Sambuc switch (AS) {
2186f4a2713aSLionel Sambuc case AS_none:
2187f4a2713aSLionel Sambuc llvm_unreachable("Invalid access specifier!");
2188f4a2713aSLionel Sambuc case AS_public:
2189f4a2713aSLionel Sambuc return "public";
2190f4a2713aSLionel Sambuc case AS_private:
2191f4a2713aSLionel Sambuc return "private";
2192f4a2713aSLionel Sambuc case AS_protected:
2193f4a2713aSLionel Sambuc return "protected";
2194f4a2713aSLionel Sambuc }
2195f4a2713aSLionel Sambuc llvm_unreachable("Invalid access specifier!");
2196f4a2713aSLionel Sambuc }
2197f4a2713aSLionel Sambuc
operator <<(const DiagnosticBuilder & DB,AccessSpecifier AS)2198f4a2713aSLionel Sambuc const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
2199f4a2713aSLionel Sambuc AccessSpecifier AS) {
2200f4a2713aSLionel Sambuc return DB << getAccessName(AS);
2201f4a2713aSLionel Sambuc }
2202f4a2713aSLionel Sambuc
operator <<(const PartialDiagnostic & DB,AccessSpecifier AS)2203f4a2713aSLionel Sambuc const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &DB,
2204f4a2713aSLionel Sambuc AccessSpecifier AS) {
2205f4a2713aSLionel Sambuc return DB << getAccessName(AS);
2206f4a2713aSLionel Sambuc }
2207