aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-03-08 08:45:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-03-08 08:45:32 +0000
commitb453ad3214d00acc51c9aa702c76c58354d84b84 (patch)
treefbf7b0f3c7bf20b921b60a43a544a87c8968cc05 /lib/Sema/SemaExpr.cpp
parentaae1d8bd6f2482e0bf13a29d5b0cb7639080974d (diff)
Add support for cooked forms of user-defined-integer-literal and
user-defined-floating-literal. Support for raw forms of these literals to follow. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152302 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp95
1 files changed, 67 insertions, 28 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f82ff4395d..c1ce02eeea 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2437,6 +2437,38 @@ ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
Context.IntTy, Loc));
}
+static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
+ QualType Ty, SourceLocation Loc) {
+ const llvm::fltSemantics &Format = S.Context.getFloatTypeSemantics(Ty);
+
+ using llvm::APFloat;
+ APFloat Val(Format);
+
+ APFloat::opStatus result = Literal.GetFloatValue(Val);
+
+ // Overflow is always an error, but underflow is only an error if
+ // we underflowed to zero (APFloat reports denormals as underflow).
+ if ((result & APFloat::opOverflow) ||
+ ((result & APFloat::opUnderflow) && Val.isZero())) {
+ unsigned diagnostic;
+ SmallString<20> buffer;
+ if (result & APFloat::opOverflow) {
+ diagnostic = diag::warn_float_overflow;
+ APFloat::getLargest(Format).toString(buffer);
+ } else {
+ diagnostic = diag::warn_float_underflow;
+ APFloat::getSmallest(Format).toString(buffer);
+ }
+
+ S.Diag(Loc, diagnostic)
+ << Ty
+ << StringRef(buffer.data(), buffer.size());
+ }
+
+ bool isExact = (result == APFloat::opOK);
+ return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc);
+}
+
ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// Fast path for a single digit (which is quite common). A single digit
// cannot have a trigraph, escaped newline, radix prefix, or type suffix.
@@ -2461,6 +2493,40 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
if (Literal.hadError)
return ExprError();
+ if (Literal.hasUDSuffix()) {
+ // We're building a user-defined literal.
+ IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
+ SourceLocation UDSuffixLoc =
+ getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset());
+
+ // FIXME: Perform literal operator lookup now, and build a raw literal if
+ // there is no usable operator.
+
+ QualType Ty;
+ Expr *Lit;
+ if (Literal.isFloatingLiteral()) {
+ // C++11 [lex.ext]p4: If S contains a literal operator with parameter type
+ // long double, the literal is treated as a call of the form
+ // operator "" X (f L)
+ Lit = BuildFloatingLiteral(*this, Literal, Context.LongDoubleTy,
+ Tok.getLocation());
+ } else {
+ // C++11 [lex.ext]p3: If S contains a literal operator with parameter type
+ // unsigned long long, the literal is treated as a call of the form
+ // operator "" X (n ULL)
+ llvm::APInt ResultVal(Context.getTargetInfo().getLongLongWidth(), 0);
+ if (Literal.GetIntegerValue(ResultVal))
+ Diag(Tok.getLocation(), diag::warn_integer_too_large);
+
+ QualType Ty = Context.UnsignedLongLongTy;
+ Lit = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
+ }
+
+ return BuildLiteralOperatorCall(UDSuffix, UDSuffixLoc,
+ llvm::makeArrayRef(&Lit, 1),
+ Tok.getLocation());
+ }
+
Expr *Res;
if (Literal.isFloatingLiteral()) {
@@ -2472,34 +2538,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
else
Ty = Context.LongDoubleTy;
- const llvm::fltSemantics &Format = Context.getFloatTypeSemantics(Ty);
-
- using llvm::APFloat;
- APFloat Val(Format);
-
- APFloat::opStatus result = Literal.GetFloatValue(Val);
-
- // Overflow is always an error, but underflow is only an error if
- // we underflowed to zero (APFloat reports denormals as underflow).
- if ((result & APFloat::opOverflow) ||
- ((result & APFloat::opUnderflow) && Val.isZero())) {
- unsigned diagnostic;
- SmallString<20> buffer;
- if (result & APFloat::opOverflow) {
- diagnostic = diag::warn_float_overflow;
- APFloat::getLargest(Format).toString(buffer);
- } else {
- diagnostic = diag::warn_float_underflow;
- APFloat::getSmallest(Format).toString(buffer);
- }
-
- Diag(Tok.getLocation(), diagnostic)
- << Ty
- << StringRef(buffer.data(), buffer.size());
- }
-
- bool isExact = (result == APFloat::opOK);
- Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation());
+ Res = BuildFloatingLiteral(*this, Literal, Ty, Tok.getLocation());
if (Ty == Context.DoubleTy) {
if (getLangOptions().SinglePrecisionConstants) {