1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// C++03 [namespace.udecl]p12:
4//   When a using-declaration brings names from a base class into a
5//   derived class scope, member functions in the derived class
6//   override and/or hide member functions with the same name and
7//   parameter types in a base class (rather than conflicting).
8
9template <unsigned n> struct Opaque {};
10template <unsigned n> void expect(Opaque<n> _) {}
11
12// PR5727
13// This just shouldn't crash.
14namespace test0 {
15  template<typename> struct RefPtr { };
16  template<typename> struct PtrHash {
17    static void f() { }
18  };
19  template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
20    using PtrHash<T*>::f;
21    static void f() { f(); }
22  };
23}
24
25// Simple hiding.
26namespace test1 {
27  struct Base {
28    Opaque<0> foo(Opaque<0>);
29    Opaque<0> foo(Opaque<1>);
30    Opaque<0> foo(Opaque<2>);
31  };
32
33  // using before decls
34  struct Test0 : Base {
35    using Base::foo;
36    Opaque<1> foo(Opaque<1>);
37    Opaque<1> foo(Opaque<3>);
38
39    void test0() { Opaque<0> _ = foo(Opaque<0>()); }
40    void test1() { Opaque<1> _ = foo(Opaque<1>()); }
41    void test2() { Opaque<0> _ = foo(Opaque<2>()); }
42    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
43  };
44
45  // using after decls
46  struct Test1 : Base {
47    Opaque<1> foo(Opaque<1>);
48    Opaque<1> foo(Opaque<3>);
49    using Base::foo;
50
51    void test0() { Opaque<0> _ = foo(Opaque<0>()); }
52    void test1() { Opaque<1> _ = foo(Opaque<1>()); }
53    void test2() { Opaque<0> _ = foo(Opaque<2>()); }
54    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
55  };
56
57  // using between decls
58  struct Test2 : Base {
59    Opaque<1> foo(Opaque<0>);
60    using Base::foo;
61    Opaque<1> foo(Opaque<2>);
62    Opaque<1> foo(Opaque<3>);
63
64    void test0() { Opaque<1> _ = foo(Opaque<0>()); }
65    void test1() { Opaque<0> _ = foo(Opaque<1>()); }
66    void test2() { Opaque<1> _ = foo(Opaque<2>()); }
67    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
68  };
69}
70
71// Crazy dependent hiding.
72namespace test2 {
73  struct Base {
74    void foo(int);
75  };
76
77  template <typename T> struct Derived1 : Base {
78    using Base::foo;
79    void foo(T);
80
81    void testUnresolved(int i) { foo(i); }
82  };
83
84  void test0(int i) {
85    Derived1<int> d1;
86    d1.foo(i);
87    d1.testUnresolved(i);
88  }
89
90  // Same thing, except with the order of members reversed.
91  template <typename T> struct Derived2 : Base {
92    void foo(T);
93    using Base::foo;
94
95    void testUnresolved(int i) { foo(i); }
96  };
97
98  void test1(int i) {
99    Derived2<int> d2;
100    d2.foo(i);
101    d2.testUnresolved(i);
102  }
103}
104
105// Hiding of member templates.
106namespace test3 {
107  struct Base {
108    template <class T> Opaque<0> foo() { return Opaque<0>(); }
109    template <int n> Opaque<1> foo() { return Opaque<1>(); }
110  };
111
112  struct Derived1 : Base {
113    using Base::foo;
114    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
115  };
116
117  struct Derived2 : Base {
118    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
119    using Base::foo;
120  };
121
122  struct Derived3 : Base {
123    using Base::foo;
124    template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
125  };
126
127  struct Derived4 : Base {
128    template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
129    using Base::foo;
130  };
131
132  void test() {
133    expect<0>(Base().foo<int>());
134    expect<1>(Base().foo<0>());
135    expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
136    expect<2>(Derived1().foo<0>());
137    expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
138    expect<2>(Derived2().foo<0>());
139    expect<3>(Derived3().foo<int>());
140    expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
141    expect<3>(Derived4().foo<int>());
142    expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
143  }
144}
145
146// PR7384: access control for member templates.
147namespace test4 {
148  class Base {
149  protected:
150    template<typename T> void foo(T);
151    template<typename T> void bar(T); // expected-note {{declared protected here}}
152  };
153
154  struct Derived : Base {
155    using Base::foo;
156  };
157
158  void test() {
159    Derived d;
160    d.foo<int>(3);
161    d.bar<int>(3); // expected-error {{'bar' is a protected member}}
162  }
163}
164