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,10 @@
+// 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/Sema/ms_lprefix.cpp
===================================================================
--- test/Sema/ms_lprefix.cpp	(revision 0)
+++ test/Sema/ms_lprefix.cpp	(revision 0)
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions
+
+void a(void) {
+ const wchar_t (*ss)[6] = &__LPREFIX("hello");
+ static int arr[sizeof(__LPREFIX("hello"))==6*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,29 @@
+// RUN: %clang_cc1 -P -E -fms-extensions %s | FileCheck -strict-whitespace %s
+
+#define _STR2WSTR(str) L##str
+#define STR2WSTR(str) _STR2WSTR(str)
+
+#define _ENDTEST(str1, str2) L##str1##str2
+#define ENDTEST(str1, str2) _ENDTEST(str1, str2)
+
+void fun() {
+// Special token pasting for __FUNCTION__ to make it seem like it's a macro
+// rather than a predefined expr
+STR2WSTR(__FUNCTION__)
+// CHECK: __LPREFIX( __FUNCTION__)
+
+// However, this rule is only applied if __FUNCTION__ would have been expanded
+// if it were a true macro.
+_STR2WSTR(__FUNCTION__)
+// CHECK: L__FUNCTION__
+
+// Make sure it's not applied for regular token pasting
+#define NOTFUNCTION NOREALLY
+STR2WSTR(NOTFUNCTION)
+// CHECK: LNOREALLY
+
+// Make sure token pasting with three arguments works with the special
+// __FUNCTION__ token pasting rule.
+ENDTEST(__FUNCTION__, JUNCTION)
+// CHECK: __LPREFIX( __FUNCTION__) JUNCTION
+}
Index: test/CodeGenCXX/ms_wide_predefined_expr.cpp
===================================================================
--- test/CodeGenCXX/ms_wide_predefined_expr.cpp	(revision 0)
+++ test/CodeGenCXX/ms_wide_predefined_expr.cpp	(revision 0)
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fms-extensions -emit-llvm -o - | FileCheck %s
+
+// CHECK: @__FUNCTION__._Z4funcv.WChar = private constant [5 x i32] [i32 102, i32 117, i32 110, i32 99, i32 0], align 4
+
+void wprint(const wchar_t*);
+
+#define __STR2WSTR(str) L##str
+#define _STR2WSTR(str) __STR2WSTR(str)
+#define STR2WSTR(str) _STR2WSTR(str)
+
+void func() {
+  wprint(STR2WSTR(__FUNCTION__));
+}
+
+int main() {
+  func();
+
+  return 0;
+}
+
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def	(revision 157363)
+++ include/clang/Basic/TokenKinds.def	(working copy)
@@ -421,6 +421,7 @@
 KEYWORD(__thiscall                  , KEYALL)
 KEYWORD(__forceinline               , KEYALL)
 KEYWORD(__unaligned                 , KEYMS)
+KEYWORD(__LPREFIX                   , KEYMS)
 
 // OpenCL-specific keywords
 KEYWORD(__kernel                    , KEYOPENCL)
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td	(revision 157363)
+++ include/clang/Basic/DiagnosticParseKinds.td	(working copy)
@@ -705,6 +705,12 @@
 
 def err_seh___finally_block : Error<
   "%0 only allowed in __finally block">;
+
+def err_ms_extensions_expected_for_lprefix : Error<
+  "Expected MS extensions to be enabled for '__LPREFIX'">;
+
+def err_lprefix_expected_string_literal : Error<
+  "Expected string literal as argument to '__LPREFIX'">;
   
 } // end of Parse Issue category.
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 157363)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -2620,7 +2620,8 @@
                                       SourceLocation LitEndLoc,
                             TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
 
-  ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
+  ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind,
+                                 CanQualType *ForceTy = 0);
   ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
   ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = 0);
   ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope = 0);
Index: include/clang/Lex/TokenLexer.h
===================================================================
--- include/clang/Lex/TokenLexer.h	(revision 157363)
+++ include/clang/Lex/TokenLexer.h	(working copy)
@@ -91,6 +91,12 @@
   /// should not be subject to further macro expansion.
   bool DisableMacroExpansion : 1;
 
+  /// MSLPrefix - This is true when we are outputing __LPREFIX( __FUNCTION__)
+  /// for Microsoft comptibility mode
+  bool MSLPrefix : 1;
+  unsigned MSLPrefixState;
+  SourceRange MSLPrefixRange;
+
   TokenLexer(const TokenLexer&);  // DO NOT IMPLEMENT
   void operator=(const TokenLexer&); // DO NOT IMPLEMENT
 public:
