<div dir="ltr">Sorry, fixed in r192140. Thanks!<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Oct 7, 2013 at 2:28 PM, jahanian <span dir="ltr"><<a href="mailto:fjahanian@apple.com" target="_blank">fjahanian@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">These tests are failing on a Windows buildbot.<div><br></div><div><pre style="font-family:'Courier New',courier,monotype,monospace">
<span>Failing Tests (2):
      Clang :: CXX/lex/lex.literal/lex.ext/p5.cpp
      Clang :: CXX/lex/lex.literal/lex.ext/p7.cpp</span></pre><div><br></div><div>- Fariborz</div><div><div class="h5"><div><br></div><div><div>On Oct 7, 2013, at 12:57 PM, Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>> wrote:</div>
<br><blockquote type="cite">Author: rsmith<br>Date: Mon Oct  7 14:57:58 2013<br>New Revision: 192128<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=192128&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=192128&view=rev</a><br>
Log:<br>Add support for WG21 N3599 (literal operator template for strings) as a GNU<br>extension. The GCC folks have decided to support this even though the standard<br>committee have not yet approved this feature.<br><br>
Patch by Hristo Venev!<br><br>Added:<br>    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p11.cpp<br>    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p12.cpp<br>Modified:<br>    cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>    cfe/trunk/include/clang/Sema/Sema.h<br>    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>    cfe/trunk/lib/Sema/SemaExpr.cpp<br>    cfe/trunk/lib/Sema/SemaLookup.cpp<br>
    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp<br>    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp<br><br>Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br>+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Oct  7 14:57:58 2013<br>
@@ -59,6 +59,8 @@ def GNUConditionalOmittedOperand : DiagG<br> def ConfigMacros : DiagGroup<"config-macros">;<br> def : DiagGroup<"ctor-dtor-privacy">;<br> def GNUDesignator : DiagGroup<"gnu-designator">;<br>
+def GNUStringLiteralOperatorTemplate :<br>+  DiagGroup<"gnu-string-literal-operator-template">;<br><br> def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;<br> def AbstractFinalClass : DiagGroup<"abstract-final-class">;<br>
@@ -561,6 +563,7 @@ def GNU : DiagGroup<"gnu", [GNUAlignofEx<br>                             GNUImaginaryConstant, GNULabelsAsValue,<br>                             RedeclaredClassMember, GNURedeclaredEnum,<br>
                             GNUStatementExpression, GNUStaticFloatInit,<br>+                            GNUStringLiteralOperatorTemplate,<br>                             GNUUnionCast, GNUVariableSizedTypeNotAtEnd,<br>                             ZeroLengthArray, GNUZeroLineDirective,<br>
                             GNUZeroVariadicMacroArguments]>;<br><br>Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct  7 14:57:58 2013<br>
@@ -2811,7 +2811,8 @@ def err_addr_ovl_no_qualifier : Error<<br> def err_ovl_no_viable_literal_operator : Error<<br>   "no matching literal operator for call to %0"<br>   "%select{| with argument of type %2| with arguments of types %2 and %3}1"<br>
-  "%select{| or 'const char *', and no matching literal operator template}4">;<br>+  "%select{| or 'const char *'}4"<br>+  "%select{|, and no matching literal operator template}5">;<br>
<br> // C++ Template Declarations<br> def err_template_param_shadow : Error<<br>@@ -5913,6 +5914,9 @@ def err_literal_operator_params : Error<<br>   "parameter declaration for literal operator %0 is not valid">;<br>
 def err_literal_operator_extern_c : Error<<br>   "literal operator must have C++ linkage">;<br>+def ext_string_literal_operator_template : ExtWarn<<br>+  "string literal operator templates are a GNU extension">,<br>
+  InGroup<GNUStringLiteralOperatorTemplate>;<br> def warn_user_literal_reserved : Warning<<br>   "user-defined literal suffixes not starting with '_' are reserved"<br>   "%select{; no literal will invoke this operator|}0">,<br>
<br>Modified: cfe/trunk/include/clang/Sema/Sema.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>+++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct  7 14:57:58 2013<br>@@ -2400,7 +2400,11 @@ public:<br>
     /// \brief The lookup found an overload set of literal operator templates,<br>     /// which expect the characters of the spelling of the literal token to be<br>     /// passed as a non-type template argument pack.<br>
