Skip to content

Mangling of C++26 reflections #208

@jakubjelinek

Description

@jakubjelinek

I think we need mangling for all the 22 different kinds of reflection constants (and for some kinds different ways how to mangle different types of the reflections of the same kind, see later.
https://eel.is/c++draft/basic.fundamental#17 lists the 22 kinds (0th is the null reflection). std::meta::info values which are template parameter equivalent need to mangle the same, those which are not need to mangle differently.

#include <meta>

template <auto A>
void foo () {}

int arr[] = {1, 2, 3};
auto [a1, a2, a3] = arr;
[[=1]] void fn(int n);
enum Enum { A };
using Alias = int;
struct B {};
struct S : B {
  int mem;
  int : 0;
};
template<auto> struct TCls {};
template<auto> void TFn();
template<auto> int TVar;
template<auto N> using TAlias = TCls<N>;
template<auto> concept Concept = requires { true; };
namespace NS {};
namespace NSAlias = NS;

constexpr auto ctx = std::meta::access_context::current();

void bar () {
  foo <std::meta::info {}> (); // null reflection
  foo <std::meta::reflect_constant(42)> (); // value
  foo <std::meta::reflect_object(arr[1])> (); // object
  foo <^^arr> (); // variable
  foo <^^a3> (); // structured binding
  foo <^^fn> (); // function
  foo <std::meta::parameters_of(^^fn)[0]> (); // function parameter
  foo <^^Enum::A> (); // enumerator
  foo <std::meta::annotations_of(^^fn)[0]> (); // annotation
  foo <^^Alias> (); // type alias; could be either also specialization of template alias
  foo <^^S> (); // type
  foo <^^S::mem> (); // class member
  foo <std::meta::members_of(^^S, ctx)[1]> (); // unnamed bit-field
  foo <^^TCls> (); // class template
  foo <^^TFn> (); // function template
  foo <^^TVar> (); // variable template
  foo <^^TAlias> (); // alias template
  foo <^^Concept> (); // concept
  foo <^^NSAlias> (); // namespace alias
  foo <^^NS> (); // namespace
  foo <^^::> (); // global namespace (special case of namespace that might need to be mangled differently
  foo <std::meta::bases_of(^^S, ctx)[0]> (); // direct base class relationship
  foo <std::meta::data_member_spec(^^int, {.name="member"})> (); // data member description
}

Guess we need some 2 letter prefix for mangling all std::meta::info objects and then one (or two letters?) for each of the 22 kinds and then depending on the kind some way how to mangle what exactly it reflects, ideally using some existing non-terminals in the mangling grammar to mangle existing concepts like namespaces (except :: is special), types, variables, enumerators, ...
For value it can be a scalar constant (so 42, 1.0f, or even a std::meta::info constant recursively) or a structured type constant, those can be mangled guess like the non-type template arguments, types like template arguments. For annotations, I think best is to mangle it as Nth
annotation of something (function, namespace, variable, etc.). Direct base class relationship could be mangled as Nth direct base of a particular derived type. Data member description needs to be mangled as quintuple of type, optional identifier, optional integer constant (alignment), optional integer constant (bit_width) and integer constant (false/true). For parameters again Nth parameter of some function.
For class members or unnamed bit-fields or variables it might be interesting, some class members can be easy if they have a unique name, mangle the corresponding class name and the name in it. Except that there can be unnamed class members (e.g. anonymous unions, or the unnamed bitfields). For class members those could be still in theory mangled as Nth non-static data member or Nth unnamed bit-field.
What to do for anonymous unions at class scope? Pedantically

static union {};

is invalid but some compiler accept that (though e.g. in GCC it is not reachable through members_of right now because we though we don't have to bother with something hard which is not pedantically valid).

@katzdm @jicama @zygoloid

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions