This completes the implementation of P1091R3 and P1381R1. This patch allow the capture of structured bindings both for C++20+ and C++17, with extension/compat warning. In addition, capturing an anonymous union member, a bitfield, or a structured binding thereof now has a better diagnostic. We only support structured bindings - as opposed to other kinds of structured statements/blocks. We still emit an error for those. In addition, support for structured bindings capture is entirely disabled in OpenMP mode as this needs more investigation - a specific diagnostic indicate the feature is not yet supported there. Note that the rest of P1091R3 (static/thread_local structured bindings) was already implemented. at the request of @shafik, i can confirm the correct behavior of lldb wit this change. Fixes https://github.com/llvm/llvm-project/issues/54300 Fixes https://github.com/llvm/llvm-project/issues/54300 Fixes https://github.com/llvm/llvm-project/issues/52720 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D122768
142 lines
2.6 KiB
C++
142 lines
2.6 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
|
|
// expected-no-diagnostics
|
|
|
|
template <typename, typename>
|
|
constexpr bool is_same = false;
|
|
template <typename T>
|
|
constexpr bool is_same<T, T> = true;
|
|
|
|
struct S {
|
|
int i;
|
|
int &j;
|
|
};
|
|
|
|
void check_category() {
|
|
int a = 42;
|
|
{
|
|
auto [v, r] = S{1, a};
|
|
(void)[ v, r ] {
|
|
static_assert(is_same<decltype(v), int>);
|
|
static_assert(is_same<decltype(r), int &>);
|
|
};
|
|
}
|
|
{
|
|
auto [v, r] = S{1, a};
|
|
(void)[&v, &r ] {
|
|
static_assert(is_same<decltype(v), int>);
|
|
static_assert(is_same<decltype(r), int &>);
|
|
};
|
|
}
|
|
{
|
|
S s{1, a};
|
|
const auto &[v, r] = s;
|
|
(void)[ v, r ] {
|
|
static_assert(is_same<decltype(v), const int>);
|
|
static_assert(is_same<decltype(r), int &>);
|
|
};
|
|
}
|
|
{
|
|
S s{1, a};
|
|
const auto &[v, r] = s;
|
|
(void)[&v, &r ] {
|
|
static_assert(is_same<decltype(v), const int>);
|
|
static_assert(is_same<decltype(r), int &>);
|
|
};
|
|
}
|
|
}
|
|
|
|
void check_array() {
|
|
int arr[2] = {42, 42};
|
|
auto &[a, b] = arr;
|
|
(void)[ a, &b ] {
|
|
static_assert(is_same<decltype(a), int>);
|
|
static_assert(is_same<decltype(b), int>);
|
|
};
|
|
}
|
|
|
|
struct tuple {
|
|
template <unsigned long I>
|
|
decltype(auto) get() {
|
|
if constexpr (I == 0) {
|
|
return a;
|
|
} else {
|
|
return b;
|
|
}
|
|
}
|
|
|
|
template <unsigned long I>
|
|
decltype(auto) get() const {
|
|
if constexpr (I == 0) {
|
|
return a;
|
|
} else {
|
|
return b;
|
|
}
|
|
}
|
|
|
|
int a = 0;
|
|
int &b = a;
|
|
};
|
|
|
|
namespace std {
|
|
|
|
template <typename T>
|
|
struct tuple_size {
|
|
static constexpr unsigned long value = 2;
|
|
};
|
|
|
|
template <unsigned long, typename T>
|
|
struct tuple_element;
|
|
|
|
template <>
|
|
struct tuple_element<0, tuple> {
|
|
using type = int;
|
|
};
|
|
|
|
template <>
|
|
struct tuple_element<1, tuple> {
|
|
using type = int &;
|
|
};
|
|
|
|
template <>
|
|
struct tuple_element<0, const tuple> {
|
|
using type = int;
|
|
};
|
|
|
|
template <>
|
|
struct tuple_element<1, const tuple> {
|
|
using type = const int &;
|
|
};
|
|
} // namespace std
|
|
|
|
void check_tuple_like() {
|
|
tuple t;
|
|
{
|
|
auto [v, r] = t;
|
|
(void)[ v, r ] {
|
|
static_assert(is_same<decltype(v), int>);
|
|
static_assert(is_same<decltype(r), int &>);
|
|
};
|
|
}
|
|
{
|
|
auto &[v, r] = t;
|
|
(void)[&v, &r ] {
|
|
static_assert(is_same<decltype(v), int>);
|
|
static_assert(is_same<decltype(r), int &>);
|
|
};
|
|
}
|
|
{
|
|
const auto &[v, r] = t;
|
|
(void)[ v, r ] {
|
|
static_assert(is_same<decltype(v), int>);
|
|
static_assert(is_same<decltype(r), const int &>);
|
|
};
|
|
}
|
|
{
|
|
const auto &[v, r] = t;
|
|
(void)[&v, &r ] {
|
|
static_assert(is_same<decltype(v), int>);
|
|
static_assert(is_same<decltype(r), const int &>);
|
|
};
|
|
}
|
|
}
|