163 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 5namespace A {6 class A {7 friend void func(A);8 friend A operator+(A,A);9 };10}11 12namespace B {13 class B {14 static void func(B);15 };16 B operator+(B,B);17}18 19namespace D {20 class D {};21}22 23namespace C {24 class C {}; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'B::B' to 'const C &' for 1st argument}}25#if __cplusplus >= 201103L // C++11 or later26 // expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'B::B' to 'C &&' for 1st argument}}27#endif28 void func(C); // expected-note {{'C::func' declared here}} \29 // expected-note {{passing argument to parameter here}}30 C operator+(C,C);31 D::D operator+(D::D,D::D);32}33 34namespace D {35 using namespace C;36}37 38namespace Test {39 void test() {40 func(A::A());41 // FIXME: namespace-aware typo correction causes an extra, misleading42 // message in this case; some form of backtracking, diagnostic message43 // delaying, or argument checking before emitting diagnostics is needed to44 // avoid accepting and printing out a typo correction that proves to be45 // incorrect once argument-dependent lookup resolution has occurred.46 func(B::B()); // expected-error {{use of undeclared identifier 'func'; did you mean 'C::func'?}} \47 // expected-error {{no viable conversion from 'B::B' to 'C'}}48 func(C::C());49 A::A() + A::A();50 B::B() + B::B();51 C::C() + C::C();52 D::D() + D::D(); // expected-error {{invalid operands to binary expression ('D::D' and 'D::D')}}53 }54}55 56// PR671657namespace test1 {58 template <class T> class A {59 template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('const A<int>') would lose const qualifier}}60 61 public:62 A();63 };64 65 void test() {66 const A<int> a;67 foo(a, 10); // expected-error {{no matching function for call to 'foo'}}68 }69}70 71 72// Check the rules described in p4:73// When considering an associated namespace, the lookup is the same as the lookup74// performed when the associated namespace is used as a qualifier (6.4.3.2) except that:75 76// - Any using-directives in the associated namespace are ignored.77namespace test_using_directives {78 namespace M { struct S; }79 namespace N {80 void f(M::S); // expected-note {{declared here}}81 }82 namespace M {83 using namespace N;84 struct S {};85 }86 void test() {87 M::S s;88 f(s); // expected-error {{use of undeclared}}89 M::f(s); // ok90 }91}92 93// - Any namespace-scope friend functions or friend function templates declared in94// associated classes are visible within their respective namespaces even if95// they are not visible during an ordinary lookup96// (Note: For the friend declaration to be visible, the corresponding class must be97// included in the set of associated classes. Merely including the namespace in98// the set of associated namespaces is not enough.)99namespace test_friend1 {100 namespace N {101 struct S;102 struct T {103 friend void f(S); // #1104 };105 struct S { S(); S(T); };106 }107 108 void test() {109 N::S s;110 N::T t;111 f(s); // expected-error {{use of undeclared}}112 f(t); // ok, #1113 }114}115 116// credit: Arthur O’Dwyer117namespace test_friend2 {118 struct A {119 struct B {120 struct C {};121 };122 friend void foo(...); // #1123 };124 125 struct D {126 friend void foo(...); // #2127 };128 template<class> struct E {129 struct F {};130 };131 132 template<class> struct G {};133 template<class> struct H {};134 template<class> struct I {};135 struct J { friend void foo(...) {} }; // #3136 137 void test() {138 A::B::C c;139 foo(c); // #1 is not visible since A is not an associated class140 // expected-error@-1 {{use of undeclared}}141 E<D>::F f;142 foo(f); // #2 is not visible since D is not an associated class143 // expected-error@-1 {{use of undeclared}}144 G<H<I<J> > > j;145 foo(j); // ok, #3.146 }147}148 149// - All names except those of (possibly overloaded) functions and150// function templates are ignored.151namespace test_other_names {152 namespace N {153 struct S {};154 struct Callable { void operator()(S); };155 static struct Callable Callable;156 }157 158 void test() {159 N::S s;160 Callable(s); // expected-error {{use of undeclared}}161 }162}163