-    LOLR_Template<br>+    LOLR_Template,<br>+    /// \brief The lookup found an overload set of literal operator templates,<br>+    /// which expect the character type and characters of the spelling of the<br>+    /// string literal token to be passed as template arguments.<br>
+    LOLR_StringTemplate<br>   };<br><br>   SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,<br>@@ -2467,7 +2471,9 @@ public:<br><br>   LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,<br>
                                                     ArrayRef<QualType> ArgTys,<br>-                                                    bool AllowRawAndTemplate);<br>+                                                    bool AllowRaw,<br>
+                                                    bool AllowTemplate,<br>+                                                    bool AllowStringTemplate);<br>   bool isKnownName(StringRef name);<br><br>   void ArgumentDependentLookup(DeclarationName Name, bool Operator,<br>
<br>Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct  7 14:57:58 2013<br>@@ -10917,11 +10917,12 @@ bool Sema::CheckLiteralOperatorDeclarati<br>
   if (!TpDecl)<br>     TpDecl = FnDecl->getPrimaryTemplate();<br><br>-  // template <char...> type operator "" name() is the only valid template<br>-  // signature, and the only valid signature with no parameters.<br>
+  // template <char...> type operator "" name() and<br>+  // template <class T, T...> type operator "" name() are the only valid<br>+  // template signatures, and the only valid signatures with no parameters.<br>
   if (TpDecl) {<br>     if (FnDecl->param_size() == 0) {<br>-      // Must have only one template parameter<br>+      // Must have one or two template parameters<br>       TemplateParameterList *Params = TpDecl->getTemplateParameters();<br>
       if (Params->size() == 1) {<br>         NonTypeTemplateParmDecl *PmDecl =<br>@@ -10931,6 +10932,27 @@ bool Sema::CheckLiteralOperatorDeclarati<br>         if (PmDecl && PmDecl->isTemplateParameterPack() &&<br>
             Context.hasSameType(PmDecl->getType(), Context.CharTy))<br>           Valid = true;<br>+      } else if (Params->size() == 2) {<br>+        TemplateTypeParmDecl *PmType =<br>+          dyn_cast<TemplateTypeParmDecl>(Params->getParam(0));<br>
+        NonTypeTemplateParmDecl *PmArgs =<br>+          dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(1));<br>+<br>+        // The second template parameter must be a parameter pack with the<br>+        // first template parameter as its type.<br>
+        if (PmType && PmArgs &&<br>+            !PmType->isTemplateParameterPack() &&<br>+            PmArgs->isTemplateParameterPack()) {<br>+          const TemplateTypeParmType *TArgs =<br>
+            PmArgs->getType()->getAs<TemplateTypeParmType>();<br>+          if (TArgs && TArgs->getDepth() == PmType->getDepth() &&<br>+              TArgs->getIndex() == PmType->getIndex()) {<br>
+            Valid = true;<br>+            if (ActiveTemplateInstantiations.empty())<br>+              Diag(FnDecl->getLocation(),<br>+                   diag::ext_string_literal_operator_template);<br>+          }<br>
+        }<br>       }<br>     }<br>   } else if (FnDecl->param_size()) {<br><br>Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Oct  7 14:57:58 2013<br>@@ -1461,7 +1461,8 @@ static ExprResult BuildCookedLiteralOper<br>
<br>   LookupResult R(S, OpName, UDSuffixLoc, Sema::LookupOrdinaryName);<br>   if (S.LookupLiteralOperator(Scope, R, llvm::makeArrayRef(ArgTy, Args.size()),<br>-                              /*AllowRawAndTemplate*/false) == Sema::LOLR_Error)<br>
+                              /*AllowRaw*/false, /*AllowTemplate*/false,<br>+                              /*AllowStringTemplate*/false) == Sema::LOLR_Error)<br>     return ExprError();<br><br>   return S.BuildLiteralOperatorCall(R, OpNameInfo, Args, LitEndLoc);<br>
@@ -1486,36 +1487,34 @@ Sema::ActOnStringLiteral(const Token *St<br>   for (unsigned i = 0; i != NumStringToks; ++i)<br>     StringTokLocs.push_back(StringToks[i].getLocation());<br><br>-  QualType StrTy = Context.CharTy;<br>
-  if (Literal.isWide())<br>-    StrTy = Context.getWideCharType();<br>-  else if (Literal.isUTF16())<br>-    StrTy = Context.Char16Ty;<br>-  else if (Literal.isUTF32())<br>-    StrTy = Context.Char32Ty;<br>-  else if (Literal.isPascal())<br>
-    StrTy = Context.UnsignedCharTy;<br>-<br>+  QualType CharTy = Context.CharTy;<br>   StringLiteral::StringKind Kind = StringLiteral::Ascii;<br>-  if (Literal.isWide())<br>+  if (Literal.isWide()) {<br>+    CharTy = Context.getWideCharType();<br>
     Kind = StringLiteral::Wide;<br>-  else if (Literal.isUTF8())<br>+  } else if (Literal.isUTF8()) {<br>     Kind = StringLiteral::UTF8;<br>-  else if (Literal.isUTF16())<br>+  } else if (Literal.isUTF16()) {<br>+    CharTy = Context.Char16Ty;<br>
     Kind = StringLiteral::UTF16;<br>-  else if (Literal.isUTF32())<br>+  } else if (Literal.isUTF32()) {<br>+    CharTy = Context.Char32Ty;<br>     Kind = StringLiteral::UTF32;<br>+  } else if (Literal.isPascal()) {<br>+    CharTy = Context.UnsignedCharTy;<br>
+  }<br><br>+  QualType CharTyConst = CharTy;<br>   // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).<br>   if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)<br>-    StrTy.addConst();<br>
+    CharTyConst.addConst();<br><br>   // Get an array type for the string, according to C99 6.4.5.  This includes<br>   // the nul terminator character as well as the string length for pascal<br>   // strings.<br>-  StrTy = Context.getConstantArrayType(StrTy,<br>
+  QualType StrTy = Context.getConstantArrayType(CharTyConst,<br>                                  llvm::APInt(32, Literal.GetNumStringChars()+1),<br>-                                       ArrayType::Normal, 0);<br>+                                 ArrayType::Normal, 0);<br>
<br>   // Pass &StringTokLocs[0], StringTokLocs.size() to factory!<br>   StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(),<br>@@ -1538,12 +1537,57 @@ Sema::ActOnStringLiteral(const Token *St<br>
   // C++11 [lex.ext]p5: The literal L is treated as a call of the form<br>   //   operator "" X (str, len)<br>   QualType SizeType = Context.getSizeType();<br>-  llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars());<br>
