When performing name lookup within a class template or class template

partial specialization, make sure we look into non-dependent base
classes (but not dependent base classes). Fixes PR4951.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81584 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-09-11 22:57:37 +00:00
Родитель 4f213d3d74
Коммит 4719f4e86a
3 изменённых файлов: 51 добавлений и 6 удалений

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

@ -139,9 +139,12 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
QualType BaseType = Context.getCanonicalType(BaseSpec->getType());
BaseType = BaseType.getUnqualifiedType();
// If a base class of the class template depends on a template-parameter,
// the base class scope is not examined during unqualified name lookup.
// [temp.dep]p3.
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
// if a base class of the class template depends on a template-parameter,
// the base class scope is not examined during unqualified name lookup
// either at the point of definition of the class template or member or
// during an instantiation of the class tem- plate or member.
if (BaseType->isDependentType())
continue;

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

@ -1032,9 +1032,8 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
return LookupResult::CreateLookupResult(Context, I, E);
// If this isn't a C++ class, we aren't allowed to look into base
// classes, we're done, or the lookup context is dependent, we're done.
if (RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx) ||
LookupCtx->isDependentContext())
// classes, we're done.
if (RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx))
return LookupResult::CreateLookupResult(Context, 0);
// Perform lookup into our base classes.

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

@ -0,0 +1,43 @@
// RUN: clang-cc -fsyntax-only -verify %s
struct A0 {
struct K { };
};
template <typename T> struct B0: A0 {
static void f() {
K k;
}
};
namespace E1 {
typedef double A;
template<class T> class B {
typedef int A;
};
template<class T>
struct X : B<T> {
A* blarg(double *dp) {
return dp;
}
};
}
namespace E2 {
struct A {
struct B;
int *a;
int Y;
};
int a;
template<class T> struct Y : T {
struct B { /* ... */ };
B b;
void f(int i) { a = i; }
Y* p;
};
Y<A> ya;
}