Skip to content

Commit b36c8d6

Browse files
author
foxfromabyss
committed
[Clang][Diagnostics] Use "structured binding" instead of "decomposition"
P0615R0 changed the term "decomposition" to "structured binding". Some diagnostic messages were created before this paper. These messages should be updated using "structured binding" to avoid making users confused. See for context: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0615r0.html
1 parent d72cd24 commit b36c8d6

24 files changed

+152
-152
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,10 @@ def err_expected_end_of_enumerator : Error<
504504
def err_expected_coloncolon_after_super : Error<
505505
"expected '::' after '__super'">;
506506

507-
def ext_decomp_decl_empty : ExtWarn<
508-
"ISO C++17 does not allow a decomposition group to be empty">,
509-
InGroup<DiagGroup<"empty-decomposition">>;
507+
def ext_decomp_decl_empty
508+
: ExtWarn<
509+
"ISO C++17 does not allow a structured binding group to be empty">,
510+
InGroup<DiagGroup<"empty-structured-binding">>;
510511

511512
def err_function_parameter_limit_exceeded : Error<
512513
"too many function parameters; subsequent parameters will be ignored">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ defm constexpr_body_multiple_return : CXX14Compat<
3131
defm variable_template : CXX14Compat<"variable templates are">;
3232

3333
// C++17 compatibility with C++14 and earlier.
34-
defm decomp_decl : CXX17Compat<"decomposition declarations are">;
34+
defm decomp_decl : CXX17Compat<"structured binding declarations are">;
3535
defm inline_variable : CXX17Compat<"inline variables are">;
3636

3737
// C++20 compatibility with C++17 and earlier.
3838
defm decomp_decl_spec
39-
: CXX20Compat<"decomposition declaration declared '%0' is">;
39+
: CXX20Compat<"structured binding declaration declared '%0' is">;
4040
defm constexpr_local_var_no_init : CXX20Compat<
4141
"uninitialized variable in a constexpr %select{function|constructor}0 is">;
4242
defm constexpr_function_try_block : CXX20Compat<
@@ -589,60 +589,59 @@ def warn_modifying_shadowing_decl :
589589
"field of %1">,
590590
InGroup<ShadowFieldInConstructorModified>, DefaultIgnore;
591591

