blob: 01ede32f9a08b96ead8977b430725ba3ec23c95d [file] [log] [blame]
// RUN: %clang_cc1 -fsyntax-only -verify %s
class A;
class S {
public:
template<typename T> struct A {
struct Nested {
typedef T type;
};
};
};
int i;
S::A<int>::Nested::type *ip = &i;
template<typename T>
struct Outer {
template<typename U>
class Inner0;
template<typename U>
class Inner1 {
struct ReallyInner;
T foo(U);
template<typename V> T bar(V);
template<typename V> T* bar(V);
static T value1;
static U value2;
};
};
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 {
static Y value3;
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();
}
template<typename X>
template<typename Y>
template<typename Z>
X Outer<X>::Inner1<Y>::bar(Z) {
return X();
}
template<typename X>
template<typename Y>
template<typename Z>
X* Outer<X>::Inner1<Y>::bar(Z) {
return 0;
}
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();
template<typename X>
template<typename Y>
Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y();
template<typename X>
template<typename Y>
Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}}
template<typename T>
struct X0 { };
template<typename T>
struct X0<T*> {
template<typename U>
void f(U u = T()) { }
};
// PR5103
template<typename>
struct X1 {
template<typename, bool = false> struct B { };
};
template struct X1<int>::B<bool>;
// 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;
X2<float> x2a; // expected-note{{instantiation}}
X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}