1// RUN: %clang_cc1 -fsyntax-only -verify %s 2 3// This is just the test for [namespace.udecl]p4 with 'using' 4// uniformly stripped out. 5 6// C++03 [namespace.udecl]p4: 7// A using-declaration used as a member-declaration shall refer to a 8// member of a base class of the class being defined, shall refer to 9// a member of an anonymous union that is a member of a base class 10// of the class being defined, or shall refer to an enumerator for 11// an enumeration type that is a member of a base class of the class 12// being defined. 13 14// There is no directly analogous paragraph in C++0x, and the feature 15// works sufficiently differently there that it needs a separate test. 16 17namespace test0 { 18 namespace NonClass { 19 typedef int type; 20 struct hiding {}; 21 int hiding; 22 static union { double union_member; }; 23 enum tagname { enumerator }; 24 } 25 26 class Test0 { 27 NonClass::type; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} 28 NonClass::hiding; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} 29 NonClass::union_member; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} 30 NonClass::enumerator; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} 31 }; 32} 33 34struct Opaque0 {}; 35 36namespace test1 { 37 struct A { 38 typedef int type; 39 struct hiding {}; // expected-note {{previous use is here}} 40 Opaque0 hiding; 41 union { double union_member; }; 42 enum tagname { enumerator }; 43 }; 44 45 struct B : A { 46 A::type; // expected-warning {{access declarations are deprecated}} 47 A::hiding; // expected-warning {{access declarations are deprecated}} 48 A::union_member; // expected-warning {{access declarations are deprecated}} 49 A::enumerator; // expected-warning {{access declarations are deprecated}} 50 A::tagname; // expected-warning {{access declarations are deprecated}} 51 52 void test0() { 53 type t = 0; 54 } 55 56 void test1() { 57 typedef struct A::hiding local; 58 struct hiding _ = local(); 59 } 60 61 void test2() { 62 union hiding _; // expected-error {{tag type that does not match previous}} 63 } 64 65 void test3() { 66 char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; 67 } 68 69 void test4() { 70 enum tagname _ = enumerator; 71 } 72 73 void test5() { 74 Opaque0 _ = hiding; 75 } 76 }; 77} 78 79namespace test2 { 80 struct A { 81 typedef int type; 82 struct hiding {}; // expected-note {{previous use is here}} 83 int hiding; 84 union { double union_member; }; 85 enum tagname { enumerator }; 86 }; 87 88 template <class T> struct B : A { 89 A::type; // expected-warning {{access declarations are deprecated}} 90 A::hiding; // expected-warning {{access declarations are deprecated}} 91 A::union_member; // expected-warning {{access declarations are deprecated}} 92 A::enumerator; // expected-warning {{access declarations are deprecated}} 93 A::tagname; // expected-warning {{access declarations are deprecated}} 94 95 void test0() { 96 type t = 0; 97 } 98 99 void test1() { 100 typedef struct A::hiding local; 101 struct hiding _ = local(); 102 } 103 104 void test2() { 105 union hiding _; // expected-error {{tag type that does not match previous}} 106 } 107 108 void test3() { 109 char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; 110 } 111 112 void test4() { 113 enum tagname _ = enumerator; 114 } 115 116 void test5() { 117 Opaque0 _ = hiding; 118 } 119 }; 120} 121 122namespace test3 { 123 struct hiding {}; 124 125 template <class T> struct A { 126 typedef int type; // expected-note {{target of using declaration}} 127 struct hiding {}; 128 Opaque0 hiding; 129 union { double union_member; }; 130 enum tagname { enumerator }; // expected-note {{target of using declaration}} 131 }; 132 133 template <class T> struct B : A<T> { 134 A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}} 135 A<T>::hiding; // expected-warning {{access declarations are deprecated}} 136 A<T>::union_member; // expected-warning {{access declarations are deprecated}} 137 A<T>::enumerator; // expected-warning {{access declarations are deprecated}} 138 A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}} 139 140 // FIXME: re-enable these when the various bugs involving tags are fixed 141#if 0 142 void test1() { 143 typedef struct A<T>::hiding local; 144 struct hiding _ = local(); 145 } 146 147 void test2() { 148 typedef struct A<T>::hiding local; 149 union hiding _ = local(); 150 } 151#endif 152 153 void test3() { 154 char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; 155 } 156 157#if 0 158 void test4() { 159 enum tagname _ = enumerator; 160 } 161#endif 162 163 void test5() { 164 Opaque0 _ = hiding; 165 } 166 }; 167 168 template struct B<int>; // expected-note {{in instantiation}} 169} 170 171namespace test4 { 172 struct Base { 173 int foo(); 174 }; 175 176 struct Unrelated { 177 int foo(); 178 }; 179 180 struct Subclass : Base { 181 }; 182 183 namespace InnerNS { 184 int foo(); 185 } 186 187 // We should be able to diagnose these without instantiation. 188 template <class T> struct C : Base { 189 InnerNS::foo; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} 190 Base::bar; // expected-error {{no member named 'bar'}} expected-warning {{access declarations are deprecated}} 191 Unrelated::foo; // expected-error {{not a base class}} expected-warning {{access declarations are deprecated}} 192 C::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}} 193 Subclass::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}} 194 195 int bar(); //expected-note {{target of using declaration}} 196 C::bar; // expected-error {{refers to its own class}} expected-warning {{access declarations are deprecated}} 197 }; 198} 199 200