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