mgehre created this revision. 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.
https://reviews.llvm.org/D30848 Files: include/clang/Parse/Parser.h include/clang/Sema/Sema.h lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaCXXScopeSpec.cpp test/CXX/drs/dr3xx.cpp www/cxx_dr_status.html
Index: www/cxx_dr_status.html =================================================================== --- www/cxx_dr_status.html +++ www/cxx_dr_status.html @@ -2279,7 +2279,7 @@ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#373">373</a></td> <td>C++11</td> <td>Lookup on namespace qualified name in using-directive</td> - <td class="none" align="center">No</td> + <td class="full" align="center">Yes</td> </tr> <tr id="374"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374">374</a></td> Index: test/CXX/drs/dr3xx.cpp =================================================================== --- test/CXX/drs/dr3xx.cpp +++ test/CXX/drs/dr3xx.cpp @@ -908,15 +908,14 @@ } } -namespace dr373 { // dr373: no - // FIXME: This is valid. - namespace X { int dr373; } // expected-note 2{{here}} +namespace dr373 { // dr373: yes + namespace X { int dr373; } struct dr373 { // expected-note {{here}} void f() { - using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + using namespace dr373::X; int k = dr373; // expected-error {{does not refer to a value}} - namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + namespace Y = dr373::X; k = Y::dr373; } }; Index: lib/Sema/SemaCXXScopeSpec.cpp =================================================================== --- lib/Sema/SemaCXXScopeSpec.cpp +++ lib/Sema/SemaCXXScopeSpec.cpp @@ -461,6 +461,7 @@ /// are allowed. The bool value pointed by this parameter is set to /// 'true' if the identifier is treated as if it was followed by ':', /// not '::'. +/// \param OnlyNamespace If true, only considers namespaces in lookup. /// /// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in /// that it contains an extra parameter \p ScopeLookupResult, which provides @@ -479,9 +480,15 @@ CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, - bool *IsCorrectedToColon) { + bool *IsCorrectedToColon, + bool OnlyNamespace) { + + Sema::LookupNameKind LNameKind = LookupNestedNameSpecifierName; + if (OnlyNamespace) + LNameKind = LookupNamespaceName; + LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc, - LookupNestedNameSpecifierName); + LNameKind); QualType ObjectType = GetTypeFromParser(IdInfo.ObjectType); // Determine where to perform name lookup @@ -824,14 +831,16 @@ bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup, - bool *IsCorrectedToColon) { + bool *IsCorrectedToColon, + bool OnlyNamespace) { if (SS.isInvalid()) return true; return BuildCXXNestedNameSpecifier(S, IdInfo, EnteringContext, SS, /*ScopeLookupResult=*/nullptr, false, - IsCorrectedToColon); + IsCorrectedToColon, + OnlyNamespace); } bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -141,13 +141,16 @@ /// 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++"); @@ -452,7 +455,7 @@ bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr; if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), IdInfo, EnteringContext, SS, - false, CorrectionFlagPtr)) { + false, CorrectionFlagPtr, OnlyNamespace)) { // Identifier is not recognized as a nested name, but we can have // mistyped '::' instead of ':'. if (CorrectionFlagPtr && IsCorrectedToColon) { Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -266,7 +266,11 @@ 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)) { Diag(Tok, diag::err_expected_namespace_name); @@ -487,7 +491,11 @@ 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(); Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -5134,7 +5134,8 @@ CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); /// \brief The parser has parsed a nested-name-specifier 'identifier::'. /// @@ -5158,13 +5159,16 @@ /// are allowed. The bool value pointed by this parameter is set to 'true' /// if the identifier is treated as if it was followed by ':', not '::'. /// + /// \param OnlyNamespace If true, only considers namespaces in lookup. + /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup = false, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); ExprResult ActOnDecltypeExpression(Expr *E); Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -1534,7 +1534,8 @@ bool EnteringContext, bool *MayBePseudoDestructor = nullptr, bool IsTypename = false, - IdentifierInfo **LastII = nullptr); + IdentifierInfo **LastII = nullptr, + bool OnlyNamespace = false); //===--------------------------------------------------------------------===// // C++0x 5.1.2: Lambda expressions
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits