[cfe-commits] r142329 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/SemaCXX/cxx0x-compat.cpp test/SemaTemplate/temp_explicit.cpp test/SemaTemplate/temp_explicit_cxx0x.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Oct 17 19:28:33 PDT 2011


Author: rsmith
Date: Mon Oct 17 21:28:33 2011
New Revision: 142329

URL: http://llvm.org/viewvc/llvm-project?rev=142329&view=rev
Log:
Refactor the checking for explicit template instantiations being performed in
the right namespace in C++11 mode. Teach the code to prefer the 'must be in
precisely this namespace' diagnostic whenever that's true, and fix a defect
which resulted in the -Wc++11-compat warning in C++98 mode sometimes being
omitted.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaCXX/cxx0x-compat.cpp
    cfe/trunk/test/SemaTemplate/temp_explicit.cpp
    cfe/trunk/test/SemaTemplate/temp_explicit_cxx0x.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=142329&r1=142328&r2=142329&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 17 21:28:33 2011
@@ -2434,9 +2434,9 @@
   "qualifier in explicit instantiation of %q0 requires a template-id "
   "(a typedef is not permitted)">;
 def err_explicit_instantiation_unqualified_wrong_namespace : Error<
-  "explicit instantiation of %q0 must occur in %1">;
+  "explicit instantiation of %q0 must occur in namespace %1">;
 def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
-  "explicit instantiation of %q0 must occur in %1">, 
+  "explicit instantiation of %q0 must occur in namespace %1">,
   InGroup<CXX11Compat>;
 def err_explicit_instantiation_undefined_member : Error<
   "explicit instantiation of undefined %select{member class|member function|"

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=142329&r1=142328&r2=142329&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Oct 17 21:28:33 2011
@@ -5728,45 +5728,41 @@
     return true;
   }
 
-  // C++0x [temp.explicit]p2:
+  // C++11 [temp.explicit]p3:
   //   An explicit instantiation shall appear in an enclosing namespace of its
-  //   template.
+  //   template. If the name declared in the explicit instantiation is an
+  //   unqualified name, the explicit instantiation shall appear in the
+  //   namespace where its template is declared or, if that namespace is inline
+  //   (7.3.1), any namespace from its enclosing namespace set.
   //
   // This is DR275, which we do not retroactively apply to C++98/03.
-  if (S.getLangOptions().CPlusPlus0x &&
-      !CurContext->Encloses(OrigContext)) {
-    if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext))
+  if (WasQualifiedName) {
+    if (CurContext->Encloses(OrigContext))
+      return false;
+  } else {
+    if (CurContext->InEnclosingNamespaceSetOf(OrigContext))
+      return false;
+  }
+
+  if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) {
+    if (WasQualifiedName)
       S.Diag(InstLoc,
              S.getLangOptions().CPlusPlus0x?
-                 diag::err_explicit_instantiation_out_of_scope
-               : diag::warn_explicit_instantiation_out_of_scope_0x)
+               diag::err_explicit_instantiation_out_of_scope :
+               diag::warn_explicit_instantiation_out_of_scope_0x)
         << D << NS;
     else
       S.Diag(InstLoc,
              S.getLangOptions().CPlusPlus0x?
-                 diag::err_explicit_instantiation_must_be_global
-               : diag::warn_explicit_instantiation_out_of_scope_0x)
-        << D;
-    S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
-    return false;
-  }
-
-  // C++0x [temp.explicit]p2:
-  //   If the name declared in the explicit instantiation is an unqualified
-  //   name, the explicit instantiation shall appear in the namespace where
-  //   its template is declared or, if that namespace is inline (7.3.1), any
-  //   namespace from its enclosing namespace set.
-  if (WasQualifiedName)
-    return false;
-
-  if (CurContext->InEnclosingNamespaceSetOf(OrigContext))
-    return false;
-
-  S.Diag(InstLoc,
-         S.getLangOptions().CPlusPlus0x?
-             diag::err_explicit_instantiation_unqualified_wrong_namespace
-           : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
-    << D << OrigContext;
+               diag::err_explicit_instantiation_unqualified_wrong_namespace :
+               diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
+        << D << NS;
+  } else
+    S.Diag(InstLoc,
+           S.getLangOptions().CPlusPlus0x?
+             diag::err_explicit_instantiation_must_be_global :
+             diag::warn_explicit_instantiation_must_be_global_0x)
+      << D;
   S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
   return false;
 }
