[clang-tools-extra] r364390 - [clangd] Add Value field to HoverInfo
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 26 01:00:25 PDT 2019
Author: kadircet
Date: Wed Jun 26 01:00:24 2019
New Revision: 364390
URL: http://llvm.org/viewvc/llvm-project?rev=364390&view=rev
Log:
[clangd] Add Value field to HoverInfo
Summary:
Put a symbols value information which is deduced from initializer
expression into HoverInfo struct.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63330
Modified:
clang-tools-extra/trunk/clangd/XRefs.cpp
clang-tools-extra/trunk/clangd/XRefs.h
clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=364390&r1=364389&r2=364390&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Wed Jun 26 01:00:24 2019
@@ -707,6 +707,21 @@ static HoverInfo getHoverContents(const
VD->getType().print(OS, Policy);
}
+ // Fill in value with evaluated initializer if possible.
+ // FIXME(kadircet): Also set Value field for expressions like "sizeof" and
+ // function calls.
+ if (const auto *Var = dyn_cast<VarDecl>(D)) {
+ if (const Expr *Init = Var->getInit()) {
+ Expr::EvalResult Result;
+ if (!Init->isValueDependent() && Init->EvaluateAsRValue(Result, Ctx)) {
+ HI.Value.emplace();
+ llvm::raw_string_ostream ValueOS(*HI.Value);
+ Result.Val.printPretty(ValueOS, const_cast<ASTContext &>(Ctx),
+ Var->getType());
+ }
+ }
+ }
+
HI.Definition = printDefinition(D);
return HI;
}
Modified: clang-tools-extra/trunk/clangd/XRefs.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.h?rev=364390&r1=364389&r2=364390&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.h (original)
+++ clang-tools-extra/trunk/clangd/XRefs.h Wed Jun 26 01:00:24 2019
@@ -103,6 +103,8 @@ struct HoverInfo {
llvm::Optional<std::vector<Param>> Parameters;
/// Set for all templates(function, class, variable).
llvm::Optional<std::vector<Param>> TemplateParameters;
+ /// Contains the evaluated value of the symbol if available.
+ llvm::Optional<std::string> Value;
/// Produce a user-readable information.
FormattedString present() const;
Modified: clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp?rev=364390&r1=364389&r2=364390&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp Wed Jun 26 01:00:24 2019
@@ -661,14 +661,14 @@ TEST(Hover, Structured) {
}},
// 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>";
}},
// Implicit template instantiation
@@ -911,6 +911,72 @@ void foo())cpp";
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 the Decl referenced, even if it comes from an
+ // implicit instantiation.
+ {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);
@@ -938,6 +1004,7 @@ void foo())cpp";
EXPECT_EQ(H->Parameters, Expected.Parameters);
EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
EXPECT_EQ(H->SymRange, Expected.SymRange);
+ EXPECT_EQ(H->Value, Expected.Value);
}
} // namespace clang
More information about the cfe-commits
mailing list