diff options
author | John McCall <rjmccall@apple.com> | 2009-12-11 20:04:54 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-12-11 20:04:54 +0000 |
commit | e7e278bce2301990107cef3f873cbbf7da94469a (patch) | |
tree | 12f51a760758256e6f1cbcccaccca7fc837018a2 /lib/Sema/SemaCXXScopeSpec.cpp | |
parent | ef96eac2b83e2ed62144bb25b051d09a02296fe0 (diff) |
Don't enter a new scope for a namespace-qualified declarator unless we're
in a file context. In well-formed code, only happens with friend functions.
Fixes PR 5760.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91146 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 3c5dd547d6..039691f122 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -559,6 +559,44 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, T.getTypePtr()); } +bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { + assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); + + NestedNameSpecifier *Qualifier = + static_cast<NestedNameSpecifier*>(SS.getScopeRep()); + + // There are only two places a well-formed program may qualify a + // declarator: first, when defining a namespace or class member + // out-of-line, and second, when naming an explicitly-qualified + // friend function. The latter case is governed by + // C++03 [basic.lookup.unqual]p10: + // In a friend declaration naming a member function, a name used + // in the function declarator and not part of a template-argument + // in a template-id is first looked up in the scope of the member + // function's class. If it is not found, or if the name is part of + // a template-argument in a template-id, the look up is as + // described for unqualified names in the definition of the class + // granting friendship. + // i.e. we don't push a scope unless it's a class member. + + switch (Qualifier->getKind()) { + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Namespace: + // These are always namespace scopes. We never want to enter a + // namespace scope from anything but a file context. + return CurContext->getLookupContext()->isFileContext(); + + case NestedNameSpecifier::Identifier: + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + // These are never namespace scopes. + return true; + } + + // Silence bogus warning. + return false; +} + /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global /// scope or nested-name-specifier) is parsed, part of a declarator-id. /// After this method is called, according to [C++ 3.4.3p3], names should be |