Introduce check_consteval_only_fn and call it in grokfndecl
and instantiate_body. Also make std::meta::exception special
member functions consteval.
I couldn't use check_consteval_only_fn in tsubst_function_decl
due to too many failures in libstdc++.
This adds to the Itanium mangling's <builtin-type> non-terminal:
::= Dm # std::meta::info (i.e., decltype(^^int))
and to <expr-primary>
::= L Dm <value reflection> E # C++26 reflection value
and new non-terminal:
<reflection> ::= nu # null reflection
::= vl <expression> # value
::= ob <expression> # object
::= vr <variable name> # variable
::= sb <sb name> # structured binding
::= fn <function encoding> # function
::= pa [ <nonnegative number> ] _ <encoding> # function parameter
::= en <prefix> <unqualified-name> # enumerator
::= an [ <nonnegative number> ] _ # annotation
::= ta <alias prefix> # type alias
::= ty <type> # type
::= dm <prefix> <unqualified-name> # non-static data member
::= un <prefix> [ <nonnegative number> ] _ # unnamed bit-field
::= ct [ <prefix> ] <unqualified-name> # class template
::= ft [ <prefix> ] <unqualified-name> # function template
::= vt [ <prefix> ] <unqualified-name> # variable template
::= at [ <prefix> ] <unqualified-name> # alias template
::= co [ <prefix> ] <unqualified-name> # concept
::= na [ <prefix> ] <unqualified-name> # namespace alias
::= ns [ <prefix> ] <unqualified-name> # namespace
::= ng # ^^::
::= ba [ <nonnegative number> ] _ <type> # direct base class relationship
::= ds <type> _ [ <unqualified-name> ] _
[ <alignment number> ] _ [ <bit-width number> ] _
[ n ] # data member description
The first 2 letters are based on which [meta.reflection.queries] function
is true on the reflection (nu is for std::meta::info{}, then for
reflection satisfying is_value, is_object, is_variable, is_structured_binding,
is_function, is_function_parameter, is_enumerator, is_annotation, is_type_alias,
is_type, is_nonstatic_data_member, is_bit_field && !has_identifier,
is_class_template, is_function_template, is_variable_template, is_alias_template,
is_concept, is_namespace_alias, is_namespace (except for ^^::), ^^::,
is_base and is_data_member_spec.
Function parameter reflections are encoded as Nth parameter of <encoding>,
where just _ is 1st, 0_ 2nd, 1_ 3rd etc. Annotation reflections are always
TU-local, so are mangled just as some implementation-defined non-negative number
unique to each annotation in the translation unit (_ is for 1st, 0_ 2nd, 1_ 3rd
etc.). Reflections of unnamed bit-fields are mangled as Nth unnamed bit-field
in a particular class represented by <prefix>. Reflections of direct base
class relationship are mangled as Nth direct base of <type>. Reflections of
data member descriptions are mangled as the elements of the quintuple separated
with _ characters, required type, optional identifier, optional alignment,
optional bit-width and optional character n if .no_unique_address is true.
Something that should be still specified is what mangling to use
for constructors and destructors, the patch currently uses C4 and D4 (which aren't
in the Itanium mangling base grammar, but there is nothing about the original
cdtors before they get cloned).
Plus fix up diagnostics of invalid annotations on namespaces.
Still needs tests for ordering of annotations on namespaces, finish
direct base relationship annotations, and guess test ordering of
annotations on all kinds of stuff, in templates etc.
Unfortunately this needed other changes. I need to have a function to
check if a splice-expression is valid so I had to factor out some code
out to check_splice_expr. Then I realized pt.cc needs to know in which
context the original SPLICE_EXPR was found so that needed two new flags.
compare_reflections has a new hack, but this should be fixed rather soon
on trunk and then the hack can go after a rebase.
I discovered a new ICE, fixed, and tested in crash13.C.
Annotations are to be done, but it should be easy.
This isn't in std::meta namespace, so I've used a FE builtin to implement
it instead of process_metafunction.
Also, I think using vector; in std::meta namespace is wrong, the standard
doesn't mention it and we don't want people to use std::meta::vector<int>
in their code.
This also fixes is_function_parameter and introduces REFLECT_EXPR_KIND
because sometimes the handle isn't enough to distinguish different
categories of reflections. For example, a PARM_DECL handle can be both
is_variable or is_function_parameter, but we can't know which one it is
just by looking at the PARM_DECL.
Some cases aren't done yet because they depend on the implementation
of other metafunctions and decision how those reflections will be
represented.
I had to change process_metafunction/get_info, because some tests
in the new testcase were failing otherwise. cxx_constant_value
is a wrong way to evaluate arguments of metafunction, they need to
be evaluated in the same constant expression context as the rest,
they can also throw, break, continue, return (the latter three only
when using GNU statement expressions), and e.g. could perform heap
allocation if something during the same evaluation later on deletes
those etc.
In particular, e.g. type_of (reflect_constant (42)) didn't work,
because it attempted to constant evaluate reflect_constant separately.
This is harder because we clear ENUM_IS_OPAQUE flag when parsing
the { of the enum specifier and so during parsing (or instantiation)
of the enumerator values we don't know if it is still being defined
or not (and COMPLETE_TYPE_P doesn't work due to enums with underlying
type).
We didn't detect namespace-scope vars of consteval-only type
without constexpr/constinit. Fixed by calling check_out_of_consteval_use
in cp_finish_decl.
Also remove consteval_only_var_p and consteval_only_type_p in
favor of consteval_only_p.
Sadly,
info baz () { return ^^int; }
still ICEs. To be fixed.