aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclCXX.h85
-rw-r--r--lib/Sema/SemaDeclCXX.cpp14
-rw-r--r--lib/Sema/SemaInit.cpp7
-rw-r--r--lib/Sema/SemaLookup.cpp20
4 files changed, 60 insertions, 66 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 1678cd916a..afa94989c6 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -722,7 +722,8 @@ public:
/// \brief Determine whether this class has any default constructors.
bool hasDefaultConstructor() const {
- return !data().UserDeclaredConstructor || hasDeclaredDefaultConstructor();
+ return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) ||
+ needsImplicitDefaultConstructor();
}
/// \brief Determine if we need to declare a default constructor for
@@ -730,13 +731,8 @@ public:
///
/// This value is used for lazy creation of default constructors.
bool needsImplicitDefaultConstructor() const {
- return !data().UserDeclaredConstructor && !hasDeclaredDefaultConstructor();
- }
-
- /// \brief Determine whether any default constructors have been declared for
- /// this class (either explicitly or implicitly).
- bool hasDeclaredDefaultConstructor() const {
- return data().DeclaredSpecialMembers & SMF_DefaultConstructor;
+ return !data().UserDeclaredConstructor &&
+ !(data().DeclaredSpecialMembers & SMF_DefaultConstructor);
}
/// hasConstCopyConstructor - Determines whether this class has a
@@ -785,12 +781,10 @@ public:
return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
}
- /// \brief Determine whether this class has had its copy constructor
- /// declared, either via the user or via an implicit declaration.
- ///
- /// This value is used for lazy creation of copy constructors.
- bool hasDeclaredCopyConstructor() const {
- return data().DeclaredSpecialMembers & SMF_CopyConstructor;
+ /// \brief Determine whether this class needs an implicit copy
+ /// constructor to be lazily declared.
+ bool needsImplicitCopyConstructor() const {
+ return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
}
/// \brief Determine whether an implicit copy constructor for this type
@@ -803,7 +797,7 @@ public:
/// a parameter type which is a reference to a const-qualified type.
bool hasCopyConstructorWithConstParam() const {
return data().HasDeclaredCopyConstructorWithConstParam ||
- (!hasDeclaredCopyConstructor() &&
+ (needsImplicitCopyConstructor() &&
implicitCopyConstructorHasConstParam());
}
@@ -821,10 +815,12 @@ public:
return data().UserDeclaredSpecialMembers & SMF_MoveConstructor;
}
- /// \brief Determine whether this class has had a move constructor
- /// declared.
- bool hasDeclaredMoveConstructor() const {
- return data().DeclaredSpecialMembers & SMF_MoveConstructor;
+ /// \brief Determine whether this class has a move constructor.
+ /// FIXME: This can be wrong if the implicit move constructor would be
+ /// deleted.
+ bool hasMoveConstructor() const {
+ return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
+ needsImplicitMoveConstructor();
}
/// \brief Determine whether implicit move constructor generation for this
@@ -847,7 +843,7 @@ public:
/// result.
bool needsImplicitMoveConstructor() const {
return !hasFailedImplicitMoveConstructor() &&
- !hasDeclaredMoveConstructor() &&
+ !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveAssignment() &&
@@ -861,12 +857,10 @@ public:
return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
}
- /// \brief Determine whether this class has had its copy assignment operator
- /// declared, either via the user or via an implicit declaration.
- ///
- /// This value is used for lazy creation of copy assignment operators.
- bool hasDeclaredCopyAssignment() const {
- return data().DeclaredSpecialMembers & SMF_CopyAssignment;
+ /// \brief Determine whether this class needs an implicit copy
+ /// assignment operator to be lazily declared.
+ bool needsImplicitCopyAssignment() const {
+ return !(data().DeclaredSpecialMembers & SMF_CopyAssignment);
}
/// \brief Determine whether an implicit copy assignment operator for this
@@ -880,7 +874,7 @@ public:
/// a reference..
bool hasCopyAssignmentWithConstParam() const {
return data().HasDeclaredCopyAssignmentWithConstParam ||
- (!hasDeclaredCopyAssignment() &&
+ (needsImplicitCopyAssignment() &&
implicitCopyAssignmentHasConstParam());
}
@@ -890,10 +884,11 @@ public:
return data().UserDeclaredSpecialMembers & SMF_MoveAssignment;
}
- /// hasDeclaredMoveAssignment - Whether this class has a
- /// declared move assignment operator.
- bool hasDeclaredMoveAssignment() const {
- return data().DeclaredSpecialMembers & SMF_MoveAssignment;
+ /// \brief Determine whether this class has a move assignment operator.
+ /// FIXME: This can be wrong if the implicit move assignment would be deleted.
+ bool hasMoveAssignment() const {
+ return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
+ needsImplicitMoveAssignment();
}
/// \brief Determine whether implicit move assignment generation for this
@@ -916,7 +911,7 @@ public:
/// constructor wouldn't be deleted.
bool needsImplicitMoveAssignment() const {
return !hasFailedImplicitMoveAssignment() &&
- !hasDeclaredMoveAssignment() &&
+ !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
@@ -930,12 +925,10 @@ public:
return data().UserDeclaredSpecialMembers & SMF_Destructor;
}
- /// \brief Determine whether this class has had its destructor declared,
- /// either via the user or via an implicit declaration.
- ///
- /// This value is used for lazy creation of destructors.
- bool hasDeclaredDestructor() const {
- return data().DeclaredSpecialMembers & SMF_Destructor;
+ /// \brief Determine whether this class needs an implicit destructor to
+ /// be lazily declared.
+ bool needsImplicitDestructor() const {
+ return !(data().DeclaredSpecialMembers & SMF_Destructor);
}
/// \brief Determine whether this class describes a lambda function object.
@@ -1076,8 +1069,8 @@ public:
/// FIXME: This can be wrong if the class has multiple move constructors,
/// or if the implicit move constructor would be deleted.
bool hasTrivialMoveConstructor() const {
- return (data().HasTrivialSpecialMembers & SMF_MoveConstructor) &&
- (hasDeclaredMoveConstructor() || needsImplicitMoveConstructor());
+ return hasMoveConstructor() &&
+ (data().HasTrivialSpecialMembers & SMF_MoveConstructor);
}
/// \brief Determine whether this class has a non-trivial move constructor
@@ -1085,8 +1078,8 @@ public:
/// FIXME: This can be wrong if the implicit move constructor would be
/// deleted.
bool hasNonTrivialMoveConstructor() const {
- return !(data().HasTrivialSpecialMembers & SMF_MoveConstructor) &&
- (hasDeclaredMoveConstructor() || needsImplicitMoveConstructor());
+ return hasMoveConstructor() &&
+ !(data().HasTrivialSpecialMembers & SMF_MoveConstructor);
}
/// \brief Determine whether this class has a trivial copy assignment operator
@@ -1108,16 +1101,16 @@ public:
/// FIXME: This can be wrong if the class has multiple move assignment
/// operators, or if the implicit move assignment operator would be deleted.
bool hasTrivialMoveAssignment() const {
- return (data().HasTrivialSpecialMembers & SMF_MoveAssignment) &&
- (hasDeclaredMoveAssignment() || needsImplicitMoveAssignment());
+ return hasMoveAssignment() &&
+ (data().HasTrivialSpecialMembers & SMF_MoveAssignment);
}
/// \brief Determine whether this class has a non-trivial move assignment
/// operator (C++11 [class.copy]p25)
/// FIXME: This can be wrong if the implicit move assignment would be deleted.
bool hasNonTrivialMoveAssignment() const {
- return !(data().HasTrivialSpecialMembers & SMF_MoveAssignment) &&
- (hasDeclaredMoveAssignment() || needsImplicitMoveAssignment());
+ return hasMoveAssignment() &&
+ !(data().HasTrivialSpecialMembers & SMF_MoveAssignment);
}
/// \brief Determine whether this class has a trivial destructor
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 96dc1c9dee..f3a6fb5ab2 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -7342,7 +7342,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
// If a class has no user-declared destructor, a destructor is
// declared implicitly. An implicitly-declared destructor is an
// inline public member of its class.
- assert(!ClassDecl->hasDeclaredDestructor());
+ assert(ClassDecl->needsImplicitDestructor());
DeclaringSpecialMember DSM(*this, ClassDecl, CXXDestructor);
if (DSM.isAlreadyBeingDeclared())
@@ -7829,7 +7829,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
// constructor rules. Note that virtual bases are not taken into account
// for determining the argument type of the operator. Note also that
// operators taking an object instead of a reference are allowed.
- assert(!ClassDecl->hasDeclaredCopyAssignment());
+ assert(ClassDecl->needsImplicitCopyAssignment());
DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyAssignment);
if (DSM.isAlreadyBeingDeclared())
@@ -8203,14 +8203,18 @@ hasMoveOrIsTriviallyCopyable(Sema &S, QualType Type, bool IsConstructor) {
return true;
if (IsConstructor) {
+ // FIXME: Need this because otherwise hasMoveConstructor isn't guaranteed to
+ // give the right answer.
if (ClassDecl->needsImplicitMoveConstructor())
S.DeclareImplicitMoveConstructor(ClassDecl);
- return ClassDecl->hasDeclaredMoveConstructor();
+ return ClassDecl->hasMoveConstructor();
}
+ // FIXME: Need this because otherwise hasMoveAssignment isn't guaranteed to
+ // give the right answer.
if (ClassDecl->needsImplicitMoveAssignment())
S.DeclareImplicitMoveAssignment(ClassDecl);
- return ClassDecl->hasDeclaredMoveAssignment();
+ return ClassDecl->hasMoveAssignment();
}
/// Determine whether all non-static data members and direct or virtual bases
@@ -8613,7 +8617,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
// C++ [class.copy]p4:
// If the class definition does not explicitly declare a copy
// constructor, one is declared implicitly.
- assert(!ClassDecl->hasDeclaredCopyConstructor());
+ assert(ClassDecl->needsImplicitCopyConstructor());
DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyConstructor);
if (DSM.isAlreadyBeingDeclared())
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 6344aa44b1..7bf1ca90e9 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2865,9 +2865,7 @@ static void TryConstructorInitialization(Sema &S,
// If the initializer list has no elements and T has a default constructor,
// the first phase is omitted.
- if (ILE->getNumInits() != 0 ||
- (!DestRecordDecl->hasDeclaredDefaultConstructor() &&
- !DestRecordDecl->needsImplicitDefaultConstructor()))
+ if (ILE->getNumInits() != 0 || !DestRecordDecl->hasDefaultConstructor())
Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs,
CandidateSet, Ctors, Best,
CopyInitialization, AllowExplicit,
@@ -3077,8 +3075,7 @@ static void TryListInitialization(Sema &S,
// value-initialized.
if (InitList->getNumInits() == 0) {
CXXRecordDecl *RD = DestType->getAsCXXRecordDecl();
- if (RD->hasDeclaredDefaultConstructor() ||
- RD->needsImplicitDefaultConstructor()) {
+ if (RD->hasDefaultConstructor()) {
TryValueInitialization(S, Entity, Kind, Sequence, InitList);
return;
}
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 4b1c6649be..ce8e8c173e 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -546,11 +546,11 @@ void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) {
DeclareImplicitDefaultConstructor(Class);
// If the copy constructor has not yet been declared, do so now.
- if (!Class->hasDeclaredCopyConstructor())
+ if (Class->needsImplicitCopyConstructor())
DeclareImplicitCopyConstructor(Class);
// If the copy assignment operator has not yet been declared, do so now.
- if (!Class->hasDeclaredCopyAssignment())
+ if (Class->needsImplicitCopyAssignment())
DeclareImplicitCopyAssignment(Class);
if (getLangOpts().CPlusPlus0x) {
@@ -564,7 +564,7 @@ void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) {
}
// If the destructor has not yet been declared, do so now.
- if (!Class->hasDeclaredDestructor())
+ if (Class->needsImplicitDestructor())
DeclareImplicitDestructor(Class);
}
@@ -601,7 +601,7 @@ static void DeclareImplicitMemberFunctionsWithName(Sema &S,
CXXRecordDecl *Class = const_cast<CXXRecordDecl *>(Record);
if (Record->needsImplicitDefaultConstructor())
S.DeclareImplicitDefaultConstructor(Class);
- if (!Record->hasDeclaredCopyConstructor())
+ if (Record->needsImplicitCopyConstructor())
S.DeclareImplicitCopyConstructor(Class);
if (S.getLangOpts().CPlusPlus0x &&
Record->needsImplicitMoveConstructor())
@@ -611,7 +611,7 @@ static void DeclareImplicitMemberFunctionsWithName(Sema &S,
case DeclarationName::CXXDestructorName:
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
- if (Record->getDefinition() && !Record->hasDeclaredDestructor() &&
+ if (Record->getDefinition() && Record->needsImplicitDestructor() &&
CanDeclareSpecialMemberFunction(Record))
S.DeclareImplicitDestructor(const_cast<CXXRecordDecl *>(Record));
break;
@@ -623,7 +623,7 @@ static void DeclareImplicitMemberFunctionsWithName(Sema &S,
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) {
if (Record->getDefinition() && CanDeclareSpecialMemberFunction(Record)) {
CXXRecordDecl *Class = const_cast<CXXRecordDecl *>(Record);
- if (!Record->hasDeclaredCopyAssignment())
+ if (Record->needsImplicitCopyAssignment())
S.DeclareImplicitCopyAssignment(Class);
if (S.getLangOpts().CPlusPlus0x &&
Record->needsImplicitMoveAssignment())
@@ -2257,7 +2257,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
SpecialMemberCache.InsertNode(Result, InsertPoint);
if (SM == CXXDestructor) {
- if (!RD->hasDeclaredDestructor())
+ if (RD->needsImplicitDestructor())
DeclareImplicitDestructor(RD);
CXXDestructorDecl *DD = RD->getDestructor();
assert(DD && "record without a destructor");
@@ -2286,13 +2286,13 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
} else {
if (SM == CXXCopyConstructor || SM == CXXMoveConstructor) {
Name = Context.DeclarationNames.getCXXConstructorName(CanTy);
- if (!RD->hasDeclaredCopyConstructor())
+ if (RD->needsImplicitCopyConstructor())
DeclareImplicitCopyConstructor(RD);
if (getLangOpts().CPlusPlus0x && RD->needsImplicitMoveConstructor())
DeclareImplicitMoveConstructor(RD);
} else {
Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
- if (!RD->hasDeclaredCopyAssignment())
+ if (RD->needsImplicitCopyAssignment())
DeclareImplicitCopyAssignment(RD);
if (getLangOpts().CPlusPlus0x && RD->needsImplicitMoveAssignment())
DeclareImplicitMoveAssignment(RD);
@@ -2446,7 +2446,7 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
if (CanDeclareSpecialMemberFunction(Class)) {
if (Class->needsImplicitDefaultConstructor())
DeclareImplicitDefaultConstructor(Class);
- if (!Class->hasDeclaredCopyConstructor())
+ if (Class->needsImplicitCopyConstructor())
DeclareImplicitCopyConstructor(Class);
if (getLangOpts().CPlusPlus0x && Class->needsImplicitMoveConstructor())
DeclareImplicitMoveConstructor(Class);