Home | History | Annotate | Download | only in class.access.dcl
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
      3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
      4 
      5 // This is just the test for [namespace.udecl]p4 with 'using'
      6 // uniformly stripped out.
      7 
      8 // C++03 [namespace.udecl]p4:
      9 //   A using-declaration used as a member-declaration shall refer to a
     10 //   member of a base class of the class being defined, shall refer to
     11 //   a member of an anonymous union that is a member of a base class
     12 //   of the class being defined, or shall refer to an enumerator for
     13 //   an enumeration type that is a member of a base class of the class
     14 //   being defined.
     15 
     16 // There is no directly analogous paragraph in C++0x, and the feature
     17 // works sufficiently differently there that it needs a separate test.
     18 
     19 namespace test0 {
     20   namespace NonClass {
     21     typedef int type;
     22     struct hiding {};
     23     int hiding;
     24     static union { double union_member; };
     25     enum tagname { enumerator };
     26   }
     27 
     28   class Test0 {
     29     NonClass::type; // expected-error {{not a class}}
     30 #if __cplusplus <= 199711L
     31     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     32 #else
     33     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     34 #endif
     35 
     36     NonClass::hiding; // expected-error {{not a class}}
     37 #if __cplusplus <= 199711L
     38     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     39 #else
     40     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     41 #endif
     42 
     43     NonClass::union_member; // expected-error {{not a class}}
     44 #if __cplusplus <= 199711L
     45     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     46 #else
     47     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     48 #endif
     49 
     50     NonClass::enumerator; // expected-error {{not a class}}
     51 #if __cplusplus <= 199711L
     52     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     53 #else
     54     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     55 #endif
     56   };
     57 }
     58 
     59 struct Opaque0 {};
     60 
     61 namespace test1 {
     62   struct A {
     63     typedef int type;
     64     struct hiding {}; // expected-note {{previous use is here}}
     65     Opaque0 hiding;
     66     union { double union_member; };
     67     enum tagname { enumerator };
     68   };
     69 
     70   struct B : A {
     71     A::type;
     72 #if __cplusplus <= 199711L
     73     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     74 #else
     75     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     76 #endif
     77     A::hiding;
     78 #if __cplusplus <= 199711L
     79     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     80 #else
     81     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     82 #endif
     83 
     84     A::union_member;
     85 #if __cplusplus <= 199711L
     86     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     87 #else
     88     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     89 #endif
     90 
     91     A::enumerator;
     92 #if __cplusplus <= 199711L
     93     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
     94 #else
     95     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
     96 #endif
     97 
     98     A::tagname;
     99 #if __cplusplus <= 199711L
    100     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    101 #else
    102     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    103 #endif
    104 
    105     void test0() {
    106       type t = 0;
    107     }
    108 
    109     void test1() {
    110       typedef struct A::hiding local;
    111       struct hiding _ = local();
    112     }
    113 
    114     void test2() {
    115       union hiding _; // expected-error {{tag type that does not match previous}}
    116     }
    117 
    118     void test3() {
    119       char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
    120     }
    121 
    122     void test4() {
    123       enum tagname _ = enumerator;
    124     }
    125 
    126     void test5() {
    127       Opaque0 _ = hiding;
    128     }
    129   };
    130 }
    131 
    132 namespace test2 {
    133   struct A {
    134     typedef int type;
    135     struct hiding {}; // expected-note {{previous use is here}}
    136     int hiding;
    137     union { double union_member; };
    138     enum tagname { enumerator };
    139   };
    140 
    141   template <class T> struct B : A {
    142     A::type;
    143 #if __cplusplus <= 199711L
    144     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    145 #else
    146     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    147 #endif
    148 
    149     A::hiding;
    150 #if __cplusplus <= 199711L
    151     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    152 #else
    153     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    154 #endif
    155 
    156     A::union_member;
    157 #if __cplusplus <= 199711L
    158     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    159 #else
    160     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    161 #endif
    162 
    163     A::enumerator;
    164 #if __cplusplus <= 199711L
    165     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    166 #else
    167     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    168 #endif
    169 
    170     A::tagname;
    171 #if __cplusplus <= 199711L
    172     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    173 #else
    174     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    175 #endif
    176 
    177     void test0() {
    178       type t = 0;
    179     }
    180 
    181     void test1() {
    182       typedef struct A::hiding local;
    183       struct hiding _ = local();
    184     }
    185 
    186     void test2() {
    187       union hiding _; // expected-error {{tag type that does not match previous}}
    188     }
    189 
    190     void test3() {
    191       char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
    192     }
    193 
    194     void test4() {
    195       enum tagname _ = enumerator;
    196     }
    197 
    198     void test5() {
    199       Opaque0 _ = hiding;
    200     }
    201   };
    202 }
    203 
    204 namespace test3 {
    205   struct hiding {};
    206 
    207   template <class T> struct A {
    208     typedef int type; // expected-note {{target of using declaration}}
    209     struct hiding {};
    210     Opaque0 hiding;
    211     union { double union_member; };
    212     enum tagname { enumerator }; // expected-note {{target of using declaration}}
    213   };
    214 
    215   template <class T> struct B : A<T> {
    216     A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}}
    217 #if __cplusplus <= 199711L
    218     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    219 #else
    220     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    221 #endif
    222 
    223     A<T>::hiding;
    224 #if __cplusplus <= 199711L
    225     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    226 #else
    227     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    228 #endif
    229 
    230     A<T>::union_member;
    231 #if __cplusplus <= 199711L
    232     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    233 #else
    234     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    235 #endif
    236 
    237     A<T>::enumerator;
    238 #if __cplusplus <= 199711L
    239     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    240 #else
    241     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    242 #endif
    243 
    244     A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}}
    245 #if __cplusplus <= 199711L
    246     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    247 #else
    248     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    249 #endif
    250 
    251     // FIXME: re-enable these when the various bugs involving tags are fixed
    252 #if 0
    253     void test1() {
    254       typedef struct A<T>::hiding local;
    255       struct hiding _ = local();
    256     }
    257 
    258     void test2() {
    259       typedef struct A<T>::hiding local;
    260       union hiding _ = local();
    261     }
    262 #endif
    263 
    264     void test3() {
    265       char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
    266     }
    267 
    268 #if 0
    269     void test4() {
    270       enum tagname _ = enumerator;
    271     }
    272 #endif
    273 
    274     void test5() {
    275       Opaque0 _ = hiding;
    276     }
    277   };
    278 
    279   template struct B<int>; // expected-note {{in instantiation}}
    280 }
    281 
    282 namespace test4 {
    283   struct Base {
    284     int foo();
    285   };
    286 
    287   struct Unrelated {
    288     int foo();
    289   };
    290 
    291   struct Subclass : Base {
    292   };
    293 
    294   namespace InnerNS {
    295     int foo();
    296   }
    297 
    298   // We should be able to diagnose these without instantiation.
    299   template <class T> struct C : Base {
    300     InnerNS::foo; // expected-error {{not a class}}
    301 #if __cplusplus <= 199711L
    302     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    303 #else
    304     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    305 #endif
    306 
    307     Base::bar; // expected-error {{no member named 'bar'}}
    308 #if __cplusplus <= 199711L
    309     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    310 #else
    311     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    312 #endif
    313 
    314     Unrelated::foo; // expected-error {{not a base class}}
    315 #if __cplusplus <= 199711L
    316     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    317 #else
    318     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    319 #endif
    320 
    321     C::foo; // legal in C++03
    322 #if __cplusplus <= 199711L
    323     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    324 #else
    325     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    326     // expected-error@-5 {{using declaration refers to its own class}}
    327 #endif
    328 
    329     Subclass::foo; // legal in C++03
    330 #if __cplusplus <= 199711L
    331     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    332 #else
    333     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    334     // expected-error@-5 {{using declaration refers into 'Subclass::', which is not a base class of 'C'}}
    335 #endif
    336 
    337     int bar();
    338 #if __cplusplus <= 199711L
    339     //expected-note@-2 {{target of using declaration}}
    340 #endif
    341     C::bar;
    342 #if __cplusplus <= 199711L
    343     // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
    344 #else
    345     // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
    346 #endif
    347     // expected-error@-6 {{using declaration refers to its own class}}
    348   };
    349 }
    350 
    351