-  IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType,<br>-                                                  StringTokLocs[0]);<br>-  Expr *Args[] = { Lit, LenArg };<br>-  return BuildCookedLiteralOperatorCall(*this, UDLScope, UDSuffix, UDSuffixLoc,<br>
-                                        Args, StringTokLocs.back());<br>+<br>+  DeclarationName OpName =<br>+    Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);<br>+  DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc);<br>
+  OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc);<br>+<br>+  QualType ArgTy[] = {<br>+    Context.getArrayDecayedType(StrTy), SizeType<br>+  };<br>+<br>+  LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);<br>
+  switch (LookupLiteralOperator(UDLScope, R, ArgTy,<br>+                                /*AllowRaw*/false, /*AllowTemplate*/false,<br>+                                /*AllowStringTemplate*/true)) {<br>+<br>+  case LOLR_Cooked: {<br>
+    llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars());<br>+    IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType,<br>+                                                    StringTokLocs[0]);<br>
+    Expr *Args[] = { Lit, LenArg };<br>+<br>+    return BuildLiteralOperatorCall(R, OpNameInfo, Args, StringTokLocs.back());<br>+  }<br>+<br>+  case LOLR_StringTemplate: {<br>+    TemplateArgumentListInfo ExplicitArgs;<br>
+<br>+    unsigned CharBits = Context.getIntWidth(CharTy);<br>+    bool CharIsUnsigned = CharTy->isUnsignedIntegerType();<br>+    llvm::APSInt Value(CharBits, CharIsUnsigned);<br>+<br>+    TemplateArgument TypeArg(CharTy);<br>
+    TemplateArgumentLocInfo TypeArgInfo(Context.getTrivialTypeSourceInfo(CharTy));<br>+    ExplicitArgs.addArgument(TemplateArgumentLoc(TypeArg, TypeArgInfo));<br>+<br>+    for (unsigned I = 0, N = Lit->getLength(); I != N; ++I) {<br>
+      Value = Lit->getCodeUnit(I);<br>+      TemplateArgument Arg(Context, Value, CharTy);<br>+      TemplateArgumentLocInfo ArgInfo;<br>+      ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo));<br>+    }<br>
+    return BuildLiteralOperatorCall(R, OpNameInfo, None, StringTokLocs.back(),<br>+                                    &ExplicitArgs);<br>+  }<br>+  case LOLR_Raw:<br>+  case LOLR_Template:<br>+    llvm_unreachable("unexpected literal operator lookup result");<br>
+  case LOLR_Error:<br>+    return ExprError();<br>+  }<br>+  llvm_unreachable("unexpected literal operator lookup result");<br> }<br><br> ExprResult<br>@@ -2942,11 +2986,14 @@ ExprResult Sema::ActOnNumericConstant(co<br>
     DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc);<br>     OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc);<br><br>+    SourceLocation TokLoc = Tok.getLocation();<br>+<br>     // Perform literal operator lookup to determine if we're building a raw<br>
     // literal or a cooked one.<br>     LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);<br>     switch (LookupLiteralOperator(UDLScope, R, CookedTy,<br>-                                  /*AllowRawAndTemplate*/true)) {<br>
+                                  /*AllowRaw*/true, /*AllowTemplate*/true,<br>+                                  /*AllowStringTemplate*/false)) {<br>     case LOLR_Error:<br>       return ExprError();<br><br>@@ -2961,15 +3008,13 @@ ExprResult Sema::ActOnNumericConstant(co<br>
         Lit = IntegerLiteral::Create(Context, ResultVal, CookedTy,<br>                                      Tok.getLocation());<br>       }<br>-      return BuildLiteralOperatorCall(R, OpNameInfo, Lit,<br>-                                      Tok.getLocation());<br>
+      return BuildLiteralOperatorCall(R, OpNameInfo, Lit, TokLoc);<br>     }<br><br>     case LOLR_Raw: {<br>       // C++11 [lit.ext]p3, p4: If S contains a raw literal operator, the<br>       // literal is treated as a call of the form<br>
       //   operator "" X ("n")<br>-      SourceLocation TokLoc = Tok.getLocation();<br>       unsigned Length = Literal.getUDSuffixOffset();<br>       QualType StrTy = Context.getConstantArrayType(<br>
           Context.CharTy.withConst(), llvm::APInt(32, Length + 1),<br>@@ -2980,7 +3025,7 @@ ExprResult Sema::ActOnNumericConstant(co<br>       return BuildLiteralOperatorCall(R, OpNameInfo, Lit, TokLoc);<br>     }<br><br>
-    case LOLR_Template:<br>+    case LOLR_Template: {<br>       // C++11 [lit.ext]p3, p4: Otherwise (S contains a literal operator<br>       // template), L is treated as a call fo the form<br>       //   operator "" X <'c1', 'c2', ... 'ck'>()<br>
@@ -2995,11 +3040,12 @@ ExprResult Sema::ActOnNumericConstant(co<br>         TemplateArgumentLocInfo ArgInfo;<br>         ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo));<br>       }<br>-      return BuildLiteralOperatorCall(R, OpNameInfo, None, Tok.getLocation(),<br>
+      return BuildLiteralOperatorCall(R, OpNameInfo, None, TokLoc,<br>                                       &ExplicitArgs);<br>     }<br>-<br>-    llvm_unreachable("unexpected literal operator lookup result");<br>
+    case LOLR_StringTemplate:<br>+      llvm_unreachable("unexpected literal operator lookup result");<br>+    }<br>   }<br><br>   Expr *Res;<br><br>Modified: cfe/trunk/lib/Sema/SemaLookup.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)<br>+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Oct  7 14:57:58 2013<br>@@ -2711,7 +2711,8 @@ CXXDestructorDecl *Sema::LookupDestructo<br>
 Sema::LiteralOperatorLookupResult<br> Sema::LookupLiteralOperator(Scope *S, LookupResult &R,<br>                             ArrayRef<QualType> ArgTys,<br>-                            bool AllowRawAndTemplate) {<br>
+                            bool AllowRaw, bool AllowTemplate,<br>+                            bool AllowStringTemplate) {<br>   LookupName(R, S);<br>   assert(R.getResultKind() != LookupResult::Ambiguous &&<br>          "literal operator lookup can't be ambiguous");<br>
@@ -2719,8 +2720,9 @@ Sema::LookupLiteralOperator(Scope *S, Lo<br>   // Filter the lookup results appropriately.<br>   LookupResult::Filter F = R.makeFilter();<br><br>-  bool FoundTemplate = false;<br>   bool FoundRaw = false;<br>
+  bool FoundTemplate = false;<br>+  bool FoundStringTemplate = false;<br>   bool FoundExactMatch = false;<br><br>   while (F.hasNext()) {<br>@@ -2728,16 +2730,17 @@ Sema::LookupLiteralOperator(Scope *S, Lo<br>     if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))<br>
       D = USD->getTargetDecl();<br><br>-    bool IsTemplate = isa<FunctionTemplateDecl>(D);<br>-    bool IsRaw = false;<br>-    bool IsExactMatch = false;<br>-<br>     // If the declaration we found is invalid, skip it.<br>
     if (D->isInvalidDecl()) {<br>       F.erase();<br>       continue;<br>     }<br><br>+    bool IsRaw = false;<br>+    bool IsTemplate = false;<br>+    bool IsStringTemplate = false;<br>+    bool IsExactMatch = false;<br>
+<br>     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {<br>       if (FD->getNumParams() == 1 &&<br>           FD->getParamDecl(0)->getType()->getAs<PointerType>())<br>@@ -2753,19 +2756,31 @@ Sema::LookupLiteralOperator(Scope *S, Lo<br>
         }<br>       }<br>     }<br>+    if (FunctionTemplateDecl *FD = dyn_cast<FunctionTemplateDecl>(D)) {<br>+      TemplateParameterList *Params = FD->getTemplateParameters();<br>+      if (Params->size() == 1)<br>
+        IsTemplate = true;<br>+      else<br>+        IsStringTemplate = true;<br>+    }<br><br>     if (IsExactMatch) {<br>       FoundExactMatch = true;<br>-      AllowRawAndTemplate = false;<br>-      if (FoundRaw || FoundTemplate) {<br>
+      AllowRaw = false;<br>+      AllowTemplate = false;<br>+      AllowStringTemplate = false;<br>+      if (FoundRaw || FoundTemplate || FoundStringTemplate) {<br>         // Go through again and remove the raw and template decls we've<br>
         // already found.<br>         F.restart();<br>-        FoundRaw = FoundTemplate = false;<br>+        FoundRaw = FoundTemplate = FoundStringTemplate = false;<br>       }<br>-    } else if (AllowRawAndTemplate && (IsTemplate || IsRaw)) {<br>
-      FoundTemplate |= IsTemplate;<br>-      FoundRaw |= IsRaw;<br>+    } else if (AllowRaw && IsRaw) {<br>+      FoundRaw = true;<br>+    } else if (AllowTemplate && IsTemplate) {<br>+      FoundTemplate = true;<br>
+    } else if (AllowStringTemplate && IsStringTemplate) {<br>+      FoundStringTemplate = true;<br>     } else {<br>       F.erase();<br>     }<br>@@ -2800,10 +2815,14 @@ Sema::LookupLiteralOperator(Scope *S, Lo<br>
   if (FoundTemplate)<br>     return LOLR_Template;<br><br>+  if (FoundStringTemplate)<br>+    return LOLR_StringTemplate;<br>+<br>   // Didn't find anything we could use.<br>   Diag(R.getNameLoc(), diag::err_ovl_no_viable_literal_operator)<br>
     << R.getLookupName() << (int)ArgTys.size() << ArgTys[0]<br>-    << (ArgTys.size() == 2 ? ArgTys[1] : QualType()) << AllowRawAndTemplate;<br>+    << (ArgTys.size() == 2 ? ArgTys[1] : QualType()) << AllowRaw<br>
+    << (AllowTemplate || AllowStringTemplate);<br>   return LOLR_Error;<br> }<br><br><br>Added: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p11.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p11.cpp?rev=192128&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p11.cpp?rev=192128&view=auto</a><br>
==============================================================================<br>--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p11.cpp (added)<br>+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p11.cpp Mon Oct  7 14:57:58 2013<br>
@@ -0,0 +1,22 @@<br>+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s<br>+<br>+using size_t = decltype(sizeof(int));<br>+<br>+template<typename T, typename U> struct same_type;<br>+template<typename T> struct same_type<T, T> {};<br>
+template<typename T> using X = T;<br>+template<typename CharT, X<CharT>...><br>+int operator "" _x(); // expected-warning {{string literal operator templates are a GNU extension}}<br>+template<char...><br>
+double operator "" _x();<br>+<br>+auto a="string"_x;<br>+auto b=42_x;<br>+same_type<decltype(a), int> test_a;<br>+same_type<decltype(b), double> test_b;<br>+<br>+char operator "" _x(const char *begin, size_t size);<br>
+auto c="string"_x;<br>+auto d=L"string"_x;<br>+same_type<decltype(c), char> test_c;<br>+same_type<decltype(d), int> test_d;<br><br>Added: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p12.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p12.cpp?rev=192128&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p12.cpp?rev=192128&view=auto</a><br>
==============================================================================<br>--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p12.cpp (added)<br>+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p12.cpp Mon Oct  7 14:57:58 2013<br>
@@ -0,0 +1,21 @@<br>+// RUN: %clang_cc1 -std=gnu++11 -verify %s<br>+<br>+template<typename T, T... cs> struct check; // expected-note {{template is declared here}} expected-note {{template is declared here}}<br>+template<><br>
+struct check<char, 34, -47, -126, -48, -75, -47, -127, -47, -126, 32, -16, -112, -128, -128>{};<br>+template<><br>+struct check<char16_t, 34, 1090, 1077, 1089, 1090, 32, 55296, 56320>{};<br>+template<><br>
+struct check<char32_t, 34, 1090, 1077, 1089, 1090, 32, 65536>{};<br>+template<typename T, T... str> int operator""_x() { // #1 expected-warning {{string literal operator templates are a GNU extension}}<br>
+    check<T, str...> chars; // expected-error {{implicit instantiation of undefined template 'check<char, 't', 'e', 's', 't'>'}} expected-error {{implicit instantiation of undefined template 'check<char32_t, 34, 1090, 1077, 1089, 1090, 95, 65536>'}}<br>
+    return 1;<br>+}<br>+void *operator""_x(const char*); // #2<br>+void *a = 123_x; // ok, calls #2<br>+int b = u8"\"теѠт ð €€"_x; // ok, calls #1<br>+int c = u8R"("теѠт ð €€)"_x; // ok, calls #1<br>
+int d = "test"_x; // expected-note {{in instantiation of function template specialization 'operator "" _x<char, 't', 'e', 's', 't'>' requested here}}<br>+int e = uR"("теѠт ð €€)"_x;<br>
+int f = UR"("теѠт ð €€)"_x;<br>+int g = UR"("теѠт_ð €€)"_x; // expected-note {{in instantiation of function template specialization 'operator "" _x<char32_t, 34, 1090, 1077, 1089, 1090, 95, 65536>' requested here}}<br>
<br>Modified: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp (original)<br>+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp Mon Oct  7 14:57:58 2013<br>
@@ -6,7 +6,7 @@ int &operator "" _x1 (const char *);<br> double &operator "" _x1 (const char *, size_t);<br> double &i1 = "foo"_x1;<br> double &i2 = u8"foo"_x1;<br>-double &i3 = L"foo"_x1; // expected-error {{no matching literal operator}}<br>
+double &i3 = L"foo"_x1; // expected-error {{no matching literal operator for call to 'operator "" _x1' with arguments of types 'const wchar_t *' and 'unsigned long'}}<br><br>
 char &operator "" _x1(const wchar_t *, size_t);<br> char &i4 = L"foo"_x1; // ok<br><br>Modified: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp?rev=192128&r1=192127&r2=192128&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp?rev=192128&r1=192127&r2=192128&view=diff</a><br>
==============================================================================<br>--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp (original)<br>+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp Mon Oct  7 14:57:58 2013<br>
@@ -17,7 +17,7 @@ int main() {<br>   auto v1 = 1.2_w;    // calls operator "" _w(1.2L)<br>   auto v2 = u"one"_w; // calls operator "" _w(u"one", 3)<br>   auto v3 = 12_w;     // calls operator "" _w("12")<br>
-  "two"_w;            // expected-error {{no matching literal operator}}<br>+  "two"_w;            // expected-error {{no matching literal operator for call to 'operator "" _w' with arguments of types 'const char *' and 'unsigned long'}}<br>
<br>   same_type<decltype(v1), long double> test1;<br>   same_type<decltype(v2), std::string> test2;<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br></blockquote></div><br></div></div></div></div></blockquote></div><br></div>