blob: 359e2c7dfaa42244fbc3a33a7bac3e38c43cf16b [file] [log] [blame]
Douglas Gregord0c87372009-05-27 17:30:49 +00001// RUN: clang-cc -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 Gregord0c87372009-05-27 17:30:49 +000039template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{'UeberInner' does not name a tag member}}
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}