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); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits