From fdc6c1a461559668fff9f16cb813f90cb74ddb06 Mon Sep 17 00:00:00 2001 From: Stephen Canon Date: Thu, 3 May 2012 22:49:43 +0000 Subject: [PATCH] Add support for full-width 128-bit integer literals. llvm-svn: 156123 --- clang/lib/Sema/SemaExpr.cpp | 19 +++++++++++++++++-- clang/test/Sema/128bitint.c | 9 ++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index aaf579eda6fb..90435aace79f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2648,7 +2648,12 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { diag::warn_cxx98_compat_longlong : diag::ext_longlong); // Get the value in the widest-possible width. - llvm::APInt ResultVal(Context.getTargetInfo().getIntMaxTWidth(), 0); + unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth(); + // The microsoft literal suffix extensions support 128-bit literals, which + // may be wider than [u]intmax_t. + if (Literal.isMicrosoftInteger && MaxWidth < 128) + MaxWidth = 128; + llvm::APInt ResultVal(MaxWidth, 0); if (Literal.GetIntegerValue(ResultVal)) { // If this value didn't fit into uintmax_t, warn and force to ull. @@ -2696,7 +2701,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } } - // Finally, check long long if needed. + // Check long long if needed. if (Ty.isNull()) { unsigned LongLongSize = Context.getTargetInfo().getLongLongWidth(); @@ -2713,6 +2718,16 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Width = LongLongSize; } } + + // If it doesn't fit in unsigned long long, and we're using Microsoft + // extensions, then its a 128-bit integer literal. + if (Ty.isNull() && Literal.isMicrosoftInteger) { + if (Literal.isUnsigned) + Ty = Context.UnsignedInt128Ty; + else + Ty = Context.Int128Ty; + Width = 128; + } // If we still couldn't decide a type, we probably have something that // does not fit in a signed long long, but has no U suffix. diff --git a/clang/test/Sema/128bitint.c b/clang/test/Sema/128bitint.c index 89d3ee201283..ddad83554753 100644 --- a/clang/test/Sema/128bitint.c +++ b/clang/test/Sema/128bitint.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin9 %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin9 -fms-extensions %s typedef int i128 __attribute__((__mode__(TI))); typedef unsigned u128 __attribute__((__mode__(TI))); @@ -11,3 +11,10 @@ __uint128_t b = (__uint128_t)-1; // PR11916: Support for libstdc++ 4.7 __int128 i = (__int128)0; unsigned __int128 u = (unsigned __int128)-1; + +long long SignedTooBig = 123456789012345678901234567890; // expected-warning {{integer constant is too large for its type}} +__int128_t Signed128 = 123456789012345678901234567890i128; +long long Signed64 = 123456789012345678901234567890i128; // expected-warning {{implicit conversion from '__int128' to 'long long' changes value from 123456789012345678901234567890 to -4362896299872285998}} +unsigned long long UnsignedTooBig = 123456789012345678901234567890; // expected-warning {{integer constant is too large for its type}} +__uint128_t Unsigned128 = 123456789012345678901234567890Ui128; +unsigned long long Unsigned64 = 123456789012345678901234567890Ui128; // expected-warning {{implicit conversion from 'unsigned __int128' to 'unsigned long long' changes value from 123456789012345678901234567890 to 14083847773837265618}}