@@ -5776,7 +5772,7 @@
   if (!SS.isSet())
     return false;
 
-  // C++0x [temp.explicit]p2:
+  // C++11 [temp.explicit]p3:
   //   If the explicit instantiation is for a member function, a member class
   //   or a static data member of a class template specialization, the name of
   //   the class template specialization in the qualified-id for the member

Modified: cfe/trunk/test/SemaCXX/cxx0x-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-compat.cpp?rev=142329&r1=142328&r2=142329&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-compat.cpp Mon Oct 17 21:28:33 2011
@@ -1,18 +1,21 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++0x-compat -verify %s
 
 namespace N {
-  template<typename T> void f(T) {} // expected-note {{here}}
+  template<typename T> void f(T) {} // expected-note 2{{here}}
   namespace M {
-    template void f<int>(int); // expected-warning {{explicit instantiation of 'N::f' must occur in namespace 'N'}}
+    template void ::N::f<int>(int); // expected-warning {{explicit instantiation of 'f' not in a namespace enclosing 'N'}}
   }
 }
+using namespace N;
+template void f<char>(char); // expected-warning {{explicit instantiation of 'N::f' must occur in namespace 'N'}}
 
-template<typename T> void f(T) {} // expected-note {{here}}
+template<typename T> void g(T) {} // expected-note 2{{here}}
 namespace M {
-  template void f<int>(int); // expected-warning {{explicit instantiation of 'f' must occur in the global namespace}}
+  template void g<int>(int); // expected-warning {{explicit instantiation of 'g' must occur at global scope}}
+  template void ::g<char>(char); // expected-warning {{explicit instantiation of 'g' must occur at global scope}}
 }
 
-void f() {
+void g() {
   auto int n = 0; // expected-warning {{'auto' storage class specifier is redundant and incompatible with C++11}}
 }
 

Modified: cfe/trunk/test/SemaTemplate/temp_explicit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_explicit.cpp?rev=142329&r1=142328&r2=142329&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_explicit.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_explicit.cpp Mon Oct 17 21:28:33 2011
@@ -80,7 +80,7 @@
     void f(T&);
   };
 
-  struct Inner2 {
+  struct Inner2 { // expected-note {{here}}
     struct VeryInner {
       void g(T*); // expected-error 2{{pointer to a reference}}
     };
@@ -98,7 +98,7 @@
 template struct X5<float&>::Inner2; // expected-note{{instantiation}}
 
 namespace N3 {
-  template struct N2::X5<int>::Inner2;
+  template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
 }
 
 struct X6 {
@@ -147,5 +147,5 @@
 
   template struct X7<double>; // expected-warning{{must occur in namespace}}
 
-  template struct X9<float>; // expected-warning{{must occur in the global}}
+  template struct X9<float>; // expected-warning{{must occur at global scope}}
 }

Modified: cfe/trunk/test/SemaTemplate/temp_explicit_cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_explicit_cxx0x.cpp?rev=142329&r1=142328&r2=142329&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_explicit_cxx0x.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_explicit_cxx0x.cpp Mon Oct 17 21:28:33 2011
@@ -18,7 +18,7 @@
 namespace N2 {
   using namespace N1;
 
-  template struct X0<double>; // expected-error{{not in a namespace enclosing}}
+  template struct X0<double>; // expected-error{{must occur in namespace 'N1'}}
 
   template struct X2<float>; // expected-error{{at global scope}}
 }





More information about the cfe-commits mailing list