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/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/test/SemaTemplate/ms-function-specialization-class-scope.cpp
new file mode 100644
index 0000000..8821501
--- /dev/null
+++ b/test/SemaTemplate/ms-function-specialization-class-scope.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+
+
+class A {
+public:
+	template <class U>
+    A(U p) {
+	}
+	template <>
+    A(int p) { // expected-warning{{explicit specialization of 'A' within class scope in a Microsoft extension}}
+	}
+	
+	template <class U>
+    void f(U p) { 
+	}
+
+	template <>
+    void f(int p) { // expected-warning{{explicit specialization of 'f' within class scope in a Microsoft extension}}
+	}
+
+	void f(int p) { 
+    }
+};
+
+void test1()
+{
+   A a(3);
+   char* b ;
+   a.f(b);
+   a.f<int>(99);
+   a.f(100);
+}
+
+
+
+
+template <class T>
+class B {
+public:
+	template <class U>
+    B(U p) { 
+	}
+	template <>
+    B(int p) { // expected-warning{{explicit specialization of 'B<T>' within class scope in a Microsoft extension}}
+	}
+	
+	template <class U>
+    void f(U p) {
+	  T y = 9;
+	}
+
+
+    template <>
+    void f(int p) { // expected-warning{{explicit specialization of 'f' within class scope in a Microsoft extension}}
+	  T a = 3;
+	}
+
+	void f(int p) { 
+ 	  T a = 3;
+    }
+};
+
+void test2()
+{
+   B<char> b(3);
+   char* ptr;
+   b.f(ptr);
+   b.f<int>(99);
+   b.f(100);
+}
+