diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-10 16:57:35 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-10 16:57:35 +0000 |
commit | e942bbe02b6fb332d1f13d38c6e1980b416cf89a (patch) | |
tree | e1dacc15d51066da2e7d6de19f6d41ddd135fd9a /lib/Sema/SemaLookup.cpp | |
parent | 736d8a66062eeb25a4b63dcac36d1d4c261a02c4 (diff) |
When performing unqualified name lookup into a DeclContext, also look into
all of the parent DeclContexts that aren't represented within the
Scope chain. This fixes some name-lookup problems in out-of-line
definitions of members of nested classes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81451 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 44c76a86e0..67674206fb 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -636,6 +636,15 @@ static bool isNamespaceOrTranslationUnitScope(Scope *S) { return false; } +// Find the next outer declaration context corresponding to this scope. +static DeclContext *findOuterContext(Scope *S) { + for (S = S->getParent(); S; S = S->getParent()) + if (S->getEntity()) + return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext(); + + return 0; +} + std::pair<bool, Sema::LookupResult> Sema::CppLookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind, bool RedeclarationOnly) { @@ -694,30 +703,23 @@ Sema::CppLookupName(Scope *S, DeclarationName Name, } if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity())) { LookupResult R; - // Perform member lookup into struct. - // FIXME: In some cases, we know that every name that could be found by - // this qualified name lookup will also be on the identifier chain. For - // 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 (isa<RecordDecl>(Ctx)) { + + DeclContext *OuterCtx = findOuterContext(S); + for (; Ctx && Ctx->getPrimaryContext() != OuterCtx; + Ctx = Ctx->getLookupParent()) { + if (Ctx->isFunctionOrMethod()) + continue; + + // Perform qualified name lookup into this context. + // FIXME: In some cases, we know that every name that could be found by + // this qualified name lookup will also be on the identifier chain. For + // 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. R = LookupQualifiedName(Ctx, Name, NameKind, RedeclarationOnly); if (R) return std::make_pair(true, R); } - if (Ctx->getParent() != Ctx->getLexicalParent() - || isa<CXXMethodDecl>(Ctx)) { - // It is out of line defined C++ method or struct, we continue - // doing name lookup in parent context. Once we will find namespace - // or translation-unit we save it for possible checking - // using-directives later. - for (OutOfLineCtx = Ctx; OutOfLineCtx && !OutOfLineCtx->isFileContext(); - OutOfLineCtx = OutOfLineCtx->getParent()) { - R = LookupQualifiedName(OutOfLineCtx, Name, NameKind, RedeclarationOnly); - if (R) - return std::make_pair(true, R); - } - } } } |