implementation of P0194 + examples of higher level libs

476 views
Skip to first unread message

Matus Chochlik

unread,
Sep 17, 2016, 1:46:52 AM9/17/16
to refle...@isocpp.org
Dear list,

We are preparing the next revision of P0194 for the meeting in
Issaquah and the implementation in clang is almost finished (it needs
some further minor changes, cleanup and polishing + it only fakes the
use of c++-concepts as they are not yet implemented in clang), but
it's already usable.

The forked repository can be found here: https://github.com/matus-chochlik/clang

To try it out, follow the instructions from here:
http://clang.llvm.org/get_started.html
but instead of the official clang repo use the fork.

The `-freflection` option needs to be specified to enable it and the
`__cpp_reflection` PP symbol is set to 1 if it is enabled.


There is also a set of higher level reflection libraries built on top
of reflexpr hosted here:
https://github.com/matus-chochlik/mirror

It is still work-in-progress and subject to changes, but it already
has some examples and docs:
http://matus-chochlik.github.io/mirror/doc/html/

The docs also briefly describe the proposed reflection facility, but
note, that the 'mirror' libraries are *not* at the moment and in the
current form part of the proposals. They are just examples showing
that our proposal can serve as the basis for various higher-level
reflection libraries using different paradigms.

Best regards,

Matus

Mikhail Strelnikov

unread,
Sep 22, 2016, 10:20:41 PM9/22/16
to SG 7 - Reflection
Hello Matúš,

I've tried your fork, it is awesome!

I had to add "#include <random>" to clang\lib\AST\ASTContext.cpp to compile it with VC.

Then I've tried to compile "Hello World" example from docs (it asserts at SemaTemplate.cpp:5078 when -std=c++1z but works with -std=c++14) and got linker error:
undefined reference to `std::meta::get_base_name<std::__metaobject<o_random_number_ul> >::value'

When your fork will be merged?

Thanks.

Matus Chochlik

unread,
Sep 23, 2016, 5:20:43 AM9/23/16
to refle...@isocpp.org
Hi Mikhail,


On Fri, Sep 23, 2016 at 4:20 AM, Mikhail Strelnikov
<mikhail.s...@gmail.com> wrote:
> Hello Matúš,
>
> I've tried your fork, it is awesome!

Thank you for your kind words.

>
> I had to add "#include <random>" to clang\lib\AST\ASTContext.cpp to compile
> it with VC.
>
> Then I've tried to compile "Hello World" example from docs (it asserts at
> SemaTemplate.cpp:5078 when -std=c++1z but works with -std=c++14) and got
> linker error:
> undefined reference to
> `std::meta::get_base_name<std::__metaobject<o_random_number_ul> >::value'

Thanks for the feeback. I'll have a look at the assert. The issue with
`get_base_name<>::value` is related to the fact that when the `value`
static constexpr array does have a definition then the individual
characters cease to be constexpr values. When the `value` is declared,
but not defined then you cannot take its address.

We are still discussing how to resolve this. In the future we plan to
replace the `char` array with some compile-time string if any of the
proposals make it to the standard. I will probably add some workaround
for this in the meantime.

>
> When your fork will be merged?

We don't have any particular deadline, probably when/if the proposal
makes it to a TS and when the implementation is more mature and better
tested.

Best regards,

Matus

Mikhail Strelnikov

unread,
Sep 28, 2016, 7:29:24 AM9/28/16
to SG 7 - Reflection
Hi Matúš, 

There are some more questions/issues for you :-)

It crashes when cross-compiling 64->32 on Windows probably because 64-bit value calculated by encodeMetaobjectId is truncated to 32-bit because "Target->getPointerWidth(0);" returns 32 (at ASTContext.cpp:1783).

Another issue:
static_assert(std::meta::reflects_same_v<reflexpr(), reflexpr()>, ""); // OK
static_assert(std::meta::reflects_same_v<reflexpr(int), reflexpr(int)>, ""); // Fail

