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) {
+         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) {
             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 <typename T, typename C = bool> class Foo {})",
@@ -1859,19 +1878,23 @@
       },
       {
           [](HoverInfo &HI) {
-            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<std::vector<Param>> TemplateParameters;
   /// Contains the evaluated value of the symbol if available.
   llvm::Optional<std::string> Value;
+  /// Contains the byte-size of fields and types where it's interesting.
+  llvm::Optional<uint64_t> Size;
+  /// Contains the offset of fields within the enclosing class.
+  llvm::Optional<uint64_t> 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 &ND, HoverInfo &HI) {
+  const auto &Ctx = ND.getASTContext();
+
+  if (auto *RD = llvm::dyn_cast<RecordDecl>(&ND)) {
+    if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+      HI.Size = Size->getQuantity();
+    return;
+  }
+
+  if (const auto *FD = llvm::dyn_cast<FieldDecl>(&ND)) {
+    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;
+  }
+}
+
 } // namespace
 
 llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
@@ -619,6 +641,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<Decl>())
+          addLayoutInfo(*Decls.front(), *HI);
         // Look for a close enclosing expression to show the value of.
         if (!HI->Value)
           HI->Value = printExprValue(N, AST.getASTContext());
@@ -694,6 +719,13 @@
     P.appendCode(*Value);
   }
 
+  if (Offset)
+    Output.addParagraph().appendText(
+        llvm::formatv("Offset: {0} byte{1}", *Offset, *Offset == 1 ? "" : "s"));
+  if (Size)
+    Output.addParagraph().appendText(
+        llvm::formatv("Size: {0} byte{1}", *Size, *Size == 1 ? "" : "s"));
+
   if (!Documentation.empty())
     parseDocumentation(Documentation, Output);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to