[cfe-commits] r159147 - in /cfe/trunk: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h lib/AST/DeclTemplate.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/ms-function-specialization-class-scope.cpp

Nico Weber nicolasweber at gmx.de
Mon Jun 25 10:21:06 PDT 2012


Author: nico
Date: Mon Jun 25 12:21:05 2012
New Revision: 159147

URL: http://llvm.org/viewvc/llvm-project?rev=159147&view=rev
Log:
Make explicit specializations at class scope work
for non-type template parameters in microsoft mode.
PR12709.


Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=159147&r1=159146&r2=159147&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Mon Jun 25 12:21:05 2012
@@ -2086,23 +2086,33 @@
   virtual void anchor();
 
   ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
-                                       CXXMethodDecl *FD)
+                                       CXXMethodDecl *FD, bool Args,
+                                       TemplateArgumentListInfo TemplArgs)
     : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
-      Specialization(FD) {}
+      Specialization(FD), HasExplicitTemplateArgs(Args),
+      TemplateArgs(TemplArgs) {}
 
   ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
     : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
 
   CXXMethodDecl *Specialization;
+  bool HasExplicitTemplateArgs;
+  TemplateArgumentListInfo TemplateArgs;
 
 public:
   CXXMethodDecl *getSpecialization() const { return Specialization; }
+  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+  const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
 
   static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
                                                       DeclContext *DC,
                                                       SourceLocation Loc,
-                                                      CXXMethodDecl *FD) {
-    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD);
+                                                      CXXMethodDecl *FD,
+                                                   bool HasExplicitTemplateArgs,
+                                        TemplateArgumentListInfo TemplateArgs) {
+    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
+                                                        HasExplicitTemplateArgs,
+                                                        TemplateArgs);
   }
 
   static ClassScopeFunctionSpecializationDecl *

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=159147&r1=159146&r2=159147&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jun 25 12:21:05 2012
@@ -1283,7 +1283,13 @@
   })
 
 DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
-  TRY_TO(TraverseDecl(D->getSpecialization()));
+    TRY_TO(TraverseDecl(D->getSpecialization()));
+
+    if (D->hasExplicitTemplateArgs()) {
+      const TemplateArgumentListInfo& args = D->templateArgs();
+      TRY_TO(TraverseTemplateArgumentLocsHelper(
+          args.getArgumentArray(), args.size()));
+    }
  })
 
 DEF_TRAVERSE_DECL(LinkageSpecDecl, { })

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=159147&r1=159146&r2=159147&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Mon Jun 25 12:21:05 2012
@@ -869,5 +869,6 @@
                                                          unsigned ID) {
   void *Mem = AllocateDeserializedDecl(C, ID, 
                 sizeof(ClassScopeFunctionSpecializationDecl));
-  return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0);
+  return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
+                                             false, TemplateArgumentListInfo());
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=159147&r1=159146&r2=159147&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jun 25 12:21:05 2012
@@ -5066,7 +5066,11 @@
   FunctionTemplateDecl *FunctionTemplate = 0;
   bool isExplicitSpecialization = false;
   bool isFunctionTemplateSpecialization = false;
+
   bool isDependentClassScopeExplicitSpecialization = false;
+  bool HasExplicitTemplateArgs = false;
+  TemplateArgumentListInfo TemplateArgs;
+
   bool isVirtualOkay = false;
 
   FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC,
@@ -5509,8 +5513,6 @@
   } else {
     // If the declarator is a template-id, translate the parser's template 
     // argument list into our AST format.
-    bool HasExplicitTemplateArgs = false;
-    TemplateArgumentListInfo TemplateArgs;
     if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
       TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
       TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
@@ -5814,8 +5816,9 @@
   if (isDependentClassScopeExplicitSpecialization) {
     ClassScopeFunctionSpecializationDecl *NewSpec =
                          ClassScopeFunctionSpecializationDecl::Create(
-                                Context, CurContext,  SourceLocation(), 
-                                cast<CXXMethodDecl>(NewFD));
+                                Context, CurContext, SourceLocation(), 
+                                cast<CXXMethodDecl>(NewFD),
+                                HasExplicitTemplateArgs, TemplateArgs);
     CurContext->addDecl(NewSpec);
     AddToScope = false;
   }

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=159147&r1=159146&r2=159147&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Jun 25 12:21:05 2012
@@ -1952,13 +1952,22 @@
 Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
                                      ClassScopeFunctionSpecializationDecl *Decl) {
   CXXMethodDecl *OldFD = Decl->getSpecialization();
-  CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, 0, true));
+  CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD,
+                                                                0, true));
 
   LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,
                         Sema::ForRedeclaration);
 
+  TemplateArgumentListInfo TemplateArgs;
+  TemplateArgumentListInfo* TemplateArgsPtr = 0;
+  if (Decl->hasExplicitTemplateArgs()) {
+    TemplateArgs = Decl->templateArgs();
+    TemplateArgsPtr = &TemplateArgs;
+  }
+
   SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext);
-  if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, 0, Previous)) {
+  if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, TemplateArgsPtr,
+                                                  Previous)) {
     NewFD->setInvalidDecl();
     return NewFD;
   }

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=159147&r1=159146&r2=159147&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp Mon Jun 25 12:21:05 2012
@@ -69,3 +69,24 @@
    b.f(100);
 }
 
+
+namespace PR12709 {
+
+template<class T>
+class TemplateClass {
+  void member_function() {
+    specialized_member_template<false>();
+  }
+
+  template<bool b>
+  void specialized_member_template() {}
+
+  template<>
+  void specialized_member_template<false>() {}  // expected-warning{{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}}
+};
+
+void f() {
+  TemplateClass<int> t;
+}
+
+}





More information about the cfe-commits mailing list