Clang fails to compile template with dependendent Non type template parameter.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Clang fails to compile template with dependendent Non type template parameter.

KARTHIK VENKATESH BHAT
Hi All,
I'm trying to compile the following code on clang-

template <int dim> class X {};
template <class T> struct Y {
  static const unsigned int dim = 1 ;
  template <class U> X<Y<T>::dim> f();
};

template <class T> template <class U>
X<Y<T>::dim> Y<T>::f() { return X<dim>(); }

int main()
{
  Y<int>().f<int>();
}

the compilation fails with the following error-
error: out-of-line definition of 'f' does not match any declaration in 'Y<T>' X<Y<T>::dim> Y<T>::f() { return X<dim>(); }

Upon debugging I found that while parsing declaration " template <class U> X<Y<T>::dim> f();"
qualtype of expression Y<T>::dim is treated as "const unsigned int" .
But during definition of Non type parameter Y<T>::dim is treated as a dependent type and hence RebuildTypeInCurrentInstantiation
is called but Y<T>::dim is still not resolved to "const unsigned int" after call to RebuildTypeInCurrentInstantiation.

I'm a bit new to parser code of clang. My doubt were-
1) Ideally shouldn't RebuildTypeInCurrentInstantiation resolve qualtype of expression Y<T>::dim to "const unsigned int"?
2) Non type template parameters are represented as const Expressions in llvm.Everytime we come across Y<T>::dim a new Expression pointer is created which is used to represent the Arg of X<Y<T>::dim> . Since every time Y<T>::dim is a new Expression pointer
Arg for template X<Y<T>::dim> represnts a diffenent typeOrValue each time.As a result for the same expression X<Y<T>::dim> we create a new type node in getCanonicalTemplateSpecializationType resulting in type mismatch. Wanted to know if this current approach to create a new expression pointer every time the same expression is revisited again is correct?

A similar issue was fixed in gcc at http://gcc.gnu.org/viewcvs?view=revision&revision=156865 .

Would like to get some inputs from community how should i proceed to solve this issue. Thanks!

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Clang fails to compile template with dependendent Non type template parameter.

Richard Smith-33
Questions about Clang should be directed to [hidden email], not
to llvmdev@.

This issue is fixed in r166496.

On Tue, Oct 23, 2012 at 1:33 AM, KARTHIKVENKATESH BHAT
<[hidden email]> wrote:

> Hi All,
> I'm trying to compile the following code on clang-
>
> template <int dim> class X {};
> template <class T> struct Y {
>   static const unsigned int dim = 1 ;
>   template <class U> X<Y<T>::dim> f();
> };
>
> template <class T> template <class U>
> X<Y<T>::dim> Y<T>::f() { return X<dim>(); }
>
> int main()
> {
>   Y<int>().f<int>();
> }
>
> the compilation fails with the following error-
> error: out-of-line definition of 'f' does not match any declaration in 'Y<T>' X<Y<T>::dim> Y<T>::f() { return X<dim>(); }
>
> Upon debugging I found that while parsing declaration " template <class U> X<Y<T>::dim> f();"
> qualtype of expression Y<T>::dim is treated as "const unsigned int" .
> But during definition of Non type parameter Y<T>::dim is treated as a dependent type and hence RebuildTypeInCurrentInstantiation
> is called but Y<T>::dim is still not resolved to "const unsigned int" after call to RebuildTypeInCurrentInstantiation.
>
> I'm a bit new to parser code of clang. My doubt were-
> 1) Ideally shouldn't RebuildTypeInCurrentInstantiation resolve qualtype of expression Y<T>::dim to "const unsigned int"?

Yes, it should.

> 2) Non type template parameters are represented as const Expressions in llvm.Everytime we come across Y<T>::dim a new Expression pointer is created which is used to represent the Arg of X<Y<T>::dim> . Since every time Y<T>::dim is a new Expression pointer
> Arg for template X<Y<T>::dim> represnts a diffenent typeOrValue each time.As a result for the same expression X<Y<T>::dim> we create a new type node in getCanonicalTemplateSpecializationType resulting in type mismatch. Wanted to know if this current approach to create a new expression pointer every time the same expression is revisited again is correct?

The current approach is correct. When we compare expressions as
template arguments, we use their Profile members to form a description
of them which we can compare (according to C++'s 'equivalent' /
'functionally equivalent' rules). The Expr nodes need to be created
each time, because they have different SourceLocations.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Clang fails to compile template with dependendent Non type template parameter.

KARTHIK VENKATESH BHAT
In reply to this post by KARTHIK VENKATESH BHAT
Understood the fix. Thanks Richard.

------- Original Message -------
Sender : Richard Smith<[hidden email]>
Date : Oct 24, 2012 05:01 (GMT+09:00)
Title : Re: [LLVMdev] Clang fails to compile template with dependendent Non type template parameter.

Questions about Clang should be directed to [hidden email], not
to llvmdev@.

This issue is fixed in r166496.

On Tue, Oct 23, 2012 at 1:33 AM, KARTHIKVENKATESH BHAT
wrote:

> Hi All,
> I'm trying to compile the following code on clang-
>
> template class X {};
> template struct Y {
>   static const unsigned int dim = 1 ;
>   template X::dim> f();
> };
>
> template template
> X::dim> Y::f() { return X(); }
>
> int main()
> {
>   Y().f();
> }
>
> the compilation fails with the following error-
> error: out-of-line definition of 'f' does not match any declaration in 'Y' X::dim> Y::f() { return X(); }
>
> Upon debugging I found that while parsing declaration " template X::dim> f();"
> qualtype of expression Y::dim is treated as "const unsigned int" .
> But during definition of Non type parameter Y::dim is treated as a dependent type and hence RebuildTypeInCurrentInstantiation
> is called but Y::dim is still not resolved to "const unsigned int" after call to RebuildTypeInCurrentInstantiation.
>
> I'm a bit new to parser code of clang. My doubt were-
> 1) Ideally shouldn't RebuildTypeInCurrentInstantiation resolve qualtype of expression Y::dim to "const unsigned int"?

Yes, it should.

> 2) Non type template parameters are represented as const Expressions in llvm.Everytime we come across Y::dim a new Expression pointer is created which is used to represent the Arg of X::dim> . Since every time Y::dim is a new Expression pointer
> Arg for template X::dim> represnts a diffenent typeOrValue each time.As a result for the same expression X::dim> we create a new type node in getCanonicalTemplateSpecializationType resulting in type mismatch. Wanted to know if this current approach to create a new expression pointer every time the same expression is revisited again is correct?

The current approach is correct. When we compare expressions as
template arguments, we use their Profile members to form a description
of them which we can compare (according to C++'s 'equivalent' /
'functionally equivalent' rules). The Expr nodes need to be created
each time, because they have different SourceLocations.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev