On 3/28/26 12:54 PM, Jakub Jelinek wrote:
On Fri, Mar 27, 2026 at 05:40:31PM +0100, Jakub Jelinek wrote:
The following patch implements addition of std::meta::current_function,
std::meta::current_class, std::meta::current_namespace metafunctions
from P3795R2 - Miscellaneous Reflection Cleanup paper.
Reposting as no longer RFC PATCH.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2026-03-28 Jakub Jelinek <[email protected]>
gcc/cp/
* metafns.gperf (enum metafn_code): Add METAFN_CURRENT_FUNCTION,
METAFN_CURRENT_CLASS and METAFN_CURRENT_NAMESPACE.
(enum metafn_kind): Add METAFN_KIND_INFO_VOID.
(current_function, current_class, current_namespace): New
metafunctions.
* pt.cc (value_dependent_expression_p): Make current_function(),
current_class() and current_namespace() calls dependent if they
are inside of template.
* reflect.cc (current_scope, eval_current_function,
eval_current_class, eval_current_namespace): New functions.
(eval_access_context_current): Use current_scope.
(process_metafunction): Handle METAFN_CURRENT_FUNCTION,
METAFN_CURRENT_CLASS and METAFN_CURRENT_NAMESPACE.
* metafns.h: Regenerate.
gcc/testsuite/
* g++.dg/reflect/current_function1.C: New test.
* g++.dg/reflect/current_function2.C: New test.
* g++.dg/reflect/current_class1.C: New test.
* g++.dg/reflect/current_class2.C: New test.
* g++.dg/reflect/current_namespace1.C: New test.
libstdc++-v3/
* include/std/meta (std::meta::current_function,
std::meta::current_class, std::meta::current_namespace): New
declarations.
* src/c++23/std.cc.in: Export those 3.
--- gcc/cp/pt.cc.jj 2026-03-27 10:17:14.033332387 +0100
+++ gcc/cp/pt.cc 2026-03-27 15:20:11.586883334 +0100
@@ -29794,12 +29794,19 @@ value_dependent_expression_p (tree expre
is enclosed by a scope corresponding to a templated entity. */
if (flag_reflection
&& fn
- && metafunction_p (fn)
- && id_equal (DECL_NAME (fn), "current")
- && DECL_CLASS_SCOPE_P (fn)
- && id_equal (TYPE_IDENTIFIER (DECL_CONTEXT (fn)),
- "access_context"))
- return true;
+ && metafunction_p (fn))
+ {
+ if (id_equal (DECL_NAME (fn), "current")
+ && DECL_CLASS_SCOPE_P (fn)
+ && id_equal (TYPE_IDENTIFIER (DECL_CONTEXT (fn)),
+ "access_context"))
+ return true;
+ /* Similarly for these 3 metafns. */
+ if (id_equal (DECL_NAME (fn), "current_function")
+ || id_equal (DECL_NAME (fn), "current_class")
+ || id_equal (DECL_NAME (fn), "current_namespace"))
Optionally, I wonder about looking up the METAFN_ code rather than a
bunch of id_equal?
--- gcc/cp/reflect.cc.jj 2026-03-27 10:17:14.033332387 +0100
+++ gcc/cp/reflect.cc 2026-03-27 15:51:18.122236375 +0100
@@ -6236,11 +6236,11 @@ eval_reflect_constant_array (location_t
return get_reflection_raw (loc, decl);
}
-/* Process std::meta::access_context::current. */
+/* Return CURRENT-SCOPE(P). */
static tree
-eval_access_context_current (location_t loc, const constexpr_ctx *ctx,
- tree call, bool *non_constant_p)
+current_scope (location_t loc, const constexpr_ctx *ctx, tree call,
There's already a current_scope in search.cc, this shouldn't have the
same name.
+/* Process std::meta::current_namespace. */
+
+static tree
+eval_current_namespace (location_t loc, const constexpr_ctx *ctx,
+ tree call, bool *non_constant_p)
+{
+ tree scope = current_scope (loc, ctx, call, non_constant_p,
+ "std::meta::current_namespace");
+ while (TREE_CODE (scope) != NAMESPACE_DECL)
+ {
+ if (DECL_P (scope))
+ scope = CP_DECL_CONTEXT (scope);
+ else
+ scope = CP_TYPE_CONTEXT (scope);
+ }
decl_namespace_context?
Jason