sammccall updated this revision to Diff 453652.
sammccall added a comment.
fix type to be const in both c & c++, not sure where I got that idea from...
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits