NamedDecl *D = F.next();
if (!isDeclInScope(D, CurContext, S))
F.erase();
+ // If we found a local extern declaration that's not ordinarily visible,
+ // and this declaration is being added to a non-block scope, ignore it.
+ // We're only checking for scope conflicts here, not also for violations
+ // of the linkage rules.
+ else if (!CurContext->isFunctionOrMethod() && D->isLocalExternDecl() &&
+ !(D->getIdentifierNamespace() & Decl::IDNS_Ordinary))
+ F.erase();
}
F.done();
} else {
IDNS = Decl::IDNS_Tag;
}
break;
+
case Sema::LookupLabel:
IDNS = Decl::IDNS_Label;
break;
-
+
case Sema::LookupMemberName:
IDNS = Decl::IDNS_Member;
if (CPlusPlus)
break;
case Sema::LookupUsingDeclName:
- IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag
- | Decl::IDNS_Member | Decl::IDNS_Using;
+ assert(Redeclaration && "should only be used for redecl lookup");
+ IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member |
+ Decl::IDNS_Using | Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend |
+ Decl::IDNS_LocalExtern;
break;
case Sema::LookupObjCProtocolName:
}
using N::M::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_nested_specifier::N::M'; did you mean 'N::FFF'?}}
}
+
+namespace UsingDeclVsHiddenName {
+ namespace A {
+ enum HiddenTag1 {}; // expected-note {{previous use is here}}
+ enum HiddenTag2 {}; // expected-note {{target}}
+ int HiddenFn1; // expected-note {{target}}
+ int HiddenFn2; // expected-note {{target}}
+ int HiddenLocalExtern1;
+ int HiddenLocalExtern2;
+ }
+
+ namespace B {
+ using A::HiddenTag1;
+ using A::HiddenFn1; // expected-note {{using declaration}}
+ using A::HiddenLocalExtern1;
+
+ struct S {
+ friend struct HiddenTag1; // expected-error {{tag type that does not match previous}}
+ friend struct HiddenTag2; // expected-note {{conflicting declaration}}
+ friend void HiddenFn1(); // expected-error {{cannot befriend target of using declaration}}
+ friend void HiddenFn2(); // expected-note {{conflicting declaration}}
+ void f() {
+ // OK, these are not in the scope of namespace B, even though they're
+ // members of the namespace.
+ void HiddenLocalExtern1();
+ void HiddenLocalExtern2();
+ }
+ };
+
+ using A::HiddenTag2; // expected-error {{conflicts with declaration already in scope}}
+ using A::HiddenFn2; // expected-error {{conflicts with declaration already in scope}}
+ using A::HiddenLocalExtern2;
+ }
+}