]> granicus.if.org Git - clang/commitdiff
Specializations cannot be module-hidden. Diagnose attempts to do so.
authorDouglas Gregor <dgregor@apple.com>
Fri, 9 Sep 2011 20:53:38 +0000 (20:53 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 9 Sep 2011 20:53:38 +0000 (20:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139406 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 96252654dd27cdbf82cd9da2fb1308e03db7af03..0f3b998c6533cb2ff4f2548f8ffea754979c6bdc 100644 (file)
@@ -574,12 +574,14 @@ def err_seh___except_filter : Error<
 
 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
index 846b32ba89eb19c9127bb21f5d36cdb42170b0f0..49d7bed09ac44055cb369696db7ecc691538536e 100644 (file)
@@ -4719,7 +4719,9 @@ def note_related_result_type_inferred : Note<
 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.
index 3306a0f7f5b7b6f9b1ea22f5a7bd1315e15de9f2..4e61fd1744fe3fd3b8df2a7fb8f212699aafd4f1 100644 (file)
@@ -3836,6 +3836,7 @@ public:
   DeclResult
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                    SourceLocation KWLoc,
+                                   SourceLocation ModulePrivateLoc,
                                    CXXScopeSpec &SS,
                                    TemplateTy Template,
                                    SourceLocation TemplateNameLoc,
index dbdb184d4a2f522f66d7799e7a9726ab3e4e57dd..75c65481c482d88c8caa71606010d1765828afe6 100644 (file)
@@ -1141,7 +1141,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
       // Build the class template specialization.
       TagOrTempResult
         = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
-                       StartLoc, SS,
+                       StartLoc, DS.getModulePrivateSpecLoc(), SS,
                        TemplateId->Template,
                        TemplateId->TemplateNameLoc,
                        TemplateId->LAngleLoc,
index 003be8289f626834b4fdc9d4c563f522cb785080..355378eded78e50372c36eddb710a2e7bea65d89 100644 (file)
@@ -3821,8 +3821,14 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
       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 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
 
     // 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 @@ CreateNewDecl:
   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();
index 4b3f6c45d55deedde32eed73a1cce2dc2b7b9af6..f613ebb36c6c2cb64033d09267e5a9f637f7a6fb 100644 (file)
@@ -4725,6 +4725,7 @@ DeclResult
 Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                                        TagUseKind TUK,
                                        SourceLocation KWLoc,
+                                       SourceLocation ModulePrivateLoc,
                                        CXXScopeSpec &SS,
                                        TemplateTy TemplateD,
                                        SourceLocation TemplateNameLoc,
@@ -5090,6 +5091,11 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
   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
index 3ee59c8a9c1745032de0ca00a4586678d38fca14..0f1d5923dc4f0f545695a47012dabf64d2023422 100644 (file)
@@ -88,5 +88,22 @@ __module_private__ void public_func_template(); // expected-error{{__module_priv
 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