@@ -768,58 +768,44 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
768
768
// C++23 [dcl.pre]/6:
769
769
// Each decl-specifier in the decl-specifier-seq shall be static,
770
770
// thread_local, auto (9.2.9.6 [dcl.spec.auto]), or a cv-qualifier.
771
+ // C++23 [dcl.pre]/7:
772
+ // Each decl-specifier in the decl-specifier-seq shall be constexpr,
773
+ // constinit, static, thread_local, auto, or a cv-qualifier
771
774
auto &DS = D.getDeclSpec();
772
- {
773
- // Note: While constrained-auto needs to be checked, we do so separately so
774
- // we can emit a better diagnostic.
775
- SmallVector<StringRef, 8> BadSpecifiers;
776
- SmallVector<SourceLocation, 8> BadSpecifierLocs;
777
- SmallVector<StringRef, 8> CPlusPlus20Specifiers;
778
- SmallVector<SourceLocation, 8> CPlusPlus20SpecifierLocs;
779
- if (auto SCS = DS.getStorageClassSpec()) {
780
- if (SCS == DeclSpec::SCS_static) {
781
- CPlusPlus20Specifiers.push_back(DeclSpec::getSpecifierName(SCS));
782
- CPlusPlus20SpecifierLocs.push_back(DS.getStorageClassSpecLoc());
783
- } else {
784
- BadSpecifiers.push_back(DeclSpec::getSpecifierName(SCS));
785
- BadSpecifierLocs.push_back(DS.getStorageClassSpecLoc());
786
- }
787
- }
788
- if (auto TSCS = DS.getThreadStorageClassSpec()) {
789
- CPlusPlus20Specifiers.push_back(DeclSpec::getSpecifierName(TSCS));
790
- CPlusPlus20SpecifierLocs.push_back(DS.getThreadStorageClassSpecLoc());
791
- }
792
- if (DS.hasConstexprSpecifier()) {
793
- BadSpecifiers.push_back(
794
- DeclSpec::getSpecifierName(DS.getConstexprSpecifier()));
795
- BadSpecifierLocs.push_back(DS.getConstexprSpecLoc());
796
- }
797
- if (DS.isInlineSpecified()) {
798
- BadSpecifiers.push_back("inline");
799
- BadSpecifierLocs.push_back(DS.getInlineSpecLoc());
800
- }
801
-
802
- if (!BadSpecifiers.empty()) {
803
- auto &&Err = Diag(BadSpecifierLocs.front(), diag::err_decomp_decl_spec);
804
- Err << (int)BadSpecifiers.size()
805
- << llvm::join(BadSpecifiers.begin(), BadSpecifiers.end(), " ");
806
- // Don't add FixItHints to remove the specifiers; we do still respect
807
- // them when building the underlying variable.
808
- for (auto Loc : BadSpecifierLocs)
809
- Err << SourceRange(Loc, Loc);
810
- } else if (!CPlusPlus20Specifiers.empty()) {
811
- auto &&Warn = DiagCompat(CPlusPlus20SpecifierLocs.front(),
812
- diag_compat::decomp_decl_spec);
813
- Warn << (int)CPlusPlus20Specifiers.size()
814
- << llvm::join(CPlusPlus20Specifiers.begin(),
815
- CPlusPlus20Specifiers.end(), " ");
816
- for (auto Loc : CPlusPlus20SpecifierLocs)
817
- Warn << SourceRange(Loc, Loc);
818
- }
819
- // We can't recover from it being declared as a typedef.
820
- if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef)
821
- return nullptr;
775
+ auto DiagBadSpecifier = [&](StringRef Name, SourceLocation Loc) {
776
+ Diag(Loc, diag::err_decomp_decl_spec) << Name;
777
+ };
778
+
779
+ auto DiagCpp20Specifier = [&](StringRef Name, SourceLocation Loc) {
780
+ DiagCompat(Loc, diag_compat::decomp_decl_spec) << Name;
781
+ };
782
+
783
+ if (auto SCS = DS.getStorageClassSpec()) {
784
+ if (SCS == DeclSpec::SCS_static)
785
+ DiagCpp20Specifier(DeclSpec::getSpecifierName(SCS),
786
+ DS.getStorageClassSpecLoc());
787
+ else
788
+ DiagBadSpecifier(DeclSpec::getSpecifierName(SCS),
789
+ DS.getStorageClassSpecLoc());
822
790
}
791
+ if (auto TSCS = DS.getThreadStorageClassSpec())
792
+ DiagCpp20Specifier(DeclSpec::getSpecifierName(TSCS),
793
+ DS.getThreadStorageClassSpecLoc());
794
+
795
+ if (DS.isInlineSpecified())
796
+ DiagBadSpecifier("inline", DS.getInlineSpecLoc());
797
+
798
+ if (ConstexprSpecKind ConstexprSpec = DS.getConstexprSpecifier();
799
+ ConstexprSpec != ConstexprSpecKind::Unspecified) {
800
+ if (ConstexprSpec == ConstexprSpecKind::Consteval ||
801
+ !getLangOpts().CPlusPlus26)
802
+ DiagBadSpecifier(DeclSpec::getSpecifierName(ConstexprSpec),
803
+ DS.getConstexprSpecLoc());
804
+ }
805
+
806
+ // We can't recover from it being declared as a typedef.
807
+ if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef)
808
+ return nullptr;
823
809
824
810
// C++2a [dcl.struct.bind]p1:
825
811
// A cv that includes volatile is deprecated
0 commit comments