[PATCH] D77355: [clangd] show layout info when hovering on a class/field definition.

2020-04-08 Thread Sam McCall via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc1a00b89add8: [clangd] show layout info when hovering on a 
class/field definition. (authored by sammccall).

Changed prior to commit:
  https://reviews.llvm.org/D77355?vs=254786=255964#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77355

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
@@ -66,7 +66,7 @@
   {R"cpp(
   namespace ns1 { namespace ns2 {
 struct Foo {
-  int [[b^ar]];
+  char [[b^ar]];
 };
   }}
   )cpp",
@@ -75,8 +75,10 @@
  HI.LocalScope = "Foo::";
  HI.Name = "bar";
  HI.Kind = index::SymbolKind::Field;
- HI.Definition = "int bar";
- HI.Type = "int";
+ HI.Definition = "char bar";
+ HI.Type = "char";
+ HI.Offset = 0;
+ HI.Size = 1;
}},
   // Local to class method.
   {R"cpp(
@@ -100,7 +102,7 @@
   {R"cpp(
   namespace ns1 { namespace {
 struct {
-  int [[b^ar]];
+  char [[b^ar]];
 } T;
   }}
   )cpp",
@@ -109,8 +111,21 @@
  HI.LocalScope = "(anonymous struct)::";
  HI.Name = "bar";
  HI.Kind = index::SymbolKind::Field;
- HI.Definition = "int bar";
- HI.Type = "int";
+ HI.Definition = "char bar";
+ HI.Type = "char";
+ HI.Offset = 0;
+ HI.Size = 1;
+   }},
+  // Struct definition shows size.
+  {R"cpp(
+  struct [[^X]]{};
+  )cpp",
+   [](HoverInfo ) {
+ HI.NamespaceScope = "";
+ HI.Name = "X";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct X {}";
+ HI.Size = 1;
}},
   // Variable with template type
   {R"cpp(
@@ -698,6 +713,8 @@
 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
 EXPECT_EQ(H->SymRange, Expected.SymRange);
 EXPECT_EQ(H->Value, Expected.Value);
+EXPECT_EQ(H->Size, Expected.Size);
+EXPECT_EQ(H->Offset, Expected.Offset);
   }
 }
 
@@ -1862,6 +1879,7 @@
   {
   [](HoverInfo ) {
 HI.Kind = index::SymbolKind::Class;
+HI.Size = 10;
 HI.TemplateParameters = {
 {std::string("typename"), std::string("T"), llvm::None},
 {std::string("typename"), std::string("C"),
@@ -1875,6 +1893,7 @@
   },
   R"(class foo
 
+Size: 10 bytes
 documentation
 
 template  class Foo {})",
@@ -1911,19 +1930,23 @@
   },
   {
   [](HoverInfo ) {
-HI.Kind = index::SymbolKind::Variable;
-HI.LocalScope = "test::bar::";
+HI.Kind = index::SymbolKind::Field;
+HI.LocalScope = "test::Bar::";
 HI.Value = "value";
 HI.Name = "foo";
 HI.Type = "type";
 HI.Definition = "def";
+HI.Size = 4;
+HI.Offset = 12;
   },
-  R"(variable foo
+  R"(field foo
 
 Type: type
 Value = value
+Offset: 12 bytes
+Size: 4 bytes
 
-// In test::bar
+// In test::Bar
 def)",
   },
   };
Index: clang-tools-extra/clangd/Hover.h
===
--- clang-tools-extra/clangd/Hover.h
+++ clang-tools-extra/clangd/Hover.h
@@ -70,6 +70,10 @@
   llvm::Optional> TemplateParameters;
   /// Contains the evaluated value of the symbol if available.
   llvm::Optional Value;
+  /// Contains the byte-size of fields and types where it's interesting.
+  llvm::Optional Size;
+  /// Contains the offset of fields within the enclosing class.
+  llvm::Optional Offset;
 
   /// Produce a user-readable information.
   markup::Document present() const;
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -651,6 +651,28 @@
   return punctuationIndicatesLineBreak(Line) || isHardLineBreakIndicator(Rest);
 }
 
+void addLayoutInfo(const NamedDecl , HoverInfo ) {
+  const auto  = ND.getASTContext();
+
+  if (auto *RD = llvm::dyn_cast()) {
+if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+  HI.Size = Size->getQuantity();
+return;
+  }
+
+  if (const auto *FD = llvm::dyn_cast()) {
+const auto *Record = FD->getParent()->getDefinition();
+if (Record && !Record->isDependentType()) {
+  uint64_t OffsetBits = Ctx.getFieldOffset(FD);
+  if (auto Size = 

[PATCH] D77355: [clangd] show layout info when hovering on a class/field definition.

2020-04-03 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet marked an inline comment as done.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks!




Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:69
 struct Foo {
-  int [[b^ar]];
+  char [[b^ar]];
 };

sammccall wrote:
> kadircet wrote:
> > any reason for changing these from int to char ?
> hardcoding sizeof(int) isn't portable unless we want to set the target 
> explicitly
right, the test already sets the target though.

I suppose relying less on it is better, so feel free to keep it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77355



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77355: [clangd] show layout info when hovering on a class/field definition.

2020-04-03 Thread Sam McCall via Phabricator via cfe-commits
sammccall added inline comments.



Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:69
 struct Foo {
-  int [[b^ar]];
+  char [[b^ar]];
 };

kadircet wrote:
> any reason for changing these from int to char ?
hardcoding sizeof(int) isn't portable unless we want to set the target 
explicitly


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77355



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77355: [clangd] show layout info when hovering on a class/field definition.

2020-04-03 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 254786.
sammccall marked 5 inline comments as done.
sammccall added a comment.

address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77355

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
@@ -66,7 +66,7 @@
   {R"cpp(
   namespace ns1 { namespace ns2 {
 struct Foo {
-  int [[b^ar]];
+  char [[b^ar]];
 };
   }}
   )cpp",
@@ -75,8 +75,10 @@
  HI.LocalScope = "Foo::";
  HI.Name = "bar";
  HI.Kind = index::SymbolKind::Field;
- HI.Definition = "int bar";
- HI.Type = "int";
+ HI.Definition = "char bar";
+ HI.Type = "char";
+ HI.Offset = 0;
+ HI.Size = 1;
}},
   // Local to class method.
   {R"cpp(
@@ -100,7 +102,7 @@
   {R"cpp(
   namespace ns1 { namespace {
 struct {
-  int [[b^ar]];
+  char [[b^ar]];
 } T;
   }}
   )cpp",
@@ -109,8 +111,21 @@
  HI.LocalScope = "(anonymous struct)::";
  HI.Name = "bar";
  HI.Kind = index::SymbolKind::Field;
- HI.Definition = "int bar";
- HI.Type = "int";
+ HI.Definition = "char bar";
+ HI.Type = "char";
+ HI.Offset = 0;
+ HI.Size = 1;
+   }},
+  // Struct definition shows size.
+  {R"cpp(
+  struct [[^X]]{};
+  )cpp",
+   [](HoverInfo ) {
+ HI.NamespaceScope = "";
+ HI.Name = "X";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct X {}";
+ HI.Size = 1;
}},
   // Variable with template type
   {R"cpp(
@@ -646,6 +661,8 @@
 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
 EXPECT_EQ(H->SymRange, Expected.SymRange);
 EXPECT_EQ(H->Value, Expected.Value);
+EXPECT_EQ(H->Size, Expected.Size);
+EXPECT_EQ(H->Offset, Expected.Offset);
   }
 }
 
