2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
2009-03-27 12:21:56 +08:00
|
|
|
class A;
|
|
|
|
|
|
|
|
class S {
|
|
|
|
public:
|
|
|
|
template<typename T> struct A {
|
|
|
|
struct Nested {
|
|
|
|
typedef T type;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
int i;
|
|
|
|
S::A<int>::Nested::type *ip = &i;
|
|
|
|
|
2009-08-25 07:03:25 +08:00
|
|
|
template<typename T>
|
2009-08-26 01:23:04 +08:00
|
|
|
struct Outer {
|
|
|
|
template<typename U>
|
|
|
|
class Inner0;
|
2009-08-25 07:03:25 +08:00
|
|
|
|
|
|
|
template<typename U>
|
2009-08-26 01:23:04 +08:00
|
|
|
class Inner1 {
|
|
|
|
struct ReallyInner;
|
|
|
|
|
|
|
|
T foo(U);
|
|
|
|
template<typename V> T bar(V);
|
Improve support for out-of-line definitions of nested templates and
their members, including member class template, member function
templates, and member classes and functions of member templates.
To actually parse the nested-name-specifiers that qualify the name of
an out-of-line definition of a member template, e.g.,
template<typename X> template<typename Y>
X Outer<X>::Inner1<Y>::foo(Y) {
return X();
}
we need to look for the template names (e.g., "Inner1") as a member of
the current instantiation (Outer<X>), even before we have entered the
scope of the current instantiation. Since we can't do this in general
(i.e., we should not be looking into all dependent
nested-name-specifiers as if they were the current instantiation), we
rely on the parser to tell us when it is parsing a declaration
specifier sequence, and, therefore, when we should consider the
current scope specifier to be a current instantiation.
Printing of complicated, dependent nested-name-specifiers may be
somewhat broken by this commit; I'll add tests for this issue and fix
the problem (if it still exists) in a subsequent commit.
llvm-svn: 80044
2009-08-26 06:51:20 +08:00
|
|
|
template<typename V> T* bar(V);
|
2009-08-26 06:53:07 +08:00
|
|
|
|
|
|
|
static T value1;
|
|
|
|
static U value2;
|
2009-08-25 07:03:25 +08:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2009-08-26 01:23:04 +08:00
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
class Outer<X>::Inner0 {
|
|
|
|
public:
|
|
|
|
void f(X, Y);
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
void Outer<X>::Inner0<Y>::f(X, Y) {
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
struct Outer<X>::Inner1<Y>::ReallyInner {
|
2009-08-26 06:54:02 +08:00
|
|
|
static Y value3;
|
|
|
|
|
2009-08-26 01:23:04 +08:00
|
|
|
void g(X, Y);
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
void Outer<X>::Inner1<Y>::ReallyInner::g(X, Y) {
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
X Outer<X>::Inner1<Y>::foo(Y) {
|
|
|
|
return X();
|
|
|
|
}
|
2009-08-25 07:03:25 +08:00
|
|
|
|
2009-08-26 01:23:04 +08:00
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
template<typename Z>
|
|
|
|
X Outer<X>::Inner1<Y>::bar(Z) {
|
|
|
|
return X();
|
|
|
|
}
|
Improve support for out-of-line definitions of nested templates and
their members, including member class template, member function
templates, and member classes and functions of member templates.
To actually parse the nested-name-specifiers that qualify the name of
an out-of-line definition of a member template, e.g.,
template<typename X> template<typename Y>
X Outer<X>::Inner1<Y>::foo(Y) {
return X();
}
we need to look for the template names (e.g., "Inner1") as a member of
the current instantiation (Outer<X>), even before we have entered the
scope of the current instantiation. Since we can't do this in general
(i.e., we should not be looking into all dependent
nested-name-specifiers as if they were the current instantiation), we
rely on the parser to tell us when it is parsing a declaration
specifier sequence, and, therefore, when we should consider the
current scope specifier to be a current instantiation.
Printing of complicated, dependent nested-name-specifiers may be
somewhat broken by this commit; I'll add tests for this issue and fix
the problem (if it still exists) in a subsequent commit.
llvm-svn: 80044
2009-08-26 06:51:20 +08:00
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
template<typename Z>
|
|
|
|
X* Outer<X>::Inner1<Y>::bar(Z) {
|
|
|
|
return 0;
|
|
|
|
}
|
2009-08-26 06:53:07 +08:00
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
X Outer<X>::Inner1<Y>::value1 = 0;
|
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
Y Outer<X>::Inner1<Y>::value2 = Y();
|
2009-08-26 06:54:02 +08:00
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y();
|
2009-08-26 08:04:55 +08:00
|
|
|
|
|
|
|
template<typename X>
|
|
|
|
template<typename Y>
|
|
|
|
Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}}
|
2009-09-10 08:12:48 +08:00
|
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct X0 { };
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct X0<T*> {
|
|
|
|
template<typename U>
|
|
|
|
void f(U u = T()) { }
|
|
|
|
};
|
2009-10-24 07:25:44 +08:00
|
|
|
|
|
|
|
// PR5103
|
|
|
|
template<typename>
|
|
|
|
struct X1 {
|
|
|
|
template<typename, bool = false> struct B { };
|
|
|
|
};
|
|
|
|
template struct X1<int>::B<bool>;
|
2009-11-12 00:58:32 +08:00
|
|
|
|
|
|
|
// Template template parameters
|
|
|
|
template<typename T>
|
|
|
|
struct X2 {
|
|
|
|
template<template<class U, T Value> class> // expected-error{{cannot have type 'float'}} \
|
|
|
|
// expected-note{{previous non-type template}}
|
|
|
|
struct Inner { };
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T,
|
|
|
|
int Value> // expected-note{{template non-type parameter}}
|
|
|
|
struct X2_arg;
|
|
|
|
|
|
|
|
X2<int>::Inner<X2_arg> x2i1;
|
2009-11-12 03:13:48 +08:00
|
|
|
X2<float> x2a; // expected-note{{instantiation}}
|
2009-11-12 00:58:32 +08:00
|
|
|
X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
|
|
|
|
|
|
|
|
|