summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--include/clang/Sema/Sema.h5
-rw-r--r--lib/Lex/LiteralSupport.cpp44
-rw-r--r--lib/Sema/SemaExpr.cpp25
-rw-r--r--lib/Sema/SemaLookup.cpp16
-rw-r--r--test/SemaCXX/imaginary-constants.cpp44
7 files changed, 41 insertions, 97 deletions
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 7e11939e6c..77db8993f0 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -173,6 +173,8 @@ def warn_char_constant_too_large : Warning<
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">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 6da5682a83..2013036d57 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -194,8 +194,6 @@ def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">,
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>;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e18995a1d2..4c69fb6420 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2946,8 +2946,6 @@ 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,
@@ -3072,8 +3070,7 @@ public:
ArrayRef<QualType> ArgTys,
bool AllowRaw,
bool AllowTemplate,
- bool AllowStringTemplate,
- bool DiagnoseMissing);
+ bool AllowStringTemplate);
bool isKnownName(StringRef name);
void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 1fead55e80..1e2cbde825 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -651,6 +651,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
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':
@@ -662,34 +665,35 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
break;
}
- // "i", "if", and "il" are user-defined suffixes in C++1y.
- if (s != ThisTokEnd || isImaginary) {
+ if (s != ThisTokEnd) {
// FIXME: Don't bother expanding UCNs if !tok.hasUCN().
expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd - SuffixBegin));
if (isValidUDSuffix(PP.getLangOpts(), UDSuffixBuf)) {
- if (!isImaginary) {
- // 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;
- }
+ // 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;
}
- 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;
- }
+ // 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, SuffixBegin - ThisTokBegin),
+ diag::ext_imaginary_constant);
}
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 83387c2132..759c82eeaa 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1609,9 +1609,8 @@ static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope,
LookupResult R(S, OpName, UDSuffixLoc, Sema::LookupOrdinaryName);
if (S.LookupLiteralOperator(Scope, R, llvm::makeArrayRef(ArgTy, Args.size()),
- /*AllowRaw*/ false, /*AllowTemplate*/ false,
- /*AllowStringTemplate*/ false,
- /*DiagnoseMissing*/ true) == Sema::LOLR_Error)
+ /*AllowRaw*/false, /*AllowTemplate*/false,
+ /*AllowStringTemplate*/false) == Sema::LOLR_Error)
return ExprError();
return S.BuildLiteralOperatorCall(R, OpNameInfo, Args, LitEndLoc);
@@ -1702,9 +1701,8 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);
switch (LookupLiteralOperator(UDLScope, R, ArgTy,
- /*AllowRaw*/ false, /*AllowTemplate*/ false,
- /*AllowStringTemplate*/ true,
- /*DiagnoseMissing*/ true)) {
+ /*AllowRaw*/false, /*AllowTemplate*/false,
+ /*AllowStringTemplate*/true)) {
case LOLR_Cooked: {
llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars());
@@ -1737,7 +1735,6 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
}
case LOLR_Raw:
case LOLR_Template:
- case LOLR_ErrorNoDiagnostic:
llvm_unreachable("unexpected literal operator lookup result");
case LOLR_Error:
return ExprError();
@@ -3360,15 +3357,11 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// literal or a cooked one.
LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);
switch (LookupLiteralOperator(UDLScope, R, CookedTy,
- /*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;
+ /*AllowRaw*/true, /*AllowTemplate*/true,
+ /*AllowStringTemplate*/false)) {
case LOLR_Error:
return ExprError();
+
case LOLR_Cooked: {
Expr *Lit;
if (Literal.isFloatingLiteral()) {
@@ -3584,12 +3577,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
}
// 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;
}
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 48f4a0251f..c97da740e4 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3066,7 +3066,7 @@ Sema::LiteralOperatorLookupResult
Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
ArrayRef<QualType> ArgTys,
bool AllowRaw, bool AllowTemplate,
- bool AllowStringTemplate, bool DiagnoseMissing) {
+ bool AllowStringTemplate) {
LookupName(R, S);
assert(R.getResultKind() != LookupResult::Ambiguous &&
"literal operator lookup can't be ambiguous");
@@ -3167,15 +3167,11 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
return LOLR_StringTemplate;
// Didn't find anything we could use.
- 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;
+ 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;
}
void ADLResult::insert(NamedDecl *New) {
diff --git a/test/SemaCXX/imaginary-constants.cpp b/test/SemaCXX/imaginary-constants.cpp
deleted file mode 100644
index bbff92755a..0000000000
--- a/test/SemaCXX/imaginary-constants.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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