[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)

Florian Hahn via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 14:56:29 PST 2024


================
@@ -294,18 +297,49 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
         return false;
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD);
 
     unsigned idx = 0;
-    for (RecordDecl::field_iterator i = RD->field_begin(),
-         e = RD->field_end(); i != e; ++i, ++idx) {
-      if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
+    for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e;) {
+      if ((*i)->isZeroSize(Context)) {
+        ++i;
+        ++idx;
         continue;
-      uint64_t Offset = BaseOffset +
-                        Layout.getFieldOffset(idx) / Context.getCharWidth();
+      }
+
+      uint64_t Offset =
+          BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth();
       QualType FieldQTy = i->getType();
+      // Create a single field for consecutive named bitfields using char as
+      // base type.
+      if ((*i)->isBitField() && !(*i)->isUnnamedBitfield()) {
+        unsigned CurrentBitFieldSize = 0;
+        unsigned CurrentBitFieldOffset = CGRL.getBitFieldInfo(*i).Offset;
+        while (i != e && (*i)->isBitField() && !(*i)->isUnnamedBitfield()) {
+          const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i);
+          if (CurrentBitFieldSize + CurrentBitFieldOffset != Info.Offset)
+            break;
+          CurrentBitFieldSize += Info.Size;
----------------
fhahn wrote:

Thanks, updated the patch to add a field for the first bitfield in the run using its StorageSize, and skip bitfields where the offset in the run isn't 0 (`Offset`). 

https://github.com/llvm/llvm-project/pull/82922


More information about the cfe-commits mailing list