mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
Implement std::meta::is_{{conversion,operator}_function,literal_operator,constructor}_template.
Still no idea how to test is_conversion_function_template and is_constructor_template. Also, unsure if is_constructor is not incorrect (i.e. whether it should only return true for FUNCTION_DECLs and not TEMPLATE_DECLs).
This commit is contained in:
committed by
Marek Polacek
parent
c80c5aba39
commit
ab12ae0594
@@ -1684,10 +1684,68 @@ eval_is_destructor (tree r)
|
||||
Otherwise, false. */
|
||||
|
||||
static tree
|
||||
eval_is_conversion_function_template (const_tree)
|
||||
eval_is_conversion_function_template (tree r)
|
||||
{
|
||||
// Need members_of to test this.
|
||||
gcc_assert (!"TODO");
|
||||
r = MAYBE_BASELINK_FUNCTIONS (r);
|
||||
r = OVL_FIRST (r);
|
||||
|
||||
if (DECL_FUNCTION_TEMPLATE_P (r) && DECL_CONV_FN_P (r))
|
||||
return boolean_true_node;
|
||||
else
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
/* Process std::meta::is_operator_function_template.
|
||||
Returns: true if r represents an operator function template.
|
||||
Otherwise, false. */
|
||||
|
||||
static tree
|
||||
eval_is_operator_function_template (tree r)
|
||||
{
|
||||
r = MAYBE_BASELINK_FUNCTIONS (r);
|
||||
r = OVL_FIRST (r);
|
||||
|
||||
if (DECL_FUNCTION_TEMPLATE_P (r))
|
||||
{
|
||||
r = STRIP_TEMPLATE (r);
|
||||
if (DECL_OVERLOADED_OPERATOR_P (r) && !DECL_CONV_FN_P (r))
|
||||
return boolean_true_node;
|
||||
}
|
||||
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
/* Process std::meta::is_literal_operator_template.
|
||||
Returns: true if r represents a literal operator template.
|
||||
Otherwise, false. */
|
||||
|
||||
static tree
|
||||
eval_is_literal_operator_template (tree r)
|
||||
{
|
||||
/* No MAYBE_BASELINK_FUNCTIONS here because a literal operator
|
||||
template must be a non-member function template. */
|
||||
r = OVL_FIRST (r);
|
||||
|
||||
if (DECL_FUNCTION_TEMPLATE_P (r) && UDLIT_OPER_P (DECL_NAME (r)))
|
||||
return boolean_true_node;
|
||||
else
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
/* Process std::meta::is_constructor_template.
|
||||
Returns: true if r represents a function that is an operator function
|
||||
template. Otherwise, false. */
|
||||
|
||||
static tree
|
||||
eval_is_constructor_template (tree r)
|
||||
{
|
||||
r = MAYBE_BASELINK_FUNCTIONS (r);
|
||||
r = OVL_FIRST (r);
|
||||
|
||||
if (DECL_FUNCTION_TEMPLATE_P (r) && DECL_CONSTRUCTOR_P (r))
|
||||
return boolean_true_node;
|
||||
else
|
||||
return boolean_false_node;
|
||||
}
|
||||
|
||||
/* Process std::meta::operator_of.
|
||||
@@ -2403,14 +2461,11 @@ eval_has_identifier (tree r, reflect_kind kind)
|
||||
}
|
||||
if (eval_is_template (r) == boolean_true_node)
|
||||
{
|
||||
#if 0
|
||||
// TODO: Implement these first
|
||||
if (eval_is_constructor_template (r) == boolean_true_node
|
||||
|| eval_is_operator_function_template (r) == boolean_true_node
|
||||
|| eval_is_conversion_function_template (r) == boolean_true_node)
|
||||
return boolean_false_node;
|
||||
else
|
||||
#endif
|
||||
return boolean_true_node;
|
||||
}
|
||||
if (eval_is_function_parameter (r, kind) == boolean_true_node)
|
||||
@@ -4300,6 +4355,12 @@ process_metafunction (const constexpr_ctx *ctx, tree call,
|
||||
return eval_is_destructor (h);
|
||||
if (!strcmp (ident, "conversion_function_template"))
|
||||
return eval_is_conversion_function_template (h);
|
||||
if (!strcmp (ident, "operator_function_template"))
|
||||
return eval_is_operator_function_template (h);
|
||||
if (!strcmp (ident, "literal_operator_template"))
|
||||
return eval_is_literal_operator_template (h);
|
||||
if (!strcmp (ident, "constructor_template"))
|
||||
return eval_is_constructor_template (h);
|
||||
if (!strcmp (ident, "function_type"))
|
||||
return eval_is_function_type (loc, ctx, h, jump_target);
|
||||
if (!strcmp (ident, "void_type"))
|
||||
|
||||
@@ -22,7 +22,7 @@ struct S {
|
||||
|
||||
struct T {
|
||||
template <typename T>
|
||||
operator T();
|
||||
operator T ();
|
||||
};
|
||||
|
||||
bool operator&&(const S&, const S&);
|
||||
@@ -35,9 +35,8 @@ int operator""_a(const char *);
|
||||
template<char...>
|
||||
int operator""_b();
|
||||
|
||||
#if 0
|
||||
constexpr auto conversion_template =
|
||||
(members_of(^^T, ctx) | std::views::filter(std::meta::is_template)).front();
|
||||
//constexpr auto conversion_template =
|
||||
// (members_of(^^T, ctx) | std::views::filter(std::meta::is_template)).front();
|
||||
|
||||
static_assert (!is_conversion_function_template (null_reflection));
|
||||
static_assert (!is_conversion_function_template (^^int));
|
||||
@@ -48,8 +47,7 @@ static_assert (!is_conversion_function_template (^^operator&&));
|
||||
static_assert (!is_conversion_function_template (^^operator||));
|
||||
static_assert (!is_conversion_function_template (^^S::operator-));
|
||||
static_assert (!is_conversion_function_template (^^S::operator int));
|
||||
static_assert (is_conversion_function_template (conversion_template));
|
||||
//static_assert (is_conversion_function_template (conversion_template));
|
||||
static_assert (!is_conversion_function_template (^^S::fn));
|
||||
static_assert (!is_conversion_function_template (^^operator""_a));
|
||||
static_assert (!is_conversion_function_template (^^operator""_b));
|
||||
#endif
|
||||
|
||||
55
gcc/testsuite/g++.dg/reflect/is_literal_operator_template1.C
Normal file
55
gcc/testsuite/g++.dg/reflect/is_literal_operator_template1.C
Normal file
@@ -0,0 +1,55 @@
|
||||
// { dg-do compile { target c++26 } }
|
||||
// { dg-additional-options "-freflection" }
|
||||
// Test std::meta::is_literal_operator_template.
|
||||
|
||||
#include <meta>
|
||||
|
||||
using namespace std::meta;
|
||||
|
||||
constexpr info null_reflection;
|
||||
void foo ();
|
||||
|
||||
struct S {
|
||||
S &operator+(const S&);
|
||||
|
||||
template <typename T>
|
||||
S &operator-(const S&);
|
||||
|
||||
operator int();
|
||||
|
||||
void fn();
|
||||
};
|
||||
|
||||
struct T {
|
||||
template <typename T>
|
||||
operator T();
|
||||
};
|
||||
|
||||
bool operator&&(const S&, const S&);
|
||||
|
||||
template <typename T>
|
||||
bool operator||(const S&, const T&);
|
||||
|
||||
int operator""_a(const char *);
|
||||
|
||||
template<char...>
|
||||
int operator""_b();
|
||||
|
||||
//constexpr auto conversion_template =
|
||||
// (members_of(^^T, ctx) | std::views::filter(std::meta::is_template)).front();
|
||||
|
||||
static_assert (!is_literal_operator_template (null_reflection));
|
||||
static_assert (!is_literal_operator_template (^^int));
|
||||
static_assert (!is_literal_operator_template (^^::));
|
||||
static_assert (!is_literal_operator_template (^^foo));
|
||||
static_assert (!is_literal_operator_template (^^S::operator+));
|
||||
static_assert (!is_literal_operator_template (^^operator&&));
|
||||
static_assert (!is_literal_operator_template (^^operator||));
|
||||
static_assert (!is_literal_operator_template (^^operator||<int>));
|
||||
static_assert (!is_literal_operator_template (^^S::operator-));
|
||||
static_assert (!is_literal_operator_template (^^S::operator-<int>));
|
||||
static_assert (!is_literal_operator_template (^^S::operator int));
|
||||
//static_assert (!is_literal_operator_template (conversion_template));
|
||||
static_assert (!is_literal_operator_template (^^S::fn));
|
||||
static_assert (!is_literal_operator_template (^^operator""_a));
|
||||
static_assert (is_literal_operator_template (^^operator""_b));
|
||||
@@ -0,0 +1,56 @@
|
||||
// { dg-do compile { target c++26 } }
|
||||
// { dg-additional-options "-freflection" }
|
||||
// Test std::meta::is_operator_function_template.
|
||||
|
||||
#include <meta>
|
||||
|
||||
using namespace std::meta;
|
||||
|
||||
constexpr info null_reflection;
|
||||
void foo ();
|
||||
|
||||
struct S {
|
||||
S &operator+(const S&);
|
||||
|
||||
template <typename T>
|
||||
S &operator-(const S&);
|
||||
|
||||
operator int();
|
||||
|
||||
void fn();
|
||||
};
|
||||
|
||||
struct T {
|
||||
template <typename T>
|
||||
operator T ();
|
||||
};
|
||||
|
||||
bool operator&&(const S&, const S&);
|
||||
|
||||
template <typename T>
|
||||
bool operator||(const S&, const T&);
|
||||
|
||||
int operator""_a(const char *);
|
||||
|
||||
template<char...>
|
||||
int operator""_b();
|
||||
|
||||
//constexpr auto conversion_template =
|
||||
// (members_of(^^T, ctx) | std::views::filter(std::meta::is_template)).front();
|
||||
|
||||
static_assert (!is_operator_function_template (null_reflection));
|
||||
static_assert (!is_operator_function_template (^^int));
|
||||
static_assert (!is_operator_function_template (^^::));
|
||||
static_assert (!is_operator_function_template (^^foo));
|
||||
static_assert (!is_operator_function_template (^^S::operator+));
|
||||
static_assert (!is_operator_function_template (^^operator&&));
|
||||
static_assert (is_operator_function_template (^^operator||));
|
||||
static_assert (!is_operator_function_template (^^operator||<int>));
|
||||
static_assert (is_operator_function_template (^^S::operator-));
|
||||
static_assert (!is_operator_function_template (^^S::operator-<int>));
|
||||
static_assert (is_operator_function_template (template_of (^^S::operator-<int>)));
|
||||
static_assert (!is_operator_function_template (^^S::operator int));
|
||||
//static_assert (!is_operator_function_template (conversion_template));
|
||||
static_assert (!is_operator_function_template (^^S::fn));
|
||||
static_assert (!is_operator_function_template (^^operator""_a));
|
||||
static_assert (!is_operator_function_template (^^operator""_b));
|
||||
@@ -228,6 +228,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
consteval bool is_class_template(info);
|
||||
consteval bool is_alias_template(info);
|
||||
consteval bool is_conversion_function_template(info);
|
||||
consteval bool is_operator_function_template(info);
|
||||
consteval bool is_literal_operator_template(info);
|
||||
consteval bool is_constructor_template(info);
|
||||
consteval bool is_concept(info);
|
||||
|
||||
consteval bool is_object(info);
|
||||
|
||||
Reference in New Issue
Block a user