1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | namespace N { |
3 | struct Outer { |
4 | struct Inner { |
5 | template<typename T> |
6 | struct InnerTemplate { |
7 | struct VeryInner { |
8 | typedef T type; |
9 | |
10 | static enum K1 { K1Val = sizeof(T) } Kind1; |
11 | static enum { K2Val = sizeof(T)*2 } Kind2; |
12 | enum { K3Val = sizeof(T)*2 } Kind3; |
13 | |
14 | void foo() { |
15 | K1 k1 = K1Val; |
16 | Kind1 = K1Val; |
17 | Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; |
18 | Kind3 = K3Val; |
19 | } |
20 | |
21 | struct UeberInner { |
22 | void bar() { |
23 | K1 k1 = K1Val; |
24 | Kind1 = K1Val; |
25 | Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; |
26 | |
27 | InnerTemplate t; |
28 | InnerTemplate<type> t2; |
29 | } |
30 | }; |
31 | }; |
32 | }; |
33 | }; |
34 | }; |
35 | } |
36 | |
37 | typedef int INT; |
38 | template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner; |
39 | template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}} |
40 | |
41 | namespace N2 { |
42 | struct Outer2 { |
43 | template<typename T, typename U = T> |
44 | struct Inner { |
45 | void foo() { |
46 | enum { K1Val = sizeof(T) } k1; |
47 | enum K2 { K2Val = sizeof(T)*2 } k2a; |
48 | |
49 | K2 k2b = K2Val; |
50 | |
51 | struct S { T x, y; } s1; |
52 | struct { U x, y; } s2; |
53 | s1.x = s2.x; // expected-error{{incompatible}} |
54 | |
55 | typedef T type; |
56 | type t2 = s1.x; |
57 | |
58 | typedef struct { T z; } type2; |
59 | type2 t3 = { s1.x }; |
60 | |
61 | Inner i1; |
62 | i1.foo(); |
63 | Inner<T> i2; |
64 | i2.foo(); |
65 | } |
66 | }; |
67 | }; |
68 | } |
69 | |
70 | template struct N2::Outer2::Inner<float>; |
71 | template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}} |
72 | |
73 | // Test dependent pointer-to-member expressions. |
74 | template<typename T> |
75 | struct smart_ptr { |
76 | struct safe_bool { |
77 | int member; |
78 | }; |
79 | |
80 | operator int safe_bool::*() const { |
81 | return ptr? &safe_bool::member : 0; |
82 | } |
83 | |
84 | T* ptr; |
85 | }; |
86 | |
87 | void test_smart_ptr(smart_ptr<int> p) { |
88 | if (p) { } |
89 | } |
90 | |
91 | // PR5517 |
92 | namespace test0 { |
93 | template <int K> struct X { |
94 | X() { extern void x(); } |
95 | }; |
96 | void g() { X<2>(); } |
97 | } |
98 | |
99 | // <rdar://problem/8302161> |
100 | namespace test1 { |
101 | template <typename T> void f(T const &t) { |
102 | union { char c; T t_; }; |
103 | c = 'a'; // <- this shouldn't silently fail to instantiate |
104 | T::foo(); // expected-error {{has no members}} |
105 | } |
106 | template void f(int const &); // expected-note {{requested here}} |
107 | } |
108 | |
109 | namespace test2 { |
110 | template<typename T> void f() { |
111 | T::error; // expected-error {{no member}} |
112 | } |
113 | void g() { |
114 | // This counts as an odr-use, so should trigger the instantiation of f<int>. |
115 | (void)&f<int>; // expected-note {{here}} |
116 | } |
117 | } |
118 | |