// shouldn't be diagnosing.
LookupName(Previous, S);
+ // When declaring or defining a tag, ignore ambiguities introduced
+ // by types using'ed into this scope.
if (Previous.isAmbiguous() &&
(TUK == TUK_Definition || TUK == TUK_Declaration)) {
LookupResult::Filter F = Previous.makeFilter();
}
F.done();
}
+
+ // C++11 [namespace.memdef]p3:
+ // If the name in a friend declaration is neither qualified nor
+ // a template-id and the declaration is a function or an
+ // elaborated-type-specifier, the lookup to determine whether
+ // the entity has been previously declared shall not consider
+ // any scopes outside the innermost enclosing namespace.
+ //
+ // Does it matter that this should be by scope instead of by
+ // semantic context?
+ if (!Previous.empty() && TUK == TUK_Friend) {
+ DeclContext *EnclosingNS = SearchDC->getEnclosingNamespaceContext();
+ LookupResult::Filter F = Previous.makeFilter();
+ while (F.hasNext()) {
+ NamedDecl *ND = F.next();
+ DeclContext *DC = ND->getDeclContext()->getRedeclContext();
+ if (DC->isFileContext() && !EnclosingNS->Encloses(ND->getDeclContext()))
+ F.erase();
+ }
+ F.done();
+ }
// Note: there used to be some attempt at recovery here.
if (Previous.isAmbiguous())
template void f<int>(int);
template void f<long>(long); //expected-note {{instantiation}}
}
+
+// rdar://13393749
+namespace test6 {
+ class A;
+ namespace ns {
+ class B {
+ static void foo(); // expected-note {{implicitly declared private here}}
+ friend union A;
+ };
+
+ union A {
+ void test() {
+ B::foo();
+ }
+ };
+ }
+
+ class A {
+ void test() {
+ ns::B::foo(); // expected-error {{'foo' is a private member of 'test6::ns::B'}}
+ }
+ };
+}
+
+// We seem to be following a correct interpretation with these, but
+// the standard could probably be a bit clearer.
+namespace test7a {
+ namespace ns {
+ class A;
+ }
+
+ using namespace ns;
+ class B {
+ static void foo();
+ friend class A;
+ };
+
+ class ns::A {
+ void test() {
+ B::foo();
+ }
+ };
+}
+namespace test7b {
+ namespace ns {
+ class A;
+ }
+
+ using ns::A;
+ class B {
+ static void foo();
+ friend class A;
+ };
+
+ class ns::A {
+ void test() {
+ B::foo();
+ }
+ };
+}
+namespace test7c {
+ namespace ns1 {
+ class A;
+ }
+
+ namespace ns2 {
+ // ns1::A appears as if declared in test7c according to [namespace.udir]p2.
+ // I think that means we aren't supposed to find it.
+ using namespace ns1;
+ class B {
+ static void foo(); // expected-note {{implicitly declared private here}}
+ friend class A;
+ };
+ }
+
+ class ns1::A {
+ void test() {
+ ns2::B::foo(); // expected-error {{'foo' is a private member of 'test7c::ns2::B'}}
+ }
+ };
+}
+namespace test7d {
+ namespace ns1 {
+ class A;
+ }
+
+ namespace ns2 {
+ // Honor the lexical context of a using-declaration, though.
+ using ns1::A;
+ class B {
+ static void foo();
+ friend class A;
+ };
+ }
+
+ class ns1::A {
+ void test() {
+ ns2::B::foo();
+ }
+ };
+}