diff options
author | Matthias Gehre <M.Gehre@gmx.de> | 2017-03-17 21:41:20 +0000 |
---|---|---|
committer | Matthias Gehre <M.Gehre@gmx.de> | 2017-03-17 21:41:20 +0000 |
commit | 8c121042c9a805118c4552a1bd7b64d8ffe70988 (patch) | |
tree | a31cf05dd44964a477681639b1158bb0953712ff /lib/Parse | |
parent | 31801a78220872a1dcee9b261328ce7239eaa7e9 (diff) |
Implement DR 373 "Lookup on namespace qualified name in using-directive"
Summary:
3.4.6 [basic.lookup.udir] paragraph 1:
In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier, only namespace names are considered.
Reviewers: rsmith, aaron.ballman
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D30848
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@298126 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 30 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 11 |
2 files changed, 33 insertions, 8 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 618c8ab2ea..87facc449f 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -266,15 +266,26 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, CXXScopeSpec SS; // Parse (optional) nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false); + ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false, + /*MayBePseudoDestructor=*/nullptr, + /*IsTypename=*/false, + /*LastII=*/nullptr, + /*OnlyNamespace=*/true); - if (SS.isInvalid() || Tok.isNot(tok::identifier)) { + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_namespace_name); // Skip to end of the definition and eat the ';'. SkipUntil(tok::semi); return nullptr; } + if (SS.isInvalid()) { + // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier. + // Skip to end of the definition and eat the ';'. + SkipUntil(tok::semi); + return nullptr; + } + // Parse identifier. IdentifierInfo *Ident = Tok.getIdentifierInfo(); SourceLocation IdentLoc = ConsumeToken(); @@ -487,13 +498,17 @@ Decl *Parser::ParseUsingDirective(unsigned Context, CXXScopeSpec SS; // Parse (optional) nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false); + ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false, + /*MayBePseudoDestructor=*/nullptr, + /*IsTypename=*/false, + /*LastII=*/nullptr, + /*OnlyNamespace=*/true); IdentifierInfo *NamespcName = nullptr; SourceLocation IdentLoc = SourceLocation(); // Parse namespace-name. - if (SS.isInvalid() || Tok.isNot(tok::identifier)) { + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_namespace_name); // If there was invalid namespace name, skip to end of decl, and eat ';'. SkipUntil(tok::semi); @@ -501,6 +516,13 @@ Decl *Parser::ParseUsingDirective(unsigned Context, return nullptr; } + if (SS.isInvalid()) { + // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier. + // Skip to end of the definition and eat the ';'. + SkipUntil(tok::semi); + return nullptr; + } + // Parse identifier. NamespcName = Tok.getIdentifierInfo(); IdentLoc = ConsumeToken(); diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index cb56ebb104..10339fc96b 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -141,13 +141,16 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, /// filled in with the leading identifier in the last component of the /// nested-name-specifier, if any. /// +/// \param OnlyNamespace If true, only considers namespaces in lookup. +/// /// \returns true if there was an error parsing a scope specifier bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename, - IdentifierInfo **LastII) { + IdentifierInfo **LastII, + bool OnlyNamespace) { assert(getLangOpts().CPlusPlus && "Call sites of this function should be guarded by checking for C++"); @@ -450,9 +453,9 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, bool IsCorrectedToColon = false; bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr; - if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), IdInfo, - EnteringContext, SS, - false, CorrectionFlagPtr)) { + if (Actions.ActOnCXXNestedNameSpecifier( + getCurScope(), IdInfo, EnteringContext, SS, false, + CorrectionFlagPtr, OnlyNamespace)) { // Identifier is not recognized as a nested name, but we can have // mistyped '::' instead of ':'. if (CorrectionFlagPtr && IsCorrectedToColon) { |