kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added subscribers: cfe-commits, arphaman, jkorous, MaskRay,
ilya-biryukov.
Herald added a project: clang.
Put a symbols value information which is deduced from initializer
expression into HoverInfo struct.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D63330
Files:
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/XRefs.h
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -661,15 +661,16 @@
}},
// Variable with template type
{R"cpp(
- template <typename T, class... Ts> class Foo {};
- Foo<int, char, bool> [[fo^o]];
+ template <typename T, class... Ts> class Foo { public: Foo(int); };
+ Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
)cpp",
[](HoverInfo &HI) {
HI.NamespaceScope = "";
HI.Name = "foo";
HI.Kind = SymbolKind::Variable;
- HI.Definition = "Foo<int, char, bool> foo";
+ HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
HI.Type = "Foo<int, char, bool>";
+ HI.Value = "Foo<int, char, bool>(5)";
}},
// Implicit template instantiation
{R"cpp(
@@ -786,6 +787,7 @@
{std::string("int"), std::string("T"), llvm::None},
{std::string("bool"), std::string("B"), llvm::None},
};
+ HI.Value = "&b";
return HI;
}},
// Lambda parameter with decltype reference
@@ -850,6 +852,7 @@
{std::string("int"), std::string("T"), llvm::None},
{std::string("bool"), std::string("B"), llvm::None},
};
+ HI.Value = "[&bar](int T, bool B) -> bool {}";
return HI;
}},
// Local variable in lambda
@@ -911,6 +914,72 @@
HI.Name = "MACRO", HI.Kind = SymbolKind::String,
HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z);";
}},
+
+ // constexprs
+ {R"cpp(
+ constexpr int add(int a, int b) { return a + b; }
+ int [[b^ar]] = add(1, 2);
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "bar";
+ HI.Definition = "int bar = add(1, 2)";
+ HI.Kind = SymbolKind::Variable;
+ HI.Type = "int";
+ HI.NamespaceScope = "";
+ HI.Value = "3";
+ }},
+ {R"cpp(
+ int [[b^ar]] = sizeof(char);
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "bar";
+ HI.Definition = "int bar = sizeof(char)";
+ HI.Kind = SymbolKind::Variable;
+ HI.Type = "int";
+ HI.NamespaceScope = "";
+ HI.Value = "1";
+ }},
+ {R"cpp(
+ template<int a, int b> struct Add {
+ static constexpr int result = a + b;
+ };
+ int [[ba^r]] = Add<1, 2>::result;
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "bar";
+ HI.Definition = "int bar = Add<1, 2>::result";
+ HI.Kind = SymbolKind::Variable;
+ HI.Type = "int";
+ HI.NamespaceScope = "";
+ HI.Value = "3";
+ }},
+ // FIXME: We should use TypeLoc instead of Decl to extract the concrete
+ // value.
+ {R"cpp(
+ template<int a, int b> struct Add {
+ static constexpr int result = a + b;
+ };
+ int bar = Add<1, 2>::[[resu^lt]];
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "result";
+ HI.Definition = "static constexpr int result = a + b";
+ HI.Kind = SymbolKind::Property;
+ HI.Type = "const int";
+ HI.NamespaceScope = "";
+ HI.LocalScope = "Add::";
+ }},
+ {R"cpp(
+ const char *[[ba^r]] = "1234";
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "bar";
+ HI.Definition = "const char *bar = \"1234\"";
+ HI.Kind = SymbolKind::Variable;
+ HI.Type = "const char *";
+ HI.NamespaceScope = "";
+ HI.Value = "&\"1234\"[0]";
+ }},
};
for (const auto &Case : Cases) {
SCOPED_TRACE(Case.Code);
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -103,6 +103,8 @@
llvm::Optional<std::vector<Param>> Parameters;
/// Set for all templates(function, class, variable).
llvm::Optional<std::vector<Param>> TemplateParameters;
+ /// Contains the initializer expression or constant folded result.
+ llvm::Optional<std::string> Value;
/// Produce a user-readable information.
FormattedString present() const;
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -719,6 +719,22 @@
VD->getType().print(OS, Policy);
}
+ // Fill in value with initializer. Puts evaluated version if possible.
+ if (const auto *Var = dyn_cast<VarDecl>(D)) {
+ if (const Expr *Init = Var->getInit()) {
+ if (!Init->isValueDependent()) {
+ Expr::EvalResult Result;
+ HI.Value.emplace();
+ llvm::raw_string_ostream ValueOS(*HI.Value);
+ if (Init->EvaluateAsRValue(Result, Ctx))
+ Result.Val.printPretty(ValueOS, const_cast<ASTContext &>(Ctx),
+ Var->getType());
+ else
+ Init->printPretty(ValueOS, nullptr, Policy);
+ }
+ }
+ }
+
HI.Definition = printDefinition(D);
return HI;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits