diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-11 19:58:34 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-11 19:58:34 +0000 |
commit | 42af25f865a82022a04bedeb483ac251c4412e29 (patch) | |
tree | 579ef3cff4425baa0298aab2b3495d56ace030ba /lib/Sema/SemaLookup.cpp | |
parent | 8c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9 (diff) |
Implement the notions of the "current instantiation" and "unknown
specialization" within a C++ template, and permit name lookup into the
current instantiation. For example, given:
template<typename T, typename U>
struct X {
typedef T type;
X* x1; // current instantiation
X<T, U> *x2; // current instantiation
X<U, T> *x3; // not current instantiation
::X<type, U> *x4; // current instantiation
X<typename X<type, U>::type, U>: *x5; // current instantiation
};
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71471 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index b1643bb50b..64acbe04c1 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -17,6 +17,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/Parse/DeclSpec.h" #include "clang/Basic/LangOptions.h" @@ -1117,14 +1118,37 @@ Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS, DeclarationName Name, LookupNameKind NameKind, bool RedeclarationOnly, bool AllowBuiltinCreation, SourceLocation Loc) { - if (SS) { - if (SS->isInvalid() || RequireCompleteDeclContext(*SS)) + if (SS && (SS->isSet() || SS->isInvalid())) { + // If the scope specifier is invalid, don't even look for + // anything. + if (SS->isInvalid()) return LookupResult::CreateLookupResult(Context, 0); - if (SS->isSet()) { - return LookupQualifiedName(computeDeclContext(*SS), - Name, NameKind, RedeclarationOnly); + assert(!isUnknownSpecialization(*SS) && "Can't lookup dependent types"); + + if (isDependentScopeSpecifier(*SS)) { + // Determine whether we are looking into the current + // instantiation. + NestedNameSpecifier *NNS + = static_cast<NestedNameSpecifier *>(SS->getScopeRep()); + CXXRecordDecl *Current = getCurrentInstantiationOf(NNS); + assert(Current && "Bad dependent scope specifier"); + + // We nested name specifier refers to the current instantiation, + // so now we will look for a member of the current instantiation + // (C++0x [temp.dep.type]). + unsigned IDNS = getIdentifierNamespacesFromLookupNameKind(NameKind, true); + DeclContext::lookup_iterator I, E; + for (llvm::tie(I, E) = Current->lookup(Context, Name); I != E; ++I) + if (isAcceptableLookupResult(*I, NameKind, IDNS)) + return LookupResult::CreateLookupResult(Context, I, E); } + + if (RequireCompleteDeclContext(*SS)) + return LookupResult::CreateLookupResult(Context, 0); + + return LookupQualifiedName(computeDeclContext(*SS), + Name, NameKind, RedeclarationOnly); } return LookupName(S, Name, NameKind, RedeclarationOnly, @@ -1601,4 +1625,3 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, } } } - |