[clang-tools-extra] [clangd] Add padding to struct hover information (PR #115665)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 10 09:57:44 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
Author: Kevin Kremer (Xoltus)
<details>
<summary>Changes</summary>
Hi team, I've written a small patch as a small quality of life improvement for my development and figured it may be worth sharing. Please let me know what you think:
HI.Padding is already available for a struct's member variables but the struct itself is not displaying how much padding has been added to it. This commit sums up all padding within a struct and adds it to a struct's hover information.
```
struct Foo
{
char a;
int b;
char c;
};
```
results in
![Screenshot 2024-11-10 at 9 50 52 AM](https://github.com/user-attachments/assets/163d1582-4de0-4673-9024-8f04465f221a)
I've also added additional tests to HoverTests.cpp.
---
Full diff: https://github.com/llvm/llvm-project/pull/115665.diff
2 Files Affected:
- (modified) clang-tools-extra/clangd/Hover.cpp (+27)
- (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+62)
``````````diff
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 298fa79e3fd0ba..9ef32a777d73fe 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -1006,6 +1006,33 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
HI.Size = Size->getQuantity() * 8;
if (!RD->isDependentType() && RD->isCompleteDefinition())
HI.Align = Ctx.getTypeAlign(RD->getTypeForDecl());
+ if (HI.Size && !RD->field_empty()) {
+ HI.Padding = 0;
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+ auto NumFields = std::distance(RD->field_begin(), RD->field_end());
+ auto FieldIt = RD->field_begin();
+ for (; --NumFields; ++FieldIt) {
+ unsigned Offset = Layout.getFieldOffset(FieldIt->getFieldIndex());
+ unsigned NextOffset =
+ Layout.getFieldOffset(FieldIt->getFieldIndex() + 1);
+ if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FieldIt->getType())) {
+ unsigned EndOfField = Offset + Size->getQuantity() * 8;
+ if (NextOffset > EndOfField)
+ HI.Padding = *HI.Padding + NextOffset - EndOfField;
+ } else {
+ HI.Padding.reset();
+ break;
+ }
+ }
+ // We've processed all but the last field. If we still have valid
+ // HI.Padding, finish the calculation
+ auto Size = Ctx.getTypeSizeInCharsIfKnown(FieldIt->getType());
+ if (HI.Padding && Size) {
+ unsigned Offset = Layout.getFieldOffset(FieldIt->getFieldIndex());
+ HI.Padding = *HI.Padding + *HI.Size - Offset - Size->getQuantity() * 8;
+ }
+ }
+
return;
}
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 69f6df46c87ce0..96fb4d8f317328 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -73,6 +73,68 @@ TEST(Hover, Structured) {
HI.Type = "void ()";
HI.Parameters.emplace();
}},
+ {R"cpp(
+ struct [[F^oo]] {
+ char a;
+ long long b;
+ };
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.Name = "Foo";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct Foo {}";
+ HI.Size = 128;
+ HI.Padding = 56;
+ HI.Align = 64;
+ }},
+ {R"cpp(
+ struct [[F^oo]] {
+ int b;
+ char a;
+ };
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.Name = "Foo";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct Foo {}";
+ HI.Size = 64;
+ HI.Padding = 24;
+ HI.Align = 32;
+ }},
+ {R"cpp(
+ struct [[F^oo]] {
+ double a;
+ char b;
+ double c;
+ };
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.Name = "Foo";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct Foo {}";
+ HI.Size = 192;
+ HI.Padding = 46;
+ HI.Align = 64;
+ }}, {R"cpp(
+ struct [[F^oo]] {
+ double a;
+ char b;
+ double c;
+ char d;
+ };
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.Name = "Foo";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct Foo {}";
+ HI.Size = 256;
+ HI.Padding = 112;
+ HI.Align = 64;
+ }},
// Field
{R"cpp(
namespace ns1 { namespace ns2 {
``````````
</details>
https://github.com/llvm/llvm-project/pull/115665
More information about the cfe-commits
mailing list