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