blob: ced56dfc6abc86bc272e56dccf727c6cb4e78cf4 [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Douglas Gregor2bba76b2009-05-27 17:07:49 +00002namespace 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;
Douglas Gregor8dbc3c62009-05-27 17:20:35 +000011 static enum { K2Val = sizeof(T)*2 } Kind2;
Douglas Gregord0c87372009-05-27 17:30:49 +000012 enum { K3Val = sizeof(T)*2 } Kind3;
Douglas Gregor2bba76b2009-05-27 17:07:49 +000013
14 void foo() {
15 K1 k1 = K1Val;
16 Kind1 = K1Val;
17 Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
Douglas Gregord0c87372009-05-27 17:30:49 +000018 Kind3 = K3Val;
Douglas Gregor2bba76b2009-05-27 17:07:49 +000019 }
Douglas Gregord0c87372009-05-27 17:30:49 +000020
21 struct UeberInner {
22 void bar() {
23 K1 k1 = K1Val;
24 Kind1 = K1Val;
25 Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
Douglas Gregored961e72009-05-27 17:54:46 +000026
27 InnerTemplate t;
28 InnerTemplate<type> t2;
Douglas Gregord0c87372009-05-27 17:30:49 +000029 }
30 };
Douglas Gregor2bba76b2009-05-27 17:07:49 +000031 };
32 };
33 };
34 };
35}
36
37typedef int INT;
38template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
Douglas Gregor1eabb7d2010-03-31 23:17:41 +000039template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
Douglas Gregor6569d682009-05-27 23:11:45 +000040
41namespace N2 {
42 struct Outer2 {
Douglas Gregor8e92bf32009-05-29 14:25:00 +000043 template<typename T, typename U = T>
Douglas Gregor6569d682009-05-27 23:11:45 +000044 struct Inner {
45 void foo() {
46 enum { K1Val = sizeof(T) } k1;
Douglas Gregor8e92bf32009-05-29 14:25:00 +000047 enum K2 { K2Val = sizeof(T)*2 } k2a;
Douglas Gregor6569d682009-05-27 23:11:45 +000048
Douglas Gregor8e92bf32009-05-29 14:25:00 +000049 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;
Douglas Gregor6569d682009-05-27 23:11:45 +000057
Douglas Gregor7b0a5722009-05-29 14:26:40 +000058 typedef struct { T z; } type2;
59 type2 t3 = { s1.x };
60
Douglas Gregor6569d682009-05-27 23:11:45 +000061 Inner i1;
62 i1.foo();
63 Inner<T> i2;
64 i2.foo();
65 }
66 };
67 };
68}
69
Douglas Gregor8e92bf32009-05-29 14:25:00 +000070template struct N2::Outer2::Inner<float>;
71template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
Douglas Gregorc86a6e92009-11-04 07:01:15 +000072
73// Test dependent pointer-to-member expressions.
74template<typename T>
75struct 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
87void test_smart_ptr(smart_ptr<int> p) {
88 if (p) { }
89}
John McCall68b6b872010-02-06 01:50:47 +000090
91// PR5517
92namespace test0 {
93 template <int K> struct X {
94 X() { extern void x(); }
95 };
96 void g() { X<2>(); }
97}
John McCallec8045d2010-08-17 21:27:17 +000098
99// <rdar://problem/8302161>
100namespace 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}