DavidFerencSzabo updated this revision to Diff 553745.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158933/new/

https://reviews.llvm.org/D158933

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/unsigned-bitfields.c

Index: clang/test/Sema/unsigned-bitfields.c
===================================================================
--- /dev/null
+++ clang/test/Sema/unsigned-bitfields.c
@@ -0,0 +1,160 @@
+// RUN: %clang_cc1 -fdump-record-layouts -emit-codegen-only %s -funsigned-bitfields | FileCheck %s
+
+// CHECK: BitFields
+// CHECK: Offset:0 Size:1 IsSigned:0
+// CHECK: Offset:1 Size:1 IsSigned:1
+// CHECK: Offset:2 Size:1 IsSigned:1
+// CHECK: Offset:3 Size:1 IsSigned:1
+// CHECK: Offset:4 Size:1 IsSigned:1
+// CHECK: Offset:5 Size:1 IsSigned:1
+// CHECK: Offset:6 Size:1 IsSigned:0
+// CHECK: Offset:7 Size:1 IsSigned:0
+// CHECK: Offset:8 Size:1 IsSigned:0
+// CHECK: Offset:9 Size:1 IsSigned:0
+// CHECK: Offset:10 Size:1 IsSigned:1
+// CHECK: Offset:11 Size:1 IsSigned:1
+// CHECK: Offset:12 Size:1 IsSigned:1
+// CHECK: Offset:13 Size:1 IsSigned:1
+// CHECK: Offset:14 Size:1 IsSigned:1
+// CHECK: Offset:15 Size:1 IsSigned:0
+// CHECK: Offset:16 Size:1 IsSigned:0
+// CHECK: Offset:17 Size:1 IsSigned:0
+// CHECK: Offset:18 Size:1 IsSigned:0
+// CHECK: Offset:19 Size:1 IsSigned:1
+// CHECK: Offset:20 Size:1 IsSigned:1
+// CHECK: Offset:21 Size:1 IsSigned:1
+// CHECK: Offset:22 Size:1 IsSigned:1
+// CHECK: Offset:23 Size:1 IsSigned:1
+// CHECK: Offset:24 Size:1 IsSigned:0
+// CHECK: Offset:25 Size:1 IsSigned:0
+// CHECK: Offset:26 Size:1 IsSigned:0
+// CHECK: Offset:27 Size:1 IsSigned:0
+// CHECK: Offset:28 Size:1 IsSigned:1
+// CHECK: Offset:29 Size:1 IsSigned:1
+// CHECK: Offset:30 Size:1 IsSigned:1
+// CHECK: Offset:31 Size:1 IsSigned:1
+// CHECK: Offset:32 Size:1 IsSigned:1
+// CHECK: Offset:33 Size:1 IsSigned:0
+// CHECK: Offset:34 Size:1 IsSigned:0
+// CHECK: Offset:35 Size:1 IsSigned:0
+// CHECK: Offset:36 Size:1 IsSigned:0
+// CHECK: Offset:37 Size:1 IsSigned:1
+// CHECK: Offset:38 Size:1 IsSigned:1
+// CHECK: Offset:39 Size:1 IsSigned:1
+// CHECK: Offset:40 Size:1 IsSigned:1
+// CHECK: Offset:41 Size:1 IsSigned:1
+// CHECK: Offset:42 Size:1 IsSigned:0
+// CHECK: Offset:43 Size:1 IsSigned:0
+// CHECK: Offset:44 Size:1 IsSigned:0
+
+
+
+typedef char c;
+typedef signed char sc;
+typedef unsigned char uc;
+typedef short s;
+typedef signed short ss;
+typedef unsigned short us;
+typedef int i;
+typedef signed int si;
+typedef unsigned int ui;
+typedef long l;
+typedef signed long sl;
+typedef unsigned long ul;
+typedef long long ll;
+typedef signed long long sll;
+typedef unsigned long long ull;
+
+typedef c ct;
+typedef sc sct;
+typedef uc uct;
+typedef s st;
+typedef ss sst;
+typedef us ust;
+typedef i it;
+typedef si sit;
+typedef ui uit;
+typedef l lt;
+typedef sl slt;
+typedef ul ult;
+typedef ll llt;
+typedef sll sllt;
+typedef ull ullt;
+
+struct foo {
+  char char0 : 1;
+  c char1 : 1;
+  ct char2 : 1;
+  signed char schar0 : 1;
+  sc schar1 : 1;
+  sct schar2 : 1;
+  unsigned char uchar0 : 1;
+  uc uchar1 : 1;
+  uct uchar2 : 1;
+  short short0 : 1;
+  s short1 : 1;
+  st short2 : 1;
+  signed short sshort0 : 1;
+  ss sshort1 : 1;
+  sst sshort2 : 1;
+  unsigned short ushort0 : 1;
+  us ushort1 : 1;
+  ust ushort2 : 1;
+  int int3 : 1;
+  i int4 : 1;
+  it int5 : 1;
+  signed int sint0 : 1;
+  si sint1 : 1;
+  sit sint2 : 1;
+  unsigned int uint0 : 1;
+  ui uint1 : 1;
+  uit uint2 : 1;
+  long long0 : 1;
+  l long1 : 1;
+  lt long2 : 1;
+  signed long slong0 : 1;
+  sl slong1 : 1;
+  slt slong2 : 1;
+  unsigned long ulong0 : 1;
+  ul ulong1 : 1;
+  ult ulong2 : 1;
+  long long llong0 : 1;
+  ll llong1 : 1;
+  llt llong2 : 1;
+  signed long long sllong0 : 1;
+  sll sllong1 : 1;
+  sllt sllong2 : 1;
+  unsigned long long ullong0 : 1;
+  ull ullong1 : 1;
+  ullt ullong2 : 1;
+};
+
+struct foo x;
+
+extern void abort (void);
+extern void exit (int);
+extern void *memset (void *, int, __SIZE_TYPE__);
+
+int
+main (void)
+{
+  memset (&x, (unsigned char)-1, sizeof(x));
+  if (x.char0 != 1 || x.char1 != 1 || x.char2 != 1
+      || x.schar0 != -1 || x.schar1 != -1 || x.schar2 != -1
+      || x.uchar0 != 1 || x.uchar1 != 1 || x.uchar2 != 1
+      || x.short0 != 1 || x.short1 != 1 || x.short2 != 1
+      || x.sshort0 != -1 || x.sshort1 != -1 || x.sshort2 != -1
+      || x.ushort0 != 1 || x.ushort1 != 1 || x.ushort2 != 1
+      || x.int3 != 1 || x.int4 != 1 || x.int5 != 1
+      || x.sint0 != -1 || x.sint1 != -1 || x.sint2 != -1
+      || x.uint0 != 1 || x.uint1 != 1 || x.uint2 != 1
+      || x.long0 != 1 || x.long1 != 1 || x.long2 != 1
+      || x.slong0 != -1 || x.slong1 != -1 || x.slong2 != -1
+      || x.ulong0 != 1 || x.ulong1 != 1 || x.ulong2 != 1
+      || x.llong0 != 1 || x.llong1 != 1 || x.llong2 != 1
+      || x.sllong0 != -1 || x.sllong1 != -1 || x.sllong2 != -1
+      || x.ullong0 != 1 || x.ullong1 != 1 || x.ullong2 != 1
+      )
+    abort();
+  exit (0);
+}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -18109,6 +18109,56 @@
 
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType T = TInfo->getType();
+
+  if (!getLangOpts().CPlusPlus && getLangOpts().IntBitfieldsAreUnsigned &&
+      BitWidth &&
+      (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename ||
+       D.getDeclSpec().getTypeSpecSign() == TypeSpecifierSign::Unspecified)) {
+    QualType ResultType = T;
+    bool Skip = false;
+
+    if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename) {
+      // The below code will not work since QualType does not have the info of
+      // explicit signdess
+
+      // const TypedefType *Typedef = nullptr;
+      // while ((Typedef = ResultType->getAs<TypedefType>())) {
+      //   ResultType = Typedef->desugar();
+      // }
+
+      // Possible other path is to find the inner most typedef and its type
+      // const TypedefType *Typedef = ResultType->getAs<TypedefType>();
+      // const TypedefType *NextTypedef = nullptr;
+      // while((NextTypedef = ResultType->getAs<TypedefType>())) {
+      //   Typedef = NextTypedef;
+      //   ResultType = Typedef->desugar();
+      // }
+
+      // TODO: Somehow get the explicit signdness info, maybe with the usage of
+      // the typedef's name (Typedef->getDecl()->getNameAsString()), look it up
+      // somehow the DeclSpec for its declaration and if it is explicitly
+      // signed then make Skip = true
+      Skip = true; // skip for now
+    }
+
+    if (!Skip) {
+
+      // Change to unsigned variant
+      if (ResultType == Context.CharTy)
+        ResultType = Context.UnsignedCharTy;
+      else if (ResultType == Context.ShortTy)
+        ResultType = Context.UnsignedShortTy;
+      else if (ResultType == Context.IntTy)
+        ResultType = Context.UnsignedIntTy;
+      else if (ResultType == Context.LongTy)
+        ResultType = Context.UnsignedLongTy;
+      else if (ResultType == Context.LongLongTy)
+        ResultType = Context.UnsignedLongLongTy;
+
+      T = ResultType;
+    }
+  }
+
   if (getLangOpts().CPlusPlus) {
     CheckExtraCXXDefaultArguments(D);
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3679,7 +3679,9 @@
 def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>,
   HelpText<"Do not process trigraph sequences">,
   Visibility<[ClangOption, CC1Option]>;
-def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
+defm unsigned_bitfields : BoolFOption<"unsigned-bitfields",
+  LangOpts<"IntBitfieldsAreUnsigned">, DefaultFalse,
+  PosFlag<SetTrue, [CC1Option], "int is signed">, NegFlag<SetFalse>>;
 def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
 def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
 def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>;
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -224,6 +224,7 @@
 LANGOPT(CharIsSigned      , 1, 1, "signed char")
 LANGOPT(WCharSize         , 4, 0, "width of wchar_t")
 LANGOPT(WCharIsSigned        , 1, 0, "signed or unsigned wchar_t")
+LANGOPT(IntBitfieldsAreUnsigned     , 1, 0, "int is unsigned for bitfield")
 ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
 ENUM_LANGOPT(DefaultCallingConv, DefaultCallingConvention, 3, DCC_None, "default calling convention")
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to