Home | History | Annotate | Download | only in class.access.dcl
      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 
     17 namespace 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 
     34 struct Opaque0 {};
     35 
     36 namespace 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 
     79 namespace 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 
    122 namespace 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 
    171 namespace 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