Stop stripping UnresolvedUsingDecls out of LookupResults that have other

results in them (which we were doing intentionally as a stopgap).  Fix
an DeclContext lookup-table ordering problem which was causing UsingDecls to
show up incorrectly when looking for ordinary results.  And oh hey
Clang-Code-Syntax passes now.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90367 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2009-12-03 00:58:24 +00:00
Родитель 74635d8cd3
Коммит fda8e12774
3 изменённых файлов: 77 добавлений и 25 удалений

Просмотреть файл

@ -200,11 +200,37 @@ public:
}
VectorTy &Vec = *getAsVector();
if (isa<UsingDirectiveDecl>(D) ||
D->getIdentifierNamespace() == Decl::IDNS_Tag)
// Using directives end up in a special entry which contains only
// other using directives, so all this logic is wasted for them.
// But avoiding the logic wastes time in the far-more-common case
// that we're *not* adding a new using directive.
// Tag declarations always go at the end of the list so that an
// iterator which points at the first tag will start a span of
// decls that only contains tags.
if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
Vec.push_back(reinterpret_cast<uintptr_t>(D));
else if (reinterpret_cast<NamedDecl *>(Vec.back())
->getIdentifierNamespace() == Decl::IDNS_Tag) {
// Resolved using declarations go at the front of the list so that
// they won't show up in other lookup results. Unresolved using
// declarations (which are always in IDNS_Using | IDNS_Ordinary)
// follow that so that the using declarations will be contiguous.
else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
VectorTy::iterator I = Vec.begin();
if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
while (I != Vec.end() &&
reinterpret_cast<NamedDecl *>(*I)
->getIdentifierNamespace() == Decl::IDNS_Using)
++I;
}
Vec.insert(I, reinterpret_cast<uintptr_t>(D));
// All other declarations go at the end of the list, but before any
// tag declarations. But we can be clever about tag declarations
// because there can only ever be one in a scope.
} else if (reinterpret_cast<NamedDecl *>(Vec.back())
->getIdentifierNamespace() == Decl::IDNS_Tag) {
uintptr_t TagD = Vec.back();
Vec.back() = reinterpret_cast<uintptr_t>(D);
Vec.push_back(TagD);

Просмотреть файл

@ -282,9 +282,6 @@ void LookupResult::resolveKind() {
// If it's not unique, pull something off the back (and
// continue at this index).
Decls[I] = Decls[--N];
} else if (isa<UnresolvedUsingValueDecl>(D)) {
// FIXME: support unresolved using value declarations
Decls[I] = Decls[--N];
} else {
// Otherwise, do some decl type analysis and then continue.
@ -318,13 +315,13 @@ void LookupResult::resolveKind() {
// wherever the object, function, or enumerator name is visible.
// But it's still an error if there are distinct tag types found,
// even if they're not visible. (ref?)
if (HideTags && HasTag && !Ambiguous && !HasUnresolved &&
(HasFunction || HasNonFunction))
if (HideTags && HasTag && !Ambiguous &&
(HasFunction || HasNonFunction || HasUnresolved))
Decls[UniqueTagIndex] = Decls[--N];
Decls.set_size(N);
if (HasFunction && HasNonFunction)
if (HasNonFunction && (HasFunction || HasUnresolved))
Ambiguous = true;
if (Ambiguous)

Просмотреть файл

@ -1,20 +1,49 @@
// RUN: clang-cc -fsyntax-only -verify %s
namespace N { }
namespace test0 {
namespace N { }
template<typename T>
struct A {
void f();
};
template<typename T>
struct A {
void f();
};
template<typename T>
struct B : A<T> {
using A<T>::f;
void g() {
using namespace N;
f();
template<typename T>
struct B : A<T> {
using A<T>::f;
void g() {
using namespace N;
f();
}
};
template struct B<int>;
}
namespace test1 {
template <class Derived> struct Visitor1 {
void Visit(struct Object1*);
};
template <class Derived> struct Visitor2 {
void Visit(struct Object2*); // expected-note {{candidate function}}
};
template <class Derived> struct JoinVisitor
: Visitor1<Derived>, Visitor2<Derived> {
typedef Visitor1<Derived> Base1;
typedef Visitor2<Derived> Base2;
void Visit(struct Object1*); // expected-note {{candidate function}}
using Base2::Visit;
};
class Knot : JoinVisitor<Knot> {
};
void test() {
Knot().Visit((struct Object1*) 0);
Knot().Visit((struct Object2*) 0);
Knot().Visit((struct Object3*) 0); // expected-error {{no matching member function for call}}
}
};
template struct B<int>;
}