r327705 - Implement C++ DR727, which permits explicit specializations at class scope.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 16 06:36:57 PDT 2018


Author: rsmith
Date: Fri Mar 16 06:36:56 2018
New Revision: 327705

URL: http://llvm.org/viewvc/llvm-project?rev=327705&view=rev
Log:
Implement C++ DR727, which permits explicit specializations at class scope.

More generally, this permits a template to be specialized in any scope in which
it could be defined, so this also supersedes DR44 and DR374 (the latter of
which we previously only implemented in C++11 mode onwards due to unclarity as
to whether it was a DR).

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/ASTDumper.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CXX/drs/dr0xx.cpp
    cfe/trunk/test/CXX/drs/dr3xx.cpp
    cfe/trunk/test/CXX/drs/dr7xx.cpp
    cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp
    cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
    cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
    cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
    cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
    cfe/trunk/test/Misc/ast-dump-decl.cpp
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
    cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
    cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp
    cfe/trunk/test/SemaTemplate/class-template-spec.cpp
    cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
    cfe/trunk/test/SemaTemplate/function-template-specialization.cpp
    cfe/trunk/test/SemaTemplate/instantiate-method.cpp
    cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
    cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp
    cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Mar 16 06:36:56 2018
@@ -4144,42 +4144,20 @@ def note_explicit_specialization_declare
   "explicit specialization declared here">;
 def err_template_spec_decl_function_scope : Error<
   "explicit specialization of %0 in function scope">;
-def err_template_spec_decl_class_scope : Error<
-  "explicit specialization of %0 in class scope">;
 def err_template_spec_decl_friend : Error<
   "cannot declare an explicit specialization in a friend">;
-def err_template_spec_decl_out_of_scope_global : Error<
-  "%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 must originally be declared in the global scope">;
-def err_template_spec_decl_out_of_scope : Error<
-  "%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 must originally be declared in namespace %2">;
-def ext_template_spec_decl_out_of_scope : ExtWarn<
-  "first declaration of %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 %2 is a "
-  "C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_template_spec_decl_out_of_scope : Warning<
-  "%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 %2 is incompatible with C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 def err_template_spec_redecl_out_of_scope : Error<
   "%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 not in a namespace enclosing %2">;
+  "specialization of %1 not in %select{a namespace enclosing %2|"
+  "class %2 or an enclosing namespace}3">;
 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 "
+  "specialization of %1 not in %select{a namespace enclosing %2|"
+  "class %2 or an enclosing namespace}3 "
   "is a Microsoft extension">, InGroup<MicrosoftTemplate>;
 def err_template_spec_redecl_global_scope : Error<
   "%select{class template|class template partial|variable template|"
@@ -4201,11 +4179,6 @@ def err_template_spec_default_arg : Erro
 def err_not_class_template_specialization : Error<
   "cannot specialize a %select{dependent template|template template "
   "parameter}0">;
-def err_function_specialization_in_class : Error<
-  "cannot specialize a function %0 within class scope">;
-def ext_function_specialization_in_class : ExtWarn<
-  "explicit specialization of %0 within class scope is a Microsoft extension">,
-  InGroup<MicrosoftTemplate>;
 def ext_explicit_specialization_storage_class : ExtWarn<
   "explicit specialization cannot have a storage class">;
 def err_explicit_specialization_inconsistent_storage_class : Error<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Mar 16 06:36:56 2018
@@ -1849,8 +1849,8 @@ public:
   void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S);
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
-                                    DeclarationName Name,
-                                    SourceLocation Loc);
+                                    DeclarationName Name, SourceLocation Loc,
+                                    bool IsTemplateId);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
                             SourceLocation FallbackLoc,

Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Fri Mar 16 06:36:56 2018
@@ -1602,7 +1602,7 @@ void ASTDumper::VisitClassTemplatePartia
 
 void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
     const ClassScopeFunctionSpecializationDecl *D) {
-  dumpDeclRef(D->getSpecialization());
+  dumpDecl(D->getSpecialization());
   if (D->hasExplicitTemplateArgs())
     dumpTemplateArgumentListInfo(D->templateArgs());
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Mar 16 06:36:56 2018
@@ -5231,10 +5231,13 @@ bool Sema::DiagnoseClassNameShadow(DeclC
 ///
 /// \param Loc The location of the name of the entity being declared.
 ///
+/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus
+/// we're declaring an explicit / partial specialization / instantiation.
+///
 /// \returns true if we cannot safely recover from this error, false otherwise.
 bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
                                         DeclarationName Name,
-                                        SourceLocation Loc) {
+                                        SourceLocation Loc, bool IsTemplateId) {
   DeclContext *Cur = CurContext;
   while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur))
     Cur = Cur->getParent();
@@ -5261,8 +5264,9 @@ bool Sema::diagnoseQualifiedDeclaration(
   }
 
   // Check whether the qualifying scope encloses the scope of the original
