r303694 - Sema: allow imaginary constants via GNU extension if UDL overloads not present.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue May 23 14:47:59 PDT 2017


On 23 May 2017 at 14:41, Tim Northover via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: tnorthover
> Date: Tue May 23 16:41:49 2017
> New Revision: 303694
>
> URL: http://llvm.org/viewvc/llvm-project?rev=303694&view=rev
> Log:
> Sema: allow imaginary constants via GNU extension if UDL overloads not
> present.
>
> C++14 added user-defined literal support for complex numbers so that you
> can
> write something like "complex<double> val = 2i". However, there is an
> existing
> GNU extension supporting this syntax and interpreting the result as a
> _Complex
> type.
>
> This changes parsing so that such literals are interpreted in terms of
> C++14's
> operators if an overload is present but otherwise falls back to the
> original
> GNU extension.
>
> Added:
>     cfe/trunk/test/SemaCXX/imaginary-constants.cpp
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/lib/Lex/LiteralSupport.cpp
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/lib/Sema/SemaLookup.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticLexKinds.td?rev=303694&r1=303693&r2=303694&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue May 23
> 16:41:49 2017
> @@ -173,8 +173,6 @@ def warn_char_constant_too_large : Warni
>  def err_multichar_utf_character_literal : Error<
>    "Unicode character literals may not contain multiple characters">;
>  def err_exponent_has_no_digits : Error<"exponent has no digits">;
> -def ext_imaginary_constant : Extension<
> -  "imaginary constants are a GNU extension">,
> InGroup<GNUImaginaryConstant>;
>  def err_hex_constant_requires : Error<
>    "hexadecimal floating %select{constant|literal}0 requires "
>    "%select{an exponent|a significand}1">;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticSemaKinds.td?rev=303694&r1=303693&r2=303694&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 23
> 16:41:49 2017
> @@ -194,6 +194,8 @@ def warn_duplicate_declspec : Warning<"d
>    InGroup<DuplicateDeclSpecifier>;
>  def ext_plain_complex : ExtWarn<
>    "plain '_Complex' requires a type specifier; assuming '_Complex
> double'">;
> +def ext_imaginary_constant : Extension<
> +  "imaginary constants are a GNU extension">,
> InGroup<GNUImaginaryConstant>;
>  def ext_integer_complex : Extension<
>    "complex integer types are a GNU extension">,
> InGroup<GNUComplexInteger>;
>
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Sema.h?rev=303694&r1=303693&r2=303694&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue May 23 16:41:49 2017
> @@ -2946,6 +2946,8 @@ public:
>    enum LiteralOperatorLookupResult {
>      /// \brief The lookup resulted in an error.
>      LOLR_Error,
> +    /// \brief The lookup found no match but no diagnostic was issued.
> +    LOLR_ErrorNoDiagnostic,
>      /// \brief The lookup found a single 'cooked' literal operator, which
>      /// expects a normal literal to be built and passed to it.
>      LOLR_Cooked,
> @@ -3070,7 +3072,8 @@ public:
>                                                      ArrayRef<QualType>
> ArgTys,
>                                                      bool AllowRaw,
>                                                      bool AllowTemplate,
> -                                                    bool
> AllowStringTemplate);
> +                                                    bool
> AllowStringTemplate,
> +                                                    bool DiagnoseMissing);
>    bool isKnownName(StringRef name);
>
>    void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
>
> Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/
> LiteralSupport.cpp?rev=303694&r1=303693&r2=303694&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
> +++ cfe/trunk/lib/Lex/LiteralSupport.cpp Tue May 23 16:41:49 2017
> @@ -652,9 +652,6 @@ NumericLiteralParser::NumericLiteralPars
>            break;
>          }
>        }
> -      // "i", "if", and "il" are user-defined suffixes in C++1y.
> -      if (*s == 'i' && PP.getLangOpts().CPlusPlus14)
> -        break;
>        // fall through.
>      case 'j':
>      case 'J':
> @@ -667,36 +664,34 @@ NumericLiteralParser::NumericLiteralPars
>      break;
>    }
>
> -  if (s != ThisTokEnd) {
> +  // "i", "if", and "il" are user-defined suffixes in C++1y.
> +  if (s != ThisTokEnd || isImaginary) {
>      // FIXME: Don't bother expanding UCNs if !tok.hasUCN().
>      expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd -
> SuffixBegin));
>      if (isValidUDSuffix(PP.getLangOpts(), UDSuffixBuf)) {
> -      // Any suffix pieces we might have parsed are actually part of the
> -      // ud-suffix.
> -      isLong = false;
> -      isUnsigned = false;
> -      isLongLong = false;
> -      isFloat = false;
> -      isHalf = false;
> -      isImaginary = false;
> -      MicrosoftInteger = 0;
> +      if (!isImaginary) {
>

Shouldn't this be "if (s != ThisTokEnd)"? (That is, if this was not a valid
builtin suffix, reset the suffix information.)

+        // Any suffix pieces we might have parsed are actually part of the
> +        // ud-suffix.
> +        isLong = false;
> +        isUnsigned = false;
> +        isLongLong = false;
> +        isFloat = false;
> +        isHalf = false;
> +        isImaginary = false;
> +        MicrosoftInteger = 0;
> +      }
>
>        saw_ud_suffix = true;
>        return;
>      }
>
> -    // Report an error if there are any.
> -    PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, SuffixBegin -
> ThisTokBegin),
> -            diag::err_invalid_suffix_constant)
> -      << StringRef(SuffixBegin, ThisTokEnd-SuffixBegin) << isFPConstant;
> -    hadError = true;
> -    return;
> -  }
> -
> -  if (isImaginary) {
> -    PP.Diag(PP.AdvanceToTokenCharacter(TokLoc,
> -                                       ImaginarySuffixLoc - ThisTokBegin),
> -            diag::ext_imaginary_constant);
> +    if (s != ThisTokEnd) {
> +      // Report an error if there are any.
> +      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, SuffixBegin -
> ThisTokBegin),
> +              diag::err_invalid_suffix_constant)
> +          << StringRef(SuffixBegin, ThisTokEnd - SuffixBegin) <<
> isFPConstant;
> +      hadError = true;
> +    }
>    }
>  }
>
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaExpr.cpp?rev=303694&r1=303693&r2=303694&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue May 23 16:41:49 2017
> @@ -1599,8 +1599,9 @@ static ExprResult BuildCookedLiteralOper
>
>    LookupResult R(S, OpName, UDSuffixLoc, Sema::LookupOrdinaryName);
>    if (S.LookupLiteralOperator(Scope, R, llvm::makeArrayRef(ArgTy,
> Args.size()),
> -                              /*AllowRaw*/false, /*AllowTemplate*/false,
> -                              /*AllowStringTemplate*/false) ==
> Sema::LOLR_Error)
> +                              /*AllowRaw*/ false, /*AllowTemplate*/ false,
> +                              /*AllowStringTemplate*/ false,
> +                              /*DiagnoseMissing*/ true) ==
> Sema::LOLR_Error)
>      return ExprError();
>
>    return S.BuildLiteralOperatorCall(R, OpNameInfo, Args, LitEndLoc);
> @@ -1691,8 +1692,9 @@ Sema::ActOnStringLiteral(ArrayRef<Token>
>
>    LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);
>    switch (LookupLiteralOperator(UDLScope, R, ArgTy,
> -                                /*AllowRaw*/false, /*AllowTemplate*/false,
> -                                /*AllowStringTemplate*/true)) {
> +                                /*AllowRaw*/ false, /*AllowTemplate*/
> false,
> +                                /*AllowStringTemplate*/ true,
> +                                /*DiagnoseMissing*/ true)) {
>
>    case LOLR_Cooked: {
>      llvm::APInt Len(Context.getIntWidth(SizeType),
> Literal.GetNumStringChars());
> @@ -1725,6 +1727,7 @@ Sema::ActOnStringLiteral(ArrayRef<Token>
>    }
>    case LOLR_Raw:
>    case LOLR_Template:
> +  case LOLR_ErrorNoDiagnostic:
>      llvm_unreachable("unexpected literal operator lookup result");
>    case LOLR_Error:
>      return ExprError();
> @@ -3347,11 +3350,15 @@ ExprResult Sema::ActOnNumericConstant(co
>      // literal or a cooked one.
>      LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);
>      switch (LookupLiteralOperator(UDLScope, R, CookedTy,
> -                                  /*AllowRaw*/true, /*AllowTemplate*/true,
> -                                  /*AllowStringTemplate*/false)) {
> +                                  /*AllowRaw*/ true, /*AllowTemplate*/
> true,
> +                                  /*AllowStringTemplate*/ false,
> +                                  /*DiagnoseMissing*/
> !Literal.isImaginary)) {
> +    case LOLR_ErrorNoDiagnostic:
> +      // Lookup failure for imaginary constants isn't fatal, there's
> still the
> +      // GNU extension producing _Complex types.
> +      break;
>      case LOLR_Error:
>        return ExprError();
> -
>      case LOLR_Cooked: {
>        Expr *Lit;
>        if (Literal.isFloatingLiteral()) {
> @@ -3567,10 +3574,12 @@ ExprResult Sema::ActOnNumericConstant(co
>    }
>
>    // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
> -  if (Literal.isImaginary)
> +  if (Literal.isImaginary) {
>      Res = new (Context) ImaginaryLiteral(Res,
>                                          Context.getComplexType(Res->
> getType()));
>
> +    Diag(Tok.getLocation(), diag::ext_imaginary_constant);
> +  }
>    return Res;
>  }
>
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaLookup.cpp?rev=303694&r1=303693&r2=303694&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue May 23 16:41:49 2017
> @@ -3066,7 +3066,7 @@ Sema::LiteralOperatorLookupResult
>  Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
>                              ArrayRef<QualType> ArgTys,
>                              bool AllowRaw, bool AllowTemplate,
> -                            bool AllowStringTemplate) {
> +                            bool AllowStringTemplate, bool
> DiagnoseMissing) {
>    LookupName(R, S);
>    assert(R.getResultKind() != LookupResult::Ambiguous &&
>           "literal operator lookup can't be ambiguous");
> @@ -3167,11 +3167,15 @@ Sema::LookupLiteralOperator(Scope *S, Lo
>      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()) << AllowRaw
> -    << (AllowTemplate || AllowStringTemplate);
> -  return LOLR_Error;
> +  if (DiagnoseMissing) {
> +    Diag(R.getNameLoc(), diag::err_ovl_no_viable_literal_operator)
> +        << R.getLookupName() << (int)ArgTys.size() << ArgTys[0]
> +        << (ArgTys.size() == 2 ? ArgTys[1] : QualType()) << AllowRaw
> +        << (AllowTemplate || AllowStringTemplate);
> +    return LOLR_Error;
> +  }
> +
> +  return LOLR_ErrorNoDiagnostic;
>  }
>
>  void ADLResult::insert(NamedDecl *New) {
>
> Added: cfe/trunk/test/SemaCXX/imaginary-constants.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/imaginary-constants.cpp?rev=303694&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/imaginary-constants.cpp (added)
> +++ cfe/trunk/test/SemaCXX/imaginary-constants.cpp Tue May 23 16:41:49
> 2017
> @@ -0,0 +1,44 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=gnu++98
> +// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=c++11
> +// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=c++14
> -DCXX14=1
> +
> +// expected-no-diagnostics
> +
> +#ifndef HEADER
> +#define HEADER
> +
> +_Complex int val1 = 2i;
> +_Complex long val2 = 2il;
> +_Complex long long val3 = 2ill;
> +_Complex float val4 = 2.0if;
> +_Complex double val5 = 2.0i;
> +_Complex long double val6 = 2.0il;
> +
> +#if CXX14
> +
> +#pragma clang system_header
> +
> +namespace std {
> +  template<typename T> struct complex {};
> +  complex<float> operator""if(unsigned long long);
> +  complex<float> operator""if(long double);
> +
> +  complex<double> operator"" i(unsigned long long);
> +  complex<double> operator"" i(long double);
> +
> +  complex<long double> operator"" il(unsigned long long);
> +  complex<long double> operator"" il(long double);
> +}
> +
> +using namespace std;
> +
> +complex<float> f1 = 2.0if;
> +complex<float> f2 = 2if;
> +complex<double> d1 = 2.0i;
> +complex<double> d2 = 2i;
> +complex<long double> l1 = 2.0il;
> +complex<long double> l2 = 2il;
> +
> +#endif
> +
> +#endif
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170523/ffe04ebb/attachment-0001.html>


More information about the cfe-commits mailing list