brintos

brintos / llvm-project-archived public Read only

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