-  // declaration.
-  if (!Cur->Encloses(DC)) {
+  // declaration. For a template-id, we perform the checks in
+  // CheckTemplateSpecializationScope.
+  if (!Cur->Encloses(DC) && !IsTemplateId) {
     if (Cur->isRecord())
       Diag(Loc, diag::err_member_qualification)
         << Name << SS.getRange();
@@ -5374,8 +5378,9 @@ NamedDecl *Sema::HandleDeclarator(Scope
       return nullptr;
     }
     if (!D.getDeclSpec().isFriendSpecified()) {
-      if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC,
-                                      Name, D.getIdentifierLoc())) {
+      if (diagnoseQualifiedDeclaration(
+              D.getCXXScopeSpec(), DC, Name, D.getIdentifierLoc(),
+              D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId)) {
         if (DC->isRecord())
           return nullptr;
 
@@ -8828,10 +8833,6 @@ Sema::ActOnFunctionDeclarator(Scope *S,
       if (CurContext->isDependentContext() && CurContext->isRecord()
           && !isFriend) {
         isDependentClassScopeExplicitSpecialization = true;
-        Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ?
-          diag::ext_function_specialization_in_class :
-          diag::err_function_specialization_in_class)
-          << NewFD->getDeclName();
       } else if (!NewFD->isInvalidDecl() &&
                  CheckFunctionTemplateSpecialization(
                      NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr),
@@ -9117,12 +9118,12 @@ Sema::ActOnFunctionDeclarator(Scope *S,
   }
 
   // Here we have an function template explicit specialization at class scope.
-  // The actually specialization will be postponed to template instatiation
+  // The actual specialization will be postponed to template instatiation
   // time via the ClassScopeFunctionSpecializationDecl node.
   if (isDependentClassScopeExplicitSpecialization) {
     ClassScopeFunctionSpecializationDecl *NewSpec =
                          ClassScopeFunctionSpecializationDecl::Create(
-                                Context, CurContext, SourceLocation(),
+                                Context, CurContext, NewFD->getLocation(),
                                 cast<CXXMethodDecl>(NewFD),
                                 HasExplicitTemplateArgs, TemplateArgs);
     CurContext->addDecl(NewSpec);
@@ -9633,16 +9634,16 @@ bool Sema::CheckFunctionDeclaration(Scop
     Previous.clear();
     Previous.addDecl(OldDecl);
 
-    if (FunctionTemplateDecl *OldTemplateDecl
-                                  = dyn_cast<FunctionTemplateDecl>(OldDecl)) {
+    if (FunctionTemplateDecl *OldTemplateDecl =
+            dyn_cast<FunctionTemplateDecl>(OldDecl)) {
       auto *OldFD = OldTemplateDecl->getTemplatedDecl();
       NewFD->setPreviousDeclaration(OldFD);
       adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
       FunctionTemplateDecl *NewTemplateDecl
         = NewFD->getDescribedFunctionTemplate();
       assert(NewTemplateDecl && "Template/non-template mismatch");
-      if (auto *Method = dyn_cast<CXXMethodDecl>(NewFD)) {
-        Method->setAccess(OldTemplateDecl->getAccess());
+      if (NewFD->isCXXClassMember()) {
+        NewFD->setAccess(OldTemplateDecl->getAccess());
         NewTemplateDecl->setAccess(OldTemplateDecl->getAccess());
       }
 
@@ -9668,7 +9669,7 @@ bool Sema::CheckFunctionDeclaration(Scop
         // This needs to happen first so that 'inline' propagates.
         NewFD->setPreviousDeclaration(OldFD);
         adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
-        if (isa<CXXMethodDecl>(NewFD))
+        if (NewFD->isCXXClassMember())
           NewFD->setAccess(OldFD->getAccess());
       }
     }
@@ -14310,13 +14311,10 @@ CreateNewDecl:
   if (SS.isNotEmpty()) {
     if (SS.isSet()) {
       // If this is either a declaration or a definition, check the
-      // nested-name-specifier against the current context. We don't do this
-      // for explicit specializations, because they have similar checking
-      // (with more specific diagnostics) in the call to
-      // CheckMemberSpecialization, below.
-      if (!isMemberSpecialization &&
-          (TUK == TUK_Definition || TUK == TUK_Declaration) &&
-          diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc))
+      // nested-name-specifier against the current context.
+      if ((TUK == TUK_Definition || TUK == TUK_Declaration) &&
+          diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc,
+                                       isMemberSpecialization))
         Invalid = true;
 
       New->setQualifierInfo(SS.getWithLocInContext(Context));

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Mar 16 06:36:56 2018
@@ -3051,7 +3051,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S,
       //   int X::member;
       // };
       if (DeclContext *DC = computeDeclContext(SS, false))
-        diagnoseQualifiedDeclaration(SS, DC, Name, D.getIdentifierLoc());
+        diagnoseQualifiedDeclaration(SS, DC, Name, D.getIdentifierLoc(),
+                                     D.getName().getKind() ==
+                                         UnqualifiedIdKind::IK_TemplateId);
       else
         Diag(D.getIdentifierLoc(), diag::err_member_qualification)
           << Name << SS.getRange();

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Mar 16 06:36:56 2018
@@ -1262,7 +1262,7 @@ Sema::CheckClassTemplate(Scope *S, unsig
       if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams))
         Invalid = true;
     } else if (TUK != TUK_Friend && TUK != TUK_Reference)
-      diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc);
+      diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc, false);
 
     LookupQualifiedName(Previous, SemanticContext);
   } else {
@@ -7124,120 +7124,43 @@ static bool CheckTemplateSpecializationS
   }
 
   // C++ [temp.expl.spec]p2:
-  //   An explicit specialization shall be declared in the namespace
-  //   of which the template is a member, or, for member templates, in
-  //   the namespace of which the enclosing class or enclosing class
-  //   template is a member. An explicit specialization of a member
-  //   function, member class or static data member of a class
-  //   template shall be declared in the namespace of which the class
-  //   template is a member. Such a declaration may also be a
-  //   definition. If the declaration is not a definition, the
-  //   specialization may be defined later in the name- space in which
-  //   the explicit specialization was declared, or in a namespace
-  //   that encloses the one in which the explicit specialization was
-  //   declared.
+  //   An explicit specialization may be declared in any scope in which
+  //   the corresponding primary template may be defined.
   if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) {
     S.Diag(Loc, diag::err_template_spec_decl_function_scope)
       << Specialized;
     return true;
   }
 
-  if (S.CurContext->isRecord() && !IsPartialSpecialization) {
-    if (S.getLangOpts().MicrosoftExt) {
-      // Do not warn for class scope explicit specialization during
-      // instantiation, warning was already emitted during pattern
-      // semantic analysis.
-      if (!S.inTemplateInstantiation())
-        S.Diag(Loc, diag::ext_function_specialization_in_class)
-          << Specialized;
-    } else {
-      S.Diag(Loc, diag::err_template_spec_decl_class_scope)
-        << Specialized;
-      return true;
-    }
-  }
-
-  if (S.CurContext->isRecord() &&
-      !S.CurContext->Equals(Specialized->getDeclContext())) {
-    // Make sure that we're specializing in the right record context.
-    // Otherwise, things can go horribly wrong.
-    S.Diag(Loc, diag::err_template_spec_decl_class_scope)
-      << Specialized;
-    return true;
-  }
-
   // C++ [temp.class.spec]p6:
-  //   A class template partial specialization may be declared or redeclared
-  //   in any namespace scope in which its definition may be defined (14.5.1
-  //   and 14.5.2).
-  DeclContext *SpecializedContext
-    = Specialized->getDeclContext()->getEnclosingNamespaceContext();
-  DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
-
-  // Make sure that this redeclaration (or definition) occurs in an enclosing
-  // namespace.
-  // Note that HandleDeclarator() performs this check for explicit
-  // specializations of function templates, static data members, and member
-  // functions, so we skip the check here for those kinds of entities.
-  // FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
-  // Should we refactor that check, so that it occurs later?
-  if (!DC->Encloses(SpecializedContext) &&
-      !(isa<FunctionTemplateDecl>(Specialized) ||
-        isa<FunctionDecl>(Specialized) ||
-        isa<VarTemplateDecl>(Specialized) ||
-        isa<VarDecl>(Specialized))) {
+  //   A class template partial specialization may be declared in any
+  //   scope in which the primary template may be defined.
+  DeclContext *SpecializedContext =
+      Specialized->getDeclContext()->getRedeclContext();
+  DeclContext *DC = S.CurContext->getRedeclContext();
+
+  // Make sure that this redeclaration (or definition) occurs in the same
+  // scope or an enclosing namespace.
+  if (!(DC->isFileContext() ? DC->Encloses(SpecializedContext)
+                            : DC->Equals(SpecializedContext))) {
     if (isa<TranslationUnitDecl>(SpecializedContext))
       S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
         << EntityKind << Specialized;
-    else if (isa<NamespaceDecl>(SpecializedContext)) {
+    else {
+      auto *ND = cast<NamedDecl>(SpecializedContext);
       int Diag = diag::err_template_spec_redecl_out_of_scope;
-      if (S.getLangOpts().MicrosoftExt)
+      if (S.getLangOpts().MicrosoftExt && !DC->isRecord())
         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");
+                        << ND << isa<CXXRecordDecl>(ND);
+    }
 
     S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
-  } else if ((!PrevDecl ||
-              getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
-              getTemplateSpecializationKind(PrevDecl) ==
-                  TSK_ImplicitInstantiation)) {
-    // C++ [temp.exp.spec]p2:
-    //   An explicit specialization shall be declared in the namespace of which
-    //   the template is a member, or, for member templates, in the namespace
-    //   of which the enclosing class or enclosing class template is a member.
-    //   An explicit specialization of a member function, member class or
-    //   static data member of a class template shall be declared in the
-    //   namespace of which the class template is a member.
-    //
-    // C++11 [temp.expl.spec]p2:
-    //   An explicit specialization shall be declared in a namespace enclosing
-    //   the specialized template.
-    // C++11 [temp.explicit]p3:
-    //   An explicit instantiation shall appear in an enclosing namespace of its
-    //   template.
-    if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
-      bool IsCPlusPlus11Extension = DC->Encloses(SpecializedContext);
-      if (isa<TranslationUnitDecl>(SpecializedContext)) {
-        assert(!IsCPlusPlus11Extension &&
-               "DC encloses TU but isn't in enclosing namespace set");
-        S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
-          << EntityKind << Specialized;
-      } else if (isa<NamespaceDecl>(SpecializedContext)) {
-        int Diag;
-        if (!IsCPlusPlus11Extension)
-          Diag = diag::err_template_spec_decl_out_of_scope;
-        else if (!S.getLangOpts().CPlusPlus11)
-          Diag = diag::ext_template_spec_decl_out_of_scope;
-        else
-          Diag = diag::warn_cxx98_compat_template_spec_decl_out_of_scope;
-        S.Diag(Loc, Diag)
-          << EntityKind << Specialized << cast<NamedDecl>(SpecializedContext);
-      }
 
-      S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
-    }
+    // Don't allow specializing in the wrong class during error recovery.
+    // Otherwise, things can go horribly wrong.
+    if (DC->isRecord())
+      return true;
   }
 
   return false;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Mar 16 06:36:56 2018
@@ -1653,6 +1653,7 @@ Decl *TemplateDeclInstantiator::VisitFun
       NameInfo, T, TInfo, D->getSourceRange().getEnd());
     if (DGuide->isCopyDeductionCandidate())
       cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate();
+    Function->setAccess(D->getAccess());
   } else {
     Function = FunctionDecl::Create(
         SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo,
@@ -2711,6 +2712,8 @@ Decl *TemplateDeclInstantiator::VisitCla
   assert(Specialization && "Class scope Specialization is null");
   SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD);
 
+  // FIXME: If this is a definition, check for redefinition errors!
+
   return NewFD;
 }
 

Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr0xx.cpp Fri Mar 16 06:36:56 2018
@@ -499,10 +499,10 @@ namespace dr42 { // dr42: yes
 
 // dr43: na
 
-namespace dr44 { // dr44: yes
+namespace dr44 { // dr44: sup 727
   struct A {
     template<int> void f();
-    template<> void f<0>(); // expected-error {{explicit specialization of 'f' in class scope}}
+    template<> void f<0>();
   };
 }
 

Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr3xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr3xx.cpp Fri Mar 16 06:36:56 2018
@@ -925,7 +925,7 @@ namespace dr373 { // dr373: 5
   using namespace A::B; // expected-error {{expected namespace name}}
 }
 
-namespace dr374 { // dr374: yes c++11
+namespace dr374 { // dr374: yes
   namespace N {
     template<typename T> void f();
     template<typename T> struct A { void f(); };
@@ -933,11 +933,6 @@ namespace dr374 { // dr374: yes c++11
   template<> void N::f<char>() {}
   template<> void N::A<char>::f() {}
   template<> struct N::A<int> {};
-#if __cplusplus < 201103L
-  // expected-error at -4 {{extension}} expected-note at -7 {{here}}
-  // expected-error at -4 {{extension}} expected-note at -7 {{here}}
-  // expected-error at -4 {{extension}} expected-note at -8 {{here}}
-#endif
 }
 
 // dr375: dup 345

Modified: cfe/trunk/test/CXX/drs/dr7xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr7xx.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr7xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr7xx.cpp Fri Mar 16 06:36:56 2018
@@ -3,6 +3,53 @@
 // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
+namespace dr727 { // dr727: 7
+  struct A {
+    template<typename T> struct C; // expected-note 6{{here}}
+    template<typename T> void f(); // expected-note {{here}}
+    template<typename T> static int N; // expected-error 0-1{{C++14}} expected-note 6{{here}}
+
+    template<> struct C<int>;
+    template<> void f<int>();
+    template<> static int N<int>;
+
+    template<typename T> struct C<T*>;
+    template<typename T> static int N<T*>;
+
+    struct B {
+      template<> struct C<float>; // expected-error {{not in class 'A' or an enclosing namespace}}
+      template<> void f<float>(); // expected-error {{no function template matches}}
+      template<> static int N<float>; // expected-error {{not in class 'A' or an enclosing namespace}}
+
+      template<typename T> struct C<T**>; // expected-error {{not in class 'A' or an enclosing namespace}}
+      template<typename T> static int N<T**>; // expected-error {{not in class 'A' or an enclosing namespace}}
+
+      template<> struct A::C<double>; // expected-error {{not in class 'A' or an enclosing namespace}}
+      template<> void A::f<double>(); // expected-error {{no function template matches}} expected-error {{cannot have a qualified name}}
+      template<> static int A::N<double>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}
+
+      template<typename T> struct A::C<T***>; // expected-error {{not in class 'A' or an enclosing namespace}}
+      template<typename T> static int A::N<T***>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}
+    };
+  };
+
+  template<> struct A::C<char>;
+  template<> void A::f<char>();
+  template<> int A::N<char>;
+
+  template<typename T> struct A::C<T****>;
+  template<typename T> int A::N<T****>;
+
+  namespace C {
+    template<> struct A::C<long>; // expected-error {{not in class 'A' or an enclosing namespace}}
+    template<> void A::f<long>(); // expected-error {{not in class 'A' or an enclosing namespace}}
+    template<> int A::N<long>; // expected-error {{not in class 'A' or an enclosing namespace}}
+
+    template<typename T> struct A::C<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}}
+    template<typename T> int A::N<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}}
+  }
+}
+
 namespace dr777 { // dr777: 3.7
 #if __cplusplus >= 201103L
 template <typename... T>
@@ -16,5 +63,3 @@ template <typename... T>
 void h(int i = 0, T ...args, int j = 1) {}
 #endif
 }
