diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -21,6 +21,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/Expr.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Type.h" #include "clang/Index/IndexSymbol.h" @@ -445,9 +446,13 @@ // Look for a close enclosing expression to show the value of. if (!HI->Value) HI->Value = printExprValue(N, AST.getASTContext()); + } else if (const Expr *E = N->ASTNode.get()) { + // For expressions we currently print the type and the value, if they + // are evaluatable. + HI = getHoverContents(E->getType(), AST.getASTContext(), Index); + HI->Value = printExprValue(E, AST.getASTContext()); } // FIXME: support hovers for other nodes? - // - certain expressions (sizeof etc) // - built-in types // - literals (esp user-defined) } diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -1512,6 +1512,30 @@ HI.Name = "b"; HI.Type = "int"; }}, + { + R"cpp(// sizeof expr + void foo() { + (void)[[size^of]](char); + })cpp", + [](HoverInfo &HI) { + HI.Name = "unsigned long"; + HI.Value = "1"; + }}, + { + R"cpp(// alignof expr + void foo() { + (void)[[align^of]](char); + })cpp", + [](HoverInfo &HI) { + HI.Name = "unsigned long"; + HI.Value = "1"; + }}, + { + R"cpp(// non-evaluatable expr + template void foo() { + (void)[[size^of]](T); + })cpp", + [](HoverInfo &HI) { HI.Name = "unsigned long"; }}, }; // Create a tiny index, so tests above can verify documentation is fetched.