Index: test/Sema/ms_wide_predefined_expr.cpp
===================================================================
--- test/Sema/ms_wide_predefined_expr.cpp	(revision 0)
+++ test/Sema/ms_wide_predefined_expr.cpp	(revision 0)
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions
+
+// Wide character predefined identifiers
+#define _STR2WSTR(str) L##str
+#define STR2WSTR(str) _STR2WSTR(str)
+void abcdefghi12(void) {
+ const wchar_t (*ss)[12] = &STR2WSTR(__FUNCTION__);
+ static int arr[sizeof(STR2WSTR(__FUNCTION__))==12*sizeof(wchar_t) ? 1 : -1];
+}
Index: test/Preprocessor/macro_paste_msextensions.cpp
===================================================================
--- test/Preprocessor/macro_paste_msextensions.cpp	(revision 0)
+++ test/Preprocessor/macro_paste_msextensions.cpp	(revision 0)
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -P -E -fms-extensions %s | FileCheck -strict-whitespace %s
+
+#define _STR2WSTR(str) L##str
+#define STR2WSTR(str) _STR2WSTR(str)
+
+void fun() {
+STR2WSTR(__FUNCTION__)
+// CHECK: L__FUNCTION__
+
+_STR2WSTR(__FUNCTION__)
+// CHECK: L__FUNCTION__
+
+// Make sure it's not applied for regular token pasting
+#define NOTFUNCTION NOREALLY
+STR2WSTR(NOTFUNCTION)
+// CHECK: LNOREALLY
+}
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def	(revision 158594)
+++ include/clang/Basic/TokenKinds.def	(working copy)
@@ -342,6 +342,9 @@
 // GNU Extensions (outside impl-reserved namespace)
 KEYWORD(typeof                      , KEYGNU)
 
+// MS Extensions
+KEYWORD(L__FUNCTION__               , KEYMS)
+
 // GNU and MS Type Traits
 KEYWORD(__has_nothrow_assign        , KEYCXX)
 KEYWORD(__has_nothrow_copy          , KEYCXX)
@@ -421,6 +424,7 @@
 KEYWORD(__thiscall                  , KEYALL)
 KEYWORD(__forceinline               , KEYALL)
 KEYWORD(__unaligned                 , KEYMS)
+KEYWORD(__LPREFIX                   , KEYMS)
 
 // OpenCL-specific keywords
 KEYWORD(__kernel                    , KEYOPENCL)
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h	(revision 158594)
+++ include/clang/AST/Expr.h	(working copy)
@@ -1047,6 +1047,7 @@
   enum IdentType {
     Func,
     Function,
+    LFunction,  // Same as Function, but as wide string.
     PrettyFunction,
     /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
     /// 'virtual' keyword is omitted for virtual member functions.
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 158594)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -2419,6 +2419,7 @@
   default: llvm_unreachable("Unknown simple primary expr!");
   case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
   case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
+  case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break;
   case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
   }
 
@@ -2440,7 +2441,10 @@
     unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
 
     llvm::APInt LengthI(32, Length + 1);
-    ResTy = Context.CharTy.withConst();
+    if (Kind == tok::kw_L__FUNCTION__)
+      ResTy = Context.WCharTy.withConst();
+    else
+      ResTy = Context.CharTy.withConst();
     ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
   }
   return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
Index: lib/AST/StmtDumper.cpp
===================================================================
--- lib/AST/StmtDumper.cpp	(revision 158594)
+++ lib/AST/StmtDumper.cpp	(working copy)
@@ -424,6 +424,7 @@
   default: llvm_unreachable("unknown case");
   case PredefinedExpr::Func:           OS <<  " __func__"; break;
   case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
+  case PredefinedExpr::LFunction:       OS <<  " L__FUNCTION__"; break;
   case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
   }
 }
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp	(revision 158594)
+++ lib/AST/StmtPrinter.cpp	(working copy)
@@ -643,6 +643,9 @@
     case PredefinedExpr::Function:
       OS << "__FUNCTION__";
       break;
+    case PredefinedExpr::LFunction:
+      OS << "L__FUNCTION__";
+      break;
     case PredefinedExpr::PrettyFunction:
       OS << "__PRETTY_FUNCTION__";
       break;
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp	(revision 158594)
+++ lib/CodeGen/CGExpr.cpp	(working copy)
@@ -21,6 +21,7 @@
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/Basic/ConvertUTF.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/LLVMContext.h"
@@ -1701,7 +1702,76 @@
                         E->getType());
 }
 
