zhouyizhou created this revision.
zhouyizhou added reviewers: aaron.ballman, doug.gregor, eddy-geek, rjmccall, 
MaskRay, ChuanqiXu, pengfei.
Herald added a project: All.
zhouyizhou requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Add 128-bit integer support to enum element like GCC extension do.

Also remove comment: "TODO" from the code.  This comment is added by 
4ef40013d75ca ("Implement capturing of enum values and chaining of enums 
together"), while 6791a0d43b681 ("Improve handling of enumerator values for C 
and C++") has accomplished that "TODO".

I don't have write access to LLVM

Signed-off-by: Zhouyi Zhou <zhouzho...@gmail.com>

Thanks a lot
Zhouyi


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144157

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/enum.c


Index: clang/test/Sema/enum.c
===================================================================
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -1,7 +1,12 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple %s -fsyntax-only -verify 
-pedantic
+enum b {
+   b0 = (__uint128_t)-1, // expected-warning {{ISO C restricts enumerator 
values to range of 'int'}}
+   b1 = (__uint128_t)0x123456789abcdef0ULL << 64|0x0fedcba987654321ULL, // 
expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+};
+
 enum e {A,
-        B = 42LL << 32,        // expected-warning {{ISO C restricts 
enumerator values to range of 'int'}}
-      C = -4, D = 12456 };
+   B = 42LL << 32,        // expected-warning {{ISO C restricts enumerator 
values to range of 'int'}}
+   C = -4, D = 12456 };
 
 enum f { a = -2147483648, b = 2147483647 }; // ok.
 
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -19568,9 +19568,6 @@
     return;
   }
 
-  // TODO: If the result value doesn't fit in an int, it must be a long or long
-  // long value.  ISO C does not support this, but GCC does as an extension,
-  // emit a warning.
   unsigned IntWidth = Context.getTargetInfo().getIntWidth();
   unsigned CharWidth = Context.getTargetInfo().getCharWidth();
   unsigned ShortWidth = Context.getTargetInfo().getShortWidth();
@@ -19690,14 +19687,20 @@
       BestPromotionType
         = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
                            ? Context.UnsignedLongTy : Context.LongTy;
-    } else {
+    } else if (NumPositiveBits <= Context.getTargetInfo().getLongLongWidth()) {
       BestWidth = Context.getTargetInfo().getLongLongWidth();
-      assert(NumPositiveBits <= BestWidth &&
-             "How could an initializer get larger than ULL?");
       BestType = Context.UnsignedLongLongTy;
       BestPromotionType
         = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
                            ? Context.UnsignedLongLongTy : Context.LongLongTy;
+    } else {
+      BestWidth = 128;
+      assert(NumPositiveBits <= BestWidth &&
+             "How could an initializer get larger than unsigned 128-bit 
integer type?");
+      BestType = Context.UnsignedInt128Ty;
+      BestPromotionType
+        = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
+                           ? Context.UnsignedInt128Ty : Context.Int128Ty;
     }
   }
 


Index: clang/test/Sema/enum.c
===================================================================
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -1,7 +1,12 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple %s -fsyntax-only -verify -pedantic
+enum b {
+   b0 = (__uint128_t)-1, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+   b1 = (__uint128_t)0x123456789abcdef0ULL << 64|0x0fedcba987654321ULL, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+};
+
 enum e {A,
-        B = 42LL << 32,        // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
-      C = -4, D = 12456 };
+   B = 42LL << 32,        // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+   C = -4, D = 12456 };
 
 enum f { a = -2147483648, b = 2147483647 }; // ok.
 
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -19568,9 +19568,6 @@
     return;
   }
 
-  // TODO: If the result value doesn't fit in an int, it must be a long or long
-  // long value.  ISO C does not support this, but GCC does as an extension,
-  // emit a warning.
   unsigned IntWidth = Context.getTargetInfo().getIntWidth();
   unsigned CharWidth = Context.getTargetInfo().getCharWidth();
   unsigned ShortWidth = Context.getTargetInfo().getShortWidth();
@@ -19690,14 +19687,20 @@
       BestPromotionType
         = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
                            ? Context.UnsignedLongTy : Context.LongTy;
-    } else {
+    } else if (NumPositiveBits <= Context.getTargetInfo().getLongLongWidth()) {
       BestWidth = Context.getTargetInfo().getLongLongWidth();
-      assert(NumPositiveBits <= BestWidth &&
-             "How could an initializer get larger than ULL?");
       BestType = Context.UnsignedLongLongTy;
       BestPromotionType
         = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
                            ? Context.UnsignedLongLongTy : Context.LongLongTy;
+    } else {
+      BestWidth = 128;
+      assert(NumPositiveBits <= BestWidth &&
+             "How could an initializer get larger than unsigned 128-bit integer type?");
+      BestType = Context.UnsignedInt128Ty;
+      BestPromotionType
+        = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
+                           ? Context.UnsignedInt128Ty : Context.Int128Ty;
     }
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to