[cfe-commits] r139406 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/Modules/module-private.cpp

Douglas Gregor dgregor at apple.com
Fri Sep 9 13:53:38 PDT 2011


Author: dgregor
Date: Fri Sep  9 15:53:38 2011
New Revision: 139406

URL: http://llvm.org/viewvc/llvm-project?rev=139406&view=rev
Log:
Specializations cannot be module-hidden. Diagnose attempts to do so.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/Modules/module-private.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Sep  9 15:53:38 2011
@@ -574,12 +574,14 @@
 
 def err_seh___finally_block : Error<
   "%0 only allowed in __finally block">;
+  
+} // end of Parse Issue category.
 
-// Modules
+let CategoryName = "Modules Issue" in {
 def err_module_expected_ident : Error<
   "expected a module name after '__import_module__'">;
 def err_module_expected_semi : Error<
   "expected a semicolon name after module name">;
-  
-} // end of Parse Issue category.
+}
+
 } // end of Parser diagnostics

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Sep  9 15:53:38 2011
@@ -4719,7 +4719,9 @@
 let CategoryName = "Modules Issue" in {
 def err_module_private_follows_public : Error<
   "__module_private__ declaration of %0 follows public declaration">;
-  
+def err_module_private_specialization : Error<
+  "%select{template|partial|member}0 specialization cannot be "
+  "declared __module_private__">;
 }
 
 } // end of sema component.

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Sep  9 15:53:38 2011
@@ -3836,6 +3836,7 @@
   DeclResult
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                    SourceLocation KWLoc,
+                                   SourceLocation ModulePrivateLoc,
                                    CXXScopeSpec &SS,
                                    TemplateTy Template,
                                    SourceLocation TemplateNameLoc,

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Sep  9 15:53:38 2011
@@ -1141,7 +1141,7 @@
       // Build the class template specialization.
       TagOrTempResult
         = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
-                       StartLoc, SS,
+                       StartLoc, DS.getModulePrivateSpecLoc(), SS,
                        TemplateId->Template,
                        TemplateId->TemplateNameLoc,
                        TemplateId->LAngleLoc,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Sep  9 15:53:38 2011
@@ -3821,8 +3821,14 @@
       NewVD->setThreadSpecified(true);
   }
 
-  if (D.getDeclSpec().isModulePrivateSpecified())
-    NewVD->setModulePrivate();
+  if (D.getDeclSpec().isModulePrivateSpecified()) {
+    if (isExplicitSpecialization)
+      Diag(NewVD->getLocation(), diag::err_module_private_specialization)
+        << 2
+        << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
+    else
+      NewVD->setModulePrivate();
+  }
 
   // Set the lexical context. If the declarator has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
@@ -4709,9 +4715,17 @@
 
     // If __module_private__ was specified, mark the function accordingly.
     if (D.getDeclSpec().isModulePrivateSpecified()) {
-      NewFD->setModulePrivate();
-      if (FunctionTemplate)
-        FunctionTemplate->setModulePrivate();
+      if (isFunctionTemplateSpecialization) {
+        SourceLocation ModulePrivateLoc
+          = D.getDeclSpec().getModulePrivateSpecLoc();
+        Diag(ModulePrivateLoc, diag::err_module_private_specialization)
+          << 0
+          << FixItHint::CreateRemoval(ModulePrivateLoc);
+      } else {
+        NewFD->setModulePrivate();
+        if (FunctionTemplate)
+          FunctionTemplate->setModulePrivate();
+      }
     }
 
     // Filter out previous declarations that don't match the scope.
@@ -7751,7 +7765,11 @@
   if (PrevDecl && PrevDecl->isModulePrivate())
     New->setModulePrivate();
   else if (ModulePrivateLoc.isValid()) {
-    if (PrevDecl && !PrevDecl->isModulePrivate())
+    if (isExplicitSpecialization)
+      Diag(New->getLocation(), diag::err_module_private_specialization)
+        << 2
+        << FixItHint::CreateRemoval(ModulePrivateLoc);
+    else if (PrevDecl && !PrevDecl->isModulePrivate())
       diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc);
     else
       New->setModulePrivate();

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Sep  9 15:53:38 2011
@@ -4725,6 +4725,7 @@
 Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                                        TagUseKind TUK,
                                        SourceLocation KWLoc,
+                                       SourceLocation ModulePrivateLoc,
                                        CXXScopeSpec &SS,
                                        TemplateTy TemplateD,
                                        SourceLocation TemplateNameLoc,
@@ -5090,6 +5091,11 @@
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
+  if (ModulePrivateLoc.isValid())
+    Diag(Specialization->getLocation(), diag::err_module_private_specialization)
+      << (isPartialSpecialization? 1 : 0)
+      << FixItHint::CreateRemoval(ModulePrivateLoc);
+  
   // Build the fully-sugared type for this class template
   // specialization as the user wrote in the specialization
   // itself. This means that we'll pretty-print the type retrieved

Modified: cfe/trunk/test/Modules/module-private.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/module-private.cpp?rev=139406&r1=139405&r2=139406&view=diff
==============================================================================
--- cfe/trunk/test/Modules/module-private.cpp (original)
+++ cfe/trunk/test/Modules/module-private.cpp Fri Sep  9 15:53:38 2011
@@ -88,5 +88,22 @@
 struct public_struct; // expected-note{{previous declaration is here}}
 __module_private__ struct public_struct; // expected-error{{__module_private__ declaration of 'public_struct' follows public declaration}}
 
+// Check for attempts to make specializations private
+template<> __module_private__ void public_func_template<int>(); // expected-error{{template specialization cannot be declared __module_private__}}
+
+template<typename T>
+struct public_class {
+  struct inner_struct;
+  static int static_var;
+};
+
+template<> __module_private__ struct public_class<int>::inner_struct { }; // expected-error{{member specialization cannot be declared __module_private__}}
+template<> __module_private__ int public_class<int>::static_var = 17; // expected-error{{member specialization cannot be declared __module_private__}}
+
+template<>
+__module_private__ struct public_class<float> { }; // expected-error{{template specialization cannot be declared __module_private__}}
+
+template<typename T>
+__module_private__ struct public_class<T *> { }; // expected-error{{partial specialization cannot be declared __module_private__}}
 
 #endif





More information about the cfe-commits mailing list