forked from OSchip/llvm-project
Make a somewhat more convincing test case for unqualified lookup through
using directives, and fix a bug thereby exposed: since we're playing tricks with pointers, we need to make certain we're always using the same pointers for things. Also tweak an existing error message. llvm-svn: 86679
This commit is contained in:
parent
dca0c28452
commit
9757d0363d
|
@ -230,7 +230,7 @@ def ext_ellipsis_exception_spec : Extension<
|
|||
def err_expected_catch : Error<"expected catch">;
|
||||
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
|
||||
def err_using_namespace_in_class : Error<
|
||||
"'using namespace' in class not allowed">;
|
||||
"'using namespace' is not allowed in classes">;
|
||||
def err_ident_in_pseudo_dtor_not_a_type : Error<
|
||||
"identifier %0 in pseudo-destructor expression does not name a type">;
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ namespace {
|
|||
DeclContext *Common = UD->getNominatedNamespace();
|
||||
while (!Common->Encloses(EffectiveDC))
|
||||
Common = Common->getParent();
|
||||
Common = Common->getPrimaryContext();
|
||||
|
||||
list.push_back(UnqualUsingEntry(UD->getNominatedNamespace(), Common));
|
||||
}
|
||||
|
@ -187,7 +188,7 @@ namespace {
|
|||
|
||||
std::pair<const_iterator,const_iterator>
|
||||
getNamespacesFor(DeclContext *DC) const {
|
||||
return std::equal_range(begin(), end(), DC,
|
||||
return std::equal_range(begin(), end(), DC->getPrimaryContext(),
|
||||
UnqualUsingEntry::Comparator());
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
// (this actually occurs before paragraph 1)
|
||||
namespace test0 {
|
||||
namespace A {}
|
||||
class B {
|
||||
using namespace A; // expected-error {{'using namespace' is not allowed in classes}}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
struct opaque0 {};
|
||||
struct opaque1 {};
|
||||
|
||||
// Test that names appear as if in deepest common ancestor.
|
||||
namespace test1 {
|
||||
namespace A {
|
||||
namespace B {
|
||||
opaque0 foo(); // expected-note {{candidate}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace C {
|
||||
opaque1 foo(); // expected-note {{candidate}}
|
||||
|
||||
opaque1 test() {
|
||||
using namespace A::B;
|
||||
return foo(); // C::foo
|
||||
}
|
||||
}
|
||||
|
||||
opaque1 test() {
|
||||
using namespace A::B;
|
||||
using namespace C;
|
||||
return foo(); // expected-error {{call to 'foo' is ambiguous}}
|
||||
}
|
||||
}
|
||||
|
||||
// Same thing, but with the directives in namespaces.
|
||||
namespace test2 {
|
||||
namespace A {
|
||||
namespace B {
|
||||
opaque0 foo(); // expected-note {{candidate}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace C {
|
||||
opaque1 foo(); // expected-note {{candidate}}
|
||||
|
||||
namespace test {
|
||||
using namespace A::B;
|
||||
|
||||
opaque1 test() {
|
||||
return foo(); // C::foo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace test {
|
||||
using namespace A::B;
|
||||
using namespace C;
|
||||
|
||||
opaque1 test() {
|
||||
return foo(); // expected-error {{call to 'foo' is ambiguous}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transitivity.
|
||||
namespace test3 {
|
||||
namespace A {
|
||||
namespace B {
|
||||
opaque0 foo();
|
||||
}
|
||||
}
|
||||
namespace C {
|
||||
using namespace A;
|
||||
}
|
||||
|
||||
opaque0 test0() {
|
||||
using namespace C;
|
||||
using namespace B;
|
||||
return foo();
|
||||
}
|
||||
|
||||
namespace D {
|
||||
using namespace C;
|
||||
}
|
||||
namespace A {
|
||||
opaque1 foo();
|
||||
}
|
||||
|
||||
opaque1 test1() {
|
||||
using namespace D;
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
|
||||
// Transitivity acts like synthetic using directives.
|
||||
namespace test4 {
|
||||
namespace A {
|
||||
namespace B {
|
||||
opaque0 foo(); // expected-note {{candidate}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace C {
|
||||
using namespace A::B;
|
||||
}
|
||||
|
||||
opaque1 foo(); // expected-note {{candidate}}
|
||||
|
||||
namespace A {
|
||||
namespace D {
|
||||
using namespace C;
|
||||
}
|
||||
|
||||
opaque0 test() {
|
||||
using namespace D;
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
|
||||
opaque0 test() {
|
||||
using namespace A::D;
|
||||
return foo(); // expected-error {{call to 'foo' is ambiguous}}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue