Page MenuHomePhabricator

[libcxx] Use __decltype instead of __typeof__
ClosedPublic

Authored by EricWF on Jun 12 2015, 7:37 PM.

Details

Summary

Both clang and GCC provide C++11 decltype semantics as decltype in c++03 mode. We should use this instead of typeof__ when availble.

GCC added decltype in 4.6.0, and AFAIK clang provided decltype ever since 3.3. Unfortunately __has_builtin(__decltype) doesn't work for clang so we need to check the compiler version instead.

Diff Detail

Event Timeline

EricWF updated this revision to Diff 27624.Jun 12 2015, 7:37 PM
EricWF retitled this revision from to [libcxx] Use __decltype instead of __typeof__.
EricWF updated this object.
EricWF edited the test plan for this revision. (Show Details)
EricWF added a reviewer: mclow.lists.
EricWF added a subscriber: Unknown Object (MLST).
mclow.lists accepted this revision.Jun 12 2015, 10:43 PM
mclow.lists edited edge metadata.

LGTM.

This revision is now accepted and ready to land.Jun 12 2015, 10:43 PM

Here is the mailing list post that talks about adding __decltype to clang:
http://lists.cs.uiuc.edu/pipermail/llvmbugs/2011-March/017470.html

mclow.lists added inline comments.Jun 12 2015, 10:44 PM
include/__config
29

I'm not really pleased with the idea of switching off the clang version. This kind of stuff grows over time.

If there is a better test, I'd rather use that.
If not, well...

To confirm the first clang release that has __decltype in C++98 is 2.9. I think I'll play it safe and enable it for clang >= 3.3.

EricWF updated this revision to Diff 27631.Jun 12 2015, 11:17 PM
EricWF edited edge metadata.

@mclow.lists expressed concern about the _CLANG_VER macro so I removed it.
I also properly handle Apple clang's version numbers. __decltype is enabled for XCode 5.0 (based off of LLVM 3.3) and greater.

EricWF closed this revision.Jun 12 2015, 11:31 PM

Is there a concrete benefit that this provides?

Is there a concrete benefit that this provides?

It makes the #define decltype actually provide correct decltype semantics in C++03. Since clang and GCC don't provide decltype in C++03 we used to fall back on __typeof__. Because __typeof__ does not deduce references it would change the meaning of code between C++03 and C++11. I think this change is beneficial to libc++ users who use the decltype macro we provide in C++03.

A concrete example within libc++ is the C++03 implementations of __invoke and result_of used to use __typeof__ to deduce the return type of a call to a function object. If the return type was a reference we would get it wrong and __invoke will end up returning by value.

PS. I don't like that libc++ provides decltype to users in C++03 but I think it's way to late to change that.

rsmith added a subscriber: rsmith.Jun 15 2015, 6:42 PM
rsmith added inline comments.
include/__config
585–591

You can use __is_identifier for this. Clang's supported it since r206069 (version 3.5), which may be good enough? (How old a Clang release can still parse libc++?)

EricWF added inline comments.Jun 16 2015, 9:05 AM
include/__config
585–591

You can use __is_identifier for this. Clang's supported it since r206069 (version 3.5), which may be good enough?

Unless @mclow.lists has any objection to this I would like to change this to use __is_identifier. While 3.5 might be artificially limiting it seems like the safest and cleanest way to detect __decltype. I'm not super happy jumping through hoops to support old compilers with new libc++ headers.

How old a Clang release can still parse libc++?

I'm currently working on a proposal to define (and hopefully limit) the compilers which ToT libc++ supports. I'll have an answer to this question soon.