aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-15 01:44:47 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-15 01:44:47 +0000
commit7d3f576dc9ea6e866757abcd1736eb7e7433c325 (patch)
tree9baa6e6db1f568b9f259e02ea3b759cb6a8d25fb /lib/Sema/SemaLookup.cpp
parent69456f12c5e5211adbfd7c3500d13436d4fec8da (diff)
When performing qualified name lookup into the current instantiation,
do not look into base classes if there are any dependent base classes. Instead, note in the lookup result that we couldn't look into any dependent bases. Use that new result kind to detect when this case occurs, so that we can fall back to treating the type/value/etc. as a member of an unknown specialization. Fixes an issue where we were resolving lookup at template definition time and then missing an ambiguity at template instantiation time. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93497 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r--lib/Sema/SemaLookup.cpp44
1 files changed, 24 insertions, 20 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index c6ab6a6b19..cda245deba 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -623,7 +623,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
// example, inside a class without any base classes, we never need to
// perform qualified lookup because all of the members are on top of the
// identifier chain.
- if (LookupQualifiedName(R, Ctx))
+ if (LookupQualifiedName(R, Ctx, /*InUnqualifiedLookup=*/true))
return true;
}
}
@@ -927,11 +927,11 @@ static bool LookupQualifiedNameInUsingDirectives(LookupResult &R,
return Found;
}
-/// @brief Perform qualified name lookup into a given context.
+/// \brief Perform qualified name lookup into a given context.
///
/// Qualified name lookup (C++ [basic.lookup.qual]) is used to find
/// names when the context of those names is explicit specified, e.g.,
-/// "std::vector" or "x->member".
+/// "std::vector" or "x->member", or as part of unqualified name lookup.
///
/// Different lookup criteria can find different names. For example, a
/// particular scope can have both a struct and a function of the same
@@ -939,25 +939,18 @@ static bool LookupQualifiedNameInUsingDirectives(LookupResult &R,
/// information about lookup criteria, see the documentation for the
/// class LookupCriteria.
///
-/// @param LookupCtx The context in which qualified name lookup will
+/// \param R captures both the lookup criteria and any lookup results found.
+///
+/// \param LookupCtx The context in which qualified name lookup will
/// search. If the lookup criteria permits, name lookup may also search
/// in the parent contexts or (for C++ classes) base classes.
///
-/// @param Name The name of the entity that we are searching for.
-///
-/// @param Criteria The criteria that this routine will use to
-/// determine which names are visible and which names will be
-/// found. Note that name lookup will find a name that is visible by
-/// the given criteria, but the entity itself may not be semantically
-/// correct or even the kind of entity expected based on the
-/// lookup. For example, searching for a nested-name-specifier name
-/// might result in an EnumDecl, which is visible but is not permitted
-/// as a nested-name-specifier in C++03.
+/// \param InUnqualifiedLookup true if this is qualified name lookup that
+/// occurs as part of unqualified name lookup.
///
-/// @returns The result of name lookup, which includes zero or more
-/// declarations and possibly additional information used to diagnose
-/// ambiguities.
-bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx) {
+/// \returns true if lookup succeeded, false if it failed.
+bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+ bool InUnqualifiedLookup) {
assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context");
if (!R.getLookupName())
@@ -995,11 +988,22 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx) {
// If this isn't a C++ class, we aren't allowed to look into base
// classes, we're done.
- if (!isa<CXXRecordDecl>(LookupCtx))
+ CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
+ if (!LookupRec)
return false;
+ // If we're performing qualified name lookup into a dependent class,
+ // then we are actually looking into a current instantiation. If we have any
+ // dependent base classes, then we either have to delay lookup until
+ // template instantiation time (at which point all bases will be available)
+ // or we have to fail.
+ if (!InUnqualifiedLookup && LookupRec->isDependentContext() &&
+ LookupRec->hasAnyDependentBases()) {
+ R.setNotFoundInCurrentInstantiation();
+ return false;
+ }
+
// Perform lookup into our base classes.
- CXXRecordDecl *LookupRec = cast<CXXRecordDecl>(LookupCtx);
CXXBasePaths Paths;
Paths.setOrigin(LookupRec);