With get_scope_m I can find all enclosing namespaces of and given namespace. How do I find nested namespaces of given namespace?
I see how to find data members, but how do I find member functions?
There is std::meta::is_virtual in <reflexpr>, is it described anywhere?

Thanks.

Matus Chochlik

unread,
Sep 28, 2016, 8:51:49 AM9/28/16
to refle...@isocpp.org
Hi Mikhail,

Thanks for the feedback!

On Wed, Sep 28, 2016 at 1:29 PM, Mikhail Strelnikov
<mikhail.s...@gmail.com> wrote:
> Hi Matúš,
>
> There are some more questions/issues for you :-)
>
> It crashes when cross-compiling 64->32 on Windows probably because 64-bit
> value calculated by encodeMetaobjectId is truncated to 32-bit because
> "Target->getPointerWidth(0);" returns 32 (at ASTContext.cpp:1783).

I have replaced this with `8*sizeof(void*)` since it should have the
same width as the compiler's pointers.

>
> Another issue:
> static_assert(std::meta::reflects_same_v<reflexpr(), reflexpr()>, ""); // OK
> static_assert(std::meta::reflects_same_v<reflexpr(int), reflexpr(int)>, "");
> // Fail

This was on the TODO list, I did some additional improvements, which
are not yet perfect, but it should work properly in more cases than
before.

>
> With get_scope_m I can find all enclosing namespaces of and given namespace.
> How do I find nested namespaces of given namespace?

This operation is not yet implemented and it (probably won't be part
of the next revision of the paper), but we definitely plan to add it
in the future.

> I see how to find data members, but how do I find member functions?

Same as above, function reflection is not yet implemented, but we
*will* add them eventually.

> There is std::meta::is_virtual in <reflexpr>, is it described anywhere?

It will be described in the next revision of the paper. At the moment
it is only applicable on meta-Inheritance metaobjects, in the future
it will also apply to meta-Functions.

Regards,

Matus

Matus Chochlik

unread,
Nov 10, 2016, 1:12:07 AM11/10/16
to refle...@isocpp.org
On Sat, Sep 17, 2016 at 7:46 AM, Matus Chochlik <choc...@gmail.com> wrote:
Dear list,

We are preparing the next revision of P0194 for the meeting in
Issaquah and the implementation in clang is almost finished (it needs
some further minor changes, cleanup and polishing + it only fakes the
use of c++-concepts as they are not yet implemented in clang), but
it's already usable.

The forked repository can be found here: https://github.com/matus-chochlik/clang

To try it out, follow the instructions from here:
http://clang.llvm.org/get_started.html
but instead of the official clang repo use the fork.

The `-freflection` option needs to be specified to enable it and the
`__cpp_reflection` PP symbol is set to 1 if it is enabled.


There is also a set of higher level reflection libraries built on top
of reflexpr hosted here:
https://github.com/matus-chochlik/mirror

It is still work-in-progress and subject to changes, but it already
has some examples and docs:
http://matus-chochlik.github.io/mirror/doc/html/

Since the last update on this, I have added several utilities (and examples of their usage) based on top of reflection including:

- Listing all enumerators of an enum type.
- Tying references to data member of a class to a std::tuple
- Creating a hash of class data members.
- Generic comparisons of class data members.
- Enum-to-string and string-to-enum conversion
- Serialization and deserialization to/from JSON (using RapidJSON)
 
--Matus

Anton Bikineev

unread,
Dec 14, 2016, 7:18:25 AM12/14/16
to SG 7 - Reflection
Hi Matus,

I wonder, should I use default master branch of your fork or mirror-reflection or reflexpr?

Thanks.

четверг, 10 ноября 2016 г., 9:12:07 UTC+3 пользователь Matúš Chochlík написал:

Matus Chochlik

unread,
Dec 14, 2016, 3:43:43 PM12/14/16
to refle...@isocpp.org
Hi Anton,