@@ -1810,6 +1827,7 @@
   {
   [](HoverInfo ) {
 HI.Kind = index::SymbolKind::Class;
+HI.Size = 10;
 HI.TemplateParameters = {
 {std::string("typename"), std::string("T"), llvm::None},
 {std::string("typename"), std::string("C"),
@@ -1823,6 +1841,7 @@
   },
   R"(class foo
 
+Size: 10 bytes
 documentation
 
 template  class Foo {})",
@@ -1859,19 +1878,23 @@
   },
   {
   [](HoverInfo ) {
-HI.Kind = index::SymbolKind::Variable;
-HI.LocalScope = "test::bar::";
+HI.Kind = index::SymbolKind::Field;
+HI.LocalScope = "test::Bar::";
 HI.Value = "value";
 HI.Name = "foo";
 HI.Type = "type";
 HI.Definition = "def";
+HI.Size = 4;
+HI.Offset = 12;
   },
-  R"(variable foo
+  R"(field foo
 
 Type: type
 Value = value
+Offset: 12 bytes
+Size: 4 bytes
 
-// In test::bar
+// In test::Bar
 def)",
   },
   };
Index: clang-tools-extra/clangd/Hover.h
===
--- clang-tools-extra/clangd/Hover.h
+++ clang-tools-extra/clangd/Hover.h
@@ -70,6 +70,10 @@
   llvm::Optional> TemplateParameters;
   /// Contains the evaluated value of the symbol if available.
   llvm::Optional Value;
+  /// Contains the byte-size of fields and types where it's interesting.
+  llvm::Optional Size;
+  /// Contains the offset of fields within the enclosing class.
+  llvm::Optional Offset;
 
   /// Produce a user-readable information.
   markup::Document present() const;
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -563,6 +563,28 @@
  isFollowedByHardLineBreakIndicator(Str, LineBreakIndex);
 }
 
+void addLayoutInfo(const NamedDecl , HoverInfo ) {
+  const auto  = ND.getASTContext();
+
+  if (auto *RD = llvm::dyn_cast()) {
+if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+  HI.Size = Size->getQuantity();
+return;
+  }
+
+  if (const auto *FD = llvm::dyn_cast()) {
+const auto *Record = FD->getParent()->getDefinition();
+if (Record && !Record->isDependentType()) {
+  uint64_t OffsetBits = Ctx.getFieldOffset(FD);
+  if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) {
+HI.Size = Size->getQuantity();
+HI.Offset = OffsetBits / 8;
+  }
+}
+return;
+  }
+}
+
 } // 

[PATCH] D77355: [clangd] show layout info when hovering on a class/field definition.

2020-04-03 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/Hover.cpp:571
+if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+  HI.Size = Size->getQuantity();
+

QuantityType seems to be an alias for int64_t, not sure how likely it is that 
someone will have a type that's bigger than 4GB, but still, should we make 
typeof HoverInfo::Size optional instead of unsigned?



