[clang-tools-extra] 289fee4 - [clangd] Show hex value of numeric constants

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 2 07:33:14 PST 2021


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


        


More information about the cfe-commits mailing list