-
-// expected-no-diagnostics

Modified: cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp Fri Mar 16 06:36:56 2018
@@ -101,7 +101,7 @@ namespace ExplicitInst {
   struct X {
     template<typename T> struct C {};
     template<typename T> C(T) -> C<T>;
-    template<> C(int) -> C<int>; // expected-error {{explicit specialization of '<deduction guide for C>' in class scope}}
+    template<> C(int) -> C<int>; // expected-error {{deduction guide cannot be explicitly specialized}}
     extern template C(float) -> C<float>; // expected-error {{expected member name or ';'}}
     template C(char) -> C<char>; // expected-error {{expected '<' after 'template'}}
   };

Modified: cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp Fri Mar 16 06:36:56 2018
@@ -28,10 +28,8 @@ T pi1 = T(3.1415926535897932385); // exp
 
 // Should recover as if specialization
 template float pi1<float> = 1.0;  // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
-#ifndef FIXING
 namespace expected_global {
-  template<> double pi1<double> = 1.5;  // expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
-  template int pi1<int> = 10;  // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
-                                  expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
-}
+#ifndef FIXING
+  template int pi1<int> = 10;  // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} expected-error {{must occur at global scope}}
 #endif
+}

Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp Fri Mar 16 06:36:56 2018
@@ -10,9 +10,6 @@ struct NonDefaultConstructible {
   NonDefaultConstructible(int);
 };
 
