• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
fooN::Outer::Inner::InnerTemplate::VeryInner14           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 {
barN::Outer::Inner::InnerTemplate::VeryInner::UeberInner22             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 {
fooN2::Outer2::Inner45       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 
operator int safe_bool::*smart_ptr80   operator int safe_bool::*() const {
81     return ptr? &safe_bool::member : 0;
82   }
83 
84   T* ptr;
85 };
86 
test_smart_ptr(smart_ptr<int> p)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 {
Xtest0::X94     X() { extern void x(); }
95   };
g()96   void g() { X<2>(); }
97 }
98 
99 // <rdar://problem/8302161>
100 namespace test1 {
f(T const & t)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 {
f()110   template<typename T> void f() {
111     T::error; // expected-error {{no member}}
112   }
g()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