qchateau updated this revision to Diff 312545.
qchateau marked 3 inline comments as done.
qchateau added a comment.

I updated this diff according to your review. There are a few things that may 
still need change but I need your input, see my other comments :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93227/new/

https://reviews.llvm.org/D93227

Files:
  clang-tools-extra/clangd/AST.cpp
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp

Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -379,6 +379,30 @@
          HI.Definition = "class X {}";
        }},
 
+      // auto on structured bindings
+      {R"cpp(
+        void foo() {
+          struct S { int x; float y; };
+          [[au^to]] [x, y] = S();
+        }
+        )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "struct S";
+       }},
+      // undeduced auto
+      {R"cpp(
+        template<typename T>
+        void foo() {
+          [[au^to]] x = T{};
+        }
+        )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "/* not deduced */";
+       }},
       // auto on lambda
       {R"cpp(
         void foo() {
@@ -386,8 +410,9 @@
         }
         )cpp",
        [](HoverInfo &HI) {
-         HI.Name = "(lambda)";
-         HI.Kind = index::SymbolKind::Class;
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "class(lambda)";
        }},
       // auto on template instantiation
       {R"cpp(
@@ -397,8 +422,9 @@
         }
         )cpp",
        [](HoverInfo &HI) {
-         HI.Name = "Foo<int>";
-         HI.Kind = index::SymbolKind::Class;
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "class Foo<int>";
        }},
       // auto on specialized template
       {R"cpp(
@@ -409,8 +435,9 @@
         }
         )cpp",
        [](HoverInfo &HI) {
-         HI.Name = "Foo<int>";
-         HI.Kind = index::SymbolKind::Class;
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "class Foo<int>";
        }},
 
       // macro
@@ -582,8 +609,9 @@
           }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Foo<X>";
-            HI.Kind = index::SymbolKind::Class;
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "class Foo<class X>";
           }},
       {// Falls back to primary template, when the type is not instantiated.
        R"cpp(
@@ -955,20 +983,9 @@
   llvm::StringRef Tests[] = {
       "^int main() {}",
       "void foo() {^}",
-      R"cpp(// structured binding. Not supported yet
-            struct Bar {};
-            void foo() {
-              Bar a[2];
-              ^auto [x,y] = a;
-            }
-          )cpp",
-      R"cpp(// Template auto parameter. Nothing (Not useful).
-            template<a^uto T>
-            void func() {
-            }
-            void foo() {
-               func<1>();
-            }
+      "decltype(au^to) x = 0;",
+      R"cpp(// Lambda auto parameter. Nothing (Not useful).
+            auto lamb = [](a^uto){};
           )cpp",
       R"cpp(// non-named decls don't get hover. Don't crash!
             ^static_assert(1, "");
