ryee88 created this revision. ryee88 added reviewers: doug.gregor, gribozavr, francisco.lopes. ryee88 added a subscriber: cfe-commits.
Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member This is a fix for this bug: https://llvm.org/bugs/show_bug.cgi?id=14644 Essentially the diagnostic needs to distinguish between a "global-specifier with no nested-name-specifier" and nested-name-specifier (everything else) in order to provide a more helpful error message. http://reviews.llvm.org/D16965 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -3789,6 +3789,17 @@ if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() && !IsExplicitInstantiation && !IsExplicitSpecialization && !isa<ClassTemplatePartialSpecializationDecl>(Tag)) { + + // Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3: + // "Cannot introduce an qualified". + // A clang::NestedNameSpecifier can represent many kinds of specifiers. + // A global-specifier with no nested-name-specifier requires a different + // diagnostic from a nested-name specifier. + unsigned diagId = ( SS.getScopeRep()->getKind() == NestedNameSpecifier::Global && + !SS.getScopeRep()->getPrefix() ) + ? diag::err_standalone_class_specifier + : diagId = diag::err_standalone_class_nested_name_specifier; + // Per C++ [dcl.type.elab]p1, a class declaration cannot have a // nested-name-specifier unless it is an explicit instantiation // or an explicit specialization. @@ -3797,8 +3808,9 @@ // obvious intent of DR1819. // // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either. - Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier) - << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange(); + Diag(SS.getBeginLoc(), diagId) + << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange(); + return nullptr; } Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -5241,6 +5241,9 @@ def err_standalone_class_nested_name_specifier : Error< "forward declaration of %select{class|struct|interface|union|enum}0 cannot " "have a nested name specifier">; +def err_standalone_class_specifier : Error< + "forward declaration of qualified %select{class|struct|interface|union|enum}0 " + "not allowed">; def err_typecheck_sclass_func : Error<"illegal storage class on function">; def err_static_block_func : Error< "function declared in block scope cannot have 'static' storage class">;
Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -3789,6 +3789,17 @@ if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() && !IsExplicitInstantiation && !IsExplicitSpecialization && !isa<ClassTemplatePartialSpecializationDecl>(Tag)) { + + // Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3: + // "Cannot introduce an qualified". + // A clang::NestedNameSpecifier can represent many kinds of specifiers. + // A global-specifier with no nested-name-specifier requires a different + // diagnostic from a nested-name specifier. + unsigned diagId = ( SS.getScopeRep()->getKind() == NestedNameSpecifier::Global && + !SS.getScopeRep()->getPrefix() ) + ? diag::err_standalone_class_specifier + : diagId = diag::err_standalone_class_nested_name_specifier; + // Per C++ [dcl.type.elab]p1, a class declaration cannot have a // nested-name-specifier unless it is an explicit instantiation // or an explicit specialization. @@ -3797,8 +3808,9 @@ // obvious intent of DR1819. // // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either. - Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier) - << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange(); + Diag(SS.getBeginLoc(), diagId) + << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange(); + return nullptr; } Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -5241,6 +5241,9 @@ def err_standalone_class_nested_name_specifier : Error< "forward declaration of %select{class|struct|interface|union|enum}0 cannot " "have a nested name specifier">; +def err_standalone_class_specifier : Error< + "forward declaration of qualified %select{class|struct|interface|union|enum}0 " + "not allowed">; def err_typecheck_sclass_func : Error<"illegal storage class on function">; def err_static_block_func : Error< "function declared in block scope cannot have 'static' storage class">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits