[cfe-dev] PR21216 and non-type template parameters of reference type

David Blaikie dblaikie at gmail.com
Tue Oct 14 13:50:44 PDT 2014


On Tue, Oct 14, 2014 at 1:42 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

> On Tue, Oct 14, 2014 at 1:31 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>> So I'm looking at addressing PR21216
>>
>
> Are you sure that's the right bug number?
>

Nope, sorry about that. Actually PR21246:
http://llvm.org/bugs/show_bug.cgi?id=21246


>
>
>> and I've come across a few hiccups:
>>
>> * I can fix the bug as filed by using TemplateArgument's
>> isDeclForReferenceParameter to either create a reference or a pointer type
>> for the argument
>>
>> * But this doesn't include const-ness. How would I differentiate the
>> types of the arguments to these template parameters: "template<const int&,
>> int&>" ?
>>
>> * This also doesn't include rvalue ref-ness. How would I differentiate
>> the types of the arguments to these template parameters: "template<int &,
>> int&&>" ?
>>
>> * Clang prints the desugared name (which we use in the debug info, but
>> can also appear in diagnostics) somewhat strange/incorrectly:
>>
>> int i;
>> template<int& I, int *J, int&& K, const int &L>
>> struct foo {
>> };
>>
>> foo<i, &i, i, i> f;
>>
>> void f1(int);
>>
>> template<typename T>
>> void f2(T t) {
>>   f1(t);
>> }
>>
>> int main() {
>>   f1(f);
>>   f2(f);
>> }
>>
>> Clang produces (just cutting to the notes in question):
>> templ.cpp:16:3: error: no matching function for call to 'f1'
>>   f1(f);
>>   ^~
>> templ.cpp:8:6: note: candidate function not viable: no known conversion
>> from 'foo<i, &i, i, i>' to 'int' for 1st argument
>> void f1(int);
>>      ^
>> templ.cpp:12:3: error: no matching function for call to 'f1'
>>   f1(t);
>>   ^~
>> templ.cpp:17:3: note: in instantiation of function template
>> specialization 'f2<foo<&i, &i, &i, &i> >' requested here
>>   f2(f);
>>   ^
>> templ.cpp:8:6: note: candidate function not viable: no known conversion
>> from 'foo<&i, &i, &i, &i>' to 'int' for 1st argument
>> void f1(int);
>>      ^
>>
>> Note the desugaring of the template adds '&' to all the parameters, even
>> the reference parameters.
>>
>> GCC gets something that looks ugly but probably correct:
>> templ.cpp: In function ‘int main()’:
>> templ.cpp:16:7: error: cannot convert ‘foo<(* & i), (& i), (* & i),
>> ((const int&)(& i))>’ to ‘int’ for argument ‘1’ to ‘void f1(int)’
>>    f1(f);
>>        ^
>>
>> Though, weirdly, GCC doesn't reject the call to f2... which is weird.
>>
>> Anyway: where should I get the right type for my non-type template
>> arguments? Do I have to go spelunking through the template parameters (can
>> I get to them from the template arguments) & try to stitch the type
>> together? That's probably not ideal...
>>
>
> Right now, I think you need the template parameters.
>

Hrm. I'm a bit concerned about trying to make this work with complex
dependent types...

template<typename T, typename T::foo F> struct foo { };
struct outer { typedef const int &foo; };
int i;
foo<outer, i> f;

is that going to be easier than I'm thinking? I'm a bit concerned about
figuring out the instantiation of T::foo from the template parameter
description...


>
>> & what can we do about the type printing for non-type template
>> parameters? (I haven't spent too long searching for where those extra '&'
>> are coming from yet - but pointers would be appreciated)
>>
>> Thanks,
>> - David
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141014/13b2f306/attachment.html>


More information about the cfe-dev mailing list