-// FIXME: The "must originally be declared in namespace" diagnostics throughout
-// this file are wrong.
-
 // C++ [temp.expl.spec]p1:
 //   An explicit specialization of any of the following:
 
@@ -43,7 +40,7 @@ template<> void N0::f0(double) { }
 struct X1 {
   template<typename T> void f(T);
   
-  template<> void f(int); // expected-error{{in class scope}}
+  template<> void f(int); // OK (DR727)
 };
 
 //     -- class template
@@ -94,7 +91,7 @@ template<> struct N0::X0<volatile void>
 
 //     -- variable template [C++1y]
 namespace N0 {
-template<typename T> int v0; // expected-note +{{here}}
+template<typename T> int v0; // expected-note 4{{explicitly specialized declaration is here}}
 template<> extern int v0<char[1]>;
 template<> extern int v0<char[2]>;
 template<> extern int v0<char[5]>;
@@ -102,32 +99,32 @@ template<> extern int v0<char[6]>;
 }
 using N0::v0;
 
-template<typename T> int v1; // expected-note +{{here}}
+template<typename T> int v1; // expected-note 4{{explicitly specialized declaration is here}}
 template<> extern int v1<char[3]>;
 template<> extern int v1<char[4]>;
 template<> extern int v1<char[7]>;
 template<> extern int v1<char[8]>;
 
 template<> int N0::v0<int[1]>;
