This revision was automatically updated to reflect the committed changes.
Closed by commit rG13b2a0c69ba6: [clangd] Support hover on __func__ etc 
(PredefinedExpr) (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132135

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

Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -527,6 +527,10 @@
         /*error-ok*/
         void func() [[{^]])cpp",
        "CompoundStmt"},
+      {R"cpp(
+        void func() { [[__^func__]]; }
+        )cpp",
+       "PredefinedExpr"},
   };
 
   for (const Case &C : Cases) {
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -139,6 +139,33 @@
          HI.Definition = "int bar";
          HI.Type = "int";
        }},
+      // Predefined variable
+      {R"cpp(
+          void foo() {
+            [[__f^unc__]];
+          }
+          )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "__func__";
+         HI.Kind = index::SymbolKind::Variable;
+         HI.Documentation =
+             "Name of the current function (predefined variable)";
+         HI.Value = "\"foo\"";
+         HI.Type = "const char[4]";
+       }},
+      // Predefined variable (dependent)
+      {R"cpp(
+          template<int> void foo() {
+            [[__f^unc__]];
+          }
+          )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "__func__";
+         HI.Kind = index::SymbolKind::Variable;
+         HI.Documentation =
+             "Name of the current function (predefined variable)";
+         HI.Type = "const char[]";
+       }},
       // Anon namespace and local scope.
       {R"cpp(
           namespace ns1 { namespace {
Index: clang-tools-extra/clangd/Selection.cpp
===================================================================
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -720,6 +720,14 @@
     return Base::TraverseTypeConstraint(C);
   }
 
+  // Override child traversal for certain node types.
+  using RecursiveASTVisitor::getStmtChildren;
+  // PredefinedExpr like __func__ has a StringLiteral child for its value.
+  // It's not written, so don't traverse it.
+  Stmt::child_range getStmtChildren(PredefinedExpr *) {
+    return {StmtIterator{}, StmtIterator{}};
+  }
+
 private:
   using Base = RecursiveASTVisitor<SelectionVisitor>;
 
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -32,6 +32,7 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/CharInfo.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TokenKinds.h"
@@ -640,6 +641,29 @@
   return HI;
 }
 
+/// The standard defines __func__ as a "predefined variable".
+llvm::Optional<HoverInfo>
+getPredefinedExprHoverContents(const PredefinedExpr &PE, ASTContext &Ctx,
+                               const PrintingPolicy &PP) {
+  HoverInfo HI;
+  HI.Name = PE.getIdentKindName();
+  HI.Kind = index::SymbolKind::Variable;
+  HI.Documentation = "Name of the current function (predefined variable)";
+  if (const StringLiteral *Name = PE.getFunctionName()) {
+    HI.Value.emplace();
+    llvm::raw_string_ostream OS(*HI.Value);
+    Name->outputString(OS);
+    HI.Type = printType(Name->getType(), Ctx, PP);
+  } else {
+    // Inside templates, the approximate type `const char[]` is still useful.
+    QualType StringType = Ctx.getIncompleteArrayType(
+        Ctx.CharTy.withConst(), ArrayType::ArraySizeModifier::Normal,
+        /*IndexTypeQuals=*/0);
+    HI.Type = printType(StringType, Ctx, PP);
+  }
+  return HI;
+}
+
 /// Generate a \p Hover object given the macro \p MacroDecl.
 HoverInfo getHoverContents(const DefinedMacro &Macro, ParsedAST &AST) {
   HoverInfo HI;
@@ -764,6 +788,8 @@
   // For `this` expr we currently generate hover with pointee type.
   if (const CXXThisExpr *CTE = dyn_cast<CXXThisExpr>(E))
     return getThisExprHoverContents(CTE, AST.getASTContext(), PP);
+  if (const PredefinedExpr *PE = dyn_cast<PredefinedExpr>(E))
+    return getPredefinedExprHoverContents(*PE, AST.getASTContext(), PP);
   // For expressions we currently print the type and the value, iff it is
   // evaluatable.
   if (auto Val = printExprValue(E, AST.getASTContext())) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to