Implement function template specialization at class scope extension in Microsoft mode. A new AST node is introduced: ClassScopeFunctionSpecialization. This node holds a FunctionDecl that is not yet specialized; then during the class template instantiation the ClassScopeFunctionSpecialization will spawn the actual function specialization.

Example:
template <class T>
class A {
public:
  template <class U> void f(U p) {  }
  template <> void f(int p) {  } // <== class scope specialization
};

This extension is necessary to parse MSVC standard C++ headers, MFC and ATL code.
BTW, with this feature in, clang can parse (-fsyntax-only) all the MSVC 2010 standard header files without any error.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137573 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 872bb87..2554b82 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1288,7 +1288,8 @@
 
 Decl *
 TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
-                                      TemplateParameterList *TemplateParams) {
+                                      TemplateParameterList *TemplateParams,
+                                      bool IsClassScopeSpecialization) {
   FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
   void *InsertPos = 0;
   if (FunctionTemplate && !TemplateParams) {
@@ -1493,7 +1494,8 @@
   }
 
   bool Redeclaration = false;
-  SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration);
+  if (!IsClassScopeSpecialization)
+    SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration);
 
   if (D->isPure())
     SemaRef.CheckPureMethod(Method, SourceRange());
@@ -1512,7 +1514,7 @@
                             : Method);
     if (isFriend)
       Record->makeDeclVisibleInContext(DeclToAdd);
-    else
+    else if (!IsClassScopeSpecialization)
       Owner->addDecl(DeclToAdd);
   }
 
@@ -1907,6 +1909,29 @@
   return UD;
 }
 
+
+Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
+                                     ClassScopeFunctionSpecializationDecl *Decl) {
+  CXXMethodDecl *OldFD = Decl->getSpecialization();
+  CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, 0, true));
+
+  LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,
+                        Sema::ForRedeclaration);
+
+  SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext);
+  if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, 0, Previous)) {
+    NewFD->setInvalidDecl();
+    return NewFD;
+  }
+
+  // Associate the specialization with the pattern.
+  FunctionDecl *Specialization = cast<FunctionDecl>(Previous.getFoundDecl());
+  assert(Specialization && "Class scope Specialization is null");
+  SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD);
+
+  return NewFD;
+}
+
 Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
                       const MultiLevelTemplateArgumentList &TemplateArgs) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
@@ -2335,8 +2360,10 @@
   if (Function->isInvalidDecl() || Function->isDefined())
     return;
 
-  // Never instantiate an explicit specialization.
-  if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+  // Never instantiate an explicit specialization except if it is a class scope
+  // explicit specialization.
+  if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
+      !Function->getClassScopeSpecializationPattern())
     return;
 
   // Find the function body that we'll be substituting.