1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// We have to avoid ADL for this test.
4
5template <unsigned N> class test {};
6
7class foo {};	// expected-note {{candidate}}
8test<0> foo(foo); // expected-note {{candidate}}
9
10namespace Test0 {
11  class foo { int x; };
12  test<1> foo(class foo);
13
14  namespace A {
15    test<2> foo(class ::foo); // expected-note {{candidate}} \
16    // expected-note{{passing argument to parameter here}}
17
18    void test0() {
19      using ::foo;
20
21      class foo a;
22      test<0> _ = (foo)(a);
23    }
24
25    void test1() {
26      using Test0::foo;
27
28      class foo a;
29      test<1> _ = (foo)(a);
30    };
31
32    void test2() {
33      class ::foo a;
34
35      // Argument-dependent lookup is ambiguous between B:: and ::.
36      test<0> _0 = foo(a); // expected-error {{call to 'foo' is ambiguous}}
37
38      // But basic unqualified lookup is not.
39      test<2> _1 = (foo)(a);
40
41      class Test0::foo b;
42      test<2> _2 = (foo)(b); // expected-error {{no viable conversion from 'class Test0::foo' to 'class ::foo'}}
43    }
44  }
45}
46
47namespace Test1 {
48  namespace A {
49    class a {};
50  }
51
52  namespace B {
53    typedef class {} b;
54  }
55
56  namespace C {
57    int c(); // expected-note {{target of using declaration}}
58  }
59
60  namespace D {
61    using typename A::a;
62    using typename B::b;
63    using typename C::c; // expected-error {{'typename' keyword used on a non-type}}
64
65    a _1 = A::a();
66    b _2 = B::b();
67  }
68}
69
70namespace test2 {
71  class A {
72  protected:
73    operator int();
74    operator bool();
75  };
76
77  class B : private A {
78  protected:
79    using A::operator int; // expected-note {{declared protected here}}
80  public:
81    using A::operator bool;
82  };
83
84  int test() {
85    bool b = B();
86    return B(); // expected-error {{'operator int' is a protected member of 'test2::B'}}
87  }
88}
89
90namespace test3 {
91  class A {
92  public:
93    ~A();
94  };
95
96  class B {
97    friend class C;
98  private:
99    operator A*();
100  };
101
102  class C : public B {
103  public:
104    using B::operator A*;
105  };
106
107  void test() {
108    delete C();
109  }
110}
111