@@ -168,6 +174,12 @@
   /// first token on the next line.
   void HandleMicrosoftCommentPaste(Token &Tok);
 
+  /// HandleMicrosoftLPrefix - In Microsoft compatibility mode, L##__FUNCTION__
+  /// pastes to __LPREFIX( __FUNCTION__). This means it turns into multiple
+  /// tokens. When MSLPrefix is true, we output this stream of tokens. If
+  /// this returns true, the caller should immediately return the token.
+  bool HandleMicrosoftLPrefix(Token &Tok);
+
   /// \brief If \arg loc is a FileID and points inside the current macro
   /// definition, returns the appropriate source location pointing at the
   /// macro expansion source location entry.
Index: include/clang/Lex/Token.h
===================================================================
--- include/clang/Lex/Token.h	(revision 157363)
+++ include/clang/Lex/Token.h	(working copy)
@@ -76,7 +76,8 @@
     DisableExpand = 0x04,  // This identifier may never be macro expanded.
     NeedsCleaning = 0x08,   // Contained an escaped newline or trigraph.
     LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
-    HasUDSuffix = 0x20     // This string or character literal has a ud-suffix.
+    HasUDSuffix = 0x20,     // This string or character literal has a ud-suffix.
+    ExpandedFakeMacro = 0x40 // This is a fake macro that has been expanded
   };
 
   tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
@@ -267,6 +268,13 @@
   /// \brief Return true if this token is a string or character literal which
   /// has a ud-suffix.
   bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; }
+
+  /// \brief Returns true if this token is an identifier representing
+  /// a fake macro like __FUNCTION__, that would have been expanded if
+  /// it were a real macro like __FILE__
+  bool isExpandedFakeMacro() const {
+    return (Flags & ExpandedFakeMacro) ? true : false;
+  }
 };
 
 /// PPConditionalInfo - Information about the conditional stack (#if directives)
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 157363)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -1376,6 +1376,8 @@
   
   ExprResult ParseObjCBoolLiteral();
 
+  ExprResult ParseLPrefixExpression();
+
   //===--------------------------------------------------------------------===//
   // C++ Expressions
   ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 157363)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -2374,7 +2374,8 @@
   }
 }
 
-ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
+ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind,
+                                     CanQualType *ForceTy) {
   PredefinedExpr::IdentType IT;
 
   switch (Kind) {
@@ -2402,7 +2403,8 @@
     unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
 
     llvm::APInt LengthI(32, Length + 1);
-    ResTy = Context.CharTy.withConst();
+    if (ForceTy) ResTy = ForceTy->withConst();
+    else ResTy = Context.CharTy.withConst();
     ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
   }
   return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
Index: lib/Lex/TokenLexer.cpp
===================================================================
--- lib/Lex/TokenLexer.cpp	(revision 157363)
+++ lib/Lex/TokenLexer.cpp	(working copy)
@@ -32,6 +32,9 @@
   ActualArgs = Actuals;
   CurToken = 0;
 
+  MSLPrefix = false;
+  MSLPrefixState = 0;
+
   ExpandLocStart = Tok.getLocation();
   ExpandLocEnd = ELEnd;
   AtStartOfLine = Tok.isAtStartOfLine();
@@ -91,6 +94,8 @@
   DisableMacroExpansion = disableMacroExpansion;
   NumTokens = NumToks;
   CurToken = 0;
+  MSLPrefix = false;
+  MSLPrefixState = 0;
   ExpandLocStart = ExpandLocEnd = SourceLocation();
   AtStartOfLine = false;
   HasLeadingSpace = false;
@@ -354,9 +359,32 @@
   }
 }
 