On Wed, Dec 14, 2016 at 1:18 PM, Anton Bikineev <ant.bi...@gmail.com> wrote:
Hi Matus,

I wonder, should I use default master branch of your fork or mirror-reflection or reflexpr?

P0194Rx is implemented on the reflexpr branch.

Brief building instructions can be found here:

http://matus-chochlik.github.io/mirror/doc/html/implement/clang.html

HTH.

Best regards,

--Matus
 

--
You received this message because you are subscribed to the Google Groups "SG 7 - Reflection" group.
To unsubscribe from this group and stop receiving emails from it, send an email to reflection+unsubscribe@isocpp.org.
To post to this group, send email to refle...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/reflection/.
For more options, visit https://groups.google.com/a/isocpp.org/d/optout.



--
-- Matus Chochlik

Anton Bikineev

unread,
Dec 15, 2016, 7:09:42 PM12/15/16
to SG 7 - Reflection
Matus,

Thank you for response. 

When experimenting with the fork, I tried the following example and it crashed:
struct Hello
{
   
int world;
};


int main()
{
   
using refl = reflexpr(Hello);
   
using refl1 = std::meta::get_member_types_m<refl>;
   
using refl2 = std::meta::get_element_m<refl1, 0u>;
};
1.      1.cc:13:30: at annotation token
2.      1.cc:10:1: parsing function body 'main'
3.      1.cc:10:1: in compound statement ('{}')
4.      /usr/local/clang-meta/bin/../include/c++/v1/reflexpr:172:8: instantiating class definition 'std::meta::get_element<std::__metaobject<10018138037252073233>, 1>'
clang-4.0: error: unable to execute command: Abort trap: 6
clang-4.0: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 4.0.0 (https://github.com/matus-chochlik/clang 0dd8972883da9076a65bd4afc743d25e65eb1f8d) (llvm/trunk 289099)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /usr/local/clang-meta/bin
clang-4.0: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-4.0: note: diagnostic msg:
********************

Am I doing something wrong?

Thanks!

среда, 14 декабря 2016 г., 23:43:43 UTC+3 пользователь Matúš Chochlík написал:
Hi Anton,

To unsubscribe from this group and stop receiving emails from it, send an email to reflection+...@isocpp.org.

To post to this group, send email to refle...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/reflection/.
For more options, visit https://groups.google.com/a/isocpp.org/d/optout.



--
-- Matus Chochlik

Anton Bikineev

unread,
Dec 16, 2016, 2:10:41 AM12/16/16
to SG 7 - Reflection
Sorry, I missed the main part - an assertion line:
Assertion failed: ((index == 0) && "Metaobject sequence index out of range"), function operator(), file /Users/bikineev/svn/clang-meta/llvm/tools/clang/lib/AST/ExprCXX.cpp, line 2737.

Matus Chochlik

unread,
Dec 18, 2016, 2:48:54 AM12/18/16
to refle...@isocpp.org
Hi Anton,

The diagnostics are not completely user friendly yet, but the `get_element` operation is undefined with indices which exceed `get_size_v<...>-1` and since your `Hello` struct does not define any member types -- `get_size_v<refl1> == 0`, so it fails to compile.

--Matus

On Fri, Dec 16, 2016 at 8:10 AM, Anton Bikineev <ant.bi...@gmail.com> wrote:
Sorry, I missed the main part - an assertion line:
Assertion failed: ((index == 0) && "Metaobject sequence index out of range"), function operator(), file /Users/bikineev/svn/clang-meta/llvm/tools/clang/lib/AST/ExprCXX.cpp, line 2737.

--
You received this message because you are subscribed to the Google Groups "SG 7 - Reflection" group.
To unsubscribe from this group and stop receiving emails from it, send an email to reflection+unsubscribe@isocpp.org.

To post to this group, send email to refle...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/reflection/.
For more options, visit https://groups.google.com/a/isocpp.org/d/optout.



--
-- Matus Chochlik

Roman

unread,
Dec 24, 2016, 3:01:06 PM12/24/16
to refle...@isocpp.org
Hello,
 looks like build instructions are no longer valid:

llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp:593:49: error: use of undeclared identifier 'Idx'
  E->setKind(static_cast<MetaobjectKind>(Record[Idx++]));
...

llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp:610:26: error: no member named 'ReadCXXBaseSpecifier' in 'clang::ASTRecordReader'
      *BaseSpec = Record.ReadCXXBaseSpecifier(Idx);

-Roman
С уважением,
Роман Попов

Matus Chochlik

unread,
Dec 25, 2016, 3:48:03 AM12/25/16
to refle...@isocpp.org
Hi Roman,

I've made a rebase, then I've done manual fixes  locally and tested them but it seems that i forgot to amend the commit before pushing it 😐

i'll fix that tonight (GMT+1). Sorry for the inconvenience.

--Matus

Matus Chochlik

unread,
Dec 25, 2016, 2:20:13 PM12/25/16
to refle...@isocpp.org
OK, it should be working now, let me know if it doesn't (and thanks for spotting this).

--Matus

Roman

unread,
Dec 25, 2016, 9:40:53 PM12/25/16
to refle...@isocpp.org
Thank you Matus, yes, now I can build it. However I have not find a way how to use compiler properly:

Trying to build example from llvm/tools/clang/examples/reflection

$clang++ --version
clang version 4.0.0 (https://github.com/matus-chochlik/clang.git 148c3ec6a546ac456a16e7c4f6cac0a170227ba9) (https://github.com/llvm-mirror/llvm.git e6e82fb3abf3f747fa791f3a0d145b3d4c4f2bfe)

$clang++ -freflection test01.cpp 
clang-4.0: error: unknown argument: '-freflection'

$clang++ -std=c++14 -isystem ./reflection -Xclang -freflection test03.cpp
/tmp/test03-6fd9f8.o: In function `main':
test03.cpp:(.text+0x17): undefined reference to `std::meta::get_source_file<std::__metaobject<o12493377969659219292ul> >::value'
test03.cpp:(.text+0x49): undefined reference to `std::meta::get_base_name<std::__metaobject<o12493377969659219292ul> >::value'
test03.cpp:(.text+0x78): undefined reference to `std::meta::get_base_name<std::__metaobject<o12493377969659163020ul> >::value'
test03.cpp:(.text+0xa7): undefined reference to `std::meta::get_display_name<std::__metaobject<o12493377969659173260ul> >::value'
test03.cpp:(.text+0x151): undefined reference to `std::meta::get_base_name<std::__metaobject<o12493377969659137572ul> >::value'
....

Matus Chochlik

unread,
Dec 26, 2016, 1:39:12 AM12/26/16
to refle...@isocpp.org
Hi Roman,

It seems that something changes in the behaviour of constexpr const char arrays recently. But it should work now.

HTH

--Matus

Roman

unread,
Dec 26, 2016, 1:25:58 PM12/26/16
to refle...@isocpp.org
Hi Matus,
I don't see any source code updates since yesterday.  How do you use it exactly?

I have not used clang before, so probably I'm doing something wrong...

$ cd llvm/tools/
$ cd clang
$ git checkout reflexpr
$ cd ../../..
$ mkdir build
$ cmake ../llvm
$ make -j8
$ sudo make install
$ clang++ -std=c++14 -isystem /path/to/reflection -Xclang -freflection test.cpp

testx.cpp:(.text+0x3f): undefined reference to `std::meta::get_base_name<std::__metaobject<o8845212562963650963ul> >::value'
clang-4.0: error: linker command failed with exit code 1 (use -v to see invocation)


-Roman


Matus Chochlik

unread,
Dec 26, 2016, 2:44:04 PM12/26/16
to refle...@isocpp.org
Hi Roman,

Did you do a new clone since yesterday? I did amends to the reflection commit (it makes rebasing easier) and it works for me now.

Roman

unread,
Dec 26, 2016, 3:54:48 PM12/26/16
to refle...@isocpp.org
There is nothing new on github, did you pushed your commit? 

$git log

commit 9ae13c60038c8cc97b792d99dd1f1352be4040f5
Author: Matus Chochlik <choc...@gmail.com>
Date:   Thu Sep 8 10:00:54 2016 +0200

commit 0bc0e2596fac8d05fb3893385f7b5081e38958f2
Author: Amjad Aboud <amjad...@intel.com>
Date:   Sun Dec 25 10:12:27 2016 +0000


Matus Chochlik

unread,
Dec 26, 2016, 4:22:40 PM12/26/16
to refle...@isocpp.org
That is the one. I've amended the previous commit and pushed it on github this morning. When using the `build_run.sh` script all examples do work on my end.

Roman

unread,
Dec 26, 2016, 4:25:03 PM12/26/16
to refle...@isocpp.org
Ok, let me rebuild it once again. Probably I need some other repos other than llvm and clang?  compiler-rt?

--

Matus Chochlik

unread,
Dec 26, 2016, 4:26:08 PM12/26/16
to refle...@isocpp.org
llvm + the patched clang work for me.

Roman

unread,
Dec 26, 2016, 5:11:08 PM12/26/16
to refle...@isocpp.org
Well, it works now.
Don't know what exactly was wrong before. Sorry for confusion. And thanks a lot for help! 

Time to explore. 
-Roman

Thiago Macieira

unread,
Dec 26, 2016, 7:38:34 PM12/26/16
to refle...@isocpp.org
Em segunda-feira, 26 de dezembro de 2016, às 22:22:38 BRST, Matus Chochlik
escreveu:
> I've amended the previous commit and pushed it on github

DO NOT amend commits or otherwise rewrite history in Git branches other people
are tracking. This makes their life more difficult.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center

Matus Chochlik

unread,
Dec 27, 2016, 3:41:07 AM12/27/16
to refle...@isocpp.org
On Tue, Dec 27, 2016 at 1:38 AM, Thiago Macieira <thi...@macieira.org> wrote:
Em segunda-feira, 26 de dezembro de 2016, às 22:22:38 BRST, Matus Chochlik
escreveu:
> I've amended the previous commit and pushed it on github

DO NOT amend commits or otherwise rewrite history in Git branches other people
are tracking. This makes their life more difficult.

Thiago,

I'm aware why people generally shouldn't do that, but I want to have all the reflection-related changes contained and I'm regularly rebasing the commit on top of the current master branch so that people can use reflection with all the other new features as they are implemented. Also it keeps the commit history tidy; with merges it would be a big mess already. So I think that in this case the benefits outweigh the negatives and the documentation [1] says what you should do to keep the branch up to date.

[1] http://matus-chochlik.github.io/mirror/doc/html/implement/clang.html

--Matus

Thiago Macieira

unread,
Dec 27, 2016, 6:23:04 AM12/27/16
to refle...@isocpp.org
Em terça-feira, 27 de dezembro de 2016, às 09:41:05 BRST, Matus Chochlik
escreveu:
> I'm aware why people generally shouldn't do that, but I want to have all
> the reflection-related changes contained and I'm regularly rebasing the
> commit on top of the current master branch so that people can use
> reflection with all the other new features as they are implemented. Also it
> keeps the commit history tidy; with merges it would be a big mess already.
> So I think that in this case the benefits outweigh the negatives and the
> documentation [1] says what you should do to keep the branch up to date.
>
> [1] http://matus-chochlik.github.io/mirror/doc/html/implement/clang.html

It makes your life easier. It makes everyone else's lives more difficult...
Reply all
Reply to author
Forward
0 new messages