[PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

Ryan Yee via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 7 08:15:15 PST 2016


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">;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16965.47133.patch
Type: text/x-patch
Size: 2290 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160207/dec499ab/attachment-0001.bin>


More information about the cfe-commits mailing list