Implement the reflection part of P3920R0.

This commit is contained in:
Jakub Jelinek
2025-11-10 13:09:30 +01:00
committed by Marek Polacek
parent c47ed8c687
commit c3909532fd
9 changed files with 591 additions and 836 deletions

View File

@@ -165,8 +165,6 @@ enum metafn_code {
METAFN_IS_CONST_TYPE,
METAFN_IS_VOLATILE_TYPE,
METAFN_IS_TRIVIALLY_COPYABLE_TYPE,
METAFN_IS_TRIVIALLY_RELOCATABLE_TYPE,
METAFN_IS_REPLACEABLE_TYPE,
METAFN_IS_STANDARD_LAYOUT_TYPE,
METAFN_IS_EMPTY_TYPE,
METAFN_IS_POLYMORPHIC_TYPE,
@@ -207,7 +205,6 @@ enum metafn_code {
METAFN_IS_NOTHROW_SWAPPABLE_WITH_TYPE,
METAFN_IS_NOTHROW_SWAPPABLE_TYPE,
METAFN_IS_NOTHROW_DESTRUCTIBLE_TYPE,
METAFN_IS_NOTHROW_RELOCATABLE_TYPE,
METAFN_IS_IMPLICIT_LIFETIME_TYPE,
METAFN_HAS_VIRTUAL_DESTRUCTOR,
METAFN_HAS_UNIQUE_OBJECT_REPRESENTATIONS,
@@ -553,8 +550,6 @@ is_member_pointer_type, METAFN_IS_MEMBER_POINTER_TYPE, METAFN_KIND_BOOL_TINFO,
is_const_type, METAFN_IS_CONST_TYPE, METAFN_KIND_BOOL_TINFO,
is_volatile_type, METAFN_IS_VOLATILE_TYPE, METAFN_KIND_BOOL_TINFO,
is_trivially_copyable_type, METAFN_IS_TRIVIALLY_COPYABLE_TYPE, METAFN_KIND_BOOL_TINFO,
is_trivially_relocatable_type, METAFN_IS_TRIVIALLY_RELOCATABLE_TYPE, METAFN_KIND_BOOL_TINFO,
is_replaceable_type, METAFN_IS_REPLACEABLE_TYPE, METAFN_KIND_BOOL_TINFO,
is_standard_layout_type, METAFN_IS_STANDARD_LAYOUT_TYPE, METAFN_KIND_BOOL_TINFO,
is_empty_type, METAFN_IS_EMPTY_TYPE, METAFN_KIND_BOOL_TINFO,
is_polymorphic_type, METAFN_IS_POLYMORPHIC_TYPE, METAFN_KIND_BOOL_TINFO,
@@ -595,7 +590,6 @@ is_nothrow_move_assignable_type, METAFN_IS_NOTHROW_MOVE_ASSIGNABLE_TYPE, METAFN_
is_nothrow_swappable_with_type, METAFN_IS_NOTHROW_SWAPPABLE_WITH_TYPE, METAFN_KIND_BOOL_TINFO_TINFO,
is_nothrow_swappable_type, METAFN_IS_NOTHROW_SWAPPABLE_TYPE, METAFN_KIND_BOOL_TINFO,
is_nothrow_destructible_type, METAFN_IS_NOTHROW_DESTRUCTIBLE_TYPE, METAFN_KIND_BOOL_TINFO,
is_nothrow_relocatable_type, METAFN_IS_NOTHROW_RELOCATABLE_TYPE, METAFN_KIND_BOOL_TINFO,
is_implicit_lifetime_type, METAFN_IS_IMPLICIT_LIFETIME_TYPE, METAFN_KIND_BOOL_TINFO,
has_virtual_destructor, METAFN_HAS_VIRTUAL_DESTRUCTOR, METAFN_KIND_BOOL_TINFO,
has_unique_object_representations, METAFN_HAS_UNIQUE_OBJECT_REPRESENTATIONS, METAFN_KIND_BOOL_TINFO,

File diff suppressed because it is too large Load Diff

View File

@@ -4186,28 +4186,6 @@ eval_is_trivially_copyable_type (tree type)
return boolean_false_node;
}
/* Process std::meta::is_trivially_relocatable_type. */
static tree
eval_is_trivially_relocatable_type (tree type)
{
if (trivially_relocatable_type_p (type))
return boolean_true_node;
else
return boolean_false_node;
}
/* Process std::meta::is_replaceable_type. */
static tree
eval_is_replaceable_type (tree type)
{
if (replaceable_type_p (type))
return boolean_true_node;
else
return boolean_false_node;
}
/* Process std::meta::is_standard_layout_type. */
static tree
@@ -4634,14 +4612,6 @@ eval_is_nothrow_destructible_type (location_t loc, tree type)
return eval_type_trait (loc, type, CPTK_IS_NOTHROW_DESTRUCTIBLE);
}
/* Process std::meta::is_nothrow_relocatable_type. */
static tree
eval_is_nothrow_relocatable_type (location_t loc, tree type)
{
return eval_type_trait (loc, type, CPTK_IS_NOTHROW_RELOCATABLE);
}
/* Process std::meta::has_virtual_destructor. */
static tree
@@ -7870,10 +7840,6 @@ process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
return eval_is_volatile_type (h);
case METAFN_IS_TRIVIALLY_COPYABLE_TYPE:
return eval_is_trivially_copyable_type (h);
case METAFN_IS_TRIVIALLY_RELOCATABLE_TYPE:
return eval_is_trivially_relocatable_type (h);
case METAFN_IS_REPLACEABLE_TYPE:
return eval_is_replaceable_type (h);
case METAFN_IS_STANDARD_LAYOUT_TYPE:
return eval_is_standard_layout_type (h);
case METAFN_IS_EMPTY_TYPE:
@@ -7959,8 +7925,6 @@ process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
"is_nothrow_swappable");
case METAFN_IS_NOTHROW_DESTRUCTIBLE_TYPE:
return eval_is_nothrow_destructible_type (loc, h);
case METAFN_IS_NOTHROW_RELOCATABLE_TYPE:
return eval_is_nothrow_relocatable_type (loc, h);
case METAFN_IS_IMPLICIT_LIFETIME_TYPE:
return eval_is_implicit_lifetime_type (h);
case METAFN_HAS_VIRTUAL_DESTRUCTOR:

View File

@@ -128,12 +128,6 @@ eval (int n)
case 38:
is_trivially_copyable_type (^^n);
break;
case 39:
is_trivially_relocatable_type (^^n);
break;
case 40:
is_replaceable_type (^^n);
break;
case 41:
is_standard_layout_type (^^n);
break;
@@ -224,9 +218,6 @@ eval (int n)
case 70:
is_nothrow_destructible_type (^^n);
break;
case 71:
is_nothrow_relocatable_type (^^n);
break;
case 72:
has_virtual_destructor (^^n);
break;
@@ -319,8 +310,6 @@ static_assert (test (35));
static_assert (test (36));
static_assert (test (37));
static_assert (test (38));
static_assert (test (39));
static_assert (test (40));
static_assert (test (41));
static_assert (test (42));
static_assert (test (43));
@@ -351,7 +340,6 @@ static_assert (test (67));
static_assert (test (68));
static_assert (test (69));
static_assert (test (70));
static_assert (test (71));
static_assert (test (72));
static_assert (test (73));
static_assert (test (74));

View File

@@ -46,8 +46,6 @@ static_assert ((add_pointer (^^i), true)); // { dg-error "non-constant|uncaught
static_assert ((is_const_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_volatile_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_trivially_copyable_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_trivially_relocatable_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_replaceable_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_standard_layout_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_empty_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_polymorphic_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
@@ -78,7 +76,6 @@ static_assert ((is_nothrow_move_constructible_type (^^i), true)); // { dg-error
static_assert ((is_nothrow_copy_assignable_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_nothrow_move_assignable_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_nothrow_destructible_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((is_nothrow_relocatable_type (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((has_virtual_destructor (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((has_unique_object_representations (^^i), true)); // { dg-error "non-constant|uncaught exception" }
static_assert ((rank (^^i), true)); // { dg-error "non-constant|uncaught exception" }

View File

@@ -207,50 +207,6 @@ namespace N
void foo ();
}
namespace TR
{
struct A {};
struct B {
B ();
~B ();
B (const B &);
B (B &&);
B &operator= (const B &);
B &operator= (B &&);
};
struct C {
C (C &&) = delete;
C &operator= (C &&) = delete;
C () = default;
};
struct D : A {};
struct E : virtual A {};
struct F trivially_relocatable_if_eligible : virtual A {};
struct G { B data; };
struct H { ~H () = default; };
struct I { ~I (); };
I::~I () = default;
struct J { virtual ~J () = default; };
struct K { ~K () = delete; };
struct L { L (L &&) = default; };
struct M { M (M &&); };
M::M (M &&) = default;
struct N { N (N &&) = delete; };
}
int v = 1;
struct S1 { decltype (^^long) a; };
union U2 { int a; decltype (^^N::foo) b; };
@@ -316,36 +272,6 @@ static_assert (is_trivially_copyable_type (^^HasTemplateCCtor));
static_assert (is_trivially_copyable_type (^^MoveOnly));
static_assert (is_trivially_copyable_type (^^MoveOnly2));
static_assert (is_trivially_relocatable_type (^^TR::A));
static_assert (!is_trivially_relocatable_type (^^TR::B));
static_assert (!is_trivially_relocatable_type (^^TR::C));
static_assert (is_trivially_relocatable_type (^^TR::D));
static_assert (!is_trivially_relocatable_type (^^TR::E));
static_assert (!is_trivially_relocatable_type (^^TR::F));
static_assert (!is_trivially_relocatable_type (^^TR::G));
static_assert (is_trivially_relocatable_type (^^TR::H));
static_assert (!is_trivially_relocatable_type (^^TR::I));
static_assert (is_trivially_relocatable_type (^^TR::J));
static_assert (!is_trivially_relocatable_type (^^TR::K));
static_assert (!is_trivially_relocatable_type (^^TR::L));
static_assert (!is_trivially_relocatable_type (^^TR::M));
static_assert (!is_trivially_relocatable_type (^^TR::N));
static_assert (is_replaceable_type (^^TR::A));
static_assert (!is_replaceable_type (^^TR::B));
static_assert (!is_replaceable_type (^^TR::C));
static_assert (is_replaceable_type (^^TR::D));
static_assert (is_replaceable_type (^^TR::E));
static_assert (is_replaceable_type (^^TR::F));
static_assert (!is_replaceable_type (^^TR::G));
static_assert (is_replaceable_type (^^TR::H));
static_assert (!is_replaceable_type (^^TR::I));
static_assert (is_replaceable_type (^^TR::J));
static_assert (!is_replaceable_type (^^TR::K));
static_assert (!is_replaceable_type (^^TR::L));
static_assert (!is_replaceable_type (^^TR::M));
static_assert (!is_replaceable_type (^^TR::N));
static_assert (is_standard_layout_type (^^SLType));
static_assert (is_standard_layout_type (^^PODType));
static_assert (!is_standard_layout_type (^^NType));

View File

@@ -1,142 +0,0 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Test reflection type traits [meta.reflection.traits], type properties.
#include <meta>
using namespace std::meta;
struct A { A (A &&) = default; A &operator= (A &&) = default; ~A () = default; int a; };
static_assert (is_trivially_relocatable_type (^^A));
static_assert (is_nothrow_relocatable_type (^^A));
static_assert (is_replaceable_type (^^A));
struct B { B (B &&); B &operator= (B &&) = default; ~B () = default; int a; };
static_assert (!is_trivially_relocatable_type (^^B));
static_assert (!is_nothrow_relocatable_type (^^B));
static_assert (!is_replaceable_type (^^B));
struct C { C (C &&) = default; C &operator= (C &&); ~C () = default; int a; };
static_assert (!is_trivially_relocatable_type (^^C));
static_assert (is_nothrow_relocatable_type (^^C));
static_assert (!is_replaceable_type (^^C));
struct D { D (D &&) = delete; D &operator= (D &&) = default; int a; };
static_assert (!is_trivially_relocatable_type (^^D));
static_assert (!is_nothrow_relocatable_type (^^D));
static_assert (!is_replaceable_type (^^D));
struct E { E (E &&) = default; E &operator= (E &&) = delete; int a; };
static_assert (!is_trivially_relocatable_type (^^E));
static_assert (is_nothrow_relocatable_type (^^E));
static_assert (!is_replaceable_type (^^E));
struct F { F (F &&) = default; F &operator= (F &&) = default; ~F () = delete; int a; };
static_assert (!is_trivially_relocatable_type (^^F));
static_assert (!is_nothrow_relocatable_type (^^F));
static_assert (!is_replaceable_type (^^F));
struct G { G (const G &) = default; G &operator= (const G &) = default; int a; };
static_assert (is_trivially_relocatable_type (^^G));
static_assert (is_nothrow_relocatable_type (^^G));
static_assert (is_replaceable_type (^^G));
struct H { H (const H &); H &operator= (const H &) = default; int a; };
static_assert (!is_trivially_relocatable_type (^^H));
static_assert (!is_nothrow_relocatable_type (^^H));
static_assert (!is_replaceable_type (^^H));
struct I { I (const I &) = default; I &operator= (const I &); ~I () = default; int a; };
static_assert (!is_trivially_relocatable_type (^^I));
static_assert (is_nothrow_relocatable_type (^^I));
static_assert (!is_replaceable_type (^^I));
struct J { J (const J &) = delete; J &operator= (const J &) = default; int a; };
static_assert (!is_trivially_relocatable_type (^^J));
static_assert (!is_nothrow_relocatable_type (^^J));
static_assert (!is_replaceable_type (^^J));
struct K { K (const K &) = default; K &operator= (const K &) = delete; int a; };
static_assert (!is_trivially_relocatable_type (^^K));
static_assert (is_nothrow_relocatable_type (^^K));
static_assert (!is_replaceable_type (^^K));
struct M;
struct L { L (L &&) = default; L (M &&); L &operator= (L &&) = default; int a; };
static_assert (is_trivially_relocatable_type (^^L));
static_assert (is_nothrow_relocatable_type (^^L));
static_assert (is_replaceable_type (^^L));
struct M : public L { using L::L; M (const M &); M &operator= (M &&) = default; int b; };
static_assert (!is_trivially_relocatable_type (^^M));
static_assert (!is_nothrow_relocatable_type (^^M));
static_assert (!is_replaceable_type (^^M));
struct O;
struct N { N (N &&) = default; N &operator= (N &&) = default; N &operator= (O &&); int a; };
static_assert (is_trivially_relocatable_type (^^N));
static_assert (is_nothrow_relocatable_type (^^N));
static_assert (is_replaceable_type (^^N));
struct O : public N { using N::operator=; O (O &&) = default; int b; };
static_assert (!is_trivially_relocatable_type (^^O));
static_assert (is_nothrow_relocatable_type (^^O));
static_assert (!is_replaceable_type (^^O));
struct Q;
struct P { template <typename T> P (T &&) {} };
static_assert (is_trivially_relocatable_type (^^P));
static_assert (is_nothrow_relocatable_type (^^P));
static_assert (is_replaceable_type (^^P));
struct Q : public P { using P::P; Q (const Q &); };
static_assert (!is_trivially_relocatable_type (^^Q));
static_assert (!is_nothrow_relocatable_type (^^Q));
static_assert (!is_replaceable_type (^^Q));
struct S;
struct R { R (const R &) = default; R (const M &); R &operator= (R &&) = default; int a; };
static_assert (is_trivially_relocatable_type (^^R));
static_assert (is_nothrow_relocatable_type (^^R));
static_assert (is_replaceable_type (^^R));
struct S : public R { using R::R; S &operator= (S &&) = default; int b; };
static_assert (!is_trivially_relocatable_type (^^S));
static_assert (!is_nothrow_relocatable_type (^^S));
static_assert (!is_replaceable_type (^^S));
struct T { T (T &&) = default; T &operator= (T &&) = default; ~T (); int a; };
static_assert (!is_trivially_relocatable_type (^^T));
static_assert (is_nothrow_relocatable_type (^^T));
static_assert (!is_replaceable_type (^^T));
struct U { U (const U &) = default; U &operator= (const U &) = default; ~U (); int a; };
static_assert (!is_trivially_relocatable_type (^^U));
static_assert (is_nothrow_relocatable_type (^^U));
static_assert (!is_replaceable_type (^^U));
struct V { public: V (); private: V (V &&) = default; V &operator= (V &&) = default; ~V () = default; int a; };
static_assert (is_trivially_relocatable_type (^^V));
static_assert (is_nothrow_relocatable_type (^^V));
static_assert (is_replaceable_type (^^V));

View File

@@ -449,8 +449,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_const_type(info);
consteval bool is_volatile_type(info);
consteval bool is_trivially_copyable_type(info);
consteval bool is_trivially_relocatable_type(info);
consteval bool is_replaceable_type(info);
consteval bool is_standard_layout_type(info);
consteval bool is_empty_type(info);
consteval bool is_polymorphic_type(info);
@@ -504,7 +502,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_nothrow_swappable_type(info);
consteval bool is_nothrow_destructible_type(info);
consteval bool is_nothrow_relocatable_type(info);
consteval bool is_implicit_lifetime_type(info);

View File

@@ -2220,8 +2220,6 @@ export namespace std
using std::meta::is_const_type;
using std::meta::is_volatile_type;
using std::meta::is_trivially_copyable_type;
using std::meta::is_trivially_relocatable_type;
using std::meta::is_replaceable_type;
using std::meta::is_standard_layout_type;
using std::meta::is_empty_type;
using std::meta::is_polymorphic_type;
@@ -2262,7 +2260,6 @@ export namespace std
using std::meta::is_nothrow_swappable_with_type;
using std::meta::is_nothrow_swappable_type;
using std::meta::is_nothrow_destructible_type;
using std::meta::is_nothrow_relocatable_type;
using std::meta::is_implicit_lifetime_type;
using std::meta::has_virtual_destructor;
using std::meta::has_unique_object_representations;