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