https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/138139
Reverts llvm/llvm-project#138089 due to `std::underlying_type` being SFINAE-unfriendly in Clang and GCC before 9. Buildbot failure https://lab.llvm.org/buildbot/#/builders/134/builds/17904 >From 08f8efd49c7043fc8bda811041168106009612e9 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 1 May 2025 18:10:57 +0400 Subject: [PATCH] Revert "[clang] Add scoped enum support to `StreamingDiagnostic` (#138089)" This reverts commit 001cc34275111df842edbaa874b7319eef930c81. --- clang/include/clang/Basic/Diagnostic.h | 16 ----- clang/include/clang/Sema/Sema.h | 11 ++++ clang/lib/AST/ODRDiagsEmitter.cpp | 6 +- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- clang/lib/Parse/ParsePragma.cpp | 3 +- clang/lib/Parse/Parser.cpp | 2 +- clang/lib/Sema/SemaAccess.cpp | 9 ++- clang/lib/Sema/SemaCUDA.cpp | 17 ++--- clang/lib/Sema/SemaChecking.cpp | 8 ++- clang/lib/Sema/SemaDecl.cpp | 27 ++++---- clang/lib/Sema/SemaDeclAttr.cpp | 2 +- clang/lib/Sema/SemaDeclCXX.cpp | 62 ++++++++++--------- clang/lib/Sema/SemaDeclObjC.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 18 +++--- clang/lib/Sema/SemaExprCXX.cpp | 2 +- clang/lib/Sema/SemaInit.cpp | 3 +- clang/lib/Sema/SemaOverload.cpp | 5 +- clang/lib/Sema/SemaStmt.cpp | 2 +- clang/lib/Sema/SemaTemplate.cpp | 8 ++- clang/lib/Sema/SemaTemplateInstantiate.cpp | 5 +- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +- clang/lib/Sema/SemaType.cpp | 2 +- clang/lib/Sema/TreeTransform.h | 8 ++- llvm/include/llvm/ADT/STLForwardCompat.h | 4 -- 25 files changed, 125 insertions(+), 105 deletions(-) diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 92ab61b95a7c6..19524856a9bb3 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -1429,22 +1429,6 @@ operator<<(const StreamingDiagnostic &DB, T *DC) { return DB; } -// Convert scope enums to their underlying type, so that we don't have -// clutter the emitting code with `llvm::to_underlying()`. -// We also need to disable implicit conversion for the first argument, -// because classes that derive from StreamingDiagnostic define their own -// templated operator<< that accept a wide variety of types, leading -// to ambiguity. -template <typename T, typename U> -inline std::enable_if_t< - std::is_same_v<std::remove_const_t<T>, StreamingDiagnostic> && - llvm::is_scoped_enum_v<std::remove_reference_t<U>>, - const StreamingDiagnostic &> -operator<<(const T &DB, U &&SE) { - DB << llvm::to_underlying(SE); - return DB; -} - inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, SourceLocation L) { DB.AddSourceRange(CharSourceRange::getTokenRange(L)); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 003583f84cf97..28313f45b1228 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -220,6 +220,11 @@ enum class AssignmentAction { Casting, Passing_CFAudited }; +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + const AssignmentAction &AA) { + DB << llvm::to_underlying(AA); + return DB; +} namespace threadSafety { class BeforeSet; @@ -15466,6 +15471,12 @@ void Sema::PragmaStack<Sema::AlignPackInfo>::Act(SourceLocation PragmaLocation, llvm::StringRef StackSlotLabel, AlignPackInfo Value); +inline const StreamingDiagnostic & +operator<<(const StreamingDiagnostic &DB, Sema::StringEvaluationContext Ctx) { + DB << llvm::to_underlying(Ctx); + return DB; +} + } // end namespace clang #endif diff --git a/clang/lib/AST/ODRDiagsEmitter.cpp b/clang/lib/AST/ODRDiagsEmitter.cpp index 74f3881ed3c96..37f0f68c92355 100644 --- a/clang/lib/AST/ODRDiagsEmitter.cpp +++ b/clang/lib/AST/ODRDiagsEmitter.cpp @@ -461,8 +461,10 @@ bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod( } if (FirstMethod->getImplementationControl() != SecondMethod->getImplementationControl()) { - DiagError(ControlLevel) << FirstMethod->getImplementationControl(); - DiagNote(ControlLevel) << SecondMethod->getImplementationControl(); + DiagError(ControlLevel) + << llvm::to_underlying(FirstMethod->getImplementationControl()); + DiagNote(ControlLevel) << llvm::to_underlying( + SecondMethod->getImplementationControl()); return true; } if (FirstMethod->isThisDeclarationADesignatedInitializer() != diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index cd6464678c4b5..9dd9d9c637592 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2578,7 +2578,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate && D.isFirstDeclarator()) { Diag(CommaLoc, diag::err_multiple_template_declarators) - << TemplateInfo.Kind; + << llvm::to_underlying(TemplateInfo.Kind); } // Parse the next declarator. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 7e0a8af07a3be..8dfc0fa53dd88 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3472,7 +3472,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration( if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate && DeclaratorInfo.isFirstDeclarator()) { Diag(CommaLoc, diag::err_multiple_template_declarators) - << TemplateInfo.Kind; + << llvm::to_underlying(TemplateInfo.Kind); } // Parse the next declarator. diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 9f9e4bb92af8c..026a35639abdf 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -2341,8 +2341,7 @@ void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP, SourceLocation PragmaLocation = Tok.getLocation(); PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text'] if (Tok.isNot(tok::equal)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) - << SecKind; + PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << llvm::to_underlying(SecKind); return; } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index ec87317897200..120d44238ea35 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -226,7 +226,7 @@ void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) { if (Kind != ExtraSemiKind::AfterMemberFunctionDefinition || HadMultipleSemis) Diag(StartLoc, diag::ext_extra_semi) - << Kind + << llvm::to_underlying(Kind) << DeclSpec::getSpecifierName( TST, Actions.getASTContext().getPrintingPolicy()) << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 890df09157aa0..b77cbdb234f1f 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1670,21 +1670,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 45595068ea938..0a8c24f8be537 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -450,7 +450,8 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, if (Diagnose) { Diag(ClassDecl->getLocation(), diag::note_implicit_member_target_infer_collision) - << (unsigned)CSM << *InferredTarget << BaseMethodTarget; + << (unsigned)CSM << llvm::to_underlying(*InferredTarget) + << llvm::to_underlying(BaseMethodTarget); } MemberDecl->addAttr( CUDAInvalidTargetAttr::CreateImplicit(getASTContext())); @@ -495,7 +496,8 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, if (Diagnose) { Diag(ClassDecl->getLocation(), diag::note_implicit_member_target_infer_collision) - << (unsigned)CSM << *InferredTarget << FieldMethodTarget; + << (unsigned)CSM << llvm::to_underlying(*InferredTarget) + << llvm::to_underlying(FieldMethodTarget); } MemberDecl->addAttr( CUDAInvalidTargetAttr::CreateImplicit(getASTContext())); @@ -711,7 +713,7 @@ void SemaCUDA::checkAllowedInitializer(VarDecl *VD) { if (InitFnTarget != CUDAFunctionTarget::Host && InitFnTarget != CUDAFunctionTarget::HostDevice) { Diag(VD->getLocation(), diag::err_ref_bad_target_global_initializer) - << InitFnTarget << InitFn; + << llvm::to_underlying(InitFnTarget) << InitFn; Diag(InitFn->getLocation(), diag::note_previous_decl) << InitFn; VD->setInvalidDecl(); } @@ -950,8 +952,8 @@ bool SemaCUDA::CheckCall(SourceLocation Loc, FunctionDecl *Callee) { SemaDiagnosticBuilder(DiagKind, Loc, diag::err_ref_bad_target, Caller, SemaRef) - << IdentifyTarget(Callee) << /*function*/ 0 << Callee - << IdentifyTarget(Caller); + << llvm::to_underlying(IdentifyTarget(Callee)) << /*function*/ 0 << Callee + << llvm::to_underlying(IdentifyTarget(Caller)); if (!Callee->getBuiltinID()) SemaDiagnosticBuilder(DiagKind, Callee->getLocation(), diag::note_previous_decl, Caller, SemaRef) @@ -1047,7 +1049,8 @@ void SemaCUDA::checkTargetOverload(FunctionDecl *NewFD, (NewTarget == CUDAFunctionTarget::Global) || (OldTarget == CUDAFunctionTarget::Global)) { Diag(NewFD->getLocation(), diag::err_cuda_ovl_target) - << NewTarget << NewFD->getDeclName() << OldTarget << OldFD; + << llvm::to_underlying(NewTarget) << NewFD->getDeclName() + << llvm::to_underlying(OldTarget) << OldFD; Diag(OldFD->getLocation(), diag::note_previous_declaration); NewFD->setInvalidDecl(); break; @@ -1057,7 +1060,7 @@ void SemaCUDA::checkTargetOverload(FunctionDecl *NewFD, (NewTarget == CUDAFunctionTarget::Device && OldTarget == CUDAFunctionTarget::Host)) { Diag(NewFD->getLocation(), diag::warn_offload_incompatible_redeclare) - << NewTarget << OldTarget; + << llvm::to_underlying(NewTarget) << llvm::to_underlying(OldTarget); Diag(OldFD->getLocation(), diag::note_previous_declaration); } } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 92ec2fec519b1..2d648898cdea1 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8339,7 +8339,8 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, } else { EmitFormatDiagnostic( S.PDiag(diag::warn_non_pod_vararg_with_format_string) - << S.getLangOpts().CPlusPlus11 << ExprTy << CallType + << S.getLangOpts().CPlusPlus11 << ExprTy + << llvm::to_underlying(CallType) << AT.getRepresentativeTypeName(S.Context) << CSR << E->getSourceRange(), E->getBeginLoc(), /*IsStringLocation*/ false, CSR); @@ -8353,7 +8354,8 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, else if (ExprTy->isObjCObjectType()) EmitFormatDiagnostic( S.PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format) - << S.getLangOpts().CPlusPlus11 << ExprTy << CallType + << S.getLangOpts().CPlusPlus11 << ExprTy + << llvm::to_underlying(CallType) << AT.getRepresentativeTypeName(S.Context) << CSR << E->getSourceRange(), E->getBeginLoc(), /*IsStringLocation*/ false, CSR); @@ -8361,7 +8363,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // FIXME: If this is an initializer list, suggest removing the braces // or inserting a cast to the target type. S.Diag(E->getBeginLoc(), diag::err_cannot_pass_to_vararg_format) - << isa<InitListExpr>(E) << ExprTy << CallType + << isa<InitListExpr>(E) << ExprTy << llvm::to_underlying(CallType) << AT.getRepresentativeTypeName(S.Context) << E->getSourceRange(); break; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a3285e8f6f5a2..517b3067696a0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4034,13 +4034,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; } } @@ -5249,7 +5249,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, if (DS.isModulePrivateSpecified() && Tag && Tag->getDeclContext()->isFunctionOrMethod()) Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class) - << Tag->getTagKind() + << llvm::to_underlying(Tag->getTagKind()) << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc()); ActOnDocumentableDecl(TagD); @@ -7722,14 +7722,15 @@ NamedDecl *Sema::ActOnVariableDeclarator( // data members. Diag(D.getIdentifierLoc(), diag::err_static_data_member_not_allowed_in_local_class) - << Name << RD->getDeclName() << RD->getTagKind(); + << Name << RD->getDeclName() + << llvm::to_underlying(RD->getTagKind()); } else if (AnonStruct) { // C++ [class.static.data]p4: Unnamed classes and classes contained // directly or indirectly within unnamed classes shall not contain // static data members. Diag(D.getIdentifierLoc(), diag::err_static_data_member_not_allowed_in_anon_struct) - << Name << AnonStruct->getTagKind(); + << Name << llvm::to_underlying(AnonStruct->getTagKind()); Invalid = true; } else if (RD->isUnion()) { // C++98 [class.union]p1: If a union contains a static data member, @@ -17660,7 +17661,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // A tag 'foo::bar' must already exist. Diag(NameLoc, diag::err_not_tag_in_scope) - << Kind << Name << DC << SS.getRange(); + << llvm::to_underlying(Kind) << Name << DC << SS.getRange(); Name = nullptr; Invalid = true; goto CreateNewDecl; @@ -18118,7 +18119,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, !Previous.isForRedeclaration()) { NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl, Kind); Diag(NameLoc, diag::err_tag_reference_non_tag) - << PrevDecl << NTK << Kind; + << PrevDecl << NTK << llvm::to_underlying(Kind); Diag(PrevDecl->getLocation(), diag::note_declared_at); Invalid = true; @@ -19017,7 +19018,8 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { 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; + << FD->getParent()->isUnion() << FD->getDeclName() + << llvm::to_underlying(member); DiagnoseNontrivial(RDecl, member); return !getLangOpts().CPlusPlus11; } @@ -19357,7 +19359,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, unsigned DiagID = 0; if (!Record->isUnion() && !IsLastField) { Diag(FD->getLocation(), diag::err_flexible_array_not_at_end) - << FD->getDeclName() << FD->getType() << Record->getTagKind(); + << FD->getDeclName() << FD->getType() + << llvm::to_underlying(Record->getTagKind()); Diag((*(i + 1))->getLocation(), diag::note_next_field_declaration); FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); @@ -19373,7 +19376,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (DiagID) Diag(FD->getLocation(), DiagID) - << FD->getDeclName() << Record->getTagKind(); + << FD->getDeclName() << llvm::to_underlying(Record->getTagKind()); // While the layout of types that contain virtual bases is not specified // by the C++ standard, both the Itanium and Microsoft C++ ABIs place // virtual bases after the derived members. This would make a flexible @@ -19381,10 +19384,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // of the type. if (CXXRecord && CXXRecord->getNumVBases() != 0) Diag(FD->getLocation(), diag::err_flexible_array_virtual_base) - << FD->getDeclName() << Record->getTagKind(); + << FD->getDeclName() << llvm::to_underlying(Record->getTagKind()); if (!getLangOpts().C99) Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) - << FD->getDeclName() << Record->getTagKind(); + << FD->getDeclName() << llvm::to_underlying(Record->getTagKind()); // If the element type has a non-trivial destructor, we would not // implicitly destroy the elements, so disallow it for now. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 9d6a1c77f5aaf..ab66ae860f86b 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5058,7 +5058,7 @@ static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } if (S.getLangOpts().CUDA && VD->hasLocalStorage() && S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared) - << S.CUDA().CurrentTarget()) + << llvm::to_underlying(S.CUDA().CurrentTarget())) return; D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL)); } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index a7e68682d5320..645a0887c0f19 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -647,7 +647,7 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, 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); } } @@ -6978,7 +6978,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { (F->getType().isConstQualified() && F->getType()->isScalarType())) { if (!Complained) { Diag(Record->getLocation(), diag::warn_no_constructor_for_refconst) - << Record->getTagKind() << Record; + << llvm::to_underlying(Record->getTagKind()) << Record; Complained = true; } @@ -7774,14 +7774,14 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD, // 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; } } @@ -7868,7 +7868,7 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD, else { Diag(MD->getLocation(), diag::err_defaulted_special_member_volatile_param) - << CSM; + << llvm::to_underlying(CSM); HadError = true; } } @@ -7929,12 +7929,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. @@ -7967,9 +7967,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()) { @@ -7980,13 +7982,14 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD, if (ShouldDeleteForTypeMismatch && !HadError) { Diag(MD->getLocation(), diag::warn_cxx17_compat_defaulted_method_type_mismatch) - << CSM; + << 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; @@ -9552,15 +9555,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 = cast<CXXBaseSpecifier *>(Subobj); 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) @@ -9629,8 +9633,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForVariantObjCPtrMember( 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; + << llvm::to_underlying(getEffectiveCSM()) << ParentClass + << /*IsField*/ true << FD << 4 << /*IsDtorCallInCtor*/ false + << /*IsObjCPtr*/ true; } return true; @@ -9653,8 +9658,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForVariantPtrAuthMember( 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 << 2; + << llvm::to_underlying(getEffectiveCSM()) << ParentClass + << /*IsField*/ true << FD << 4 << /*IsDtorCallInCtor*/ false << 2; } return true; @@ -9679,9 +9684,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(); @@ -10177,20 +10182,21 @@ static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc, 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, @@ -11465,7 +11471,7 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) { if (ConvType->isUndeducedAutoType()) { Diag(Conversion->getTypeSpecStartLoc(), diag::err_auto_not_allowed) << getReturnTypeLoc(Conversion).getSourceRange() - << ConvType->castAs<AutoType>()->getKeyword() + << llvm::to_underlying(ConvType->castAs<AutoType>()->getKeyword()) << /* in declaration of conversion function template= */ 24; } diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 501d44180e3eb..0a14ce23a396e 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -3890,7 +3890,7 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) { if (IvarTy->isIncompleteArrayType()) { S.Diag(ivar->getLocation(), diag::err_flexible_array_not_at_end) << ivar->getDeclName() << IvarTy - << TagTypeKind::Class; // Use "class" for Obj-C. + << llvm::to_underlying(TagTypeKind::Class); // Use "class" for Obj-C. IsInvalidIvar = true; } else if (const RecordType *RecordTy = IvarTy->getAs<RecordType>()) { if (RecordTy->getDecl()->hasFlexibleArrayMember()) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index b6867077d6ff8..b1cdf37bf5c1d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1022,7 +1022,8 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { case VAK_ValidInCXX11: DiagRuntimeBehavior( E->getBeginLoc(), nullptr, - PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) << Ty << CT); + PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) + << Ty << llvm::to_underlying(CT)); [[fallthrough]]; case VAK_Valid: if (Ty->isRecordType()) { @@ -1030,7 +1031,8 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { // 'c_str' member function, the user probably meant to call that. DiagRuntimeBehavior(E->getBeginLoc(), nullptr, PDiag(diag::warn_pass_class_arg_to_vararg) - << Ty << CT << hasCStrMethod(E) << ".c_str()"); + << Ty << llvm::to_underlying(CT) + << hasCStrMethod(E) << ".c_str()"); } break; @@ -1038,21 +1040,22 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { case VAK_MSVCUndefined: DiagRuntimeBehavior(E->getBeginLoc(), nullptr, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << getLangOpts().CPlusPlus11 << Ty << CT); + << getLangOpts().CPlusPlus11 << Ty + << llvm::to_underlying(CT)); break; case VAK_Invalid: if (Ty.isDestructedType() == QualType::DK_nontrivial_c_struct) Diag(E->getBeginLoc(), diag::err_cannot_pass_non_trivial_c_struct_to_vararg) - << Ty << CT; + << Ty << llvm::to_underlying(CT); else if (Ty->isObjCObjectType()) DiagRuntimeBehavior(E->getBeginLoc(), nullptr, PDiag(diag::err_cannot_pass_objc_interface_to_vararg) - << Ty << CT); + << Ty << llvm::to_underlying(CT)); else Diag(E->getBeginLoc(), diag::err_cannot_pass_to_vararg) - << isa<InitListExpr>(E) << Ty << CT; + << isa<InitListExpr>(E) << Ty << llvm::to_underlying(CT); break; } } @@ -18554,7 +18557,8 @@ MarkVarDeclODRUsed(ValueDecl *V, SourceLocation Loc, Sema &SemaRef, // through shadow variables therefore it is not diagnosed. if (SemaRef.LangOpts.CUDAIsDevice && !SemaRef.LangOpts.HIPStdPar) { SemaRef.targetDiag(Loc, diag::err_ref_bad_target) - << /*host*/ 2 << /*variable*/ 1 << Var << UserTarget; + << /*host*/ 2 << /*variable*/ 1 << Var + << llvm::to_underlying(UserTarget); SemaRef.targetDiag(Var->getLocation(), Var->getType().isConstQualified() ? diag::note_cuda_const_var_unpromoted diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 09edc34936cfd..727eefa6ce7a4 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -865,7 +865,7 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, // Exceptions aren't allowed in CUDA device code. if (getLangOpts().CUDA) CUDA().DiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions) - << "throw" << CUDA().CurrentTarget(); + << "throw" << llvm::to_underlying(CUDA().CurrentTarget()); if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw"; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 373796212bb82..6900ccb11c3db 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -9233,7 +9233,8 @@ 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)) + << llvm::to_underlying( + S.getSpecialMember(cast<CXXMethodDecl>(Best->Function))) << DestType << ArgsRange; else { StringLiteral *Msg = Best->Function->getDeletedMessage(); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7efd92b38b0dd..b8c2356aac3fd 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -12355,7 +12355,7 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) << (unsigned)FnKindPair.first << (unsigned)ocs_non_template << FnDesc /* Ignored */ - << CalleeTarget << CallerTarget; + << llvm::to_underlying(CalleeTarget) << llvm::to_underlying(CallerTarget); // This could be an implicit constructor for which we could not infer the // target due to a collsion. Diagnose that case. @@ -15528,7 +15528,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/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 9f517b2de0f8e..e2072512d7e6a 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4318,7 +4318,7 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, // Exceptions aren't allowed in CUDA device code. if (getLangOpts().CUDA) CUDA().DiagIfDeviceCode(TryLoc, diag::err_cuda_device_exceptions) - << "try" << CUDA().CurrentTarget(); + << "try" << llvm::to_underlying(CUDA().CurrentTarget()); if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try"; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 6a258caffb7a2..633ce2bb5b4f9 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3911,7 +3911,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, // resolves to an alias template specialization, the // elaborated-type-specifier is ill-formed. Diag(TemplateLoc, diag::err_tag_reference_non_tag) - << TAT << NTK_TypeAliasTemplate << TagKind; + << TAT << NTK_TypeAliasTemplate << llvm::to_underlying(TagKind); Diag(TAT->getLocation(), diag::note_declared_at); } @@ -9779,7 +9779,8 @@ DeclResult Sema::ActOnExplicitInstantiation( if (!ClassTemplate) { NonTagKind NTK = getNonTagTypeDeclKind(TD, Kind); - Diag(TemplateNameLoc, diag::err_tag_reference_non_tag) << TD << NTK << Kind; + Diag(TemplateNameLoc, diag::err_tag_reference_non_tag) + << TD << NTK << llvm::to_underlying(Kind); Diag(TD->getLocation(), diag::note_previous_use); return true; } @@ -10642,7 +10643,8 @@ TypeResult Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (TUK == TagUseKind::Declaration || TUK == TagUseKind::Definition) { Diag(NameLoc, diag::err_dependent_tag_decl) - << (TUK == TagUseKind::Definition) << Kind << SS.getRange(); + << (TUK == TagUseKind::Definition) << llvm::to_underlying(Kind) + << SS.getRange(); return true; } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 390ff3ef02df5..0e81804f8c1e7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1124,7 +1124,7 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { DiagFunc(Active->PointOfInstantiation, PDiag(diag::note_in_declaration_of_implicit_special_member) << cast<CXXRecordDecl>(Active->Entity) - << Active->SpecialMember); + << llvm::to_underlying(Active->SpecialMember)); break; case CodeSynthesisContext::DeclaringImplicitEqualityComparison: @@ -1143,7 +1143,8 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { auto *MD = cast<CXXMethodDecl>(FD); DiagFunc(Active->PointOfInstantiation, PDiag(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 08b3a423d1526..76c055d28f091 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2211,8 +2211,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (!PrevClassTemplate && QualifierLoc) { SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope) - << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC - << QualifierLoc.getSourceRange(); + << llvm::to_underlying(D->getTemplatedDecl()->getTagKind()) + << Pattern->getDeclName() << DC << QualifierLoc.getSourceRange(); return nullptr; } } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 444b8d9ee28b4..6e7ee8b5506ff 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2298,7 +2298,7 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, (ASM != ArraySizeModifier::Normal || Quals != 0)) { Diag(Loc, getLangOpts().CPlusPlus ? diag::err_c99_array_usage_cxx : diag::ext_c99_array_usage) - << ASM; + << llvm::to_underlying(ASM); } // OpenCL v2.0 s6.12.5 - Arrays of blocks are not supported. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3bcbe0f2133a2..b6af919463124 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1223,13 +1223,14 @@ class TreeTransform { NamedDecl *SomeDecl = Result.getRepresentativeDecl(); Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind); SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) - << SomeDecl << NTK << Kind; + << SomeDecl << NTK << llvm::to_underlying(Kind); SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at); break; } default: SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope) - << Kind << Id << DC << QualifierLoc.getSourceRange(); + << llvm::to_underlying(Kind) << Id << DC + << QualifierLoc.getSourceRange(); break; } return QualType(); @@ -7509,7 +7510,8 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(), diag::err_tag_reference_non_tag) << TAT << Sema::NTK_TypeAliasTemplate - << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()); + << llvm::to_underlying( + ElaboratedType::getTagTypeKindForKeyword(T->getKeyword())); SemaRef.Diag(TAT->getLocation(), diag::note_declared_at); } } diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h index b8d4babc95fea..10c274ea8e23e 100644 --- a/llvm/include/llvm/ADT/STLForwardCompat.h +++ b/llvm/include/llvm/ADT/STLForwardCompat.h @@ -73,10 +73,6 @@ struct from_range_t { }; inline constexpr from_range_t from_range{}; -template <typename T, typename UnderlyingT = std::underlying_type_t<T>> -constexpr bool is_scoped_enum_v = - std::is_enum_v<T> && !std::is_convertible_v<T, UnderlyingT>; - } // namespace llvm #endif // LLVM_ADT_STLFORWARDCOMPAT_H _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits