[clang-tools-extra] c300884 - [clangd] Show alignment for records and fields decls (#67213)

via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 22 09:37:16 PDT 2023


Author: SR_team
Date: 2023-10-22T20:37:12+04:00
New Revision: c3008842bf19e3a00db1f8adbd95d43f71b4f09f

URL: https://github.com/llvm/llvm-project/commit/c3008842bf19e3a00db1f8adbd95d43f71b4f09f
DIFF: https://github.com/llvm/llvm-project/commit/c3008842bf19e3a00db1f8adbd95d43f71b4f09f.diff

LOG: [clangd] Show alignment for records and fields decls (#67213)

Shows align for records and fields declarations in hover information.

Example:
```cpp
struct A {
  char a;
  short b;
};
```

For this struct hover informations shows:
```
Size: 4 bytes, alignment 2 bytes
```


![image](https://github.com/llvm/llvm-project/assets/12231048/a130b353-f3f6-4203-b0d7-3d592b7a7855)

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 0ec85fc24df151b..933c69294b40926 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -1001,6 +1001,8 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
   if (auto *RD = llvm::dyn_cast<RecordDecl>(&ND)) {
     if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
       HI.Size = Size->getQuantity() * 8;
+    if (!RD->isDependentType() && RD->isCompleteDefinition())
+      HI.Align = Ctx.getTypeAlign(RD->getTypeForDecl());
     return;
   }
 
@@ -1009,6 +1011,7 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
     if (Record)
       Record = Record->getDefinition();
     if (Record && !Record->isInvalidDecl() && !Record->isDependentType()) {
+      HI.Align = Ctx.getTypeAlign(FD->getType());
       const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record);
       HI.Offset = Layout.getFieldOffset(FD->getFieldIndex());
       if (FD->isBitField())
@@ -1487,6 +1490,8 @@ markup::Document HoverInfo::present() const {
       P.appendText(
           llvm::formatv(" (+{0} padding)", formatSize(*Padding)).str());
     }
+    if (Align)
+      P.appendText(", alignment " + formatSize(*Align));
   }
 
   if (CalleeArgInfo) {

diff  --git a/clang-tools-extra/clangd/Hover.h b/clang-tools-extra/clangd/Hover.h
index 6a61100912918ea..fe689de44732ebe 100644
--- a/clang-tools-extra/clangd/Hover.h
+++ b/clang-tools-extra/clangd/Hover.h
@@ -97,6 +97,8 @@ struct HoverInfo {
   std::optional<uint64_t> Offset;
   /// Contains the padding following a field within the enclosing class.
   std::optional<uint64_t> Padding;
+  /// Contains the alignment of fields and types where it's interesting.
+  std::optional<uint64_t> Align;
   // Set when symbol is inside function call. Contains information extracted
   // from the callee definition about the argument this is passed as.
   std::optional<Param> CalleeArgInfo;

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 8c88cd52574536c..063a60db044060e 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -92,6 +92,7 @@ TEST(Hover, Structured) {
          HI.Offset = 0;
          HI.Size = 8;
          HI.Padding = 56;
+         HI.Align = 8;
          HI.AccessSpecifier = "private";
        }},
       // Union field
@@ -110,6 +111,7 @@ TEST(Hover, Structured) {
          HI.Type = "char";
          HI.Size = 8;
          HI.Padding = 120;
+         HI.Align = 8;
          HI.AccessSpecifier = "public";
        }},
       // Bitfield
@@ -128,6 +130,7 @@ TEST(Hover, Structured) {
          HI.Type = "int";
          HI.Offset = 0;
          HI.Size = 1;
+         HI.Align = 32;
          HI.AccessSpecifier = "public";
        }},
       // Local to class method.
@@ -192,6 +195,7 @@ TEST(Hover, Structured) {
          HI.Type = "char";
          HI.Offset = 0;
          HI.Size = 8;
+         HI.Align = 8;
          HI.AccessSpecifier = "public";
        }},
       // Struct definition shows size.
@@ -204,6 +208,7 @@ TEST(Hover, Structured) {
          HI.Kind = index::SymbolKind::Struct;
          HI.Definition = "struct X {}";
          HI.Size = 8;
+         HI.Align = 8;
        }},
       // Variable with template type
       {R"cpp(
@@ -1375,6 +1380,7 @@ class Foo final {})cpp";
          HI.Offset = 8;
          HI.Size = 1;
          HI.Padding = 23;
+         HI.Align = 8;
          HI.AccessSpecifier = "public";
        }}};
   for (const auto &Case : Cases) {
@@ -1411,6 +1417,7 @@ class Foo final {})cpp";
     EXPECT_EQ(H->Value, Expected.Value);
     EXPECT_EQ(H->Size, Expected.Size);
     EXPECT_EQ(H->Offset, Expected.Offset);
+    EXPECT_EQ(H->Align, Expected.Align);
     EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
     EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
     EXPECT_EQ(H->CallPassType, Expected.CallPassType);
@@ -3448,13 +3455,14 @@ template <typename T, typename C = bool> class Foo {})",
             HI.Size = 32;
             HI.Offset = 96;
             HI.Padding = 32;
+            HI.Align = 32;
           },
           R"(field foo
 
 Type: type (aka can_type)
 Value = value
 Offset: 12 bytes
-Size: 4 bytes (+4 bytes padding)
+Size: 4 bytes (+4 bytes padding), alignment 4 bytes
 
 // In test::Bar
 def)",
@@ -3470,13 +3478,14 @@ def)",
             HI.Size = 25;
             HI.Offset = 35;
             HI.Padding = 4;
+            HI.Align = 64;
           },
           R"(field foo
 
 Type: type (aka can_type)
 Value = value
 Offset: 4 bytes and 3 bits
-Size: 25 bits (+4 bits padding)
+Size: 25 bits (+4 bits padding), alignment 8 bytes
 
 // In test::Bar
 def)",


        


More information about the cfe-commits mailing list