592-
// C++ decomposition declarations
593-
def err_decomp_decl_context : Error<
594-
"decomposition declaration not permitted in this context">;
592+
// C++ structured binding declarations
593+
def err_decomp_decl_context
594+
: Error<"structured binding declaration not permitted in this context">;
595595
def err_decomp_decl_spec
596-
: Error<"decomposition declaration cannot be declared '%0'">;
597-
def err_decomp_decl_type : Error<
598-
"decomposition declaration cannot be declared with type %0; "
599-
"declared type must be 'auto' or reference to 'auto'">;
600-
def err_decomp_decl_constraint : Error<
601-
"decomposition declaration cannot be declared with constrained 'auto'">;
602-
def err_decomp_decl_parens : Error<
603-
"decomposition declaration cannot be declared with parentheses">;
604-
def err_decomp_decl_template : Error<
605-
"decomposition declaration cannot be a template">;
606-
def err_decomp_decl_not_alone : Error<
607-
"decomposition declaration must be the only declaration in its group">;
608-
def err_decomp_decl_requires_init : Error<
609-
"decomposition declaration %0 requires an initializer">;
610-
def err_decomp_decl_wrong_number_bindings : Error<
611-
"type %0 decomposes into %3 %plural{1:element|:elements}2, but "
612-
"%select{%plural{0:no|:only %1}1|%1}4 "
613-
"%plural{1:name was|:names were}1 provided">;
614-
def err_decomp_decl_unbindable_type : Error<
615-
"cannot decompose %select{union|non-class, non-array}1 type %2">;
616-
def err_decomp_decl_multiple_bases_with_members : Error<
617-
"cannot decompose class type %1: "
618-
"%select{its base classes %2 and|both it and its base class}0 %3 "
619-
"have non-static data members">;
620-
def err_decomp_decl_ambiguous_base : Error<
621-
"cannot decompose members of ambiguous base class %1 of %0:%2">;
622-
def err_decomp_decl_inaccessible_base : Error<
623-
"cannot decompose members of inaccessible base class %1 of %0">,
624-
AccessControl;
625-
def err_decomp_decl_inaccessible_field : Error<
626-
"cannot decompose %select{private|protected}0 member %1 of %3">,
627-
AccessControl;
628-
def err_decomp_decl_lambda : Error<
629-
"cannot decompose lambda closure type">;
630-
def err_decomp_decl_anon_union_member : Error<
631-
"cannot decompose class type %0 because it has an anonymous "
632-
"%select{struct|union}1 member">;
633-
def err_decomp_decl_std_tuple_element_not_specialized : Error<
634-
"cannot decompose this type; 'std::tuple_element<%0>::type' "
635-
"does not name a type">;
636-
def err_decomp_decl_std_tuple_size_not_constant : Error<
637-
"cannot decompose this type; 'std::tuple_size<%0>::value' "
638-
"is not a valid integral constant expression">;
596+
: Error<"structured binding declaration cannot be declared '%0'">;
597+
def err_decomp_decl_type
598+
: Error<"structured binding declaration cannot be declared with type %0; "
599+
"declared type must be 'auto' or reference to 'auto'">;
600+
def err_decomp_decl_constraint : Error<"structured binding declaration cannot "
601+
"be declared with constrained 'auto'">;
602+
def err_decomp_decl_parens
603+
: Error<
604+
"structured binding declaration cannot be declared with parentheses">;
605+
def err_decomp_decl_template
606+
: Error<"structured binding declaration cannot be a template">;
607+
def err_decomp_decl_not_alone : Error<"structured binding declaration must be "
608+
"the only declaration in its group">;
609+
def err_decomp_decl_requires_init
610+
: Error<"structured binding declaration %0 requires an initializer">;
611+
def err_decomp_decl_wrong_number_bindings
612+
: Error<"type %0 binds to %3 %plural{1:element|:elements}2, but "
613+
"%select{%plural{0:no|:only %1}1|%1}4 "
614+
"%plural{1:name was|:names were}1 provided">;
615+
def err_decomp_decl_unbindable_type
616+
: Error<"cannot bind %select{union|non-class, non-array}1 type %2">;
617+
def err_decomp_decl_multiple_bases_with_members
618+
: Error<"cannot bind class type %1: "
619+
"%select{its base classes %2 and|both it and its base class}0 %3 "
620+
"have non-static data members">;
621+
def err_decomp_decl_ambiguous_base
622+
: Error<"cannot bind members of ambiguous base class %1 of %0:%2">;
623+
def err_decomp_decl_inaccessible_base
624+
: Error<"cannot bind members of inaccessible base class %1 of %0">,
625+
AccessControl;
626+
def err_decomp_decl_inaccessible_field
627+
: Error<"cannot bind %select{private|protected}0 member %1 of %3">,
628+
AccessControl;
629+
def err_decomp_decl_lambda : Error<"cannot bind lambda closure type">;
630+
def err_decomp_decl_anon_union_member
631+
: Error<"cannot bind class type %0 because it has an anonymous "
632+
"%select{struct|union}1 member">;
633+
def err_decomp_decl_std_tuple_element_not_specialized
634+
: Error<"cannot bind this type; 'std::tuple_element<%0>::type' "
635+
"does not name a type">;
636+
def err_decomp_decl_std_tuple_size_not_constant
637+
: Error<"cannot bind this type; 'std::tuple_size<%0>::value' "
638+
"is not a valid integral constant expression">;
639639
def err_decomp_decl_std_tuple_size_invalid
640-
: Error<"cannot decompose this type; 'std::tuple_size<%0>::value' "
640+
: Error<"cannot bind this type; 'std::tuple_size<%0>::value' "
641641
"is not a valid size: %1">;
642642
def note_in_binding_decl_init : Note<
643643
"in implicit initialization of binding declaration %0">;
644-
def err_arg_is_not_destructurable : Error<
645-
"type %0 cannot be decomposed">;
644+
def err_arg_is_not_destructurable : Error<"type %0 cannot be bound">;
646645

647646
def err_std_type_trait_not_class_template : Error<
648647
"unsupported standard library implementation: "
@@ -2618,9 +2617,9 @@ def err_auto_variable_cannot_appear_in_own_initializer
26182617
"%VarTemplateExplicitSpec{variable template explicit "
26192618
"specialization}}0 %1 "
26202619
"declared with deduced type %2 cannot appear in its own initializer">;
2621-
def err_binding_cannot_appear_in_own_initializer : Error<
2622-
"binding %0 cannot appear in the initializer of its own "
2623-
"decomposition declaration">;
2620+
def err_binding_cannot_appear_in_own_initializer
2621+
: Error<"binding %0 cannot appear in the initializer of its own "
2622+
"structured binding declaration">;
26242623
def err_new_array_of_auto : Error<
26252624
"cannot allocate array of 'auto'">;
26262625
def err_auto_not_allowed : Error<

clang/test/Analysis/zero-size-non-pod-array.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ void zeroSizeArrayBinding() {
9595
// Note: This is an error in gcc but a warning in clang.
9696
// In MSVC the declaration of 'S arr[0]' is already an error
9797
// and it doesn't recognize this syntax as a structured binding.
98-
auto [] = arr; //expected-warning{{ISO C++17 does not allow a decomposition group to be empty}}
98+
auto [] = arr; //expected-warning{{ISO C++17 does not allow a structured binding group to be empty}}
9999

100100
clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}}
101101
}

clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ int array() {
1616
using X3 = X[3];
1717
auto [a3, b3, c3] = X3{1, 2, 3};
1818

19-
auto &[d, e] = arr; // expected-error {{type 'int[3]' decomposes into 3 elements, but only 2 names were provided}}
20-
auto &[f, g, h, i] = arr; // expected-error {{type 'int[3]' decomposes into 3 elements, but 4 names were provided}}
19+
auto &[d, e] = arr; // expected-error {{type 'int[3]' binds to 3 elements, but only 2 names were provided}}
20+
auto &[f, g, h, i] = arr; // expected-error {{type 'int[3]' binds to 3 elements, but 4 names were provided}}
2121

2222
auto &[r0, r1, r2] = arr;
2323
const auto &[cr0, cr1, cr2] = arr;

clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@ using size_t = decltype(sizeof(0));
55
struct A { int x, y; };
66
struct B { int x, y; };
77

8-
void no_tuple_size_1() { auto [x, y] = A(); } // ok, decompose elementwise
8+
void no_tuple_size_1() { auto [x, y] = A(); } // ok, bind elementwise
99

1010
namespace std { template<typename T> struct tuple_size; }
11-
void no_tuple_size_2() { auto [x, y] = A(); } // ok, decompose elementwise
11+
void no_tuple_size_2() { auto [x, y] = A(); } // ok, bind elementwise
1212

1313
struct Bad1 { int a, b; };
1414
template<> struct std::tuple_size<Bad1> {};
1515
void no_tuple_size_3() { auto [x, y] = Bad1(); } // ok, omitting value is valid after DR2386
1616

1717
struct Bad2 {};
1818
template<> struct std::tuple_size<Bad2> { const int value = 5; };
19-
void no_tuple_size_4() { auto [x, y] = Bad2(); } // expected-error {{cannot decompose this type; 'std::tuple_size<Bad2>::value' is not a valid integral constant expression}}
19+
void no_tuple_size_4() { auto [x, y] = Bad2(); } // expected-error {{cannot bind this type; 'std::tuple_size<Bad2>::value' is not a valid integral constant expression}}
2020

2121
template<> struct std::tuple_size<A> { static const int value = 3; };
2222
template<> struct std::tuple_size<B> { enum { value = 3 }; };
2323

2424
void no_get_1() {
2525
{
26-
auto [a0, a1] = A(); // expected-error {{decomposes into 3 elements}}
27-
auto [b0, b1] = B(); // expected-error {{decomposes into 3 elements}}
26+
auto [a0, a1] = A(); // expected-error {{binds to 3 elements}}
27+
auto [b0, b1] = B(); // expected-error {{binds to 3 elements}}
2828
}
2929
auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}}
3030
}

clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ namespace NonPublicMembers {
2525
struct NonPublic4 : NonPublic2 {};
2626

2727
void test() {
28-
auto [a1] = NonPublic1(); // expected-error {{cannot decompose protected member 'a' of 'NonPublicMembers::NonPublic1'}}
29-
auto [a2] = NonPublic2(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}}
30-
auto [a3] = NonPublic3(); // expected-error {{cannot decompose members of inaccessible base class 'A' of 'NonPublicMembers::NonPublic3'}}
31-
auto [a4] = NonPublic4(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}}
28+
auto [a1] = NonPublic1(); // expected-error {{cannot bind protected member 'a' of 'NonPublicMembers::NonPublic1'}}
29+
auto [a2] = NonPublic2(); // expected-error {{cannot bind private member 'a' of 'NonPublicMembers::NonPublic2'}}
30+
auto [a3] = NonPublic3(); // expected-error {{cannot bind members of inaccessible base class 'A' of 'NonPublicMembers::NonPublic3'}}
31+
auto [a4] = NonPublic4(); // expected-error {{cannot bind private member 'a' of 'NonPublicMembers::NonPublic2'}}
3232
}
3333
}
3434

@@ -46,8 +46,8 @@ namespace AnonymousMember {
4646
};
4747

4848
void test() {
49-
auto [a1] = Struct(); // expected-error {{cannot decompose class type 'Struct' because it has an anonymous struct member}}
50-
auto [a2] = Union(); // expected-error {{cannot decompose class type 'Union' because it has an anonymous union member}}
49+
auto [a1] = Struct(); // expected-error {{cannot bind class type 'Struct' because it has an anonymous struct member}}
50+
auto [a2] = Union(); // expected-error {{cannot bind class type 'Union' because it has an anonymous union member}}
5151
}
5252
}
5353

