diff clang-tools-extra/clangd/Hover.cpp @ 223:5f17cb93ff66 llvm-original

LLVM13 (2021/7/18)
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 18 Jul 2021 22:43:00 +0900
parents 79ff65ed7e25
children c4bab56944e8
line wrap: on
line diff
--- a/clang-tools-extra/clangd/Hover.cpp	Sun Jul 18 22:10:01 2021 +0900
+++ b/clang-tools-extra/clangd/Hover.cpp	Sun Jul 18 22:43:00 2021 +0900
@@ -28,6 +28,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
@@ -587,7 +588,7 @@
   } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
     // Dependent enums (e.g. nested in template classes) don't have values yet.
     if (!ECD->getType()->isDependentType())
-      HI.Value = ECD->getInitVal().toString(10);
+      HI.Value = toString(ECD->getInitVal(), 10);
   }
 
   HI.Definition = printDefinition(D, PP);
@@ -770,10 +771,30 @@
     const auto *Record = FD->getParent();
     if (Record)
       Record = Record->getDefinition();
-    if (Record && !Record->isInvalidDecl() && !Record->isDependentType()) {
-      HI.Offset = Ctx.getFieldOffset(FD) / 8;
-      if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType()))
-        HI.Size = Size->getQuantity();
+    if (Record && !Record->isInvalidDecl() && !Record->isDependentType() &&
+        !FD->isBitField()) {
+      const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record);
+      HI.Offset = Layout.getFieldOffset(FD->getFieldIndex()) / 8;
+      if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) {
+        HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity();
+        unsigned EndOfField = *HI.Offset + *HI.Size;
+
+        // Calculate padding following the field.
+        if (!Record->isUnion() &&
+            FD->getFieldIndex() + 1 < Layout.getFieldCount()) {
+          // Measure padding up to the next class field.
+          unsigned NextOffset =
+              Layout.getFieldOffset(FD->getFieldIndex() + 1) / 8;
+          if (NextOffset >= EndOfField) // next field could be a bitfield!
+            HI.Padding = NextOffset - EndOfField;
+        } else {
+          // Measure padding up to the end of the object.
+          HI.Padding = Layout.getSize().getQuantity() - EndOfField;
+        }
+      }
+      // Offset in a union is always zero, so not really useful to report.
+      if (Record->isUnion())
+        HI.Offset.reset();
     }
     return;
   }
@@ -1013,9 +1034,12 @@
     Output.addParagraph().appendText(
         llvm::formatv("Offset: {0} byte{1}", *Offset, *Offset == 1 ? "" : "s")
             .str());
-  if (Size)
-    Output.addParagraph().appendText(
+  if (Size) {
+    auto &P = Output.addParagraph().appendText(
         llvm::formatv("Size: {0} byte{1}", *Size, *Size == 1 ? "" : "s").str());
+    if (Padding && *Padding != 0)
+      P.appendText(llvm::formatv(" (+{0} padding)", *Padding).str());
+  }
 
   if (CalleeArgInfo) {
     assert(CallPassType);