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

Richard Smith richard at metafoo.co.uk
Tue Oct 14 14:48:18 PDT 2014


On Tue, Oct 14, 2014 at 1:50 PM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
> 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...
>

This is a problem; we don't preserve enough information here.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141014/1f929c44/attachment.html>


More information about the cfe-dev mailing list