@@ -73,12 +73,12 @@ namespace MultipleClasses {
7373
struct M : virtual J, L {};
7474

7575
void test() {
76-
auto [b] = B(); // expected-error {{cannot decompose class type 'B': both it and its base class 'A' have non-static data members}}
77-
auto [d] = D(); // expected-error {{cannot decompose class type 'D': its base classes 'A' and 'C' have non-static data members}}
76+
auto [b] = B(); // expected-error {{cannot bind class type 'B': both it and its base class 'A' have non-static data members}}
77+
auto [d] = D(); // expected-error {{cannot bind class type 'D': its base classes 'A' and 'C' have non-static data members}}
7878
auto [e] = E();
79-
auto [f] = F(); // expected-error-re {{cannot decompose members of ambiguous base class 'A' of 'F':{{.*}}struct MultipleClasses::F -> A{{.*}}struct MultipleClasses::F -> E -> A}}
79+
auto [f] = F(); // expected-error-re {{cannot bind members of ambiguous base class 'A' of 'F':{{.*}}struct MultipleClasses::F -> A{{.*}}struct MultipleClasses::F -> E -> A}}
8080
auto [h] = H(); // ok, only one (virtual) base subobject even though there are two paths to it
81-
auto [k] = K(); // expected-error {{cannot decompose members of ambiguous base class 'I'}}
81+
auto [k] = K(); // expected-error {{cannot bind members of ambiguous base class 'I'}}
8282
auto [m] = M(); // ok, all paths to I are through the same virtual base subobject J
8383

8484
same<decltype(m), int>();
@@ -214,7 +214,7 @@ namespace p0969r0 {
214214
auto &[x, y] = b;
215215
}
216216
void test_external(B b) {
217-
auto &[x, y] = b; // expected-error {{cannot decompose members of inaccessible base class 'A' of 'p0969r0::B'}}
217+
auto &[x, y] = b; // expected-error {{cannot bind members of inaccessible base class 'A' of 'p0969r0::B'}}
218218
}
219219

220220
struct C {
@@ -229,13 +229,13 @@ namespace p0969r0 {
229229
struct D : C {
230230
static void test_member(D d, C c) {
231231
auto &[x1, y1] = d;
232-
auto &[x2, y2] = c; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}}
232+
auto &[x2, y2] = c; // expected-error {{cannot bind protected member 'y' of 'p0969r0::C'}}
233233
}
234234
};
235235
void test_friend(D d) {
236236
auto &[x, y] = d;
237237
}
238238
void test_external(D d) {
239-
auto &[x, y] = d; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}}
239+
auto &[x, y] = d; // expected-error {{cannot bind protected member 'y' of 'p0969r0::C'}}
240240
}
241241
}

clang/test/CXX/drs/cwg22xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ namespace cwg2285 { // cwg2285: 4
202202
void test() {
203203
using T = int[1];
204204
auto [a] = T{a};
205-
// since-cxx17-error@-1 {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
205+
// since-cxx17-error@-1 {{binding 'a' cannot appear in the initializer of its own structured binding declaration}}
206206
}
207207
#endif
208208
} // namespace cwg2285

clang/test/CXX/drs/cwg23xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ template <> struct tuple_size<cwg2386::Bad2> {
440440
namespace cwg2386 {
441441
void no_value() { auto [x, y] = Bad1(); }
442442
void wrong_value() { auto [x, y] = Bad2(); }
443-
// since-cxx17-error@-1 {{type 'Bad2' decomposes into 42 elements, but only 2 names were provided}}
443+
// since-cxx17-error@-1 {{type 'Bad2' binds to 42 elements, but only 2 names were provided}}
444444
#endif
445445
} // namespace cwg2386
446446

clang/test/CXX/drs/cwg26xx.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,17 +183,17 @@ T get_T();
183183

184184
void use() {
185185
UnaryC auto [a, b] = get_S();
186-
// since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
186+
// since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}}
187187
BinaryC<int> auto [c, d] = get_S();
188-
// since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
188+
// since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}}
189189
}
190190

191191
template<typename T>
192192
void TemplUse() {
193193
UnaryC auto [a, b] = get_T<T>();
194-
// since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
194+
// since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}}
195195
BinaryC<T> auto [c, d] = get_T<T>();
196-
// since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
196+
// since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}}
197197
}
198198
#endif
199199
} // namespace cwg2635

clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ namespace X {
7575
void test_D() {
7676
#if __cplusplus >= 201703L
7777
for (extern auto [x, y] : D()) {
78-
} // expected-error@-1 {{decomposition declaration cannot be declared 'extern'}}
78+
} // expected-error@-1 {{structured binding declaration cannot be declared 'extern'}}
7979
// expected-error@-2 {{loop variable '[x, y]' may not be declared 'extern'}}
8080
#endif
8181
}

0 commit comments

Comments
 (0)