diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-15 01:44:47 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-15 01:44:47 +0000 |
commit | 7d3f576dc9ea6e866757abcd1736eb7e7433c325 (patch) | |
tree | 9baa6e6db1f568b9f259e02ea3b759cb6a8d25fb /lib/Sema/SemaLookup.cpp | |
parent | 69456f12c5e5211adbfd7c3500d13436d4fec8da (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.cpp | 44 |
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); |