+namespace {
+  /// Is the given token one that is treated as a "fake" macro, like
+  /// __FUNCTION__. A fake macro isn't really a macro; it's an identifier
+  /// that is expanded into a string literal during compilation, where
+  /// special rules are obeyed in the preprocessor to make it act a little
+  /// more like a macro. This is used to implement Microsoft's __LPREFIX
+  /// extension for __FUNCTION__.
+  bool IsTokenFakeMacro(const Token &Tok, bool MicrosoftExt) {
+    if (!MicrosoftExt) return false;
+    switch (Tok.getKind()) {
+      case tok::kw___FUNCTION__:
+        return true;
+      default:
+        return false;
+    }
+  }
+}
+
 /// Lex - Lex and return a token from this macro stream.
 ///
 void TokenLexer::Lex(Token &Tok) {
+  // Handle outputting the Microsoft __LPREFIX extension, if the
+  // MSLPrefix flag is set.
+  if (MSLPrefix && HandleMicrosoftLPrefix(Tok))
+    return;
+
   // Lexing off the end of the macro, pop this macro off the expansion stack.
   if (isAtEnd()) {
     // If this is a macro (not a token stream), mark the macro enabled now
@@ -383,6 +411,11 @@
   // Get the next token to return.
   Tok = Tokens[CurToken++];
 
+  // Check for fake macros. If this is a fake macro, mark it expanded.
+  if (IsTokenFakeMacro(Tok, PP.getLangOpts().MicrosoftExt)) {
+    Tok.setFlagValue(Token::ExpandedFakeMacro, true);
+  }
+
   bool TokenIsFromPaste = false;
 
   // If this token is followed by a token paste (##) operator, paste the tokens!
@@ -483,6 +516,34 @@
     if (BufPtr != &Buffer[LHSLen])   // Really, we want the chars in Buffer!
       memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
 
+    // If Microsoft extensions are enabled, special-case token pasting
+    // __FUNCTION__. L##__FUNCTION__ turns into __LPREFIX( __FUNCTION__)
+    if (PP.getLangOpts().MicrosoftExt) {
+      const bool isRHSFunction = RHS.isExpandedFakeMacro()
+        && RHS.getKind() == tok::kw___FUNCTION__;
+      if (isRHSFunction && LHSLen == 1 && Buffer[0] == 'L') {
+        // __LPREFIX( __FUNCTION__)
+        // For this expansion, we don't return a single token; it actually
+        // turns into four tokens. Paste the __LPREFIX token here,
+        // and set MSLPrefix to true. In Lex(), when this flag is set, we'll
+        // continue outputting this series of tokens rather than
+        // continuing to lex.
+        MSLPrefix = true;
+        MSLPrefixState = 0;
+        MSLPrefixRange.setBegin(Tok.getLocation());
+        MSLPrefixRange.setEnd(RHS.getLocation());
+
+        Tok.startToken();
+        Tok.setKind(tok::kw___LPREFIX);
+        Tok.setLength(9);
+        PP.CreateString("__LPREFIX", 9, Tok,
+                        MSLPrefixRange.getBegin(),
+                        MSLPrefixRange.getEnd());
+        ++CurToken;
+        return false;
+      }
+    }
+
     // Trim excess space.
     Buffer.resize(LHSLen+RHSLen);
 
@@ -646,6 +707,52 @@
   PP.HandleMicrosoftCommentPaste(Tok);
 }
 
+/// HandleMicrosoftLPrefix - In Microsoft compatibility mode, L##__FUNCTION__
+/// pastes to __LPREFIX( __FUNCTION__). This means it turns into multiple
+/// tokens. When MSLPrefix is true, we output this stream of tokens. If
+/// this returns true, the caller should immediately return the token.
+bool TokenLexer::HandleMicrosoftLPrefix(Token &Tok) {
+  assert(MSLPrefix && "Expected MSLPrefix to be set");
+
+  SourceLocation StartLoc = MSLPrefixRange.getBegin(),
+                 EndLoc = MSLPrefixRange.getEnd();
+  switch (MSLPrefixState++) {
+  case 0:
+    Tok.startToken();
+    Tok.setKind(tok::l_paren);
+    Tok.setLength(1);
+    PP.CreateString("(", 1, Tok, StartLoc, EndLoc);
+    return true;
+  case 1:
+    // We put a space before __FUNCTION__ to get __LPREFIX( __FUNCTION__)
+    // as Microsoft's compiler does
+    Tok.startToken();
+    Tok.setKind(tok::kw___FUNCTION__);
+    Tok.setLength(13);
+    PP.CreateString(" __FUNCTION__", 13, Tok, StartLoc, EndLoc);
+    return true;
+  case 2:
+    Tok.startToken();
+    Tok.setKind(tok::r_paren);
+    Tok.setLength(1);
+    PP.CreateString(")", 1, Tok, StartLoc, EndLoc);
+    return true;
+  case 3:
+    // Once we've pasted __LPREFIX( __FUNCTION__), look for a token
+    // paste (##) operator. If we find one, skip it. This for example:
+    // #define __ENDTEST(str1, str2) L##str1##str2
+    // #define _ENDTEST(str1, str2) __ENDTEST(str1, str2)
+    // #define ENDTEST _ENDTEST(__FUNCTION__, JUNCTION)
+    // ENDTEST should expand to __LPREFIX( __FUNCTION__)JUNCTION
+    if (Tokens[CurToken].is(tok::hashhash)) ++CurToken;
+    MSLPrefix = false;
+    return false;
+  default:
+    assert(false);
+    return false;
+  }
+}
+
 /// \brief If \arg loc is a file ID and points inside the current macro
 /// definition, returns the appropriate source location pointing at the
 /// macro expansion source location entry, otherwise it returns an invalid
Index: lib/Lex/LiteralSupport.cpp
===================================================================
--- lib/Lex/LiteralSupport.cpp	(revision 157363)
+++ lib/Lex/LiteralSupport.cpp	(working copy)
@@ -1090,6 +1090,15 @@
 
   // TODO: K&R warning: "traditional C rejects string constant concatenation"
 
+  // If the first token is __LPREFIX, parse the string literal as if it
+  // started with 'L', and skip the token. When the parser encounters
+  // __LPREFIX("string"), it passes us __LPREFIX "string" as two tokens.
+  if (Kind == tok::kw___LPREFIX) {
+    Kind = tok::wide_string_literal;
+    ++StringToks;
+    --NumStringToks;
+  }
+
   // Get the width in bytes of char/wchar_t/char16_t/char32_t
   CharByteWidth = getCharWidth(Kind, Target);
   assert((CharByteWidth & 7) == 0 && "Assumes character size is byte multiple");
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp	(revision 157363)
+++ 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"
@@ -1683,7 +1684,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:
@@ -1722,8 +1792,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/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp	(revision 157363)
+++ lib/Parse/ParseExpr.cpp	(working copy)
@@ -857,6 +857,9 @@
   case tok::utf32_string_literal:
     Res = ParseStringLiteralExpression(true);
     break;
+  case tok::kw___LPREFIX:
+    Res = ParseLPrefixExpression();
+    break;
   case tok::kw__Generic:   // primary-expression: generic-selection [C11 6.5.1]
     Res = ParseGenericSelectionExpression();
     break;
@@ -2429,3 +2432,63 @@
   tok::TokenKind Kind = Tok.getKind();
   return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind);
 }
