Index: include/clang/AST/DeclTemplate.h
===================================================================
--- include/clang/AST/DeclTemplate.h	(revision 133213)
+++ include/clang/AST/DeclTemplate.h	(working copy)
@@ -2089,6 +2089,58 @@
   friend class ASTDeclWriter;
 };
 
+/// Declaration of a function specialization at template class scope.
+/// This is a non standard extension needed to support MSVC.
+/// For example:
+/// template <class T>
+/// class A {
+///    template <class U> void foo(U a) { }
+///    template<> void foo(int a) { }
+/// }
+///
+/// "template<> foo(int a)" will be saved in Specialization as a normal
+/// CXXMethodDecl. Then during an instantiation of class A, it will be
+/// transformed into an actual function specialization.
+class ClassScopeFunctionSpecializationDecl : public Decl {
+private:
+  ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
+                                       CXXMethodDecl *FD)
+    : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
+      Specialization(FD) {}
+
+  ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
+    : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
+
+  CXXMethodDecl *Specialization;
+
+public:
+  CXXMethodDecl *getSpecialization() const { return Specialization; }
+
+  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
+                                                      DeclContext *DC,
+                                                      SourceLocation Loc,
+                                                      CXXMethodDecl *FD) {
+    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD);
+  }
+
+  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &Context,
+                                                      EmptyShell Empty) {
+    return new (Context)ClassScopeFunctionSpecializationDecl(0,
+                                                         SourceLocation(), 0);
+  }
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == Decl::ClassScopeFunctionSpecialization;
+  }
+  static bool classof(const ClassScopeFunctionSpecializationDecl *D) {
+    return true;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
 /// Implementation of inline functions that require the template declarations
 inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
   : Function(FTD) { }
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h	(revision 133213)
+++ include/clang/AST/RecursiveASTVisitor.h	(working copy)
@@ -1114,6 +1114,10 @@
     }
   })
 
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
+  TRY_TO(TraverseDecl(D->getSpecialization()));
+ })
+
 DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
 
 DEF_TRAVERSE_DECL(ObjCClassDecl, {
Index: include/clang/Basic/DeclNodes.td
===================================================================
--- include/clang/Basic/DeclNodes.td	(revision 133213)
+++ include/clang/Basic/DeclNodes.td	(working copy)
@@ -74,3 +74,4 @@
 def FriendTemplate : Decl;
 def StaticAssert : Decl;
 def Block : Decl, DeclContext;
+def ClassScopeFunctionSpecialization : Decl;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 133213)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -1867,6 +1867,9 @@
   "explicit specialization of %0 in function scope">;
 def err_template_spec_decl_class_scope : Error<
   "explicit specialization of %0 in class scope">;
+def warn_template_spec_decl_class_scope : ExtWarn<
+  "explicit specialization of %0 in class scope in a Microsoft extension">,
+  InGroup<Microsoft>;
 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<
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 133213)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -4883,7 +4883,8 @@
   void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
                                      FunctionDecl *Function,
                                      bool Recursive = false,
-                                     bool DefinitionRequired = false);
+                                     bool DefinitionRequired = false,
+                                     bool CallASTConsumer = true);
   void InstantiateStaticDataMemberDefinition(
                                      SourceLocation PointOfInstantiation,
                                      VarDecl *Var,
Index: include/clang/Sema/Template.h
===================================================================
--- include/clang/Sema/Template.h	(revision 133213)
+++ include/clang/Sema/Template.h	(working copy)
@@ -367,6 +367,8 @@
     Decl *VisitUsingShadowDecl(UsingShadowDecl *D);
     Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
     Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+    Decl *VisitClassScopeFunctionSpecializationDecl(
+                                      ClassScopeFunctionSpecializationDecl *D);
 
     // Base case. FIXME: Remove once we can instantiate everything.
     Decl *VisitDecl(Decl *D) {
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h	(revision 133213)
+++ include/clang/Serialization/ASTBitCodes.h	(working copy)
@@ -783,7 +783,10 @@
       DECL_INDIRECTFIELD,
       /// \brief A NonTypeTemplateParmDecl record that stores an expanded
       /// non-type template parameter pack.
-      DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK
+      DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK,
+      /// \brief A ClassScopeFunctionSpecializationDecl record a class scope
+      /// function specialization. (Microsoft extension).
+      DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION
     };
 
     /// \brief Record codes for each kind of statement or expression.
Index: lib/AST/DeclBase.cpp
===================================================================
--- lib/AST/DeclBase.cpp	(revision 133213)
+++ lib/AST/DeclBase.cpp	(working copy)
@@ -493,6 +493,7 @@
     case UsingDirective:
     case ClassTemplateSpecialization:
     case ClassTemplatePartialSpecialization:
+    case ClassScopeFunctionSpecialization:
     case ObjCImplementation:
     case ObjCCategory:
     case ObjCCategoryImpl:
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp	(revision 133213)
+++ lib/CodeGen/CGDecl.cpp	(working copy)
@@ -36,6 +36,7 @@
   case Decl::UnresolvedUsingTypename:
   case Decl::ClassTemplateSpecialization:
   case Decl::ClassTemplatePartialSpecialization:
+  case Decl::ClassScopeFunctionSpecialization:
   case Decl::TemplateTypeParm:
   case Decl::UnresolvedUsingValue:
   case Decl::NonTypeTemplateParm:
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 133213)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -1688,9 +1688,13 @@
       // Preserve triviality.
       NewMethod->setTrivial(OldMethod->isTrivial());
 
+      // MSVC allows explicit template specialization at class scope.
+      bool IsMSExplicitSpecialization = getLangOptions().Microsoft &&
+                                 NewMethod->isFunctionTemplateSpecialization();
       bool isFriend = NewMethod->getFriendObjectKind();
 
-      if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord()) {
+      if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord() &&
+          !IsMSExplicitSpecialization) {
         //    -- Member function declarations with the same name and the
         //       same parameter types cannot be overloaded if any of them
         //       is a static member function declaration.
@@ -4649,6 +4653,17 @@
     } else if (isFunctionTemplateSpecialization) {
       if (CurContext->isDependentContext() && CurContext->isRecord() 
           && !isFriend) {
+        if (getLangOptions().Microsoft) {
+          ClassScopeFunctionSpecializationDecl *NewSpec =
+                               ClassScopeFunctionSpecializationDecl::Create(
+                                      Context, CurContext,  SourceLocation(), 
+                                      cast<CXXMethodDecl>(NewFD));
+          CurContext->addDecl(NewSpec);
+          Redeclaration = true;
+          NewFD->setInvalidDecl();
+          return NewFD;
+        }
+
         Diag(NewFD->getLocation(), diag::err_function_specialization_in_class)
           << NewFD->getDeclName();
         NewFD->setInvalidDecl();
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp	(revision 133213)
+++ lib/Sema/SemaTemplate.cpp	(working copy)
@@ -4474,9 +4474,14 @@
   }
 
   if (S.CurContext->isRecord() && !IsPartialSpecialization) {
-    S.Diag(Loc, diag::err_template_spec_decl_class_scope)
-      << Specialized;
-    return true;
+    if (S.getLangOptions().Microsoft)
+      S.Diag(Loc, diag::warn_template_spec_decl_class_scope)
+        << Specialized;
+    else {
+      S.Diag(Loc, diag::err_template_spec_decl_class_scope)
+        << Specialized;
+      return true;
+    }
   }
 
   // C++ [temp.class.spec]p6:
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp	(revision 133213)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp	(working copy)
@@ -1890,6 +1890,89 @@
   return UD;
 }
 
+Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
+                                     ClassScopeFunctionSpecializationDecl *Decl) {
+  CXXMethodDecl *D = Decl->getSpecialization();
+
+  LocalInstantiationScope Scope(SemaRef);
+
+  llvm::SmallVector<ParmVarDecl *, 4> Params;
+  TypeSourceInfo *TInfo = D->getTypeSourceInfo();
+  TInfo = SubstFunctionType(D, Params);
+  if (!TInfo)
+    return 0;
+  QualType T = TInfo->getType();
+
+  // Build the instantiated method declaration.
+  DeclContext *DC = Owner;
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
+
+  SourceLocation StartLoc = D->getInnerLocStart();
+  DeclarationNameInfo NameInfo
+    = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
+
+  CXXMethodDecl *NewFD = 0;
+  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
+    NewFD = CXXConstructorDecl::Create(SemaRef.Context, Record,
+                                        StartLoc, NameInfo, T, TInfo,
+                                        Constructor->isExplicit(),
+                                        Constructor->isInlineSpecified(),
+                                        false);
+  } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
+    NewFD = CXXDestructorDecl::Create(SemaRef.Context, Record,
+                                       StartLoc, NameInfo, T, TInfo,
+                                       Destructor->isInlineSpecified(),
+                                       false);
+  } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
+    NewFD = CXXConversionDecl::Create(SemaRef.Context, Record,
+                                       StartLoc, NameInfo, T, TInfo,
+                                       Conversion->isInlineSpecified(),
+                                       Conversion->isExplicit(),
+                                       Conversion->getLocEnd());
+  } else {
+    NewFD = CXXMethodDecl::Create(SemaRef.Context, Record,
+                                   StartLoc, NameInfo, T, TInfo,
+                                   D->isStatic(),
+                                   D->getStorageClassAsWritten(),
+                                   D->isInlineSpecified(),
+                                   D->getLocEnd());
+  }
+
+
+  // Record that this is an instantiation of a member function.
+  NewFD->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
+  
+  // Attach the parameters
+  for (unsigned P = 0; P < Params.size(); ++P)
+    Params[P]->setOwningFunction(NewFD);
+  NewFD->setParams(Params.data(), Params.size());
+
+  if (InitMethodInstantiation(NewFD, D))
+    NewFD->setInvalidDecl();
+
+  LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
+                        Sema::ForRedeclaration);
+  bool Redeclaration = false;
+  SemaRef.CheckFunctionDeclaration(0, NewFD, Previous, false, Redeclaration);
+
+  NewFD->setAccess(D->getAccess());
+  SemaRef.CheckOverrideControl(NewFD);
+
+  // Instantiate NewFD.
+  SemaRef.InstantiateFunctionDefinition(SourceLocation(), NewFD, false,
+                                        false, false);
+  // Now specialize it.
+  SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext);
+  SemaRef.CheckFunctionTemplateSpecialization(NewFD, 0, Previous);
+
+  // Pass 'NewFD' to the ASTConsumer since it wasn't done in
+  // InstantiateFunctionDefinition.
+  DeclGroupRef DG(NewFD);
+  SemaRef.Consumer.HandleTopLevelDecl(DG);
+
+  return NewFD;
+}
+
 Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
                       const MultiLevelTemplateArgumentList &TemplateArgs) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
@@ -2309,7 +2392,8 @@
 void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
                                          FunctionDecl *Function,
                                          bool Recursive,
-                                         bool DefinitionRequired) {
+                                         bool DefinitionRequired,
+                                         bool CallASTConsumer) {
   if (Function->isInvalidDecl() || Function->isDefined())
     return;
 
@@ -2466,8 +2550,10 @@
 
   savedContext.pop();
 
-  DeclGroupRef DG(Function);
-  Consumer.HandleTopLevelDecl(DG);
+  if (CallASTConsumer) {
+    DeclGroupRef DG(Function);
+    Consumer.HandleTopLevelDecl(DG);
+  }
 
   // This class may have local implicit instantiations that need to be
   // instantiation within this scope.
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp	(revision 133213)
+++ lib/Serialization/ASTReaderDecl.cpp	(working copy)
@@ -1575,6 +1575,10 @@
     D = ClassTemplatePartialSpecializationDecl::Create(*Context,
                                                        Decl::EmptyShell());
     break;
+  case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
+    D = ClassScopeFunctionSpecializationDecl::Create(*Context,
+                                                     Decl::EmptyShell());
+    break;
   case DECL_FUNCTION_TEMPLATE:
       D = FunctionTemplateDecl::Create(*Context, Decl::EmptyShell());
     break;
Index: test/SemaTemplate/ms-function-specialization-class-scope.cpp
===================================================================
--- test/SemaTemplate/ms-function-specialization-class-scope.cpp	(revision 0)
+++ test/SemaTemplate/ms-function-specialization-class-scope.cpp	(revision 0)
@@ -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' in class scope in a Microsoft extension}}
+	}
+	
+	template <class U>
+    void f(U p) { 
+	}
+
+	template <>
+    void f(int p) { // expected-warning{{explicit specialization of 'f' in 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' in 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' in class scope in a Microsoft extension}}
+	  T a = 3;
+	}
+
+	void f(int p) { 
+ 	  T a = 3;
+    }
+};
+
+void test2()
+{
+   B<char> b(3);// expected-note{{in instantiation of template class 'B<char>'}} expected-note{{in instantiation of template class 'B<char>'}}
+   char* ptr;
+   b.f(ptr);
+   b.f<int>(99);
+   b.f(100);
+}
+
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp	(revision 133213)
+++ tools/libclang/CIndex.cpp	(working copy)
@@ -3948,6 +3948,7 @@
   case Decl::StaticAssert:
   case Decl::Block:
   case Decl::Label:  // FIXME: Is this right??
+  case Decl::ClassScopeFunctionSpecialization:
     return C;
 
   // Declaration kinds that don't make any sense here, but are
