qchateau updated this revision to Diff 312432.
qchateau added a comment.

- Rebase on master after D92041 <https://reviews.llvm.org/D92041>
- Remove the usage of the "Documentation" field
- Use the `TypeAlias` Kind on auto and decltype
- Move code related to hover on `this` in a new function
- Update hover on `this` to be consistent with this change


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/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,42 @@
          HI.Definition = "class X {}";
        }},
 
+      // auto on structured bindings
+      {R"cpp(
+        void foo() {
+          int arr[2];
+          [[au^to]] [x, y] = arr;
+        }
+        )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "int[2]";
+       }},
+      // 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 +422,9 @@
         }
         )cpp",
        [](HoverInfo &HI) {
-         HI.Name = "(lambda)";
-         HI.Kind = index::SymbolKind::Class;
+         HI.Name = "auto";
+         HI.Kind = index::SymbolKind::TypeAlias;
+         HI.Definition = "(lambda)";
        }},
       // auto on template instantiation
       {R"cpp(
@@ -397,8 +434,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 +447,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 +621,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,12 +995,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;
-            }
+      "decltype(au^to) x = 0;",
+      R"cpp(// Lambda auto parameter. Nothing (Not useful).
+            auto lamb = [](a^uto){};
           )cpp",
       R"cpp(// Template auto parameter. Nothing (Not useful).
             template<a^uto T>
@@ -1545,9 +1582,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 +1592,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 +1615,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 +1627,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 +1656,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 +1666,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 +1689,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 +1702,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,14 +1715,22 @@
               ^[[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
             struct Bar {};
@@ -1649,9 +1739,9 @@
             }
           )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
@@ -1661,9 +1751,9 @@
             }
           )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
@@ -1673,9 +1763,9 @@
             }
           )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
@@ -1686,9 +1776,9 @@
             }
           )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
@@ -1699,9 +1789,9 @@
             }
           )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
@@ -1712,9 +1802,9 @@
             }
           )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
@@ -1724,9 +1814,9 @@
             }
           )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 +1825,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 +1837,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 +1850,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 +1862,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 +1874,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,7 +1887,11 @@
               ^[[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.
             struct Bar {};
@@ -1789,10 +1903,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 +1915,21 @@
               ^[[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(// 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 {};
@@ -1827,7 +1948,11 @@
           typedef int int_type;
           ^[[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
           struct cls {};
@@ -1835,9 +1960,9 @@
           ^[[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
@@ -1846,9 +1971,45 @@
           ^[[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(// 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 +2191,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 +2206,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 +2222,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 +2238,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 +2292,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");
@@ -2150,10 +2323,9 @@
   // doc
   template <typename T> T baz;
   void foo() {
-    au^to t = X<int>();
     X^<int>();
     b^ar<int>();
-    au^to T = ba^z<X<int>>;
+    auto T = ba^z<X<int>>;
     ba^z<int> = 0;
   })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,79 @@
   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) {
+  HoverInfo HI;
+  HI.Kind = index::SymbolKind::TypeAlias;
+
+  if (QT->isUndeducedAutoType()) {
+    HI.Definition = "/* not deduced */";
+  } else {
+    CXXRecordDecl *D = QT->getAsCXXRecordDecl();
+    if (D && D->isLambda())
+      HI.Definition = "(lambda)";
+    else
+      HI.Definition = QT.getAsString();
+  }
+
+  return HI;
+}
+
+/// Visit the relevant nodes to display hover information over an "auto"
+/// keyword or "decltype()" expression. Only types not returned by
+// getDeducedType are handled.
+class ExtraAutoTypeHoverVisitor
+    : public RecursiveASTVisitor<ExtraAutoTypeHoverVisitor> {
+  SourceLocation SearchedLocation;
+
+public:
+  ExtraAutoTypeHoverVisitor(SourceLocation SearchedLocation)
+      : SearchedLocation(SearchedLocation) {}
+
+  bool VisitDeclaratorDecl(DeclaratorDecl *D) {
+    if (!D->getTypeSourceInfo() ||
+        D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
+      return true;
+
+    if (isa<NonTypeTemplateParmDecl, ParmVarDecl>(D)) {
+      // Handle template<auto k> and [](auto){}
+      // FIXME: Until we have something useful to display, just display nothing
+    } else {
+      // At this point only a few cases are left:
+      // - decomposition of arrays
+      // - undeduced auto in a declaration
+      // Just give the declaration type to getDeducedTypeHoverContents
+      // which will handle it
+      HI = getDeducedTypeHoverContents(D->getType());
+    }
+
+    return false;
+  }
+
+  llvm::Optional<HoverInfo> HI;
+};
+
 bool isLiteral(const Expr *E) {
   // Unfortunately there's no common base Literal classes inherits from
   // (apart from Expr), therefore these exclusions.
@@ -642,16 +693,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 +891,22 @@
       }
     } 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);
-        HighlightRange = Tok.range(SM).toCharRange(SM);
-        break;
+        HI = getDeducedTypeHoverContents(*Deduced);
+      } else {
+        ExtraAutoTypeHoverVisitor V(Tok.location());
+        V.TraverseAST(AST.getASTContext());
+        HI = V.HI;
       }
+
+      // If we can't find interesting hover information for this
+      // auto/decltype keyword, return nothing to avoid showing
+      // irrelevant or incorrect informations.
+      if (!HI)
+        return llvm::None;
+
+      HI->Name = tok::getTokenName(Tok.kind());
+      HighlightRange = Tok.range(SM).toCharRange(SM);
+      break;
     }
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to