@@ -1545,9 +1562,9 @@
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "int";
-            // FIXME: Should be Builtin/Integral.
-            HI.Kind = index::SymbolKind::Unknown;
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
           }},
       {
           R"cpp(// Simple initialization with const auto
@@ -1555,14 +1572,22 @@
               const ^[[auto]] i = 1;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// Simple initialization with const auto&
             void foo() {
               const ^[[auto]]& i = 1;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// Simple initialization with auto&
             void foo() {
@@ -1570,7 +1595,11 @@
               ^[[auto]]& i = x;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// Simple initialization with auto*
             void foo() {
@@ -1578,7 +1607,23 @@
               ^[[auto]]* i = &a;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
+      {
+          R"cpp(// Simple initialization with auto from pointer
+            void foo() {
+              int a = 1;
+              ^[[auto]] i = &a;
+            }
+          )cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int *";
+          }},
       {
           R"cpp(// Auto with initializer list.
             namespace std
@@ -1591,8 +1636,9 @@
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "initializer_list<int>";
-            HI.Kind = index::SymbolKind::Class;
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "class std::initializer_list<int>";
           }},
       {
           R"cpp(// User defined conversion to auto
@@ -1600,14 +1646,22 @@
               operator ^[[auto]]() const { return 10; }
             };
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// Simple initialization with decltype(auto)
             void foo() {
               ^[[decltype]](auto) i = 1;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// Simple initialization with const decltype(auto)
             void foo() {
@@ -1615,7 +1669,11 @@
               ^[[decltype]](auto) i = j;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "const int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "const int";
+          }},
       {
           R"cpp(// Simple initialization with const& decltype(auto)
             void foo() {
@@ -1624,7 +1682,11 @@
               ^[[decltype]](auto) i = j;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "const int &"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "const int &";
+          }},
       {
           R"cpp(// Simple initialization with & decltype(auto)
             void foo() {
@@ -1633,100 +1695,115 @@
               ^[[decltype]](auto) i = j;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int &"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int &";
+          }},
       {
           R"cpp(// simple trailing return type
             ^[[auto]] main() -> int {
               return 0;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
-          R"cpp(// auto function return with trailing type
+          R"cpp(
             struct Bar {};
+            // auto function return with trailing type
             ^[[auto]] test() -> decltype(Bar()) {
               return Bar();
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "auto function return with trailing type";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
-          R"cpp(// trailing return type
+          R"cpp(
             struct Bar {};
+            // trailing return type
             auto test() -> ^[[decltype]](Bar()) {
               return Bar();
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "trailing return type";
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
-          R"cpp(// auto in function return
+          R"cpp(
             struct Bar {};
+            // auto in function return
             ^[[auto]] test() {
               return Bar();
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "auto in function return";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
-          R"cpp(// auto& in function return
+          R"cpp(
             struct Bar {};
+            // auto& in function return
             ^[[auto]]& test() {
               static Bar x;
               return x;
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "auto& in function return";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
-          R"cpp(// auto* in function return
+          R"cpp(
             struct Bar {};
+            // auto* in function return
             ^[[auto]]* test() {
               Bar* bar;
               return bar;
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "auto* in function return";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
-          R"cpp(// const auto& in function return
+          R"cpp(
             struct Bar {};
+            // const auto& in function return
             const ^[[auto]]& test() {
               static Bar x;
               return x;
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "const auto& in function return";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
-          R"cpp(// decltype(auto) in function return
+          R"cpp(
             struct Bar {};
+            // decltype(auto) in function return
             ^[[decltype]](auto) test() {
               return Bar();
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "decltype(auto) in function return";
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
           R"cpp(// decltype(auto) reference in function return
@@ -1735,7 +1812,11 @@
               return (a);
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int &"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int &";
+          }},
       {
           R"cpp(// decltype lvalue reference
             void foo() {
@@ -1743,7 +1824,11 @@
               ^[[decltype]](I) J = I;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// decltype lvalue reference
             void foo() {
@@ -1752,7 +1837,11 @@
               ^[[decltype]](K) J = I;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int &"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int &";
+          }},
       {
           R"cpp(// decltype lvalue reference parenthesis
             void foo() {
@@ -1760,7 +1849,11 @@
               ^[[decltype]]((I)) J = I;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int &"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int &";
+          }},
       {
           R"cpp(// decltype rvalue reference
             void foo() {
@@ -1768,7 +1861,11 @@
               ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int &&"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int &&";
+          }},
       {
           R"cpp(// decltype rvalue reference function call
             int && bar();
@@ -1777,10 +1874,15 @@
               ^[[decltype]](bar()) J = bar();
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int &&"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int &&";
+          }},
       {
-          R"cpp(// decltype of function with trailing return type.
+          R"cpp(
             struct Bar {};
+            // decltype of function with trailing return type.
             auto test() -> decltype(Bar()) {
               return Bar();
             }
@@ -1789,10 +1891,9 @@
             }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Bar";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation =
-                "decltype of function with trailing return type.";
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct Bar";
           }},
       {
           R"cpp(// decltype of var with decltype.
@@ -1802,13 +1903,33 @@
               ^[[decltype]](J) K = J;
             }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
+      {
+          R"cpp(// decltype of dependent type
+            template <typename T>
+            struct X {
+              using Y = ^[[decltype]](T::Z);
+            };
+          )cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "<dependent type>";
+          }},
       {
           R"cpp(// More complicated structured types.
             int bar();
             ^[[auto]] (*foo)() = bar;
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
           R"cpp(// Should not crash when evaluating the initializer.
             struct Test {};
@@ -1823,32 +1944,88 @@
             HI.Definition = "Test &&test = {}";
           }},
       {
-          R"cpp(// auto on alias
+          R"cpp(
           typedef int int_type;
+          // auto on alias
           ^[[auto]] x = int_type();
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "int"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "int";
+          }},
       {
-          R"cpp(// auto on alias
+          R"cpp(
           struct cls {};
           typedef cls cls_type;
+          // auto on alias
           ^[[auto]] y = cls_type();
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "cls";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "auto on alias";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct cls";
           }},
       {
-          R"cpp(// auto on alias
+          R"cpp(
           template <class>
           struct templ {};
+          // auto on alias
           ^[[auto]] z = templ<int>();
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "templ<int>";
-            HI.Kind = index::SymbolKind::Struct;
-            HI.Documentation = "auto on alias";
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "struct templ<int>";
+          }},
+      {
+          R"cpp(// Undeduced auto declaration
+            template<typename T>
+            void foo() {
+              ^[[auto]] x = T();
+            }
+          )cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "/* not deduced */";
+          }},
+      {
+          R"cpp(// Undeduced auto return type
+            template<typename T>
+            ^[[auto]] foo() {
+              return T();
+            }
+          )cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "/* not deduced */";
+          }},
+      {
+          R"cpp(// Template auto parameter
+            template<[[a^uto]] T>
+              void func() {
+            }
+          )cpp",
+          [](HoverInfo &HI) {
+            // FIXME: not sure this is what we want, but this
+            // is what we currently get with getDeducedType
+            HI.Name = "auto";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "/* not deduced */";
+          }},
+      {
+          R"cpp(// Undeduced decltype(auto) return type
+            template<typename T>
+            ^[[decltype]](auto) foo() {
+              return T();
+            }
+          )cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "decltype";
+            HI.Kind = index::SymbolKind::TypeAlias;
+            HI.Definition = "/* not deduced */";
           }},
       {
           R"cpp(// should not crash.
@@ -2030,7 +2207,10 @@
             };
           }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "Foo *"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "this";
