C++ Logo

sg7

Advanced search

Re: Update: P1240R2 — Scalable Reflection - Clarifications

From: David Rector <davrec_at_[hidden]>
Date: Mon, 31 Jan 2022 19:47:12 -0500
> On Jan 31, 2022, at 1:23 PM, Daveed Vandevoorde via SG7 <sg7_at_[hidden]> wrote:
>
>
>
>> On Jan 31, 2022, at 1:10 PM, Peter Dimov <pdimov_at_[hidden]> wrote:
>>
>> Daveed Vandevoorde wrote:
>>>> In Boost.Describe, I support a "modifier" mod_inherited, which
>>>> includes the inherited members in the "members_of" list. I don't
>>>> currently support it for the base classes, but I could. So when you
>>>> have
>>>>
>>>> struct B {};
>>>> struct D1: B {};
>>>> struct D2: B {};
>>>> struct C: D1, D2 {};
>>>>
>>>> and you say describe_bases<C, mod_any_access | mod_inherited>, you
>>>> would get a list of base class descriptors [desc(D1), desc(B), desc(D2),
>>> desc(B)].
>>>
>>> Okay, so like the alternative API I described where you also get indirect bases.
>>> Do the descriptors maintain information about the derivation path?
>>
>> Not at the moment.
>>
>> In a prototype of mine (before the official Describe) I had base descriptors
>> have something like
>>
>> struct Desc
>> {
>> static constexpr auto pointer = [](C* p) -> B*
>> {
>> return (B*)(D1*)p;
>> };
>> };
>>
>> with the derivation path implicitly encoded in the lambda. But in Describe
>> I don't provide `pointer` for base descriptors at all, having, err, postponed it.
>>
>> A similar issue actually exists for inherited members. If you have
>>
>> struct B { int m; };
>> struct D1: B {};
>> struct D2: B {};
>> struct C: D1, D2 {};
>>
>> and you get the all members list for C, including inherited, that would
>> be two descriptors for B::m. At the moment in Describe both of these have
>>
>> struct Desc
>> {
>> static constexpr auto pointer = &B::m;
>> };
>>
>> but that's wrong; they should actually have two different member pointers
>> of type `int D::*`, one pointing to the first `m`, other to the second.
>>
>> I don't think this is achievable without compiler support, though.
>> Both &C::D1::m and &C::D2::m give &B::m.

This reminds me of a clang issue https://lists.llvm.org/pipermail/cfe-dev/2021-November/069428.html <https://lists.llvm.org/pipermail/cfe-dev/2021-November/069428.html> which might shed some light.

The gist: the clang static analyzer had a check that would warn you if two declarations in certain kinds of expressions were identical. E.g. `a || a`. The problem is that it would also warn on this: `std::is_same<int, char>::value == std::is_same<float, double>::value`.
Why? Because they are both `std::false_type` — same as &C::D1::m and &C::D2::m reflect the same AST declaration, &B::m

The solution (https://reviews.llvm.org/D114622 <https://reviews.llvm.org/D114622>) was to compare the *expressions* referencing the declarations, rather than the declarations themselves: this would differentiate the different derived to base paths.

So, this probably indicates that a means of reflecting an expression referencing a declaration (a DeclRefExpr in clang) might be needed independently of a reflection of the declaration itself (perhaps double parentheses: &((C::D1::m)) ); and corresponding queries might be needed to fetch a) the reflected scope qualifier and b) the reflected declaration of such a reflection.


>
> Right. Maybe if you had something like:
>
> template<auto PM, typename D, typename … Path> struct X {
> static constexpr auto pointer = PM;
> static auto select(D *ptr) { … }
> }
>
> where the “select” operation would apply casts down Path and then "pointer” could select from that?
>
> Seems convoluted, admittedly.
>
>
>>
>>> IIRC, in the context of P1240 someone once suggested that we should be able
>>> to write something like:
>>>
>>> D *p;
>>> auto *pb = p->[:bases_of(^D)[0]:];
>>>
>>> (assuming D has a base class). That’s similar to your suggestion of a more
>>> general pointer-to-member value concept, but it has the advantage of
>>> generalizing to bit fields as well.
>>
>> That would indeed be a way to do it.
>
> Okay, I’ll se if we can pursue that possibility then.
>
> Daveed
>
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7


Received on 2022-02-01 00:47:15