-template<> int v0<int[2]>; // FIXME: ill-formed
+template<> int v0<int[2]>;
 template<> int ::v1<int[3]>; // expected-warning {{extra qualification}}
 template<> int v1<int[4]>;
 
 template<> int N0::v0<char[1]>;
-template<> int v0<char[2]>; // FIXME: ill-formed
+template<> int v0<char[2]>;
 template<> int ::v1<char[3]>; // expected-warning {{extra qualification}}
 template<> int v1<char[4]>;
 
 namespace N1 {
-template<> int N0::v0<int[5]>; // expected-error {{must originally be declared in namespace 'N0'}} expected-error {{does not enclose namespace}}
-template<> int v0<int[6]>; // expected-error {{must originally be declared in namespace 'N0'}}
-template<> int ::v1<int[7]>; // expected-error {{must originally be declared in the global scope}} expected-error {{cannot name the global scope}}
-template<> int v1<int[8]>; // expected-error {{must originally be declared in the global scope}}
-
-template<> int N0::v0<char[5]>; // expected-error {{does not enclose namespace 'N0'}}
-template<> int v0<char[6]>; // FIXME: ill-formed
-template<> int ::v1<char[7]>; // expected-error {{cannot name the global scope}}
-template<> int v1<char[8]>; // FIXME: ill-formed
+template<> int N0::v0<int[5]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int v0<int[6]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int ::v1<int[7]>; // expected-error {{must occur at global scope}}
+template<> int v1<int[8]>; // expected-error {{must occur at global scope}}
+
+template<> int N0::v0<char[5]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int v0<char[6]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int ::v1<char[7]>; // expected-error {{must occur at global scope}}
+template<> int v1<char[8]>; // expected-error {{must occur at global scope}}
 }
 
 //     -- member function of a class template

Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp Fri Mar 16 06:36:56 2018
@@ -20,9 +20,6 @@ struct NonDefaultConstructible {
 //     -- function template
 namespace N0 {
   template<typename T> void f0(T) {
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
     T t;
   }
 
@@ -43,16 +40,13 @@ namespace N1 {
 }
 
 template<> void N0::f0(double);
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of function template specialization of 'f0' outside namespace 'N0' is a C++11 extension}}
-#endif
 
 template<> void N0::f0(double) { }
 
 struct X1 {
   template<typename T> void f(T);
   
-  template<> void f(int); // expected-error{{in class scope}}
+  template<> void f(int);
 };
 
 //     -- class template
@@ -60,38 +54,20 @@ namespace N0 {
   
 template<typename T>
 struct X0 { // expected-note {{explicitly specialized declaration is here}}
-#if __cplusplus <= 199711L
-// expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
   static T member;
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
   
   void f1(T t) {
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
     t = 17;
   }
   
   struct Inner : public T { }; // expected-note 2{{explicitly specialized declaration is here}}
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
   
   template<typename U>
   struct InnerTemplate : public T { }; // expected-note {{explicitly specialized declaration is here}}
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
-  // expected-error at -4 {{base specifier must name a class}}
+  // expected-error at -1 {{base specifier must name a class}}
   
   template<typename U>
   void ft1(T t, U u);
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
 };
 
 }
@@ -105,9 +81,6 @@ void N0::X0<T>::ft1(T t, U u) {
 template<typename T> T N0::X0<T>::member;
 
 template<> struct N0::X0<void> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'X0' outside namespace 'N0' is a C++11 extension}}
-#endif
 N0::X0<void> test_X0;
 
 namespace N1 {
@@ -124,9 +97,6 @@ template<> struct N0::X0<volatile void>
 
 //     -- member function of a class template
 template<> void N0::X0<void*>::f1(void *) { }
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of member function specialization of 'f1' outside namespace 'N0' is a C++11 extension}}
-#endif
 
 void test_spec(N0::X0<void*> xvp, void *vp) {
   xvp.f1(vp);
@@ -160,9 +130,6 @@ NonDefaultConstructible &get_static_memb
 }
 
 template<> int N0::X0<int>::member;
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of static data member specialization of 'member' outside namespace 'N0' is a C++11 extension}}
-#endif
 
 template<> float N0::X0<float>::member = 3.14f;
 
@@ -191,9 +158,6 @@ namespace N0 {
 
 template<>
 struct N0::X0<long>::Inner { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of member class specialization of 'Inner' outside namespace 'N0' is a C++11 extension}}
-#endif
 
 template<>
 struct N0::X0<float>::Inner { };
@@ -233,9 +197,6 @@ struct N0::X0<int>::InnerTemplate<long>
 
 template<> template<>
 struct N0::X0<int>::InnerTemplate<float> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'InnerTemplate' outside namespace 'N0' is a C++11 extension}}
-#endif
 
 namespace N1 {
   template<> template<>
@@ -268,9 +229,6 @@ void N0::X0<void*>::ft1(void *, unsigned
 
 template<> template<>
 void N0::X0<void*>::ft1(void *, float) { }
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of function template specialization of 'ft1' outside namespace 'N0' is a C++11 extension}}
-#endif
 
 namespace N1 {
   template<> template<>
@@ -293,6 +251,6 @@ namespace PR8979 {
     template<typename T, typename U> void f(Inner<T, U>&);
 
     typedef Inner<OtherInner, OtherInner> MyInner;
-    template<> void f(MyInner&); // expected-error{{cannot specialize a function 'f' within class scope}}
+    template<> void f(MyInner&);
   };
 }

Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp Fri Mar 16 06:36:56 2018
@@ -4,17 +4,9 @@
 
 namespace N {
   template<class T> class X; // expected-note {{'N::X' declared here}}
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
 }
 
-// TODO: Don't add a namespace qualifier to the template if it would trigger
-// the warning about the specialization being outside of the namespace.
 template<> class X<int> { /* ... */ };	// expected-error {{no template named 'X'; did you mean 'N::X'?}}
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'X' outside namespace 'N' is a C++11 extension}}
-#endif
 
 namespace N {
   

Modified: cfe/trunk/test/Misc/ast-dump-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/Misc/ast-dump-decl.cpp (original)
+++ cfe/trunk/test/Misc/ast-dump-decl.cpp Fri Mar 16 06:36:56 2018
@@ -360,7 +360,9 @@ class TestClassScopeFunctionSpecializati
   template<> void foo<int>(int a) { }
 };
 // CHECK:      ClassScopeFunctionSpecializationDecl