+namespace {
+  llvm::Constant*
+  GetAddrOfConstantWideString(StringRef Str,
+                              const char *GlobalName,
+                              ASTContext &Context,
+                              QualType Ty, SourceLocation Loc,
+                              CodeGenModule &CGM) {
 
+    StringLiteral *SL = StringLiteral::Create(Context,
+                                              Str,
+                                              StringLiteral::Wide,
+                                              /*Pascal = */false,
+                                              Ty, Loc);
+    llvm::Constant *C = CGM.GetConstantArrayFromStringLiteral(SL);
+    llvm::GlobalVariable *GV =
+      new llvm::GlobalVariable(CGM.getModule(), C->getType(),
+                               !CGM.getLangOpts().WritableStrings,
+                               llvm::GlobalValue::PrivateLinkage,
+                               C, GlobalName);
+    const unsigned WideAlignment =
+      Context.getTypeAlignInChars(Ty).getQuantity();
+    GV->setAlignment(WideAlignment);
+    return GV;
+  }
+
+  // FIXME: Mostly copied from StringLiteralParser::CopyStringFragment
+  void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
+                               SmallString<32>& Target) {
+    Target.resize(CharByteWidth * (Source.size() + 1));
+    char* ResultPtr = &Target[0];
+
+    assert(CharByteWidth==1 || CharByteWidth==2 || CharByteWidth==4);
+    ConversionResult result = conversionOK;
+    // Copy the character span over.
+    if (CharByteWidth == 1) {
+      if (!isLegalUTF8String(reinterpret_cast<const UTF8*>(&*Source.begin()),
+                             reinterpret_cast<const UTF8*>(&*Source.end())))
+        result = sourceIllegal;
+      memcpy(ResultPtr, Source.data(), Source.size());
+      ResultPtr += Source.size();
+    } else if (CharByteWidth == 2) {
+      UTF8 const *sourceStart = (UTF8 const *)Source.data();
+      // FIXME: Make the type of the result buffer correct instead of
+      // using reinterpret_cast.
+      UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
+      ConversionFlags flags = strictConversion;
+      result = ConvertUTF8toUTF16(
+        &sourceStart,sourceStart + Source.size(),
+          &targetStart,targetStart + 2*Source.size(),flags);
+      if (result==conversionOK)
+        ResultPtr = reinterpret_cast<char*>(targetStart);
+    } else if (CharByteWidth == 4) {
+      UTF8 const *sourceStart = (UTF8 const *)Source.data();
+      // FIXME: Make the type of the result buffer correct instead of
+      // using reinterpret_cast.
+      UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
+      ConversionFlags flags = strictConversion;
+      result = ConvertUTF8toUTF32(
+          &sourceStart,sourceStart + Source.size(),
+          &targetStart,targetStart + 4*Source.size(),flags);
+      if (result==conversionOK)
+        ResultPtr = reinterpret_cast<char*>(targetStart);
+    }
+    assert((result != targetExhausted)
+           && "ConvertUTF8toUTFXX exhausted target buffer");
+    assert(result == conversionOK);
+    Target.resize(ResultPtr - &Target[0]);
+  }
+}
+
 LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
   switch (E->getIdentType()) {
   default:
@@ -1709,6 +1779,7 @@
 
   case PredefinedExpr::Func:
   case PredefinedExpr::Function:
+  case PredefinedExpr::LFunction:
   case PredefinedExpr::PrettyFunction: {
     unsigned Type = E->getIdentType();
     std::string GlobalVarName;
@@ -1721,6 +1792,9 @@
     case PredefinedExpr::Function:
       GlobalVarName = "__FUNCTION__.";
       break;
+    case PredefinedExpr::LFunction:
+      GlobalVarName = "L__FUNCTION__.";
+      break;
     case PredefinedExpr::PrettyFunction:
       GlobalVarName = "__PRETTY_FUNCTION__.";
       break;
@@ -1740,8 +1814,27 @@
          ? FnName.str()
          : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurDecl));
 
-    llvm::Constant *C =
-      CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
+    const ConstantArrayType *CAT =
+      getContext().getAsConstantArrayType(E->getType());
+    QualType ElemType = CAT->getElementType();
+    llvm::Constant *C;
+    if (ElemType == getContext().WCharTy.withConst()) {
+      GlobalVarName += ".WChar";
+      SmallString<32> RawChars;
+      ConvertUTF8ToWideString(
+          getContext().getTypeSizeInChars(ElemType).getQuantity(),
+          FunctionName, RawChars);
+      C = GetAddrOfConstantWideString(RawChars,
+                                      GlobalVarName.c_str(),
+                                      getContext(),
+                                      E->getType(),
+                                      E->getLocation(),
+                                      CGM);
+    } else {
+      C = CGM.GetAddrOfConstantCString(FunctionName,
+                                       GlobalVarName.c_str(),
+                                       1);
+    }
     return MakeAddrLValue(C, E->getType());
   }
   }
Index: lib/Parse/ParseTentative.cpp
===================================================================
--- lib/Parse/ParseTentative.cpp	(revision 158594)
+++ lib/Parse/ParseTentative.cpp	(working copy)
@@ -744,6 +744,7 @@
   case tok::kw___imag:
   case tok::kw___real:
   case tok::kw___FUNCTION__:
+  case tok::kw_L__FUNCTION__:
   case tok::kw___PRETTY_FUNCTION__:
   case tok::kw___has_nothrow_assign:
   case tok::kw___has_nothrow_copy:
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp	(revision 158594)
+++ lib/Parse/ParseExpr.cpp	(working copy)
@@ -846,6 +846,7 @@
     break;
   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
+  case tok::kw_L__FUNCTION__:   // primary-expression: L__FUNCTION__ [MS]
   case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
     Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
     ConsumeToken();
