[clang-tools-extra] [clangd] Add padding to struct hover information (PR #115665)
Kevin Kremer via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 10 09:56:56 PST 2024
https://github.com/Xoltus created https://github.com/llvm/llvm-project/pull/115665
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.
>From 3b64d9d82047159fbd7cb4662d1b666c4431be9c Mon Sep 17 00:00:00 2001
From: Kevin Kremer <github at kevin-kremer.com>
Date: Sun, 10 Nov 2024 16:00:00 +0000
Subject: [PATCH] [clangd] Add padding to struct hover information
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.
---
clang-tools-extra/clangd/Hover.cpp | 27 ++++++++
.../clangd/unittests/HoverTests.cpp | 62 +++++++++++++++++++
2 files changed, 89 insertions(+)
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 {
More information about the cfe-commits
mailing list