]> granicus.if.org Git - clang/commitdiff
Add support for full-width 128-bit integer literals.
authorStephen Canon <scanon@apple.com>
Thu, 3 May 2012 22:49:43 +0000 (22:49 +0000)
committerStephen Canon <scanon@apple.com>
Thu, 3 May 2012 22:49:43 +0000 (22:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156123 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/Sema/128bitint.c

index aaf579eda6fb24d21401994a6aff83ea6b27327a..90435aace79feea44cbc51fedf14fe3ad2d80402 100644 (file)
@@ -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.
index 89d3ee201283eaff9e20985573558dc1083158d0..ddad83554753876eda523687a2116a08e91a5e8f 100644 (file)
@@ -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}}