[clangd] Disable printing of Value for tag-types on hover
authorKadir Cetinkaya <kadircet@google.com>
Mon, 22 Jun 2020 19:53:47 +0000 (21:53 +0200)
committerKadir Cetinkaya <kadircet@google.com>
Wed, 24 Jun 2020 15:32:19 +0000 (17:32 +0200)
Summary: This is both confusing and crashy.

Reviewers: sammccall

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82326

clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

index 2861d63..3d5d002 100644 (file)
@@ -341,7 +341,10 @@ llvm::Optional<std::string> printExprValue(const Expr *E,
       T->isFunctionReferenceType())
     return llvm::None;
   // Attempt to evaluate. If expr is dependent, evaluation crashes!
-  if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx))
+  if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx) ||
+      // Disable printing for record-types, as they are usually confusing and
+      // might make clang crash while printing the expressions.
+      Constant.Val.isStruct() || Constant.Val.isUnion())
     return llvm::None;
 
   // Show enums symbolically, not numerically like APValue::printPretty().
@@ -353,7 +356,7 @@ llvm::Optional<std::string> printExprValue(const Expr *E,
       if (ECD->getInitVal() == Val)
         return llvm::formatv("{0} ({1})", ECD->getNameAsString(), Val).str();
   }
-  return Constant.Val.getAsString(Ctx, E->getType());
+  return Constant.Val.getAsString(Ctx, T);
 }
 
 llvm::Optional<std::string> printExprValue(const SelectionTree::Node *N,
index dc818ea..c6c0daa 100644 (file)
@@ -696,6 +696,18 @@ class Foo {})cpp";
          HI.Parameters->back().Name = "v";
          HI.AccessSpecifier = "public";
        }},
+      {// Field type initializer.
+       R"cpp(
+          struct X { int x = 2; };
+          X ^[[x]];
+          )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "x";
+         HI.Kind = index::SymbolKind::Variable;
+         HI.NamespaceScope = "";
+         HI.Definition = "X x";
+         HI.Type = "struct X";
+       }},
   };
   for (const auto &Case : Cases) {
     SCOPED_TRACE(Case.Code);
@@ -978,13 +990,14 @@ TEST(Hover, All) {
             HI.LocalScope = "Foo::";
             HI.Type = "int";
             HI.Definition = "int x";
-            HI.Value = "{1}";
+            // FIXME: Initializer for x is a DesignatedInitListExpr, hence it is
+            // of struct type and omitted.
           }},
       {
           R"cpp(// Field, field designator
-            struct Foo { int x; };
+            struct Foo { int x; int y; };
             int main() {
-              Foo bar = { .^[[x]] = 2 };
+              Foo bar = { .^[[x]] = 2, .y = 2 };
             }
           )cpp",
           [](HoverInfo &HI) {
@@ -994,7 +1007,6 @@ TEST(Hover, All) {
             HI.LocalScope = "Foo::";
             HI.Type = "int";
             HI.Definition = "int x";
-            HI.Value = "{2}";
           }},
       {
           R"cpp(// Method call
@@ -1592,7 +1604,6 @@ TEST(Hover, All) {
             HI.LocalScope = "test::";
             HI.Type = "struct Test &&";
             HI.Definition = "Test &&test = {}";
-            HI.Value = "{}";
           }},
       {
           R"cpp(// auto on alias
@@ -1651,7 +1662,6 @@ TEST(Hover, All) {
             HI.NamespaceScope = "";
             HI.Name = "foo";
             HI.Type = "cls<cls<cls<int>>>";
-            HI.Value = "{}";
           }},
       {
           R"cpp(// type of nested templates.