<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>