[PATCH] D151128: [clangd] Show size, offset and padding for bit fields on hover

SR_team via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon May 22 11:24:21 PDT 2023


SR_team created this revision.
SR_team added a reviewer: sammccall.
SR_team added a project: clang-tools-extra.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
SR_team requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.

In some cases, we want to view the bytes offset of a bit field block, like in:

  struct SomeFlags{
    // ~32 named bit flags, before foo
    bool foo : 1;
   // ~ 31 named bit flags, after foo
  };

With this diff in hover showed offset for `foo` in bytes. This offset is floored (e.g. offset 9 bits floored to 8 bits and convert to bytes).
Size of bit fields is ceiled to convert in bytes (e.g. 9 bits ceiled to 16 bits).

Logic to calculate padding not changed, so it showed for floored bits (e.g. 9 bits floored to 8 bits and present as 1 byte)


https://reviews.llvm.org/D151128

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -125,6 +125,8 @@
          HI.Kind = index::SymbolKind::Field;
          HI.Definition = "int x : 1";
          HI.Type = "int";
+         HI.Offset = 0;
+         HI.Size = 1;
          HI.AccessSpecifier = "public";
        }},
       // Local to class method.
@@ -1285,6 +1287,26 @@
          HI.Kind = index::SymbolKind::Field;
          HI.Definition = "m_int arr[Size]";
          HI.Type = {"m_int[Size]", "int[Size]"};
+       }},
+      {// Bitfield offset, size and padding
+       R"cpp(
+            struct Foo {
+              char x;
+              char [[^y]] : 1;
+              int z;
+            };
+          )cpp",
+       [](HoverInfo &HI) {
+         HI.NamespaceScope = "";
+         HI.LocalScope = "Foo::";
+         HI.Name = "y";
+         HI.Kind = index::SymbolKind::Field;
+         HI.Definition = "char y : 1";
+         HI.Type = "char";
+         HI.Offset = 1;
+         HI.Size = 1;
+         HI.Padding = 2;
+         HI.AccessSpecifier = "public";
        }}};
   for (const auto &Case : Cases) {
     SCOPED_TRACE(Case.Code);
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -1008,12 +1008,15 @@
     const auto *Record = FD->getParent();
     if (Record)
       Record = Record->getDefinition();
-    if (Record && !Record->isInvalidDecl() && !Record->isDependentType() &&
-        !FD->isBitField()) {
+    if (Record && !Record->isInvalidDecl() && !Record->isDependentType()) {
       const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record);
       HI.Offset = Layout.getFieldOffset(FD->getFieldIndex()) / 8;
-      if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) {
+      if (FD->isBitField()) {
+        const auto SizeInBits = FD->getBitWidthValue(Ctx);
+        HI.Size = (SizeInBits + 7) >> 3;
+      } else if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType()))
         HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity();
+      if (HI.Size) {
         unsigned EndOfField = *HI.Offset + *HI.Size;
 
         // Calculate padding following the field.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151128.524399.patch
Type: text/x-patch
Size: 2412 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230522/b51b89e2/attachment-0001.bin>


More information about the cfe-commits mailing list