[cfe-dev] Adding a new compiler intrinsic

Ryan Johnson scovich at gmail.com
Tue Jul 21 10:36:10 PDT 2015


Hi all,

(Not yet a list member, please CC me in all replies)

I'm new to clang and am interested in adding a new compiler intrinsic to 
simplify my work with variadic template parameter packs in C++.  The 
first half of this message explains the intrinsic I'm hoping to add, and 
the second half is a plea for code pointers I could use as a starting 
point.

The motivation/description of the intrinsic can be illustrated by the 
following C++17 code snippet:

template <typename T>
int hash(T const &t);
/* ^^^ to be overloaded for all relevant types */

template <template <typename...> class Tuple, typename... T>
int hash(Tuple<T...> const &t)
{
    using std::get; // ADL
    return ... ^ hash(get<*__indexof(T)*>(t));
}

The new intrinsic, __indexof(T) would only be valid inside an expression 
that unpacks a parameter pack T. For each unpacked expression that is 
produced, it would evaluate to a constexpr size_t between 0 and 
sizeof...(T) giving the ordinal position of that expression within the 
pack. Without such a functionality, you end up writing a *lot* more (and 
a lot uglier) code to achieve the same result when dealing with tuples.

I'm floating this idea at the ISO std-proposals forum as a potential 
addition for C++17---it's a great complement to fold expressions---but I 
suspect it would get a lot more traction if I could show a working 
implementation. Plus, then I could use it for my own work in the meantime.

Any pointers folks might have to parts of the code base I should be 
studying as a starting point would be greatly appreciated. Currently I'm 
digesting two things:

  * Everything to do with the C++11 sizeof... operator. Hopefully this
    will identify the bits of parsing and semantic analysis that will
    need attention.
  * The changeset that introduced C++17 fold expressions. Hopefully this
    will highlight locations that expand expressions containing
    parameter packs.

So far, it looks like the best approach will be to parse __indexof(T) 
into a new IndexOfPackExpr object, and at an appropriate moment later 
on---after the pack size is known but before expansion begins---to 
replace that Expr with a non-type template pack <size_t ...Indexes>, 
whose entries start at 0 and end just before sizeof...(T). That way, 
when expansion starts the expression will contain two peer parameter 
packs of the same size and the existing machinery will dutifully expand 
both in lockstep.

Does that sound like a reasonable approach?

Thanks,
Ryan Johnson

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150721/7d56ffbf/attachment.html>


More information about the cfe-dev mailing list