Comment at: clang-tools-extra/clangd/Hover.cpp:573
+
+  if (const auto *FD = llvm::dyn_cast()) {
+const auto *Record = FD->getParent()->getDefinition();

nit: either make this `else if` or put a return above ?



Comment at: clang-tools-extra/clangd/Hover.cpp:576
+if (Record && !Record->isDependentType()) {
+  unsigned OffsetBits = Ctx.getFieldOffset(FD);
+  if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) {

similar to size, offset is also of type uint64_t



Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:69
 struct Foo {
-  int [[b^ar]];
+  char [[b^ar]];
 };

any reason for changing these from int to char ?



Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:1830
 HI.Kind = index::SymbolKind::Class;
+HI.Size = 10;
 HI.TemplateParameters = {

maybe also add offset?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77355



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77355: [clangd] show layout info when hovering on a class/field definition.

2020-04-02 Thread Sam McCall via Phabricator via cfe-commits
sammccall created this revision.
sammccall added a reviewer: kadircet.
Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, 
ilya-biryukov.
Herald added a project: clang.

This triggers only on the definition itself, not on references (probably too
noisy). Inspecting the definition seems like a decent hint for being interested
in layout.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77355

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
@@ -66,7 +66,7 @@
   {R"cpp(
   namespace ns1 { namespace ns2 {
 struct Foo {
-  int [[b^ar]];
+  char [[b^ar]];
 };
   }}
   )cpp",
@@ -75,8 +75,10 @@
  HI.LocalScope = "Foo::";
  HI.Name = "bar";
  HI.Kind = index::SymbolKind::Field;
- HI.Definition = "int bar";
- HI.Type = "int";
+ HI.Definition = "char bar";
+ HI.Type = "char";
+ HI.Offset = 0;
+ HI.Size = 1;
}},
   // Local to class method.
   {R"cpp(
@@ -100,7 +102,7 @@
   {R"cpp(
   namespace ns1 { namespace {
 struct {
-  int [[b^ar]];
+  char [[b^ar]];
 } T;
   }}
   )cpp",
@@ -109,8 +111,21 @@
  HI.LocalScope = "(anonymous struct)::";
  HI.Name = "bar";
  HI.Kind = index::SymbolKind::Field;
- HI.Definition = "int bar";
- HI.Type = "int";
+ HI.Definition = "char bar";
+ HI.Type = "char";
+ HI.Offset = 0;
+ HI.Size = 1;
+   }},
+  // Struct definition shows size.
+  {R"cpp(
+  struct [[^X]]{};
+  )cpp",
+   [](HoverInfo ) {
+ HI.NamespaceScope = "";
+ HI.Name = "X";
+ HI.Kind = index::SymbolKind::Struct;
+ HI.Definition = "struct X {}";
+ HI.Size = 1;
}},
   // Variable with template type
   {R"cpp(
@@ -646,6 +661,8 @@
 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
 EXPECT_EQ(H->SymRange, Expected.SymRange);
 EXPECT_EQ(H->Value, Expected.Value);
+EXPECT_EQ(H->Size, Expected.Size);
+EXPECT_EQ(H->Offset, Expected.Offset);
   }
 }
 
@@ -1810,6 +1827,7 @@
   {
   [](HoverInfo ) {
 HI.Kind = index::SymbolKind::Class;
+HI.Size = 10;
 HI.TemplateParameters = {
 {std::string("typename"), std::string("T"), llvm::None},
 {std::string("typename"), std::string("C"),
@@ -1823,6 +1841,7 @@
   },
   R"(class foo
 
+Size: 10 bytes
 documentation
 
 template  class Foo {})",
Index: clang-tools-extra/clangd/Hover.h
===
--- clang-tools-extra/clangd/Hover.h
+++ clang-tools-extra/clangd/Hover.h
@@ -70,6 +70,10 @@
   llvm::Optional> TemplateParameters;
   /// Contains the evaluated value of the symbol if available.
   llvm::Optional Value;
+  /// Contains the byte-size of fields and types where it's interesting.
+  llvm::Optional Size;
+  /// Contains the offset of fields within the enclosing class.
+  llvm::Optional Offset;
 
   /// Produce a user-readable information.
   markup::Document present() const;
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -563,6 +563,25 @@
  isFollowedByHardLineBreakIndicator(Str, LineBreakIndex);
 }
 
+void addLayoutInfo(const NamedDecl , HoverInfo ) {
+  const auto  = ND.getASTContext();
+
+  if (auto *RD = llvm::dyn_cast())
+if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+  HI.Size = Size->getQuantity();
+
+  if (const auto *FD = llvm::dyn_cast()) {
+const auto *Record = FD->getParent()->getDefinition();
+if (Record && !Record->isDependentType()) {
+  unsigned OffsetBits = Ctx.getFieldOffset(FD);
+  if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) {
+HI.Size = Size->getQuantity();
+HI.Offset = OffsetBits / 8;
+  }
+}
+  }
+}
+
 } // namespace
 
 llvm::Optional getHover(ParsedAST , Position Pos,
@@ -619,6 +638,9 @@
   auto Decls = explicitReferenceTargets(N->ASTNode, DeclRelation::Alias);
   if (!Decls.empty()) {
 HI = getHoverContents(Decls.front(), Index);
+// Layout info only shown when hovering on the field/class itself.
+if (Decls.front() == N->ASTNode.get())
+  addLayoutInfo(*Decls.front(), *HI);
 // Look for a close enclosing expression to show the value of.
 if