[clang] d019b9a - [clang][NFC] Refactor `CXXSpecialMember`
Vlad Serebrennikov via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 12 02:21:22 PDT 2024
Author: Vlad Serebrennikov
Date: 2024-04-12T12:21:14+03:00
New Revision: d019b9aaaaa60c858ee82fdbaf5de16e048e9db2
URL: https://github.com/llvm/llvm-project/commit/d019b9aaaaa60c858ee82fdbaf5de16e048e9db2
DIFF: https://github.com/llvm/llvm-project/commit/d019b9aaaaa60c858ee82fdbaf5de16e048e9db2.diff
LOG: [clang][NFC] Refactor `CXXSpecialMember`
In preparation for `SemaCUDA`, which requires this enum to be forward-declarable.
Added:
Modified:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaAccess.cpp
clang/lib/Sema/SemaCUDA.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/lib/Sema/SemaType.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c4a603cc5a4a74..90c91662827034 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -60,6 +60,7 @@
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -423,6 +424,17 @@ enum class TemplateDeductionResult {
AlreadyDiagnosed
};
+/// Kinds of C++ special members.
+enum class CXXSpecialMemberKind {
+ DefaultConstructor,
+ CopyConstructor,
+ MoveConstructor,
+ CopyAssignment,
+ MoveAssignment,
+ Destructor,
+ Invalid
+};
+
/// Sema - This implements semantic analysis and AST building for C.
/// \nosubgrouping
class Sema final : public SemaBase {
@@ -4077,22 +4089,11 @@ class Sema final : public SemaBase {
SourceRange SpecificationRange, ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr);
- /// Kinds of C++ special members.
- enum CXXSpecialMember {
- CXXDefaultConstructor,
- CXXCopyConstructor,
- CXXMoveConstructor,
- CXXCopyAssignment,
- CXXMoveAssignment,
- CXXDestructor,
- CXXInvalid
- };
-
class InheritedConstructorInfo;
/// Determine if a special member function should have a deleted
/// definition when it is defaulted.
- bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
+ bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
InheritedConstructorInfo *ICI = nullptr,
bool Diagnose = false);
@@ -4458,7 +4459,7 @@ class Sema final : public SemaBase {
void CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *MD);
bool CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
- CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
SourceLocation DefaultLoc);
void CheckDelayedMemberExceptionSpecs();
@@ -4618,7 +4619,7 @@ class Sema final : public SemaBase {
void CheckCXXDefaultArguments(FunctionDecl *FD);
void CheckExtraCXXDefaultArguments(Declarator &D);
- CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD) {
+ CXXSpecialMemberKind getSpecialMember(const CXXMethodDecl *MD) {
return getDefaultedFunctionKind(MD).asSpecialMember();
}
@@ -4645,7 +4646,8 @@ class Sema final : public SemaBase {
AccessSpecifier AS,
const ParsedAttr &MSPropertyAttr);
- void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
+ void DiagnoseNontrivial(const CXXRecordDecl *Record,
+ CXXSpecialMemberKind CSM);
enum TrivialABIHandling {
/// The triviality of a method unaffected by "trivial_abi".
@@ -4655,26 +4657,31 @@ class Sema final : public SemaBase {
TAH_ConsiderTrivialABI
};
- bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
+ bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
TrivialABIHandling TAH = TAH_IgnoreTrivialABI,
bool Diagnose = false);
/// For a defaulted function, the kind of defaulted function that it is.
class DefaultedFunctionKind {
+ LLVM_PREFERRED_TYPE(CXXSpecialMemberKind)
unsigned SpecialMember : 8;
unsigned Comparison : 8;
public:
DefaultedFunctionKind()
- : SpecialMember(CXXInvalid),
+ : SpecialMember(llvm::to_underlying(CXXSpecialMemberKind::Invalid)),
Comparison(llvm::to_underlying(DefaultedComparisonKind::None)) {}
- DefaultedFunctionKind(CXXSpecialMember CSM)
- : SpecialMember(CSM),
+ DefaultedFunctionKind(CXXSpecialMemberKind CSM)
+ : SpecialMember(llvm::to_underlying(CSM)),
Comparison(llvm::to_underlying(DefaultedComparisonKind::None)) {}
DefaultedFunctionKind(DefaultedComparisonKind Comp)
- : SpecialMember(CXXInvalid), Comparison(llvm::to_underlying(Comp)) {}
+ : SpecialMember(llvm::to_underlying(CXXSpecialMemberKind::Invalid)),
+ Comparison(llvm::to_underlying(Comp)) {}
- bool isSpecialMember() const { return SpecialMember != CXXInvalid; }
+ bool isSpecialMember() const {
+ return static_cast<CXXSpecialMemberKind>(SpecialMember) !=
+ CXXSpecialMemberKind::Invalid;
+ }
bool isComparison() const {
return static_cast<DefaultedComparisonKind>(Comparison) !=
DefaultedComparisonKind::None;
@@ -4684,8 +4691,8 @@ class Sema final : public SemaBase {
return isSpecialMember() || isComparison();
}
- CXXSpecialMember asSpecialMember() const {
- return static_cast<CXXSpecialMember>(SpecialMember);
+ CXXSpecialMemberKind asSpecialMember() const {
+ return static_cast<CXXSpecialMemberKind>(SpecialMember);
}
DefaultedComparisonKind asComparison() const {
return static_cast<DefaultedComparisonKind>(Comparison);
@@ -4693,7 +4700,8 @@ class Sema final : public SemaBase {
/// Get the index of this function kind for use in diagnostics.
unsigned getDiagnosticIndex() const {
- static_assert(CXXInvalid > CXXDestructor,
+ static_assert(llvm::to_underlying(CXXSpecialMemberKind::Invalid) >
+ llvm::to_underlying(CXXSpecialMemberKind::Destructor),
"invalid should have highest index");
static_assert((unsigned)DefaultedComparisonKind::None == 0,
"none should be equal to zero");
@@ -4799,7 +4807,7 @@ class Sema final : public SemaBase {
/// definition in this translation unit.
llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed;
- typedef llvm::PointerIntPair<CXXRecordDecl *, 3, CXXSpecialMember>
+ typedef llvm::PointerIntPair<CXXRecordDecl *, 3, CXXSpecialMemberKind>
SpecialMemberDecl;
/// The C++ special members which we are currently in the process of
@@ -7493,7 +7501,7 @@ class Sema final : public SemaBase {
};
SpecialMemberOverloadResult
- LookupSpecialMember(CXXRecordDecl *D, CXXSpecialMember SM, bool ConstArg,
+ LookupSpecialMember(CXXRecordDecl *D, CXXSpecialMemberKind SM, bool ConstArg,
bool VolatileArg, bool RValueThis, bool ConstThis,
bool VolatileThis);
@@ -10014,7 +10022,7 @@ class Sema final : public SemaBase {
unsigned NumCallArgs;
/// The special member being declared or defined.
- CXXSpecialMember SpecialMember;
+ CXXSpecialMemberKind SpecialMember;
};
ArrayRef<TemplateArgument> template_arguments() const {
@@ -13109,7 +13117,7 @@ class Sema final : public SemaBase {
/// The result of this call is implicit CUDA target attribute(s) attached to
/// the member declaration.
bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
- CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
CXXMethodDecl *MemberDecl,
bool ConstRHS, bool Diagnose);
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 4af3c0f30a8e8a..6a707eeb66d012 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -10,8 +10,6 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Basic/Specifiers.h"
-#include "clang/Sema/SemaInternal.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
@@ -19,9 +17,12 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DependentDiagnostic.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Sema/DelayedDiagnostic.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "llvm/ADT/STLForwardCompat.h"
using namespace clang;
using namespace sema;
@@ -1658,21 +1659,24 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
case InitializedEntity::EK_Base:
PD = PDiag(diag::err_access_base_ctor);
PD << Entity.isInheritedVirtualBase()
- << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
+ << Entity.getBaseSpecifier()->getType()
+ << llvm::to_underlying(getSpecialMember(Constructor));
break;
case InitializedEntity::EK_Member:
case InitializedEntity::EK_ParenAggInitMember: {
const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
PD = PDiag(diag::err_access_field_ctor);
- PD << Field->getType() << getSpecialMember(Constructor);
+ PD << Field->getType()
+ << llvm::to_underlying(getSpecialMember(Constructor));
break;
}
case InitializedEntity::EK_LambdaCapture: {
StringRef VarName = Entity.getCapturedVarName();
PD = PDiag(diag::err_access_lambda_capture);
- PD << VarName << Entity.getType() << getSpecialMember(Constructor);
+ PD << VarName << Entity.getType()
+ << llvm::to_underlying(getSpecialMember(Constructor));
break;
}
diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp
index 4d4f4b6a2d4d95..1596222e3d1da3 100644
--- a/clang/lib/Sema/SemaCUDA.cpp
+++ b/clang/lib/Sema/SemaCUDA.cpp
@@ -358,7 +358,7 @@ resolveCalleeCUDATargetConflict(Sema::CUDAFunctionTarget Target1,
}
bool Sema::inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
- CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
CXXMethodDecl *MemberDecl,
bool ConstRHS,
bool Diagnose) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index afd9e407946a03..b448bacd49f324 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -48,6 +48,7 @@
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TargetParser/Triple.h"
@@ -4049,13 +4050,13 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S,
} else {
Diag(NewMethod->getLocation(),
diag::err_definition_of_implicitly_declared_member)
- << New << getSpecialMember(OldMethod);
+ << New << llvm::to_underlying(getSpecialMember(OldMethod));
return true;
}
} else if (OldMethod->getFirstDecl()->isExplicitlyDefaulted() && !isFriend) {
Diag(NewMethod->getLocation(),
diag::err_definition_of_explicitly_defaulted_member)
- << getSpecialMember(OldMethod);
+ << llvm::to_underlying(getSpecialMember(OldMethod));
return true;
}
}
@@ -18847,22 +18848,22 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) {
// because otherwise we'll never get complaints about
// copy constructors.
- CXXSpecialMember member = CXXInvalid;
+ CXXSpecialMemberKind member = CXXSpecialMemberKind::Invalid;
// We're required to check for any non-trivial constructors. Since the
// implicit default constructor is suppressed if there are any
// user-declared constructors, we just need to check that there is a
// trivial default constructor and a trivial copy constructor. (We don't
// worry about move constructors here, since this is a C++98 check.)
if (RDecl->hasNonTrivialCopyConstructor())
- member = CXXCopyConstructor;
+ member = CXXSpecialMemberKind::CopyConstructor;
else if (!RDecl->hasTrivialDefaultConstructor())
- member = CXXDefaultConstructor;
+ member = CXXSpecialMemberKind::DefaultConstructor;
else if (RDecl->hasNonTrivialCopyAssignment())
- member = CXXCopyAssignment;
+ member = CXXSpecialMemberKind::CopyAssignment;
else if (RDecl->hasNonTrivialDestructor())
- member = CXXDestructor;
+ member = CXXSpecialMemberKind::Destructor;
- if (member != CXXInvalid) {
+ if (member != CXXSpecialMemberKind::Invalid) {
if (!getLangOpts().CPlusPlus11 &&
getLangOpts().ObjCAutoRefCount && RDecl->hasObjectMember()) {
// Objective-C++ ARC: it is an error to have a non-trivial field of
@@ -18879,10 +18880,13 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) {
}
}
- Diag(FD->getLocation(), getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_nontrivial_union_or_anon_struct_member :
- diag::err_illegal_union_or_anon_struct_member)
- << FD->getParent()->isUnion() << FD->getDeclName() << member;
+ Diag(
+ FD->getLocation(),
+ getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_nontrivial_union_or_anon_struct_member
+ : diag::err_illegal_union_or_anon_struct_member)
+ << FD->getParent()->isUnion() << FD->getDeclName()
+ << llvm::to_underlying(member);
DiagnoseNontrivial(RDecl, member);
return !getLangOpts().CPlusPlus11;
}
@@ -19132,10 +19136,10 @@ static void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
static bool AreSpecialMemberFunctionsSameKind(ASTContext &Context,
CXXMethodDecl *M1,
CXXMethodDecl *M2,
- Sema::CXXSpecialMember CSM) {
+ CXXSpecialMemberKind CSM) {
// We don't want to compare templates to non-templates: See
// https://github.com/llvm/llvm-project/issues/59206
- if (CSM == Sema::CXXDefaultConstructor)
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor)
return bool(M1->getDescribedFunctionTemplate()) ==
bool(M2->getDescribedFunctionTemplate());
// FIXME: better resolve CWG
@@ -19158,7 +19162,7 @@ static bool AreSpecialMemberFunctionsSameKind(ASTContext &Context,
/// [CWG2595], if any, are satisfied is more constrained.
static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
ArrayRef<CXXMethodDecl *> Methods,
- Sema::CXXSpecialMember CSM) {
+ CXXSpecialMemberKind CSM) {
SmallVector<bool, 4> SatisfactionStatus;
for (CXXMethodDecl *Method : Methods) {
@@ -19216,7 +19220,8 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
// DR1734 and DR1496.
if (!AnotherMethodIsMoreConstrained) {
Method->setIneligibleOrNotSelected(false);
- Record->addedEligibleSpecialMemberFunction(Method, 1 << CSM);
+ Record->addedEligibleSpecialMemberFunction(Method,
+ 1 << llvm::to_underlying(CSM));
}
}
}
@@ -19255,13 +19260,15 @@ static void ComputeSpecialMemberFunctionsEligiblity(Sema &S,
}
SetEligibleMethods(S, Record, DefaultConstructors,
- Sema::CXXDefaultConstructor);
- SetEligibleMethods(S, Record, CopyConstructors, Sema::CXXCopyConstructor);
- SetEligibleMethods(S, Record, MoveConstructors, Sema::CXXMoveConstructor);
+ CXXSpecialMemberKind::DefaultConstructor);
+ SetEligibleMethods(S, Record, CopyConstructors,
+ CXXSpecialMemberKind::CopyConstructor);
+ SetEligibleMethods(S, Record, MoveConstructors,
+ CXXSpecialMemberKind::MoveConstructor);
SetEligibleMethods(S, Record, CopyAssignmentOperators,
- Sema::CXXCopyAssignment);
+ CXXSpecialMemberKind::CopyAssignment);
SetEligibleMethods(S, Record, MoveAssignmentOperators,
- Sema::CXXMoveAssignment);
+ CXXSpecialMemberKind::MoveAssignment);
}
void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
@@ -19630,7 +19637,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
if (CXXRecord) {
auto *Dtor = CXXRecord->getDestructor();
if (Dtor && Dtor->isImplicit() &&
- ShouldDeleteSpecialMember(Dtor, CXXDestructor)) {
+ ShouldDeleteSpecialMember(Dtor, CXXSpecialMemberKind::Destructor)) {
CXXRecord->setImplicitDestructorIsDeleted();
SetDeclDeleted(Dtor, CXXRecord->getLocation());
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 858951580ea45b..51c14443d2d8f1 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -46,6 +46,7 @@
#include "clang/Sema/Template.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -657,13 +658,13 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
// is ill-formed. This can only happen for constructors.
if (isa<CXXConstructorDecl>(New) &&
New->getMinRequiredArguments() < Old->getMinRequiredArguments()) {
- CXXSpecialMember NewSM = getSpecialMember(cast<CXXMethodDecl>(New)),
- OldSM = getSpecialMember(cast<CXXMethodDecl>(Old));
+ CXXSpecialMemberKind NewSM = getSpecialMember(cast<CXXMethodDecl>(New)),
+ OldSM = getSpecialMember(cast<CXXMethodDecl>(Old));
if (NewSM != OldSM) {
ParmVarDecl *NewParam = New->getParamDecl(New->getMinRequiredArguments());
assert(NewParam->hasDefaultArg());
Diag(NewParam->getLocation(), diag::err_default_arg_makes_ctor_special)
- << NewParam->getDefaultArgRange() << NewSM;
+ << NewParam->getDefaultArgRange() << llvm::to_underlying(NewSM);
Diag(Old->getLocation(), diag::note_previous_declaration);
}
}
@@ -6779,7 +6780,7 @@ void Sema::propagateDLLAttrToBaseClassTemplate(
///
/// If the function is both a default constructor and a copy / move constructor
/// (due to having a default argument for the first parameter), this picks
-/// CXXDefaultConstructor.
+/// CXXSpecialMemberKind::DefaultConstructor.
///
/// FIXME: Check that case is properly handled by all callers.
Sema::DefaultedFunctionKind
@@ -6787,23 +6788,23 @@ Sema::getDefaultedFunctionKind(const FunctionDecl *FD) {
if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(FD)) {
if (Ctor->isDefaultConstructor())
- return Sema::CXXDefaultConstructor;
+ return CXXSpecialMemberKind::DefaultConstructor;
if (Ctor->isCopyConstructor())
- return Sema::CXXCopyConstructor;
+ return CXXSpecialMemberKind::CopyConstructor;
if (Ctor->isMoveConstructor())
- return Sema::CXXMoveConstructor;
+ return CXXSpecialMemberKind::MoveConstructor;
}
if (MD->isCopyAssignmentOperator())
- return Sema::CXXCopyAssignment;
+ return CXXSpecialMemberKind::CopyAssignment;
if (MD->isMoveAssignmentOperator())
- return Sema::CXXMoveAssignment;
+ return CXXSpecialMemberKind::MoveAssignment;
if (isa<CXXDestructorDecl>(FD))
- return Sema::CXXDestructor;
+ return CXXSpecialMemberKind::Destructor;
}
switch (FD->getDeclName().getCXXOverloadedOperator()) {
@@ -6843,26 +6844,26 @@ static void DefineDefaultedFunction(Sema &S, FunctionDecl *FD,
return S.DefineDefaultedComparison(DefaultLoc, FD, DFK.asComparison());
switch (DFK.asSpecialMember()) {
- case Sema::CXXDefaultConstructor:
+ case CXXSpecialMemberKind::DefaultConstructor:
S.DefineImplicitDefaultConstructor(DefaultLoc,
cast<CXXConstructorDecl>(FD));
break;
- case Sema::CXXCopyConstructor:
+ case CXXSpecialMemberKind::CopyConstructor:
S.DefineImplicitCopyConstructor(DefaultLoc, cast<CXXConstructorDecl>(FD));
break;
- case Sema::CXXCopyAssignment:
+ case CXXSpecialMemberKind::CopyAssignment:
S.DefineImplicitCopyAssignment(DefaultLoc, cast<CXXMethodDecl>(FD));
break;
- case Sema::CXXDestructor:
+ case CXXSpecialMemberKind::Destructor:
S.DefineImplicitDestructor(DefaultLoc, cast<CXXDestructorDecl>(FD));
break;
- case Sema::CXXMoveConstructor:
+ case CXXSpecialMemberKind::MoveConstructor:
S.DefineImplicitMoveConstructor(DefaultLoc, cast<CXXConstructorDecl>(FD));
break;
- case Sema::CXXMoveAssignment:
+ case CXXSpecialMemberKind::MoveAssignment:
S.DefineImplicitMoveAssignment(DefaultLoc, cast<CXXMethodDecl>(FD));
break;
- case Sema::CXXInvalid:
+ case CXXSpecialMemberKind::Invalid:
llvm_unreachable("Invalid special member.");
}
}
@@ -7182,9 +7183,9 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
// For an explicitly defaulted or deleted special member, we defer
// determining triviality until the class is complete. That time is now!
- CXXSpecialMember CSM = getSpecialMember(M);
+ CXXSpecialMemberKind CSM = getSpecialMember(M);
if (!M->isImplicit() && !M->isUserProvided()) {
- if (CSM != CXXInvalid) {
+ if (CSM != CXXSpecialMemberKind::Invalid) {
M->setTrivial(SpecialMemberIsTrivial(M, CSM));
// Inform the class that we've finished declaring this member.
Record->finishedDefaultedOrDeletedMember(M);
@@ -7197,8 +7198,10 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
// Set triviality for the purpose of calls if this is a user-provided
// copy/move constructor or destructor.
- if ((CSM == CXXCopyConstructor || CSM == CXXMoveConstructor ||
- CSM == CXXDestructor) && M->isUserProvided()) {
+ if ((CSM == CXXSpecialMemberKind::CopyConstructor ||
+ CSM == CXXSpecialMemberKind::MoveConstructor ||
+ CSM == CXXSpecialMemberKind::Destructor) &&
+ M->isUserProvided()) {
M->setTrivialForCall(HasTrivialABI);
Record->setTrivialForCallFlags(M);
}
@@ -7207,8 +7210,9 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
M->hasAttr<DLLExportAttr>()) {
if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) &&
M->isTrivial() &&
- (CSM == CXXDefaultConstructor || CSM == CXXCopyConstructor ||
- CSM == CXXDestructor))
+ (CSM == CXXSpecialMemberKind::DefaultConstructor ||
+ CSM == CXXSpecialMemberKind::CopyConstructor ||
+ CSM == CXXSpecialMemberKind::Destructor))
M->dropAttr<DLLExportAttr>();
if (M->hasAttr<DLLExportAttr>()) {
@@ -7220,8 +7224,8 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
// Define defaulted constexpr virtual functions that override a base class
// function right away.
// FIXME: We can defer doing this until the vtable is marked as used.
- if (CSM != CXXInvalid && !M->isDeleted() && M->isDefaulted() &&
- M->isConstexpr() && M->size_overridden_methods())
+ if (CSM != CXXSpecialMemberKind::Invalid && !M->isDeleted() &&
+ M->isDefaulted() && M->isConstexpr() && M->size_overridden_methods())
DefineDefaultedFunction(*this, M, M->getLocation());
if (!Incomplete)
@@ -7343,15 +7347,18 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
/// \param ConstRHS True if this is a copy operation with a const object
/// on its RHS, that is, if the argument to the outer special member
/// function is 'const' and this is not a field marked 'mutable'.
-static Sema::SpecialMemberOverloadResult lookupCallFromSpecialMember(
- Sema &S, CXXRecordDecl *Class, Sema::CXXSpecialMember CSM,
- unsigned FieldQuals, bool ConstRHS) {
+static Sema::SpecialMemberOverloadResult
+lookupCallFromSpecialMember(Sema &S, CXXRecordDecl *Class,
+ CXXSpecialMemberKind CSM, unsigned FieldQuals,
+ bool ConstRHS) {
unsigned LHSQuals = 0;
- if (CSM == Sema::CXXCopyAssignment || CSM == Sema::CXXMoveAssignment)
+ if (CSM == CXXSpecialMemberKind::CopyAssignment ||
+ CSM == CXXSpecialMemberKind::MoveAssignment)
LHSQuals = FieldQuals;
unsigned RHSQuals = FieldQuals;
- if (CSM == Sema::CXXDefaultConstructor || CSM == Sema::CXXDestructor)
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor ||
+ CSM == CXXSpecialMemberKind::Destructor)
RHSQuals = 0;
else if (ConstRHS)
RHSQuals |= Qualifiers::Const;
@@ -7447,12 +7454,10 @@ class Sema::InheritedConstructorInfo {
/// Is the special member function which would be selected to perform the
/// specified operation on the specified class type a constexpr constructor?
-static bool
-specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
- Sema::CXXSpecialMember CSM, unsigned Quals,
- bool ConstRHS,
- CXXConstructorDecl *InheritedCtor = nullptr,
- Sema::InheritedConstructorInfo *Inherited = nullptr) {
+static bool specialMemberIsConstexpr(
+ Sema &S, CXXRecordDecl *ClassDecl, CXXSpecialMemberKind CSM, unsigned Quals,
+ bool ConstRHS, CXXConstructorDecl *InheritedCtor = nullptr,
+ Sema::InheritedConstructorInfo *Inherited = nullptr) {
// Suppress duplicate constraint checking here, in case a constraint check
// caused us to decide to do this. Any truely recursive checks will get
// caught during these checks anyway.
@@ -7461,16 +7466,16 @@ specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
// If we're inheriting a constructor, see if we need to call it for this base
// class.
if (InheritedCtor) {
- assert(CSM == Sema::CXXDefaultConstructor);
+ assert(CSM == CXXSpecialMemberKind::DefaultConstructor);
auto BaseCtor =
Inherited->findConstructorForBase(ClassDecl, InheritedCtor).first;
if (BaseCtor)
return BaseCtor->isConstexpr();
}
- if (CSM == Sema::CXXDefaultConstructor)
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor)
return ClassDecl->hasConstexprDefaultConstructor();
- if (CSM == Sema::CXXDestructor)
+ if (CSM == CXXSpecialMemberKind::Destructor)
return ClassDecl->hasConstexprDestructor();
Sema::SpecialMemberOverloadResult SMOR =
@@ -7485,8 +7490,8 @@ specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
/// Determine whether the specified special member function would be constexpr
/// if it were implicitly defined.
static bool defaultedSpecialMemberIsConstexpr(
- Sema &S, CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
- bool ConstArg, CXXConstructorDecl *InheritedCtor = nullptr,
+ Sema &S, CXXRecordDecl *ClassDecl, CXXSpecialMemberKind CSM, bool ConstArg,
+ CXXConstructorDecl *InheritedCtor = nullptr,
Sema::InheritedConstructorInfo *Inherited = nullptr) {
if (!S.getLangOpts().CPlusPlus11)
return false;
@@ -7495,7 +7500,7 @@ static bool defaultedSpecialMemberIsConstexpr(
// In the definition of a constexpr constructor [...]
bool Ctor = true;
switch (CSM) {
- case Sema::CXXDefaultConstructor:
+ case CXXSpecialMemberKind::DefaultConstructor:
if (Inherited)
break;
// Since default constructor lookup is essentially trivial (and cannot
@@ -7506,23 +7511,23 @@ static bool defaultedSpecialMemberIsConstexpr(
// constructor is constexpr to determine whether the type is a literal type.
return ClassDecl->defaultedDefaultConstructorIsConstexpr();
- case Sema::CXXCopyConstructor:
- case Sema::CXXMoveConstructor:
+ case CXXSpecialMemberKind::CopyConstructor:
+ case CXXSpecialMemberKind::MoveConstructor:
// For copy or move constructors, we need to perform overload resolution.
break;
- case Sema::CXXCopyAssignment:
- case Sema::CXXMoveAssignment:
+ case CXXSpecialMemberKind::CopyAssignment:
+ case CXXSpecialMemberKind::MoveAssignment:
if (!S.getLangOpts().CPlusPlus14)
return false;
// In C++1y, we need to perform overload resolution.
Ctor = false;
break;
- case Sema::CXXDestructor:
+ case CXXSpecialMemberKind::Destructor:
return ClassDecl->defaultedDestructorIsConstexpr();
- case Sema::CXXInvalid:
+ case CXXSpecialMemberKind::Invalid:
return false;
}
@@ -7534,7 +7539,7 @@ static bool defaultedSpecialMemberIsConstexpr(
// will be initialized (if the constructor isn't deleted), we just don't know
// which one.
if (Ctor && ClassDecl->isUnion())
- return CSM == Sema::CXXDefaultConstructor
+ return CSM == CXXSpecialMemberKind::DefaultConstructor
? ClassDecl->hasInClassInitializer() ||
!ClassDecl->hasVariantMembers()
: true;
@@ -7575,7 +7580,8 @@ static bool defaultedSpecialMemberIsConstexpr(
for (const auto *F : ClassDecl->fields()) {
if (F->isInvalidDecl())
continue;
- if (CSM == Sema::CXXDefaultConstructor && F->hasInClassInitializer())
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
+ F->hasInClassInitializer())
continue;
QualType BaseType = S.Context.getBaseElementType(F->getType());
if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
@@ -7584,7 +7590,7 @@ static bool defaultedSpecialMemberIsConstexpr(
BaseType.getCVRQualifiers(),
ConstArg && !F->isMutable()))
return false;
- } else if (CSM == Sema::CXXDefaultConstructor) {
+ } else if (CSM == CXXSpecialMemberKind::DefaultConstructor) {
return false;
}
}
@@ -7615,9 +7621,10 @@ struct ComputingExceptionSpec {
}
static Sema::ImplicitExceptionSpecification
-ComputeDefaultedSpecialMemberExceptionSpec(
- Sema &S, SourceLocation Loc, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
- Sema::InheritedConstructorInfo *ICI);
+ComputeDefaultedSpecialMemberExceptionSpec(Sema &S, SourceLocation Loc,
+ CXXMethodDecl *MD,
+ CXXSpecialMemberKind CSM,
+ Sema::InheritedConstructorInfo *ICI);
static Sema::ImplicitExceptionSpecification
ComputeDefaultedComparisonExceptionSpec(Sema &S, SourceLocation Loc,
@@ -7641,7 +7648,7 @@ computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, FunctionDecl *FD) {
Sema::InheritedConstructorInfo ICI(
S, Loc, CD->getInheritedConstructor().getShadowDecl());
return ComputeDefaultedSpecialMemberExceptionSpec(
- S, Loc, CD, Sema::CXXDefaultConstructor, &ICI);
+ S, Loc, CD, CXXSpecialMemberKind::DefaultConstructor, &ICI);
}
static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S,
@@ -7693,11 +7700,11 @@ void Sema::CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *FD) {
}
bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
- CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
SourceLocation DefaultLoc) {
CXXRecordDecl *RD = MD->getParent();
- assert(MD->isExplicitlyDefaulted() && CSM != CXXInvalid &&
+ assert(MD->isExplicitlyDefaulted() && CSM != CXXSpecialMemberKind::Invalid &&
"not an explicitly-defaulted special member");
// Defer all checking for special members of a dependent type.
@@ -7723,21 +7730,22 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
bool DeleteOnTypeMismatch = getLangOpts().CPlusPlus20 && First;
bool ShouldDeleteForTypeMismatch = false;
unsigned ExpectedParams = 1;
- if (CSM == CXXDefaultConstructor || CSM == CXXDestructor)
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor ||
+ CSM == CXXSpecialMemberKind::Destructor)
ExpectedParams = 0;
if (MD->getNumExplicitParams() != ExpectedParams) {
// This checks for default arguments: a copy or move constructor with a
// default argument is classified as a default constructor, and assignment
// operations and destructors can't have default arguments.
Diag(MD->getLocation(), diag::err_defaulted_special_member_params)
- << CSM << MD->getSourceRange();
+ << llvm::to_underlying(CSM) << MD->getSourceRange();
HadError = true;
} else if (MD->isVariadic()) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
else {
Diag(MD->getLocation(), diag::err_defaulted_special_member_variadic)
- << CSM << MD->getSourceRange();
+ << llvm::to_underlying(CSM) << MD->getSourceRange();
HadError = true;
}
}
@@ -7745,13 +7753,14 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
const FunctionProtoType *Type = MD->getType()->castAs<FunctionProtoType>();
bool CanHaveConstParam = false;
- if (CSM == CXXCopyConstructor)
+ if (CSM == CXXSpecialMemberKind::CopyConstructor)
CanHaveConstParam = RD->implicitCopyConstructorHasConstParam();
- else if (CSM == CXXCopyAssignment)
+ else if (CSM == CXXSpecialMemberKind::CopyAssignment)
CanHaveConstParam = RD->implicitCopyAssignmentHasConstParam();
QualType ReturnType = Context.VoidTy;
- if (CSM == CXXCopyAssignment || CSM == CXXMoveAssignment) {
+ if (CSM == CXXSpecialMemberKind::CopyAssignment ||
+ CSM == CXXSpecialMemberKind::MoveAssignment) {
// Check for return type matching.
ReturnType = Type->getReturnType();
QualType ThisType = MD->getFunctionObjectParameterType();
@@ -7765,7 +7774,8 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
if (!Context.hasSameType(ReturnType, ExpectedReturnType)) {
Diag(MD->getLocation(), diag::err_defaulted_special_member_return_type)
- << (CSM == CXXMoveAssignment) << ExpectedReturnType;
+ << (CSM == CXXSpecialMemberKind::MoveAssignment)
+ << ExpectedReturnType;
HadError = true;
}
@@ -7775,7 +7785,8 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
ShouldDeleteForTypeMismatch = true;
else {
Diag(MD->getLocation(), diag::err_defaulted_special_member_quals)
- << (CSM == CXXMoveAssignment) << getLangOpts().CPlusPlus14;
+ << (CSM == CXXSpecialMemberKind::MoveAssignment)
+ << getLangOpts().CPlusPlus14;
HadError = true;
}
}
@@ -7793,7 +7804,8 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
else {
Diag(MD->getLocation(),
diag::err_defaulted_special_member_explicit_object_mismatch)
- << (CSM == CXXMoveAssignment) << RD << MD->getSourceRange();
+ << (CSM == CXXSpecialMemberKind::MoveAssignment) << RD
+ << MD->getSourceRange();
HadError = true;
}
}
@@ -7815,7 +7827,8 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
ShouldDeleteForTypeMismatch = true;
else {
Diag(MD->getLocation(),
- diag::err_defaulted_special_member_volatile_param) << CSM;
+ diag::err_defaulted_special_member_volatile_param)
+ << llvm::to_underlying(CSM);
HadError = true;
}
}
@@ -7823,23 +7836,25 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
if (HasConstParam && !CanHaveConstParam) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
- else if (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment) {
+ else if (CSM == CXXSpecialMemberKind::CopyConstructor ||
+ CSM == CXXSpecialMemberKind::CopyAssignment) {
Diag(MD->getLocation(),
diag::err_defaulted_special_member_copy_const_param)
- << (CSM == CXXCopyAssignment);
+ << (CSM == CXXSpecialMemberKind::CopyAssignment);
// FIXME: Explain why this special member can't be const.
HadError = true;
} else {
Diag(MD->getLocation(),
diag::err_defaulted_special_member_move_const_param)
- << (CSM == CXXMoveAssignment);
+ << (CSM == CXXSpecialMemberKind::MoveAssignment);
HadError = true;
}
}
} else if (ExpectedParams) {
// A copy assignment operator can take its argument by value, but a
// defaulted one cannot.
- assert(CSM == CXXCopyAssignment && "unexpected non-ref argument");
+ assert(CSM == CXXSpecialMemberKind::CopyAssignment &&
+ "unexpected non-ref argument");
Diag(MD->getLocation(), diag::err_defaulted_copy_assign_not_ref);
HadError = true;
}
@@ -7874,12 +7889,12 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
if (!MD->isConsteval() && RD->getNumVBases()) {
Diag(MD->getBeginLoc(),
diag::err_incorrect_defaulted_constexpr_with_vb)
- << CSM;
+ << llvm::to_underlying(CSM);
for (const auto &I : RD->vbases())
Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here);
} else {
Diag(MD->getBeginLoc(), diag::err_incorrect_defaulted_constexpr)
- << CSM << MD->isConsteval();
+ << llvm::to_underlying(CSM) << MD->isConsteval();
}
HadError = true;
// FIXME: Explain why the special member can't be constexpr.
@@ -7912,9 +7927,11 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
if (First) {
SetDeclDeleted(MD, MD->getLocation());
if (!inTemplateInstantiation() && !HadError) {
- Diag(MD->getLocation(), diag::warn_defaulted_method_deleted) << CSM;
+ Diag(MD->getLocation(), diag::warn_defaulted_method_deleted)
+ << llvm::to_underlying(CSM);
if (ShouldDeleteForTypeMismatch) {
- Diag(MD->getLocation(), diag::note_deleted_type_mismatch) << CSM;
+ Diag(MD->getLocation(), diag::note_deleted_type_mismatch)
+ << llvm::to_underlying(CSM);
} else if (ShouldDeleteSpecialMember(MD, CSM, nullptr,
/*Diagnose*/ true) &&
DefaultLoc.isValid()) {
@@ -7924,13 +7941,15 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
}
if (ShouldDeleteForTypeMismatch && !HadError) {
Diag(MD->getLocation(),
- diag::warn_cxx17_compat_defaulted_method_type_mismatch) << CSM;
+ diag::warn_cxx17_compat_defaulted_method_type_mismatch)
+ << llvm::to_underlying(CSM);
}
} else {
// C++11 [dcl.fct.def.default]p4:
// [For a] user-provided explicitly-defaulted function [...] if such a
// function is implicitly defined as deleted, the program is ill-formed.
- Diag(MD->getLocation(), diag::err_out_of_line_default_deletes) << CSM;
+ Diag(MD->getLocation(), diag::err_out_of_line_default_deletes)
+ << llvm::to_underlying(CSM);
assert(!ShouldDeleteForTypeMismatch && "deleted non-first decl");
ShouldDeleteSpecialMember(MD, CSM, nullptr, /*Diagnose*/true);
HadError = true;
@@ -9271,28 +9290,28 @@ template<typename Derived>
struct SpecialMemberVisitor {
Sema &S;
CXXMethodDecl *MD;
- Sema::CXXSpecialMember CSM;
+ CXXSpecialMemberKind CSM;
Sema::InheritedConstructorInfo *ICI;
// Properties of the special member, computed for convenience.
bool IsConstructor = false, IsAssignment = false, ConstArg = false;
- SpecialMemberVisitor(Sema &S, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
+ SpecialMemberVisitor(Sema &S, CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
Sema::InheritedConstructorInfo *ICI)
: S(S), MD(MD), CSM(CSM), ICI(ICI) {
switch (CSM) {
- case Sema::CXXDefaultConstructor:
- case Sema::CXXCopyConstructor:
- case Sema::CXXMoveConstructor:
+ case CXXSpecialMemberKind::DefaultConstructor:
+ case CXXSpecialMemberKind::CopyConstructor:
+ case CXXSpecialMemberKind::MoveConstructor:
IsConstructor = true;
break;
- case Sema::CXXCopyAssignment:
- case Sema::CXXMoveAssignment:
+ case CXXSpecialMemberKind::CopyAssignment:
+ case CXXSpecialMemberKind::MoveAssignment:
IsAssignment = true;
break;
- case Sema::CXXDestructor:
+ case CXXSpecialMemberKind::Destructor:
break;
- case Sema::CXXInvalid:
+ case CXXSpecialMemberKind::Invalid:
llvm_unreachable("invalid special member kind");
}
@@ -9307,7 +9326,8 @@ struct SpecialMemberVisitor {
/// Is this a "move" special member?
bool isMove() const {
- return CSM == Sema::CXXMoveConstructor || CSM == Sema::CXXMoveAssignment;
+ return CSM == CXXSpecialMemberKind::MoveConstructor ||
+ CSM == CXXSpecialMemberKind::MoveAssignment;
}
/// Look up the corresponding special member in the given class.
@@ -9322,7 +9342,7 @@ struct SpecialMemberVisitor {
Sema::SpecialMemberOverloadResult lookupInheritedCtor(CXXRecordDecl *Class) {
if (!ICI)
return {};
- assert(CSM == Sema::CXXDefaultConstructor);
+ assert(CSM == CXXSpecialMemberKind::DefaultConstructor);
auto *BaseCtor =
cast<CXXConstructorDecl>(MD)->getInheritedConstructor().getConstructor();
if (auto *MD = ICI->findConstructorForBase(Class, BaseCtor).first)
@@ -9392,15 +9412,15 @@ struct SpecialMemberDeletionInfo
bool AllFieldsAreConst;
SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
- Sema::CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
Sema::InheritedConstructorInfo *ICI, bool Diagnose)
: SpecialMemberVisitor(S, MD, CSM, ICI), Diagnose(Diagnose),
Loc(MD->getLocation()), AllFieldsAreConst(true) {}
bool inUnion() const { return MD->getParent()->isUnion(); }
- Sema::CXXSpecialMember getEffectiveCSM() {
- return ICI ? Sema::CXXInvalid : CSM;
+ CXXSpecialMemberKind getEffectiveCSM() {
+ return ICI ? CXXSpecialMemberKind::Invalid : CSM;
}
bool shouldDeleteForVariantObjCPtrMember(FieldDecl *FD, QualType FieldType);
@@ -9466,7 +9486,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
// must be accessible and non-deleted, but need not be trivial. Such a
// destructor is never actually called, but is semantically checked as
// if it were.
- if (CSM == Sema::CXXDefaultConstructor) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor) {
// [class.default.ctor]p2:
// A defaulted default constructor for class X is defined as deleted if
// - X is a union that has a variant member with a non-trivial default
@@ -9487,15 +9507,16 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
if (Field) {
S.Diag(Field->getLocation(),
diag::note_deleted_special_member_class_subobject)
- << getEffectiveCSM() << MD->getParent() << /*IsField*/true
- << Field << DiagKind << IsDtorCallInCtor << /*IsObjCPtr*/false;
+ << llvm::to_underlying(getEffectiveCSM()) << MD->getParent()
+ << /*IsField*/ true << Field << DiagKind << IsDtorCallInCtor
+ << /*IsObjCPtr*/ false;
} else {
CXXBaseSpecifier *Base = Subobj.get<CXXBaseSpecifier*>();
S.Diag(Base->getBeginLoc(),
diag::note_deleted_special_member_class_subobject)
- << getEffectiveCSM() << MD->getParent() << /*IsField*/ false
- << Base->getType() << DiagKind << IsDtorCallInCtor
- << /*IsObjCPtr*/false;
+ << llvm::to_underlying(getEffectiveCSM()) << MD->getParent()
+ << /*IsField*/ false << Base->getType() << DiagKind
+ << IsDtorCallInCtor << /*IsObjCPtr*/ false;
}
if (DiagKind == 1)
@@ -9527,8 +9548,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
// C++11 [class.dtor]p5:
// -- any direct or virtual base class [...] has a type with a destructor
// that is deleted or inaccessible
- if (!(CSM == Sema::CXXDefaultConstructor &&
- Field && Field->hasInClassInitializer()) &&
+ if (!(CSM == CXXSpecialMemberKind::DefaultConstructor && Field &&
+ Field->hasInClassInitializer()) &&
shouldDeleteForSubobjectCall(Subobj, lookupIn(Class, Quals, IsMutable),
false))
return true;
@@ -9538,8 +9559,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
// type with a destructor that is deleted or inaccessible
if (IsConstructor) {
Sema::SpecialMemberOverloadResult SMOR =
- S.LookupSpecialMember(Class, Sema::CXXDestructor,
- false, false, false, false, false);
+ S.LookupSpecialMember(Class, CXXSpecialMemberKind::Destructor, false,
+ false, false, false, false);
if (shouldDeleteForSubobjectCall(Subobj, SMOR, true))
return true;
}
@@ -9557,15 +9578,16 @@ bool SpecialMemberDeletionInfo::shouldDeleteForVariantObjCPtrMember(
// Don't make the defaulted default constructor defined as deleted if the
// member has an in-class initializer.
- if (CSM == Sema::CXXDefaultConstructor && FD->hasInClassInitializer())
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
+ FD->hasInClassInitializer())
return false;
if (Diagnose) {
auto *ParentClass = cast<CXXRecordDecl>(FD->getParent());
- S.Diag(FD->getLocation(),
- diag::note_deleted_special_member_class_subobject)
- << getEffectiveCSM() << ParentClass << /*IsField*/true
- << FD << 4 << /*IsDtorCallInCtor*/false << /*IsObjCPtr*/true;
+ S.Diag(FD->getLocation(), diag::note_deleted_special_member_class_subobject)
+ << llvm::to_underlying(getEffectiveCSM()) << ParentClass
+ << /*IsField*/ true << FD << 4 << /*IsDtorCallInCtor*/ false
+ << /*IsObjCPtr*/ true;
}
return true;
@@ -9590,9 +9612,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) {
if (BaseCtor->isDeleted() && Diagnose) {
S.Diag(Base->getBeginLoc(),
diag::note_deleted_special_member_class_subobject)
- << getEffectiveCSM() << MD->getParent() << /*IsField*/ false
- << Base->getType() << /*Deleted*/ 1 << /*IsDtorCallInCtor*/ false
- << /*IsObjCPtr*/false;
+ << llvm::to_underlying(getEffectiveCSM()) << MD->getParent()
+ << /*IsField*/ false << Base->getType() << /*Deleted*/ 1
+ << /*IsDtorCallInCtor*/ false << /*IsObjCPtr*/ false;
S.NoteDeletedFunction(BaseCtor);
}
return BaseCtor->isDeleted();
@@ -9609,7 +9631,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
if (inUnion() && shouldDeleteForVariantObjCPtrMember(FD, FieldType))
return true;
- if (CSM == Sema::CXXDefaultConstructor) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor) {
// For a default constructor, all references must be initialized in-class
// and, if a union, it must have a non-const member.
if (FieldType->isReferenceType() && !FD->hasInClassInitializer()) {
@@ -9632,7 +9654,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
if (inUnion() && !FieldType.isConstQualified())
AllFieldsAreConst = false;
- } else if (CSM == Sema::CXXCopyConstructor) {
+ } else if (CSM == CXXSpecialMemberKind::CopyConstructor) {
// For a copy constructor, data members must not be of rvalue reference
// type.
if (FieldType->isRValueReferenceType()) {
@@ -9683,8 +9705,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
}
// At least one member in each anonymous union must be non-const
- if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst &&
- !FieldRecord->field_empty()) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
+ AllVariantFieldsAreConst && !FieldRecord->field_empty()) {
if (Diagnose)
S.Diag(FieldRecord->getLocation(),
diag::note_deleted_default_ctor_all_const)
@@ -9712,7 +9734,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
// This is a silly definition, because it gives an empty union a deleted
// default constructor. Don't do that.
- if (CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor && inUnion() &&
+ AllFieldsAreConst) {
bool AnyFields = false;
for (auto *F : MD->getParent()->fields())
if ((AnyFields = !F->isUnnamedBitfield()))
@@ -9731,7 +9754,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
/// Determine whether a defaulted special member function should be defined as
/// deleted, as specified in C++11 [class.ctor]p5, C++11 [class.copy]p11,
/// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
-bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
+bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD,
+ CXXSpecialMemberKind CSM,
InheritedConstructorInfo *ICI,
bool Diagnose) {
if (MD->isInvalidDecl())
@@ -9748,7 +9772,8 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
// assignment operator.
// C++2a adds back these operators if the lambda has no lambda-capture.
if (RD->isLambda() && !RD->lambdaIsDefaultConstructibleAndAssignable() &&
- (CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment)) {
+ (CSM == CXXSpecialMemberKind::DefaultConstructor ||
+ CSM == CXXSpecialMemberKind::CopyAssignment)) {
if (Diagnose)
Diag(RD->getLocation(), diag::note_lambda_decl);
return true;
@@ -9757,16 +9782,16 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
// For an anonymous struct or union, the copy and assignment special members
// will never be used, so skip the check. For an anonymous union declared at
// namespace scope, the constructor and destructor are used.
- if (CSM != CXXDefaultConstructor && CSM != CXXDestructor &&
- RD->isAnonymousStructOrUnion())
+ if (CSM != CXXSpecialMemberKind::DefaultConstructor &&
+ CSM != CXXSpecialMemberKind::Destructor && RD->isAnonymousStructOrUnion())
return false;
// C++11 [class.copy]p7, p18:
// If the class definition declares a move constructor or move assignment
// operator, an implicitly declared copy constructor or copy assignment
// operator is defined as deleted.
- if (MD->isImplicit() &&
- (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)) {
+ if (MD->isImplicit() && (CSM == CXXSpecialMemberKind::CopyConstructor ||
+ CSM == CXXSpecialMemberKind::CopyAssignment)) {
CXXMethodDecl *UserDeclaredMove = nullptr;
// In Microsoft mode up to MSVC 2013, a user-declared move only causes the
@@ -9777,7 +9802,8 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015);
if (RD->hasUserDeclaredMoveConstructor() &&
- (!DeletesOnlyMatchingCopy || CSM == CXXCopyConstructor)) {
+ (!DeletesOnlyMatchingCopy ||
+ CSM == CXXSpecialMemberKind::CopyConstructor)) {
if (!Diagnose) return true;
// Find any user-declared move constructor.
@@ -9789,7 +9815,8 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
}
assert(UserDeclaredMove);
} else if (RD->hasUserDeclaredMoveAssignment() &&
- (!DeletesOnlyMatchingCopy || CSM == CXXCopyAssignment)) {
+ (!DeletesOnlyMatchingCopy ||
+ CSM == CXXSpecialMemberKind::CopyAssignment)) {
if (!Diagnose) return true;
// Find any user-declared move assignment operator.
@@ -9805,8 +9832,8 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
if (UserDeclaredMove) {
Diag(UserDeclaredMove->getLocation(),
diag::note_deleted_copy_user_declared_move)
- << (CSM == CXXCopyAssignment) << RD
- << UserDeclaredMove->isMoveAssignmentOperator();
+ << (CSM == CXXSpecialMemberKind::CopyAssignment) << RD
+ << UserDeclaredMove->isMoveAssignmentOperator();
return true;
}
}
@@ -9817,7 +9844,7 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
// C++11 [class.dtor]p5:
// -- for a virtual destructor, lookup of the non-array deallocation function
// results in an ambiguity or in a function that is deleted or inaccessible
- if (CSM == CXXDestructor && MD->isVirtual()) {
+ if (CSM == CXXSpecialMemberKind::Destructor && MD->isVirtual()) {
FunctionDecl *OperatorDelete = nullptr;
DeclarationName Name =
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
@@ -9891,7 +9918,7 @@ void Sema::DiagnoseDeletedDefaultedFunction(FunctionDecl *FD) {
/// If \p ForCall is true, look at CXXRecord::HasTrivialSpecialMembersForCall to
/// determine whether the special member is trivial.
static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
- Sema::CXXSpecialMember CSM, unsigned Quals,
+ CXXSpecialMemberKind CSM, unsigned Quals,
bool ConstRHS,
Sema::TrivialABIHandling TAH,
CXXMethodDecl **Selected) {
@@ -9899,10 +9926,10 @@ static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
*Selected = nullptr;
switch (CSM) {
- case Sema::CXXInvalid:
+ case CXXSpecialMemberKind::Invalid:
llvm_unreachable("not a special member");
- case Sema::CXXDefaultConstructor:
+ case CXXSpecialMemberKind::DefaultConstructor:
// C++11 [class.ctor]p5:
// A default constructor is trivial if:
// - all the [direct subobjects] have trivial default constructors
@@ -9931,7 +9958,7 @@ static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
return false;
- case Sema::CXXDestructor:
+ case CXXSpecialMemberKind::Destructor:
// C++11 [class.dtor]p5:
// A destructor is trivial if:
// - all the direct [subobjects] have trivial destructors
@@ -9948,7 +9975,7 @@ static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
return false;
- case Sema::CXXCopyConstructor:
+ case CXXSpecialMemberKind::CopyConstructor:
// C++11 [class.copy]p12:
// A copy constructor is trivial if:
// - the constructor selected to copy each direct [subobject] is trivial
@@ -9969,7 +9996,7 @@ static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
// struct B { mutable A a; };
goto NeedOverloadResolution;
- case Sema::CXXCopyAssignment:
+ case CXXSpecialMemberKind::CopyAssignment:
// C++11 [class.copy]p25:
// A copy assignment operator is trivial if:
// - the assignment operator selected to copy each direct [subobject] is
@@ -9984,8 +10011,8 @@ static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
// treat that as a language defect.
goto NeedOverloadResolution;
- case Sema::CXXMoveConstructor:
- case Sema::CXXMoveAssignment:
+ case CXXSpecialMemberKind::MoveConstructor:
+ case CXXSpecialMemberKind::MoveAssignment:
NeedOverloadResolution:
Sema::SpecialMemberOverloadResult SMOR =
lookupCallFromSpecialMember(S, RD, CSM, Quals, ConstRHS);
@@ -10009,7 +10036,8 @@ static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
*Selected = SMOR.getMethod();
if (TAH == Sema::TAH_ConsiderTrivialABI &&
- (CSM == Sema::CXXCopyConstructor || CSM == Sema::CXXMoveConstructor))
+ (CSM == CXXSpecialMemberKind::CopyConstructor ||
+ CSM == CXXSpecialMemberKind::MoveConstructor))
return SMOR.getMethod()->isTrivialForCall();
return SMOR.getMethod()->isTrivial();
}
@@ -10047,9 +10075,10 @@ enum TrivialSubobjectKind {
/// Check whether the special member selected for a given type would be trivial.
static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc,
QualType SubType, bool ConstRHS,
- Sema::CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
TrivialSubobjectKind Kind,
- Sema::TrivialABIHandling TAH, bool Diagnose) {
+ Sema::TrivialABIHandling TAH,
+ bool Diagnose) {
CXXRecordDecl *SubRD = SubType->getAsCXXRecordDecl();
if (!SubRD)
return true;
@@ -10063,27 +10092,28 @@ static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc,
if (ConstRHS)
SubType.addConst();
- if (!Selected && CSM == Sema::CXXDefaultConstructor) {
+ if (!Selected && CSM == CXXSpecialMemberKind::DefaultConstructor) {
S.Diag(SubobjLoc, diag::note_nontrivial_no_def_ctor)
<< Kind << SubType.getUnqualifiedType();
if (CXXConstructorDecl *CD = findUserDeclaredCtor(SubRD))
S.Diag(CD->getLocation(), diag::note_user_declared_ctor);
} else if (!Selected)
S.Diag(SubobjLoc, diag::note_nontrivial_no_copy)
- << Kind << SubType.getUnqualifiedType() << CSM << SubType;
+ << Kind << SubType.getUnqualifiedType() << llvm::to_underlying(CSM)
+ << SubType;
else if (Selected->isUserProvided()) {
if (Kind == TSK_CompleteObject)
S.Diag(Selected->getLocation(), diag::note_nontrivial_user_provided)
- << Kind << SubType.getUnqualifiedType() << CSM;
+ << Kind << SubType.getUnqualifiedType() << llvm::to_underlying(CSM);
else {
S.Diag(SubobjLoc, diag::note_nontrivial_user_provided)
- << Kind << SubType.getUnqualifiedType() << CSM;
+ << Kind << SubType.getUnqualifiedType() << llvm::to_underlying(CSM);
S.Diag(Selected->getLocation(), diag::note_declared_at);
}
} else {
if (Kind != TSK_CompleteObject)
S.Diag(SubobjLoc, diag::note_nontrivial_subobject)
- << Kind << SubType.getUnqualifiedType() << CSM;
+ << Kind << SubType.getUnqualifiedType() << llvm::to_underlying(CSM);
// Explain why the defaulted or deleted special member isn't trivial.
S.SpecialMemberIsTrivial(Selected, CSM, Sema::TAH_IgnoreTrivialABI,
@@ -10097,8 +10127,7 @@ static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc,
/// Check whether the members of a class type allow a special member to be
/// trivial.
static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD,
- Sema::CXXSpecialMember CSM,
- bool ConstArg,
+ CXXSpecialMemberKind CSM, bool ConstArg,
Sema::TrivialABIHandling TAH,
bool Diagnose) {
for (const auto *FI : RD->fields()) {
@@ -10119,7 +10148,8 @@ static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD,
// A default constructor is trivial if [...]
// -- no non-static data member of its class has a
// brace-or-equal-initializer
- if (CSM == Sema::CXXDefaultConstructor && FI->hasInClassInitializer()) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
+ FI->hasInClassInitializer()) {
if (Diagnose)
S.Diag(FI->getLocation(), diag::note_nontrivial_default_member_init)
<< FI;
@@ -10148,10 +10178,12 @@ static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD,
/// Diagnose why the specified class does not have a trivial special member of
/// the given kind.
-void Sema::DiagnoseNontrivial(const CXXRecordDecl *RD, CXXSpecialMember CSM) {
+void Sema::DiagnoseNontrivial(const CXXRecordDecl *RD,
+ CXXSpecialMemberKind CSM) {
QualType Ty = Context.getRecordType(RD);
- bool ConstArg = (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment);
+ bool ConstArg = (CSM == CXXSpecialMemberKind::CopyConstructor ||
+ CSM == CXXSpecialMemberKind::CopyAssignment);
checkTrivialSubobjectCall(*this, RD->getLocation(), Ty, ConstArg, CSM,
TSK_CompleteObject, TAH_IgnoreTrivialABI,
/*Diagnose*/true);
@@ -10160,9 +10192,10 @@ void Sema::DiagnoseNontrivial(const CXXRecordDecl *RD, CXXSpecialMember CSM) {
/// Determine whether a defaulted or deleted special member function is trivial,
/// as specified in C++11 [class.ctor]p5, C++11 [class.copy]p12,
/// C++11 [class.copy]p25, and C++11 [class.dtor]p5.
-bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
+bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
TrivialABIHandling TAH, bool Diagnose) {
- assert(!MD->isUserProvided() && CSM != CXXInvalid && "not special enough");
+ assert(!MD->isUserProvided() && CSM != CXXSpecialMemberKind::Invalid &&
+ "not special enough");
CXXRecordDecl *RD = MD->getParent();
@@ -10172,13 +10205,13 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
// A [special member] is trivial if [...] its parameter-type-list is
// equivalent to the parameter-type-list of an implicit declaration [...]
switch (CSM) {
- case CXXDefaultConstructor:
- case CXXDestructor:
+ case CXXSpecialMemberKind::DefaultConstructor:
+ case CXXSpecialMemberKind::Destructor:
// Trivial default constructors and destructors cannot have parameters.
break;
- case CXXCopyConstructor:
- case CXXCopyAssignment: {
+ case CXXSpecialMemberKind::CopyConstructor:
+ case CXXSpecialMemberKind::CopyAssignment: {
const ParmVarDecl *Param0 = MD->getNonObjectParameter(0);
const ReferenceType *RT = Param0->getType()->getAs<ReferenceType>();
@@ -10207,8 +10240,8 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
break;
}
- case CXXMoveConstructor:
- case CXXMoveAssignment: {
+ case CXXSpecialMemberKind::MoveConstructor:
+ case CXXSpecialMemberKind::MoveAssignment: {
// Trivial move operations always have non-cv-qualified parameters.
const ParmVarDecl *Param0 = MD->getNonObjectParameter(0);
const RValueReferenceType *RT =
@@ -10223,7 +10256,7 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
break;
}
- case CXXInvalid:
+ case CXXSpecialMemberKind::Invalid:
llvm_unreachable("not a special member");
}
@@ -10272,7 +10305,7 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
// C++11 [class.dtor]p5:
// A destructor is trivial if [...]
// -- the destructor is not virtual
- if (CSM == CXXDestructor && MD->isVirtual()) {
+ if (CSM == CXXSpecialMemberKind::Destructor && MD->isVirtual()) {
if (Diagnose)
Diag(MD->getLocation(), diag::note_nontrivial_virtual_dtor) << RD;
return false;
@@ -10281,7 +10314,8 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
// A [special member] for class X is trivial if [...]
// -- class X has no virtual functions and no virtual base classes
- if (CSM != CXXDestructor && MD->getParent()->isDynamicClass()) {
+ if (CSM != CXXSpecialMemberKind::Destructor &&
+ MD->getParent()->isDynamicClass()) {
if (!Diagnose)
return false;
@@ -13760,7 +13794,7 @@ struct SpecialMemberExceptionSpecInfo
Sema::ImplicitExceptionSpecification ExceptSpec;
SpecialMemberExceptionSpecInfo(Sema &S, CXXMethodDecl *MD,
- Sema::CXXSpecialMember CSM,
+ CXXSpecialMemberKind CSM,
Sema::InheritedConstructorInfo *ICI,
SourceLocation Loc)
: SpecialMemberVisitor(S, MD, CSM, ICI), Loc(Loc), ExceptSpec(S) {}
@@ -13793,7 +13827,8 @@ bool SpecialMemberExceptionSpecInfo::visitBase(CXXBaseSpecifier *Base) {
}
bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) {
- if (CSM == Sema::CXXDefaultConstructor && FD->hasInClassInitializer()) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
+ FD->hasInClassInitializer()) {
Expr *E = FD->getInClassInitializer();
if (!E)
// FIXME: It's a little wasteful to build and throw away a
@@ -13852,7 +13887,7 @@ ExplicitSpecifier Sema::ActOnExplicitBoolSpecifier(Expr *ExplicitExpr) {
static Sema::ImplicitExceptionSpecification
ComputeDefaultedSpecialMemberExceptionSpec(
- Sema &S, SourceLocation Loc, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
+ Sema &S, SourceLocation Loc, CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
Sema::InheritedConstructorInfo *ICI) {
ComputingExceptionSpec CES(S, MD, Loc);
@@ -13902,7 +13937,7 @@ struct DeclaringSpecialMember {
Sema::ContextRAII SavedContext;
bool WasAlreadyBeingDeclared;
- DeclaringSpecialMember(Sema &S, CXXRecordDecl *RD, Sema::CXXSpecialMember CSM)
+ DeclaringSpecialMember(Sema &S, CXXRecordDecl *RD, CXXSpecialMemberKind CSM)
: S(S), D(RD, CSM), SavedContext(S, RD) {
WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D).second;
if (WasAlreadyBeingDeclared)
@@ -13992,13 +14027,13 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
assert(ClassDecl->needsImplicitDefaultConstructor() &&
"Should not build implicit default constructor!");
- DeclaringSpecialMember DSM(*this, ClassDecl, CXXDefaultConstructor);
+ DeclaringSpecialMember DSM(*this, ClassDecl,
+ CXXSpecialMemberKind::DefaultConstructor);
if (DSM.isAlreadyBeingDeclared())
return nullptr;
- bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
- CXXDefaultConstructor,
- false);
+ bool Constexpr = defaultedSpecialMemberIsConstexpr(
+ *this, ClassDecl, CXXSpecialMemberKind::DefaultConstructor, false);
// Create the actual constructor declaration.
CanQualType ClassType
@@ -14020,10 +14055,10 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
setupImplicitSpecialMemberType(DefaultCon, Context.VoidTy, std::nullopt);
if (getLangOpts().CUDA)
- inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXDefaultConstructor,
- DefaultCon,
- /* ConstRHS */ false,
- /* Diagnose */ false);
+ inferCUDATargetForImplicitSpecialMember(
+ ClassDecl, CXXSpecialMemberKind::DefaultConstructor, DefaultCon,
+ /* ConstRHS */ false,
+ /* Diagnose */ false);
// We don't need to use SpecialMemberIsTrivial here; triviality for default
// constructors is easy to compute.
@@ -14035,7 +14070,8 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, DefaultCon);
- if (ShouldDeleteSpecialMember(DefaultCon, CXXDefaultConstructor))
+ if (ShouldDeleteSpecialMember(DefaultCon,
+ CXXSpecialMemberKind::DefaultConstructor))
SetDeclDeleted(DefaultCon, ClassLoc);
if (S)
@@ -14127,10 +14163,10 @@ Sema::findInheritingConstructor(SourceLocation Loc,
// from which it was inherited.
InheritedConstructorInfo ICI(*this, Loc, Shadow);
- bool Constexpr =
- BaseCtor->isConstexpr() &&
- defaultedSpecialMemberIsConstexpr(*this, Derived, CXXDefaultConstructor,
- false, BaseCtor, &ICI);
+ bool Constexpr = BaseCtor->isConstexpr() &&
+ defaultedSpecialMemberIsConstexpr(
+ *this, Derived, CXXSpecialMemberKind::DefaultConstructor,
+ false, BaseCtor, &ICI);
CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create(
Context, Derived, UsingLoc, NameInfo, TInfo->getType(), TInfo,
@@ -14174,7 +14210,8 @@ Sema::findInheritingConstructor(SourceLocation Loc,
DerivedCtor->setParams(ParamDecls);
Derived->addDecl(DerivedCtor);
- if (ShouldDeleteSpecialMember(DerivedCtor, CXXDefaultConstructor, &ICI))
+ if (ShouldDeleteSpecialMember(DerivedCtor,
+ CXXSpecialMemberKind::DefaultConstructor, &ICI))
SetDeclDeleted(DerivedCtor, UsingLoc);
return DerivedCtor;
@@ -14183,8 +14220,9 @@ Sema::findInheritingConstructor(SourceLocation Loc,
void Sema::NoteDeletedInheritingConstructor(CXXConstructorDecl *Ctor) {
InheritedConstructorInfo ICI(*this, Ctor->getLocation(),
Ctor->getInheritedConstructor().getShadowDecl());
- ShouldDeleteSpecialMember(Ctor, CXXDefaultConstructor, &ICI,
- /*Diagnose*/true);
+ ShouldDeleteSpecialMember(Ctor, CXXSpecialMemberKind::DefaultConstructor,
+ &ICI,
+ /*Diagnose*/ true);
}
void Sema::DefineInheritingConstructor(SourceLocation CurrentLocation,
@@ -14275,13 +14313,13 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
// inline public member of its class.
assert(ClassDecl->needsImplicitDestructor());
- DeclaringSpecialMember DSM(*this, ClassDecl, CXXDestructor);
+ DeclaringSpecialMember DSM(*this, ClassDecl,
+ CXXSpecialMemberKind::Destructor);
if (DSM.isAlreadyBeingDeclared())
return nullptr;
- bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
- CXXDestructor,
- false);
+ bool Constexpr = defaultedSpecialMemberIsConstexpr(
+ *this, ClassDecl, CXXSpecialMemberKind::Destructor, false);
// Create the actual destructor declaration.
CanQualType ClassType
@@ -14303,10 +14341,10 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
setupImplicitSpecialMemberType(Destructor, Context.VoidTy, std::nullopt);
if (getLangOpts().CUDA)
- inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXDestructor,
- Destructor,
- /* ConstRHS */ false,
- /* Diagnose */ false);
+ inferCUDATargetForImplicitSpecialMember(
+ ClassDecl, CXXSpecialMemberKind::Destructor, Destructor,
+ /* ConstRHS */ false,
+ /* Diagnose */ false);
// We don't need to use SpecialMemberIsTrivial here; triviality for
// destructors is easy to compute.
@@ -14324,7 +14362,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
// the definition of the class, because its validity depends on the alignment
// of the class. We'll check this from ActOnFields once the class is complete.
if (ClassDecl->isCompleteDefinition() &&
- ShouldDeleteSpecialMember(Destructor, CXXDestructor))
+ ShouldDeleteSpecialMember(Destructor, CXXSpecialMemberKind::Destructor))
SetDeclDeleted(Destructor, ClassLoc);
// Introduce this destructor into its scope.
@@ -14905,7 +14943,8 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
// operators taking an object instead of a reference are allowed.
assert(ClassDecl->needsImplicitCopyAssignment());
- DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyAssignment);
+ DeclaringSpecialMember DSM(*this, ClassDecl,
+ CXXSpecialMemberKind::CopyAssignment);
if (DSM.isAlreadyBeingDeclared())
return nullptr;
@@ -14922,9 +14961,8 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
ArgType = Context.getLValueReferenceType(ArgType);
- bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
- CXXCopyAssignment,
- Const);
+ bool Constexpr = defaultedSpecialMemberIsConstexpr(
+ *this, ClassDecl, CXXSpecialMemberKind::CopyAssignment, Const);
// An implicitly-declared copy assignment operator is an inline public
// member of its class.
@@ -14945,10 +14983,10 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
setupImplicitSpecialMemberType(CopyAssignment, RetType, ArgType);
if (getLangOpts().CUDA)
- inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXCopyAssignment,
- CopyAssignment,
- /* ConstRHS */ Const,
- /* Diagnose */ false);
+ inferCUDATargetForImplicitSpecialMember(
+ ClassDecl, CXXSpecialMemberKind::CopyAssignment, CopyAssignment,
+ /* ConstRHS */ Const,
+ /* Diagnose */ false);
// Add the parameter to the operator.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment,
@@ -14959,9 +14997,10 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
CopyAssignment->setParams(FromParam);
CopyAssignment->setTrivial(
- ClassDecl->needsOverloadResolutionForCopyAssignment()
- ? SpecialMemberIsTrivial(CopyAssignment, CXXCopyAssignment)
- : ClassDecl->hasTrivialCopyAssignment());
+ ClassDecl->needsOverloadResolutionForCopyAssignment()
+ ? SpecialMemberIsTrivial(CopyAssignment,
+ CXXSpecialMemberKind::CopyAssignment)
+ : ClassDecl->hasTrivialCopyAssignment());
// Note that we have added this copy-assignment operator.
++getASTContext().NumImplicitCopyAssignmentOperatorsDeclared;
@@ -14969,7 +15008,8 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyAssignment);
- if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) {
+ if (ShouldDeleteSpecialMember(CopyAssignment,
+ CXXSpecialMemberKind::CopyAssignment)) {
ClassDecl->setImplicitCopyAssignmentIsDeleted();
SetDeclDeleted(CopyAssignment, ClassLoc);
}
@@ -15256,7 +15296,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
assert(ClassDecl->needsImplicitMoveAssignment());
- DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveAssignment);
+ DeclaringSpecialMember DSM(*this, ClassDecl,
+ CXXSpecialMemberKind::MoveAssignment);
if (DSM.isAlreadyBeingDeclared())
return nullptr;
@@ -15272,9 +15313,8 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
QualType RetType = Context.getLValueReferenceType(ArgType);
ArgType = Context.getRValueReferenceType(ArgType);
- bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
- CXXMoveAssignment,
- false);
+ bool Constexpr = defaultedSpecialMemberIsConstexpr(
+ *this, ClassDecl, CXXSpecialMemberKind::MoveAssignment, false);
// An implicitly-declared move assignment operator is an inline public
// member of its class.
@@ -15295,10 +15335,10 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
setupImplicitSpecialMemberType(MoveAssignment, RetType, ArgType);
if (getLangOpts().CUDA)
- inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXMoveAssignment,
- MoveAssignment,
- /* ConstRHS */ false,
- /* Diagnose */ false);
+ inferCUDATargetForImplicitSpecialMember(
+ ClassDecl, CXXSpecialMemberKind::MoveAssignment, MoveAssignment,
+ /* ConstRHS */ false,
+ /* Diagnose */ false);
// Add the parameter to the operator.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveAssignment,
@@ -15309,9 +15349,10 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
MoveAssignment->setParams(FromParam);
MoveAssignment->setTrivial(
- ClassDecl->needsOverloadResolutionForMoveAssignment()
- ? SpecialMemberIsTrivial(MoveAssignment, CXXMoveAssignment)
- : ClassDecl->hasTrivialMoveAssignment());
+ ClassDecl->needsOverloadResolutionForMoveAssignment()
+ ? SpecialMemberIsTrivial(MoveAssignment,
+ CXXSpecialMemberKind::MoveAssignment)
+ : ClassDecl->hasTrivialMoveAssignment());
// Note that we have added this copy-assignment operator.
++getASTContext().NumImplicitMoveAssignmentOperatorsDeclared;
@@ -15319,7 +15360,8 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, MoveAssignment);
- if (ShouldDeleteSpecialMember(MoveAssignment, CXXMoveAssignment)) {
+ if (ShouldDeleteSpecialMember(MoveAssignment,
+ CXXSpecialMemberKind::MoveAssignment)) {
ClassDecl->setImplicitMoveAssignmentIsDeleted();
SetDeclDeleted(MoveAssignment, ClassLoc);
}
@@ -15368,10 +15410,10 @@ static void checkMoveAssignmentForRepeatedMove(Sema &S, CXXRecordDecl *Class,
// If we're not actually going to call a move assignment for this base,
// or the selected move assignment is trivial, skip it.
Sema::SpecialMemberOverloadResult SMOR =
- S.LookupSpecialMember(Base, Sema::CXXMoveAssignment,
- /*ConstArg*/false, /*VolatileArg*/false,
- /*RValueThis*/true, /*ConstThis*/false,
- /*VolatileThis*/false);
+ S.LookupSpecialMember(Base, CXXSpecialMemberKind::MoveAssignment,
+ /*ConstArg*/ false, /*VolatileArg*/ false,
+ /*RValueThis*/ true, /*ConstThis*/ false,
+ /*VolatileThis*/ false);
if (!SMOR.getMethod() || SMOR.getMethod()->isTrivial() ||
!SMOR.getMethod()->isMoveAssignmentOperator())
continue;
@@ -15648,7 +15690,8 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
// constructor, one is declared implicitly.
assert(ClassDecl->needsImplicitCopyConstructor());
- DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyConstructor);
+ DeclaringSpecialMember DSM(*this, ClassDecl,
+ CXXSpecialMemberKind::CopyConstructor);
if (DSM.isAlreadyBeingDeclared())
return nullptr;
@@ -15666,9 +15709,8 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
ArgType = Context.getLValueReferenceType(ArgType);
- bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
- CXXCopyConstructor,
- Const);
+ bool Constexpr = defaultedSpecialMemberIsConstexpr(
+ *this, ClassDecl, CXXSpecialMemberKind::CopyConstructor, Const);
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(
@@ -15691,10 +15733,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
setupImplicitSpecialMemberType(CopyConstructor, Context.VoidTy, ArgType);
if (getLangOpts().CUDA)
- inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXCopyConstructor,
- CopyConstructor,
- /* ConstRHS */ Const,
- /* Diagnose */ false);
+ inferCUDATargetForImplicitSpecialMember(
+ ClassDecl, CXXSpecialMemberKind::CopyConstructor, CopyConstructor,
+ /* ConstRHS */ Const,
+ /* Diagnose */ false);
// During template instantiation of special member functions we need a
// reliable TypeSourceInfo for the parameter types in order to allow functions
@@ -15712,14 +15754,16 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
CopyConstructor->setTrivial(
ClassDecl->needsOverloadResolutionForCopyConstructor()
- ? SpecialMemberIsTrivial(CopyConstructor, CXXCopyConstructor)
+ ? SpecialMemberIsTrivial(CopyConstructor,
+ CXXSpecialMemberKind::CopyConstructor)
: ClassDecl->hasTrivialCopyConstructor());
CopyConstructor->setTrivialForCall(
ClassDecl->hasAttr<TrivialABIAttr>() ||
(ClassDecl->needsOverloadResolutionForCopyConstructor()
- ? SpecialMemberIsTrivial(CopyConstructor, CXXCopyConstructor,
- TAH_ConsiderTrivialABI)
+ ? SpecialMemberIsTrivial(CopyConstructor,
+ CXXSpecialMemberKind::CopyConstructor,
+ TAH_ConsiderTrivialABI)
: ClassDecl->hasTrivialCopyConstructorForCall()));
// Note that we have declared this constructor.
@@ -15728,7 +15772,8 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyConstructor);
- if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) {
+ if (ShouldDeleteSpecialMember(CopyConstructor,
+ CXXSpecialMemberKind::CopyConstructor)) {
ClassDecl->setImplicitCopyConstructorIsDeleted();
SetDeclDeleted(CopyConstructor, ClassLoc);
}
@@ -15793,7 +15838,8 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
CXXRecordDecl *ClassDecl) {
assert(ClassDecl->needsImplicitMoveConstructor());
- DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveConstructor);
+ DeclaringSpecialMember DSM(*this, ClassDecl,
+ CXXSpecialMemberKind::MoveConstructor);
if (DSM.isAlreadyBeingDeclared())
return nullptr;
@@ -15807,9 +15853,8 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
ArgType = Context.getAddrSpaceQualType(ClassType, AS);
ArgType = Context.getRValueReferenceType(ArgType);
- bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
- CXXMoveConstructor,
- false);
+ bool Constexpr = defaultedSpecialMemberIsConstexpr(
+ *this, ClassDecl, CXXSpecialMemberKind::MoveConstructor, false);
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(
@@ -15833,10 +15878,10 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
setupImplicitSpecialMemberType(MoveConstructor, Context.VoidTy, ArgType);
if (getLangOpts().CUDA)
- inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXMoveConstructor,
- MoveConstructor,
- /* ConstRHS */ false,
- /* Diagnose */ false);
+ inferCUDATargetForImplicitSpecialMember(
+ ClassDecl, CXXSpecialMemberKind::MoveConstructor, MoveConstructor,
+ /* ConstRHS */ false,
+ /* Diagnose */ false);
// Add the parameter to the constructor.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveConstructor,
@@ -15848,13 +15893,15 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
MoveConstructor->setTrivial(
ClassDecl->needsOverloadResolutionForMoveConstructor()
- ? SpecialMemberIsTrivial(MoveConstructor, CXXMoveConstructor)
+ ? SpecialMemberIsTrivial(MoveConstructor,
+ CXXSpecialMemberKind::MoveConstructor)
: ClassDecl->hasTrivialMoveConstructor());
MoveConstructor->setTrivialForCall(
ClassDecl->hasAttr<TrivialABIAttr>() ||
(ClassDecl->needsOverloadResolutionForMoveConstructor()
- ? SpecialMemberIsTrivial(MoveConstructor, CXXMoveConstructor,
+ ? SpecialMemberIsTrivial(MoveConstructor,
+ CXXSpecialMemberKind::MoveConstructor,
TAH_ConsiderTrivialABI)
: ClassDecl->hasTrivialMoveConstructorForCall()));
@@ -15864,7 +15911,8 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, MoveConstructor);
- if (ShouldDeleteSpecialMember(MoveConstructor, CXXMoveConstructor)) {
+ if (ShouldDeleteSpecialMember(MoveConstructor,
+ CXXSpecialMemberKind::MoveConstructor)) {
ClassDecl->setImplicitMoveConstructorIsDeleted();
SetDeclDeleted(MoveConstructor, ClassLoc);
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index a75e9925a43146..6b8ce0f633a3ea 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -31,6 +31,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -10023,8 +10024,9 @@ bool InitializationSequence::Diagnose(Sema &S,
// implicit.
if (S.isImplicitlyDeleted(Best->Function))
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
- << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function))
- << DestType << ArgsRange;
+ << llvm::to_underlying(
+ S.getSpecialMember(cast<CXXMethodDecl>(Best->Function)))
+ << DestType << ArgsRange;
else
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
<< DestType << ArgsRange;
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 38237ee578079d..d65f52b8efe81f 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -37,6 +37,7 @@
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TypoCorrection.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/edit_distance.h"
@@ -3341,21 +3342,20 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
Functions.append(Operators.begin(), Operators.end());
}
-Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
- CXXSpecialMember SM,
- bool ConstArg,
- bool VolatileArg,
- bool RValueThis,
- bool ConstThis,
- bool VolatileThis) {
+Sema::SpecialMemberOverloadResult
+Sema::LookupSpecialMember(CXXRecordDecl *RD, CXXSpecialMemberKind SM,
+ bool ConstArg, bool VolatileArg, bool RValueThis,
+ bool ConstThis, bool VolatileThis) {
assert(CanDeclareSpecialMemberFunction(RD) &&
"doing special member lookup into record that isn't fully complete");
RD = RD->getDefinition();
if (RValueThis || ConstThis || VolatileThis)
- assert((SM == CXXCopyAssignment || SM == CXXMoveAssignment) &&
+ assert((SM == CXXSpecialMemberKind::CopyAssignment ||
+ SM == CXXSpecialMemberKind::MoveAssignment) &&
"constructors and destructors always have unqualified lvalue this");
if (ConstArg || VolatileArg)
- assert((SM != CXXDefaultConstructor && SM != CXXDestructor) &&
+ assert((SM != CXXSpecialMemberKind::DefaultConstructor &&
+ SM != CXXSpecialMemberKind::Destructor) &&
"parameter-less special members can't have qualified arguments");
// FIXME: Get the caller to pass in a location for the lookup.
@@ -3363,7 +3363,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
llvm::FoldingSetNodeID ID;
ID.AddPointer(RD);
- ID.AddInteger(SM);
+ ID.AddInteger(llvm::to_underlying(SM));
ID.AddInteger(ConstArg);
ID.AddInteger(VolatileArg);
ID.AddInteger(RValueThis);
@@ -3382,7 +3382,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
Result = new (Result) SpecialMemberOverloadResultEntry(ID);
SpecialMemberCache.InsertNode(Result, InsertPoint);
- if (SM == CXXDestructor) {
+ if (SM == CXXSpecialMemberKind::Destructor) {
if (RD->needsImplicitDestructor()) {
runWithSufficientStackSpace(RD->getLocation(), [&] {
DeclareImplicitDestructor(RD);
@@ -3406,7 +3406,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
QualType ArgType = CanTy;
ExprValueKind VK = VK_LValue;
- if (SM == CXXDefaultConstructor) {
+ if (SM == CXXSpecialMemberKind::DefaultConstructor) {
Name = Context.DeclarationNames.getCXXConstructorName(CanTy);
NumArgs = 0;
if (RD->needsImplicitDefaultConstructor()) {
@@ -3415,7 +3415,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
});
}
} else {
- if (SM == CXXCopyConstructor || SM == CXXMoveConstructor) {
+ if (SM == CXXSpecialMemberKind::CopyConstructor ||
+ SM == CXXSpecialMemberKind::MoveConstructor) {
Name = Context.DeclarationNames.getCXXConstructorName(CanTy);
if (RD->needsImplicitCopyConstructor()) {
runWithSufficientStackSpace(RD->getLocation(), [&] {
@@ -3453,7 +3454,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
// Possibly an XValue is actually correct in the case of move, but
// there is no semantic
diff erence for class types in this restricted
// case.
- if (SM == CXXCopyConstructor || SM == CXXCopyAssignment)
+ if (SM == CXXSpecialMemberKind::CopyConstructor ||
+ SM == CXXSpecialMemberKind::CopyAssignment)
VK = VK_LValue;
else
VK = VK_PRValue;
@@ -3461,7 +3463,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
- if (SM != CXXDefaultConstructor) {
+ if (SM != CXXSpecialMemberKind::DefaultConstructor) {
NumArgs = 1;
Arg = &FakeArg;
}
@@ -3487,7 +3489,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
// type, rather than because there's some other declared constructor.
// Every class has a copy/move constructor, copy/move assignment, and
// destructor.
- assert(SM == CXXDefaultConstructor &&
+ assert(SM == CXXSpecialMemberKind::DefaultConstructor &&
"lookup for a constructor or assignment operator was empty");
Result->setMethod(nullptr);
Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
@@ -3505,7 +3507,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
DeclAccessPair Cand = DeclAccessPair::make(CandDecl, AS_public);
auto CtorInfo = getConstructorInfo(Cand);
if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) {
- if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
+ if (SM == CXXSpecialMemberKind::CopyAssignment ||
+ SM == CXXSpecialMemberKind::MoveAssignment)
AddMethodCandidate(M, Cand, RD, ThisTy, Classification,
llvm::ArrayRef(&Arg, NumArgs), OCS, true);
else if (CtorInfo)
@@ -3517,7 +3520,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
/*SuppressUserConversions*/ true);
} else if (FunctionTemplateDecl *Tmpl =
dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) {
- if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
+ if (SM == CXXSpecialMemberKind::CopyAssignment ||
+ SM == CXXSpecialMemberKind::MoveAssignment)
AddMethodTemplateCandidate(Tmpl, Cand, RD, nullptr, ThisTy,
Classification,
llvm::ArrayRef(&Arg, NumArgs), OCS, true);
@@ -3563,8 +3567,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
/// Look up the default constructor for the given class.
CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) {
SpecialMemberOverloadResult Result =
- LookupSpecialMember(Class, CXXDefaultConstructor, false, false, false,
- false, false);
+ LookupSpecialMember(Class, CXXSpecialMemberKind::DefaultConstructor,
+ false, false, false, false, false);
return cast_or_null<CXXConstructorDecl>(Result.getMethod());
}
@@ -3574,9 +3578,9 @@ CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class,
unsigned Quals) {
assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
"non-const, non-volatile qualifiers for copy ctor arg");
- SpecialMemberOverloadResult Result =
- LookupSpecialMember(Class, CXXCopyConstructor, Quals & Qualifiers::Const,
- Quals & Qualifiers::Volatile, false, false, false);
+ SpecialMemberOverloadResult Result = LookupSpecialMember(
+ Class, CXXSpecialMemberKind::CopyConstructor, Quals & Qualifiers::Const,
+ Quals & Qualifiers::Volatile, false, false, false);
return cast_or_null<CXXConstructorDecl>(Result.getMethod());
}
@@ -3584,9 +3588,9 @@ CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class,
/// Look up the moving constructor for the given class.
CXXConstructorDecl *Sema::LookupMovingConstructor(CXXRecordDecl *Class,
unsigned Quals) {
- SpecialMemberOverloadResult Result =
- LookupSpecialMember(Class, CXXMoveConstructor, Quals & Qualifiers::Const,
- Quals & Qualifiers::Volatile, false, false, false);
+ SpecialMemberOverloadResult Result = LookupSpecialMember(
+ Class, CXXSpecialMemberKind::MoveConstructor, Quals & Qualifiers::Const,
+ Quals & Qualifiers::Volatile, false, false, false);
return cast_or_null<CXXConstructorDecl>(Result.getMethod());
}
@@ -3618,11 +3622,10 @@ CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class,
"non-const, non-volatile qualifiers for copy assignment arg");
assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
"non-const, non-volatile qualifiers for copy assignment this");
- SpecialMemberOverloadResult Result =
- LookupSpecialMember(Class, CXXCopyAssignment, Quals & Qualifiers::Const,
- Quals & Qualifiers::Volatile, RValueThis,
- ThisQuals & Qualifiers::Const,
- ThisQuals & Qualifiers::Volatile);
+ SpecialMemberOverloadResult Result = LookupSpecialMember(
+ Class, CXXSpecialMemberKind::CopyAssignment, Quals & Qualifiers::Const,
+ Quals & Qualifiers::Volatile, RValueThis, ThisQuals & Qualifiers::Const,
+ ThisQuals & Qualifiers::Volatile);
return Result.getMethod();
}
@@ -3634,11 +3637,10 @@ CXXMethodDecl *Sema::LookupMovingAssignment(CXXRecordDecl *Class,
unsigned ThisQuals) {
assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
"non-const, non-volatile qualifiers for copy assignment this");
- SpecialMemberOverloadResult Result =
- LookupSpecialMember(Class, CXXMoveAssignment, Quals & Qualifiers::Const,
- Quals & Qualifiers::Volatile, RValueThis,
- ThisQuals & Qualifiers::Const,
- ThisQuals & Qualifiers::Volatile);
+ SpecialMemberOverloadResult Result = LookupSpecialMember(
+ Class, CXXSpecialMemberKind::MoveAssignment, Quals & Qualifiers::Const,
+ Quals & Qualifiers::Volatile, RValueThis, ThisQuals & Qualifiers::Const,
+ ThisQuals & Qualifiers::Volatile);
return Result.getMethod();
}
@@ -3651,8 +3653,8 @@ CXXMethodDecl *Sema::LookupMovingAssignment(CXXRecordDecl *Class,
/// \returns The destructor for this class.
CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) {
return cast_or_null<CXXDestructorDecl>(
- LookupSpecialMember(Class, CXXDestructor, false, false, false, false,
- false)
+ LookupSpecialMember(Class, CXXSpecialMemberKind::Destructor, false, false,
+ false, false, false)
.getMethod());
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 3808af37ff54a8..1f674dd4bb0fbd 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -36,6 +36,7 @@
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -11955,25 +11956,25 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {
CXXMethodDecl *Meth = dyn_cast<CXXMethodDecl>(Callee);
if (Meth != nullptr && Meth->isImplicit()) {
CXXRecordDecl *ParentClass = Meth->getParent();
- Sema::CXXSpecialMember CSM;
+ CXXSpecialMemberKind CSM;
switch (FnKindPair.first) {
default:
return;
case oc_implicit_default_constructor:
- CSM = Sema::CXXDefaultConstructor;
+ CSM = CXXSpecialMemberKind::DefaultConstructor;
break;
case oc_implicit_copy_constructor:
- CSM = Sema::CXXCopyConstructor;
+ CSM = CXXSpecialMemberKind::CopyConstructor;
break;
case oc_implicit_move_constructor:
- CSM = Sema::CXXMoveConstructor;
+ CSM = CXXSpecialMemberKind::MoveConstructor;
break;
case oc_implicit_copy_assignment:
- CSM = Sema::CXXCopyAssignment;
+ CSM = CXXSpecialMemberKind::CopyAssignment;
break;
case oc_implicit_move_assignment:
- CSM = Sema::CXXMoveAssignment;
+ CSM = CXXSpecialMemberKind::MoveAssignment;
break;
};
@@ -15064,7 +15065,8 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
DefaultedFunctionKind DFK = getDefaultedFunctionKind(DeletedFD);
if (DFK.isSpecialMember()) {
Diag(OpLoc, diag::err_ovl_deleted_special_oper)
- << Args[0]->getType() << DFK.asSpecialMember();
+ << Args[0]->getType()
+ << llvm::to_underlying(DFK.asSpecialMember());
} else {
assert(DFK.isComparison());
Diag(OpLoc, diag::err_ovl_deleted_comparison)
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index a265fd1c46a63e..7cd428de0bb32d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -36,6 +36,7 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
@@ -1142,7 +1143,8 @@ void Sema::PrintInstantiationStack() {
case CodeSynthesisContext::DeclaringSpecialMember:
Diags.Report(Active->PointOfInstantiation,
diag::note_in_declaration_of_implicit_special_member)
- << cast<CXXRecordDecl>(Active->Entity) << Active->SpecialMember;
+ << cast<CXXRecordDecl>(Active->Entity)
+ << llvm::to_underlying(Active->SpecialMember);
break;
case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
@@ -1160,7 +1162,8 @@ void Sema::PrintInstantiationStack() {
auto *MD = cast<CXXMethodDecl>(FD);
Diags.Report(Active->PointOfInstantiation,
diag::note_member_synthesized_at)
- << MD->isExplicitlyDefaulted() << DFK.asSpecialMember()
+ << MD->isExplicitlyDefaulted()
+ << llvm::to_underlying(DFK.asSpecialMember())
<< Context.getTagDeclType(MD->getParent());
} else if (DFK.isComparison()) {
QualType RecordType = FD->getParamDecl(0)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 707446e132094f..7f510d34d671ee 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5123,10 +5123,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
assert(PatternDecl->isDefaulted() &&
"Special member needs to be defaulted");
auto PatternSM = getDefaultedFunctionKind(PatternDecl).asSpecialMember();
- if (!(PatternSM == Sema::CXXCopyConstructor ||
- PatternSM == Sema::CXXCopyAssignment ||
- PatternSM == Sema::CXXMoveConstructor ||
- PatternSM == Sema::CXXMoveAssignment))
+ if (!(PatternSM == CXXSpecialMemberKind::CopyConstructor ||
+ PatternSM == CXXSpecialMemberKind::CopyAssignment ||
+ PatternSM == CXXSpecialMemberKind::MoveConstructor ||
+ PatternSM == CXXSpecialMemberKind::MoveAssignment))
return;
auto *NewRec = dyn_cast<CXXRecordDecl>(Function->getDeclContext());
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 8762744396f4dd..b8a1518fbe00aa 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9738,7 +9738,8 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
: diag::note_non_literal_nontrivial_dtor)
<< RD;
if (!Dtor->isUserProvided())
- SpecialMemberIsTrivial(Dtor, CXXDestructor, TAH_IgnoreTrivialABI,
+ SpecialMemberIsTrivial(Dtor, CXXSpecialMemberKind::Destructor,
+ TAH_IgnoreTrivialABI,
/*Diagnose*/ true);
}
}
More information about the cfe-commits
mailing list