+
+/// ParseLPrefixExpression - This is for a Microsoft expression.
+///         '__LPREFIX' '(' string-literal ')'
+///         '__LPREFIX' '(' __FUNCTION__ ')'
+ExprResult Parser::ParseLPrefixExpression() {
+  assert(Tok.getKind() == tok::kw___LPREFIX);
+
+  // MS extensions should be enabled or we should give an error.
+  // Still parse regularly, though.
+  if (!PP.getLangOpts().MicrosoftExt) {
+    Diag(Tok, diag::err_ms_extensions_expected_for_lprefix);
+  }
+
+  // Eat the __LPREFIX
+  Token LPrefixTok = Tok;
+  ConsumeToken();
+
+  // Expect a lparen
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen,
+                       "", tok::r_paren))
+    return ExprError();
+
+
+  ExprResult Res;
+  switch (Tok.getKind()) {
+    case tok::kw___FUNCTION__:
+      Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), Tok.getKind(),
+                                        &Actions.Context.WCharTy);
+      ConsumeToken();
+      break;
+    case tok::string_literal: {
+      // Pass the string literal parser __LPREFIX "string" without the
+      // parentheses. The string literal parser will treat __LPREFIX
+      // like 'L'.
+      SmallVector<Token, 4> StringToks;
+      StringToks.push_back(LPrefixTok);
+
+      do {
+        StringToks.push_back(Tok);
+        ConsumeStringToken();
+      } while (isTokenStringLiteral());
+
+      // Pass the set of string tokens, ready for concatenation, to the actions.
+      Res = Actions.ActOnStringLiteral(&StringToks[0], StringToks.size(), 0);
+      break;
+    }
+    default:
+      Diag(Tok, diag::err_lprefix_expected_string_literal);
+      SkipUntil(tok::r_paren);
+      Res = ExprError();
+      break;
+  }
+  
+  // Expect a rparen
+  if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen, ""))
+    return ExprError();
+
+  return Res;
+}
+