-// CHECK-NEXT:   CXXMethod{{.*}} 'foo' 'void (int)'
+// CHECK-NEXT:   CXXMethod{{.*}} foo 'void (int)'
+// CHECK-NEXT:     ParmVarDecl
+// CHECK-NEXT:     CompoundStmt
 // CHECK-NEXT:   TemplateArgument{{.*}} 'int'
 
 namespace TestTemplateTypeParmDecl {

Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Fri Mar 16 06:36:56 2018
@@ -489,7 +489,6 @@ void AfterClassBody() {
 namespace PR24246 {
 template <typename TX> struct A {
   template <bool> struct largest_type_select;
-  // expected-warning at +1 {{explicit specialization of 'largest_type_select' within class scope is a Microsoft extension}}
   template <> struct largest_type_select<false> {
     blah x;  // expected-error {{unknown type name 'blah'}}
   };

Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Fri Mar 16 06:36:56 2018
@@ -15,8 +15,8 @@ class A {
   template<typename T> static CONST T right<T,int> = 5;
   template<typename T> CONST int right<int,T>;  // expected-error {{member 'right' declared as a template}}
   template<typename T> CONST float right<float,T> = 5;  // expected-error {{member 'right' declared as a template}}
-  template<> static CONST int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
-  template<> static CONST float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
+  template<> static CONST int right<int,int> = 7;
+  template<> static CONST float right<float,int>;
   template static CONST int right<int,int>;     // expected-error {{expected '<' after 'template'}}
 };
 
@@ -163,8 +163,8 @@ namespace constexpred {
     template<typename T> constexpr int right<int,T>;  // expected-error {{member 'right' declared as a template}} \
                                                       // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
     template<typename T> constexpr float right<float,T> = 5;  // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
-    template<> static constexpr int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
-    template<> static constexpr float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
+    template<> static constexpr int right<int,int> = 7;
+    template<> static constexpr float right<float,int>; // expected-error {{requires an initializer}}
     template static constexpr int right<int,int>;     // expected-error {{expected '<' after 'template'}}
   };
 }

Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Fri Mar 16 06:36:56 2018
@@ -409,7 +409,7 @@ namespace nested {
 #endif
     float f1 = pi1a<float>;
     
-    template<> double pi1a<double> = 5.2;  // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
+    template<> double pi1a<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
     double d1 = pi1a<double>;
   }
   
@@ -422,8 +422,7 @@ namespace nested {
 #endif
     float f1 = n1::pi1b<float>;
     
-    template<> double n1::pi1b<double> = 5.2;  // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
-                                               // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
+    template<> double n1::pi1b<double> = 5.2;  // expected-error {{not in a namespace enclosing 'n1'}}
     double d1 = n1::pi1b<double>;
   }
 }

Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Fri Mar 16 06:36:56 2018
@@ -185,9 +185,9 @@ namespace RedundantParensInAddressTempla
 }
 
 namespace TemplateSpecOutOfScopeNs {
-  template<typename T> struct S {}; // expected-note {{here}}
+  template<typename T> struct S {};
 }
-template<> struct TemplateSpecOutOfScopeNs::S<char> {}; // expected-warning {{class template specialization of 'S' outside namespace 'TemplateSpecOutOfScopeNs' is incompatible with C++98}}
+template<> struct TemplateSpecOutOfScopeNs::S<char> {};
 
 struct Typename {
   template<typename T> struct Inner {};

Modified: cfe/trunk/test/SemaTemplate/class-template-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-spec.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/class-template-spec.cpp Fri Mar 16 06:36:56 2018
@@ -78,9 +78,6 @@ template<> struct ::A<double>;
 
 namespace N {
   template<typename T> struct B; // expected-note {{explicitly specialized}}
-#if __cplusplus <= 199711L
-  // expected-note at -2 {{explicitly specialized}}
-#endif
 
   template<> struct ::N::B<char>; // okay
   template<> struct ::N::B<short>; // okay
@@ -92,9 +89,6 @@ namespace N {
 template<> struct N::B<int> { }; // okay
 
 template<> struct N::B<float> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'B' outside namespace 'N' is a C++11 extension}}
-#endif
 
 
 namespace M {
@@ -121,9 +115,9 @@ class Wibble<int> { }; // expected-error
 
 namespace rdar9676205 {
   template<typename T>
-  struct X {
+  struct X { // expected-note {{here}}
     template<typename U>
-    struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
+    struct X<U*> { // expected-error{{partial specialization of 'X' not in a namespace enclosing}}
     };
   };
 

Modified: 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=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp Fri Mar 16 06:36:56 2018
@@ -18,16 +18,16 @@ template <typename T> struct X {
 namespace B {
 
 template <>
-class A::ClassTemplate<int>; // expected-warning {{class template specialization of 'ClassTemplate' outside namespace enclosing 'A' is a Microsoft extension}}
+class A::ClassTemplate<int>; // expected-warning {{class template specialization of 'ClassTemplate' not in a 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}}
+class A::ClassTemplatePartial<T1, T1 *> {}; // expected-warning {{class template partial specialization of 'ClassTemplatePartial' not in a 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}}
+struct A::X<int>::MemberClass; // expected-warning {{member class specialization of 'MemberClass' not in class 'X' or an enclosing namespace 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}}
+enum A::X<int>::MemberEnumeration; // expected-warning {{member enumeration specialization of 'MemberEnumeration' not in class 'X' or an enclosing namespace is a Microsoft extension}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
 
 }
 

Modified: cfe/trunk/test/SemaTemplate/function-template-specialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/function-template-specialization.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/function-template-specialization.cpp (original)
+++ cfe/trunk/test/SemaTemplate/function-template-specialization.cpp Fri Mar 16 06:36:56 2018
@@ -54,5 +54,5 @@ class Foo {
 
   // Don't crash here.
   template<>
-  static void Bar(const long& input) {}  // expected-error{{explicit specialization of 'Bar' in class scope}}
+  static void Bar(const long& input) {}  // expected-warning{{explicit specialization cannot have a storage class}}
 };

Modified: cfe/trunk/test/SemaTemplate/instantiate-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-method.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-method.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-method.cpp Fri Mar 16 06:36:56 2018
@@ -185,7 +185,7 @@ namespace SameSignatureAfterInstantiatio
 
 namespace PR22040 {
   template <typename T> struct Foobar {
-    template <> void bazqux(typename T::type) {}  // expected-error {{cannot specialize a function 'bazqux' within class scope}} expected-error 2{{cannot be used prior to '::' because it has no members}}
+    template <> void bazqux(typename T::type) {}  // expected-error 2{{cannot be used prior to '::' because it has no members}}
   };
 
   void test() {

Modified: cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp Fri Mar 16 06:36:56 2018
@@ -1,18 +1,15 @@
 // RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
 
+// expected-no-diagnostics
 class A {
 public:
   template<class U> A(U p) {}
-  template<> A(int p) {
-    // expected-warning at -1 {{explicit specialization of 'A' within class scope is a Microsoft extension}}
-  }
+  template<> A(int p) {}
 
   template<class U> void f(U p) {}
 
-  template<> void f(int p) {
-    // expected-warning at -1 {{explicit specialization of 'f' within class scope is a Microsoft extension}}
-  }
+  template<> void f(int p) {}
 
   void f(int p) {}
 };
@@ -28,14 +25,11 @@ void test1() {
 template<class T> class B {
 public:
   template<class U> B(U p) {}
-  template<> B(int p) {
-    // expected-warning at -1 {{explicit specialization of 'B<T>' within class scope is a Microsoft extension}}
-  }
+  template<> B(int p) {}
 
   template<class U> void f(U p) { T y = 9; }
 
   template<> void f(int p) {
-    // expected-warning at -1 {{explicit specialization of 'f' within class scope is a Microsoft extension}}
     T a = 3;
   }
 
@@ -56,9 +50,7 @@ namespace PR12709 {
 
     template<bool b> void specialized_member_template() {}
 
-    template<> void specialized_member_template<false>() {
-      // expected-warning at -1 {{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}}
-    }
+    template<> void specialized_member_template<false>() {}
   };
 
   void f() { TemplateClass<int> t; }
@@ -67,8 +59,8 @@ namespace PR12709 {
 namespace Duplicates {
   template<typename T> struct A {
     template<typename U> void f();
-    template<> void f<int>() {} // expected-warning {{Microsoft extension}}
-    template<> void f<T>() {} // expected-warning {{Microsoft extension}}
+    template<> void f<int>() {}
+    template<> void f<T>() {}
   };
 
   // FIXME: We should diagnose the duplicate explicit specialization definitions
@@ -81,6 +73,6 @@ struct S {
   template <int>
   int f(int = 0);
   template <>
-  int f<0>(int); // expected-warning {{Microsoft extension}}
+  int f<0>(int);
 };
 }

Modified: cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp Fri Mar 16 06:36:56 2018
@@ -7,17 +7,11 @@ template<typename T> struct vector;
 namespace N {
   namespace M {
     template<typename T> struct A;
-#if __cplusplus <= 199711L // C++03 or earlier modes
-    // expected-note at -2{{explicitly specialized declaration is here}}
-#endif
   }
 }
 
 template<typename T>
 struct N::M::A<T*> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2{{first declaration of class template partial specialization of 'A' outside namespace 'M' is a C++11 extension}}
-#endif
 
 // C++ [temp.class.spec]p9
 //   bullet 1, as amended by DR1315

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Fri Mar 16 06:36:56 2018
@@ -303,7 +303,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#44">44</a></td>
     <td>CD1</td>
     <td>Member specializations</td>
-    <td class="full" align="center">Yes</td>
+    <td class="svn" align="center">Superseded by <a href="#727">727</a></td>
   </tr>
   <tr id="45">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45">45</a></td>
@@ -2285,7 +2285,7 @@ of class templates</td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374">374</a></td>
     <td>CD2</td>
     <td>Can explicit specialization outside namespace use qualified name?</td>
-    <td class="full" align="center">Yes (C++11 onwards)</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="375">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#375">375</a></td>
@@ -4387,7 +4387,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#727">727</a></td>
     <td>C++17</td>
     <td>In-class explicit specializations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr class="open" id="728">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#728">728</a></td>




More information about the cfe-commits mailing list