+            HI.Definition = "Foo *";
+          }},
       {
           R"cpp(// this expr for template class
           namespace ns {
@@ -2042,7 +2222,10 @@
             };
           }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "const Foo<T> *"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "this";
+            HI.Definition = "const Foo<T> *";
+          }},
       {
           R"cpp(// this expr for specialization class
           namespace ns {
@@ -2055,7 +2238,10 @@
             };
           }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "Foo<int> *"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "this";
+            HI.Definition = "Foo<int> *";
+          }},
       {
           R"cpp(// this expr for partial specialization struct
           namespace ns {
@@ -2068,7 +2254,10 @@
             };
           }
           )cpp",
-          [](HoverInfo &HI) { HI.Name = "const Foo<int, F> *"; }},
+          [](HoverInfo &HI) {
+            HI.Name = "this";
+            HI.Definition = "const Foo<int, F> *";
+          }},
   };
 
   // Create a tiny index, so tests above can verify documentation is fetched.
@@ -2119,7 +2308,7 @@
   Annotations T(R"cpp(
   template <typename T> class X {};
   void foo() {
-    au^to t = X<int>();
+    auto t = X<int>();
     X^<int> w;
     (void)w;
   })cpp");
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
@@ -550,29 +551,6 @@
   return HI;
 }
 
-/// Generate a \p Hover object given the type \p T.
-HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
-                           const SymbolIndex *Index,
-                           bool SuppressScope = false) {
-  HoverInfo HI;
-
-  if (const auto *D = T->getAsTagDecl()) {
-    HI.Name = printName(ASTCtx, *D);
-    HI.Kind = index::getSymbolInfo(D).Kind;
-
-    const auto *CommentD = getDeclForComment(D);
-    HI.Documentation = getDeclComment(ASTCtx, *CommentD);
-    enhanceFromIndex(HI, *CommentD, Index);
-  } else {
-    // Builtin types
-    auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
-    Policy.SuppressTagKeyword = true;
-    Policy.SuppressScope = SuppressScope;
-    HI.Name = T.getAsString(Policy);
-  }
-  return HI;
-}
-
 /// Generate a \p Hover object given the macro \p MacroDecl.
 HoverInfo getHoverContents(const DefinedMacro &Macro, ParsedAST &AST) {
   HoverInfo HI;
@@ -608,6 +586,54 @@
   return HI;
 }
 
