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