Index: clang-tools-extra/clangd/Hover.cpp =================================================================== --- clang-tools-extra/clangd/Hover.cpp +++ clang-tools-extra/clangd/Hover.cpp @@ -1008,12 +1008,15 @@ const auto *Record = FD->getParent(); if (Record) Record = Record->getDefinition(); - if (Record && !Record->isInvalidDecl() && !Record->isDependentType() && - !FD->isBitField()) { + if (Record && !Record->isInvalidDecl() && !Record->isDependentType()) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record); HI.Offset = Layout.getFieldOffset(FD->getFieldIndex()) / 8; - if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) { + if (FD->isBitField()) { + const auto SizeInBits = FD->getBitWidthValue(Ctx); + HI.Size = (SizeInBits + 7) >> 3; + } else if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity(); + if (HI.Size) { unsigned EndOfField = *HI.Offset + *HI.Size; // Calculate padding following the field. Index: clang-tools-extra/clangd/unittests/HoverTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/HoverTests.cpp +++ clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -125,6 +125,8 @@ HI.Kind = index::SymbolKind::Field; HI.Definition = "int x : 1"; HI.Type = "int"; + HI.Offset = 0; + HI.Size = 1; HI.AccessSpecifier = "public"; }}, // Local to class method. @@ -1285,6 +1287,26 @@ HI.Kind = index::SymbolKind::Field; HI.Definition = "m_int arr[Size]"; HI.Type = {"m_int[Size]", "int[Size]"}; + }}, + {// Bitfield offset, size and padding + R"cpp( + struct Foo { + char x; + char [[^y]] : 1; + int z; + }; + )cpp", + [](HoverInfo &HI) { + HI.NamespaceScope = ""; + HI.LocalScope = "Foo::"; + HI.Name = "y"; + HI.Kind = index::SymbolKind::Field; + HI.Definition = "char y : 1"; + HI.Type = "char"; + HI.Offset = 1; + HI.Size = 1; + HI.Padding = 2; + HI.AccessSpecifier = "public"; }}}; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code);