+llvm::Optional<HoverInfo> getThisExprHoverContents(const CXXThisExpr *CTE,
+                                                   ASTContext &ASTCtx,
+                                                   const SymbolIndex *Index) {
+  QualType OriginThisType = CTE->getType()->getPointeeType();
+  QualType ClassType = declaredType(OriginThisType->getAsTagDecl());
+  // For partial specialization class, origin `this` pointee type will be
+  // parsed as `InjectedClassNameType`, which will ouput template arguments
+  // like "type-parameter-0-0". So we retrieve user written class type in this
+  // case.
+  QualType PrettyThisType = ASTCtx.getPointerType(
+      QualType(ClassType.getTypePtr(), OriginThisType.getCVRQualifiers()));
+
+  auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
+  Policy.SuppressTagKeyword = true;
+  Policy.SuppressScope = true;
+  HoverInfo HI;
+  HI.Name = "this";
+  HI.Definition = PrettyThisType.getAsString(Policy);
+  return HI;
+}
+
+/// Generate a HoverInfo object given the deduced type \p QT
+HoverInfo getDeducedTypeHoverContents(QualType QT, const syntax::Token &Tok,
+                                      ASTContext &ASTCtx,
+                                      const SymbolIndex *Index) {
+  HoverInfo HI;
+  // FIXME: distinguish decltype(auto) vs decltype(expr)
+  HI.Name = tok::getTokenName(Tok.kind());
+  HI.Kind = index::SymbolKind::TypeAlias;
+
+  auto PP = printingPolicyForDecls(ASTCtx.getLangOpts());
+  PP.SuppressTagKeyword = false;
+
+  if (QT->isUndeducedAutoType()) {
+    HI.Definition = "/* not deduced */";
+  } else {
+    HI.Definition = QT.getAsString(PP);
+
+    if (const auto *D = QT->getAsTagDecl()) {
+      const auto *CommentD = getDeclForComment(D);
+      HI.Documentation = getDeclComment(ASTCtx, *CommentD);
+      enhanceFromIndex(HI, *CommentD, Index);
+    }
+  }
+
+  return HI;
+}
+
 bool isLiteral(const Expr *E) {
   // Unfortunately there's no common base Literal classes inherits from
   // (apart from Expr), therefore these exclusions.
@@ -642,16 +668,7 @@
   HoverInfo HI;
   // For `this` expr we currently generate hover with pointee type.
   if (const CXXThisExpr *CTE = dyn_cast<CXXThisExpr>(E)) {
-    QualType OriginThisType = CTE->getType()->getPointeeType();
-    QualType ClassType = declaredType(OriginThisType->getAsTagDecl());
-    // For partial specialization class, origin `this` pointee type will be
-    // parsed as `InjectedClassNameType`, which will ouput template arguments
-    // like "type-parameter-0-0". So we retrieve user written class type in this
-    // case.
-    QualType PrettyThisType = AST.getASTContext().getPointerType(
-        QualType(ClassType.getTypePtr(), OriginThisType.getCVRQualifiers()));
-    return getHoverContents(PrettyThisType, AST.getASTContext(), Index,
-                            /*SuppressScope=*/true);
+    return getThisExprHoverContents(CTE, AST.getASTContext(), Index);
   }
   // For expressions we currently print the type and the value, iff it is
   // evaluatable.
@@ -849,10 +866,16 @@
       }
     } else if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
       if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) {
-        HI = getHoverContents(*Deduced, AST.getASTContext(), Index);
+        HI = getDeducedTypeHoverContents(*Deduced, Tok, AST.getASTContext(),
+                                         Index);
         HighlightRange = Tok.range(SM).toCharRange(SM);
         break;
       }
+
+      // If we can't find interesting hover information for this
+      // auto/decltype keyword, return nothing to avoid showing
+      // irrelevant or incorrect informations.
+      return llvm::None;
     }
   }
 
Index: clang-tools-extra/clangd/AST.cpp
===================================================================
--- clang-tools-extra/clangd/AST.cpp
+++ clang-tools-extra/clangd/AST.cpp
@@ -350,8 +350,7 @@
       return true;
 
     if (auto *AT = D->getType()->getContainedAutoType()) {
-      if (!AT->getDeducedType().isNull())
-        DeducedType = AT->getDeducedType();
+      DeducedType = AT->desugar();
     }
     return true;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to