Author: abataev
Date: Fri Mar 20 02:21:46 2015
New Revision: 232800

URL: http://llvm.org/viewvc/llvm-project?rev=232800&view=rev
Log:
[MSVC] Explicit specializations can be declared in any namespace (fix for 
http://llvm.org/PR13738)

MS compiler emits no errors in case of explicit specializations outside 
declaration enclosing namespaces, even when language extensions are disabled.
The patch is to suppress errors and emit extension warnings if explicit 
specializations are not declared in the corresponding namespaces.
This fixes PR13738.

Patch by Alexey Frolov.

Differential Revision: http://reviews.llvm.org/D8283

Added:
    cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp   (with props)
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=232800&r1=232799&r2=232800&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Mar 20 02:21:46 
2015
@@ -3443,6 +3443,12 @@ def err_template_spec_redecl_out_of_scop
   "variable template partial|function template|member "
   "function|static data member|member class|member enumeration}0 "
   "specialization of %1 not in a namespace enclosing %2">;
+def ext_ms_template_spec_redecl_out_of_scope: ExtWarn<
+  "%select{class template|class template partial|variable template|"
+  "variable template partial|function template|member "
+  "function|static data member|member class|member enumeration}0 "
+  "specialization of %1 outside namespace enclosing %2 "
+  "is a Microsoft extension">, InGroup<Microsoft>;
 def err_template_spec_redecl_global_scope : Error<
   "%select{class template|class template partial|variable template|"
   "variable template partial|function template|member "

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=232800&r1=232799&r2=232800&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Mar 20 02:21:46 2015
@@ -5835,11 +5835,13 @@ static bool CheckTemplateSpecializationS
     if (isa<TranslationUnitDecl>(SpecializedContext))
       S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
         << EntityKind << Specialized;
-    else if (isa<NamespaceDecl>(SpecializedContext))
-      S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
-        << EntityKind << Specialized
-        << cast<NamedDecl>(SpecializedContext);
-    else
+    else if (isa<NamespaceDecl>(SpecializedContext)) {
+      int Diag = diag::err_template_spec_redecl_out_of_scope;
+      if (S.getLangOpts().MicrosoftExt)
+        Diag = diag::ext_ms_template_spec_redecl_out_of_scope;
+      S.Diag(Loc, Diag) << EntityKind << Specialized
+                        << cast<NamedDecl>(SpecializedContext);
+    } else
       llvm_unreachable("unexpected namespace context for specialization");
 
     S.Diag(Specialized->getLocation(), diag::note_specialized_entity);

Added: cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp?rev=232800&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp (added)
+++ cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp Fri Mar 20 02:21:46 
2015
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -std=c++11 -verify %s
+
+namespace A {
+
+template <class T>
+class ClassTemplate; // expected-note {{explicitly specialized declaration is 
here}}
+
+template <class T1, class T2>
+class ClassTemplatePartial; // expected-note {{explicitly specialized 
declaration is here}}
+
+template <typename T> struct X {
+  struct MemberClass; // expected-note {{explicitly specialized declaration is 
here}}
+  enum MemberEnumeration; // expected-note {{explicitly specialized 
declaration is here}} // expected-error {{ISO C++ forbids forward references to 
'enum' types}}
+};
+
+}
+
+namespace B {
+
+template <>
+class A::ClassTemplate<int>; // expected-warning {{class template 
specialization of 'ClassTemplate' outside namespace enclosing 'A' is a 
Microsoft extension}}
+
+template <class T1>
+class A::ClassTemplatePartial<T1, T1 *> {}; // expected-warning {{class 
template partial specialization of 'ClassTemplatePartial' outside namespace 
enclosing 'A' is a Microsoft extension}}
+
+template <>
+struct A::X<int>::MemberClass; // expected-warning {{member class 
specialization of 'MemberClass' outside namespace enclosing 'A' is a Microsoft 
extension}}
+
+template <>
+enum A::X<int>::MemberEnumeration; // expected-warning {{member enumeration 
specialization of 'MemberEnumeration' outside namespace enclosing 'A' is a 
Microsoft extension}} // expected-error {{ISO C++ forbids forward references to 
'enum' types}}
+
+}
+

Propchange: cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to