SR_team updated this revision to Diff 524946.
SR_team added a comment.

Extract formatting to lambda, for simplify code modification


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

https://reviews.llvm.org/D151128

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/Hover.h
  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
@@ -89,8 +89,8 @@
          HI.Definition = "char bar";
          HI.Type = "char";
          HI.Offset = 0;
-         HI.Size = 1;
-         HI.Padding = 7;
+         HI.Size = 8;
+         HI.Padding = 56;
          HI.AccessSpecifier = "private";
        }},
       // Union field
@@ -107,8 +107,8 @@
          HI.Kind = index::SymbolKind::Field;
          HI.Definition = "char bar";
          HI.Type = "char";
-         HI.Size = 1;
-         HI.Padding = 15;
+         HI.Size = 8;
+         HI.Padding = 120;
          HI.AccessSpecifier = "public";
        }},
       // Bitfield
@@ -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.
@@ -188,7 +190,7 @@
          HI.Definition = "char bar";
          HI.Type = "char";
          HI.Offset = 0;
-         HI.Size = 1;
+         HI.Size = 8;
          HI.AccessSpecifier = "public";
        }},
       // Struct definition shows size.
@@ -200,7 +202,7 @@
          HI.Name = "X";
          HI.Kind = index::SymbolKind::Struct;
          HI.Definition = "struct X {}";
-         HI.Size = 1;
+         HI.Size = 8;
        }},
       // Variable with template type
       {R"cpp(
@@ -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 = 8;
+         HI.Size = 1;
+         HI.Padding = 23;
+         HI.AccessSpecifier = "public";
        }}};
   for (const auto &Case : Cases) {
     SCOPED_TRACE(Case.Code);
@@ -1508,7 +1530,7 @@
       {"auto s = ^[[\"Hello, world!\"]]; // string literal",
        [](HoverInfo &HI) {
          HI.Name = "string-literal";
-         HI.Size = 14;
+         HI.Size = 112;
          HI.Type = "const char[14]";
        }},
       {
@@ -3218,7 +3240,7 @@
       {
           [](HoverInfo &HI) {
             HI.Kind = index::SymbolKind::Class;
-            HI.Size = 10;
+            HI.Size = 80;
             HI.TemplateParameters = {
                 {{"typename"}, std::string("T"), std::nullopt},
                 {{"typename"}, std::string("C"), std::string("bool")},
@@ -3274,16 +3296,16 @@
             HI.Name = "foo";
             HI.Type = {"type", "can_type"};
             HI.Definition = "def";
-            HI.Size = 4;
-            HI.Offset = 12;
-            HI.Padding = 4;
+            HI.Size = 32;
+            HI.Offset = 96;
+            HI.Padding = 32;
           },
           R"(field foo
 
 Type: type (aka can_type)
 Value = value
 Offset: 12 bytes
-Size: 4 bytes (+4 padding)
+Size: 4 bytes (+4 bytes padding)
 
 // In test::Bar
 def)",
Index: clang-tools-extra/clangd/Hover.h
===================================================================
--- clang-tools-extra/clangd/Hover.h
+++ clang-tools-extra/clangd/Hover.h
@@ -91,7 +91,7 @@
   std::optional<std::vector<Param>> TemplateParameters;
   /// Contains the evaluated value of the symbol if available.
   std::optional<std::string> Value;
-  /// Contains the byte-size of fields and types where it's interesting.
+  /// Contains the bit-size of fields and types where it's interesting.
   std::optional<uint64_t> Size;
   /// Contains the offset of fields within the enclosing class.
   std::optional<uint64_t> Offset;
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -866,7 +866,7 @@
   HoverInfo HI;
 
   HI.Name = "string-literal";
-  HI.Size = (SL->getLength() + 1) * SL->getCharByteWidth();
+  HI.Size = (SL->getLength() + 1) * SL->getCharByteWidth() * 8;
   HI.Type = SL->getType().getAsString(PP).c_str();
 
   return HI;
@@ -1000,7 +1000,7 @@
   const auto &Ctx = ND.getASTContext();
   if (auto *RD = llvm::dyn_cast<RecordDecl>(&ND)) {
     if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
-      HI.Size = Size->getQuantity();
+      HI.Size = Size->getQuantity() * 8;
     return;
   }
 
@@ -1008,25 +1008,26 @@
     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())) {
-        HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity();
+      HI.Offset = Layout.getFieldOffset(FD->getFieldIndex());
+      if (FD->isBitField())
+        HI.Size = FD->getBitWidthValue(Ctx);
+      else if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType()))
+        HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity() * 8;
+      if (HI.Size) {
         unsigned EndOfField = *HI.Offset + *HI.Size;
 
         // Calculate padding following the field.
         if (!Record->isUnion() &&
             FD->getFieldIndex() + 1 < Layout.getFieldCount()) {
           // Measure padding up to the next class field.
-          unsigned NextOffset =
-              Layout.getFieldOffset(FD->getFieldIndex() + 1) / 8;
+          unsigned NextOffset = Layout.getFieldOffset(FD->getFieldIndex() + 1);
           if (NextOffset >= EndOfField) // next field could be a bitfield!
             HI.Padding = NextOffset - EndOfField;
         } else {
           // Measure padding up to the end of the object.
-          HI.Padding = Layout.getSize().getQuantity() - EndOfField;
+          HI.Padding = Layout.getSize().getQuantity() * 8 - EndOfField;
         }
       }
       // Offset in a union is always zero, so not really useful to report.
@@ -1463,15 +1464,32 @@
     P.appendCode(*Value);
   }
 
-  if (Offset)
-    Output.addParagraph().appendText(
-        llvm::formatv("Offset: {0} byte{1}", *Offset, *Offset == 1 ? "" : "s")
-            .str());
+  const auto FormatSize = [](uint64_t Bits) {
+    uint64_t Value = Bits % 8 == 0 ? Bits / 8 : Bits;
+    const char *Unit = Value != 0 && Value == Bits ? "bit" : "byte";
+    return llvm::formatv("{0} {1}{2}", Value, Unit, Value == 1 ? "" : "s")
+        .str();
+  };
+
+  if (Offset) {
+    const auto Bytes = *Offset / 8;
+    const auto Bits = *Offset % 8;
+    auto &P = Output.addParagraph().appendText("Offset: ");
+    if (Bytes != 0 || Bits == 0)
+      P.appendText(FormatSize(Bytes * 8));
+    if (Bits != 0) {
+      if (Bytes != 0)
+        P.appendText(" and ");
+      P.appendText(FormatSize(Bits));
+    }
+  }
   if (Size) {
-    auto &P = Output.addParagraph().appendText(
-        llvm::formatv("Size: {0} byte{1}", *Size, *Size == 1 ? "" : "s").str());
-    if (Padding && *Padding != 0)
-      P.appendText(llvm::formatv(" (+{0} padding)", *Padding).str());
+    auto &P = Output.addParagraph().appendText("Size: ");
+    P.appendText(FormatSize(*Size));
+    if (Padding && *Padding != 0) {
+      P.appendText(
+          llvm::formatv(" (+{0} padding)", FormatSize(*Padding)).str());
+    }
   }
 
   if (CalleeArgInfo) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to