aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate/nested-template.cpp
blob: 5ee2c9954005e3856268879817359fa78caf243e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// RUN: clang-cc -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()) { }
};