Author: Sam McCall Date: 2021-03-02T16:33:02+01:00 New Revision: 289fee4ab7626447a7efcc245eba2f475d00810e
URL: https://github.com/llvm/llvm-project/commit/289fee4ab7626447a7efcc245eba2f475d00810e DIFF: https://github.com/llvm/llvm-project/commit/289fee4ab7626447a7efcc245eba2f475d00810e.diff LOG: [clangd] Show hex value of numeric constants Don't show negative numbers Don't show numbers <10 (hex is the same as decimal) Show numeric enum values in hex too Differential Revision: https://reviews.llvm.org/D97226 Added: Modified: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 82c3ccbab47c..f9de91083558 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -43,6 +43,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <string> @@ -347,6 +348,19 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D, // FIXME: handle variadics. } +// Non-negative numbers are printed using min digits +// 0 => 0x0 +// 100 => 0x64 +// Negative numbers are sign-extended to 32/64 bits +// -2 => 0xfffffffe +// -2^32 => 0xfffffffeffffffff +static llvm::FormattedNumber printHex(const llvm::APSInt &V) { + uint64_t Bits = V.getExtValue(); + if (V.isNegative() && V.getMinSignedBits() <= 32) + return llvm::format_hex(uint32_t(Bits), 0); + return llvm::format_hex(Bits, 0); +} + llvm::Optional<std::string> printExprValue(const Expr *E, const ASTContext &Ctx) { // InitListExpr has two forms, syntactic and semantic. They are the same thing @@ -381,8 +395,17 @@ llvm::Optional<std::string> printExprValue(const Expr *E, for (const EnumConstantDecl *ECD : T->castAs<EnumType>()->getDecl()->enumerators()) if (ECD->getInitVal() == Val) - return llvm::formatv("{0} ({1})", ECD->getNameAsString(), Val).str(); + return llvm::formatv("{0} ({1})", ECD->getNameAsString(), + printHex(Constant.Val.getInt())) + .str(); } + // Show hex value of integers if they're at least 10 (or negative!) + if (T->isIntegralOrEnumerationType() && + Constant.Val.getInt().getMinSignedBits() <= 64 && + Constant.Val.getInt().uge(10)) + return llvm::formatv("{0} ({1})", Constant.Val.getAsString(Ctx, T), + printHex(Constant.Val.getInt())) + .str(); return Constant.Val.getAsString(Ctx, T); } diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 77ff91c761aa..6624290ec41c 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -490,30 +490,30 @@ class Foo {})cpp"; HI.Value = "3"; }}, {R"cpp( - enum Color { RED, GREEN, }; + enum Color { RED = -123, GREEN = 5, }; Color x = [[GR^EEN]]; )cpp", [](HoverInfo &HI) { HI.Name = "GREEN"; HI.NamespaceScope = ""; HI.LocalScope = "Color::"; - HI.Definition = "GREEN"; + HI.Definition = "GREEN = 5"; HI.Kind = index::SymbolKind::EnumConstant; HI.Type = "enum Color"; - HI.Value = "1"; // Numeric when hovering on the enumerator name. + HI.Value = "5"; // Numeric on the enumerator name, no hex as small. }}, {R"cpp( - enum Color { RED, GREEN, }; - Color x = GREEN; + enum Color { RED = -123, GREEN = 5, }; + Color x = RED; Color y = [[^x]]; )cpp", [](HoverInfo &HI) { HI.Name = "x"; HI.NamespaceScope = ""; - HI.Definition = "Color x = GREEN"; + HI.Definition = "Color x = RED"; HI.Kind = index::SymbolKind::Variable; HI.Type = "enum Color"; - HI.Value = "GREEN (1)"; // Symbolic when hovering on an expression. + HI.Value = "RED (0xffffff85)"; // Symbolic on an expression. }}, {R"cpp( template<int a, int b> struct Add { @@ -543,7 +543,7 @@ class Foo {})cpp"; HI.ReturnType = "int"; HI.Parameters.emplace(); HI.NamespaceScope = ""; - HI.Value = "42"; + HI.Value = "42 (0x2a)"; }}, {R"cpp( const char *[[ba^r]] = "1234"; @@ -1468,12 +1468,12 @@ TEST(Hover, All) { HI.Definition = "static int hey = 10"; HI.Documentation = "Global variable"; // FIXME: Value shouldn't be set in this case - HI.Value = "10"; + HI.Value = "10 (0xa)"; }}, { R"cpp(// Global variable in namespace namespace ns1 { - static int hey = 10; + static long long hey = -36637162602497; } void foo() { ns1::[[he^y]]++; @@ -1483,9 +1483,9 @@ TEST(Hover, All) { HI.Name = "hey"; HI.Kind = index::SymbolKind::Variable; HI.NamespaceScope = "ns1::"; - HI.Type = "int"; - HI.Definition = "static int hey = 10"; - HI.Value = "10"; + HI.Type = "long long"; + HI.Definition = "static long long hey = -36637162602497"; + HI.Value = "-36637162602497 (0xffffdeadbeefffff)"; // needs 64 bits }}, { R"cpp(// Field in anonymous struct _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits