[clangd] Fix hover crash on InitListExpr.

Fixes https://github.com/clangd/clangd/issues/455

Differential Revision: https://reviews.llvm.org/D83546
This commit is contained in:
Haojian Wu 2020-07-10 16:18:10 +02:00
parent 22c8a08fd8
commit 015a0faa5e
2 changed files with 26 additions and 1 deletions

View File

@ -329,13 +329,23 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
llvm::Optional<std::string> printExprValue(const Expr *E,
const ASTContext &Ctx) {
Expr::EvalResult Constant;
// InitListExpr has two forms, syntactic and semantic. They are the same thing
// (refer to a same AST node) in most cases.
// When they are different, RAV returns the syntactic form, and we should feed
// the semantic form to EvaluateAsRValue.
if (const auto *ILE = llvm::dyn_cast<InitListExpr>(E)) {
if (!ILE->isSemanticForm())
E = ILE->getSemanticForm();
}
// Evaluating [[foo]]() as "&foo" isn't useful, and prevents us walking up
// to the enclosing call.
QualType T = E->getType();
if (T.isNull() || T->isFunctionType() || T->isFunctionPointerType() ||
T->isFunctionReferenceType())
return llvm::None;
Expr::EvalResult Constant;
// Attempt to evaluate. If expr is dependent, evaluation crashes!
if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx) ||
// Disable printing for record-types, as they are usually confusing and

View File

@ -801,6 +801,21 @@ class Foo {})cpp";
HI.LocalScope = "Foo::";
HI.Type = "int";
HI.AccessSpecifier = "public";
}},
{// No crash on InitListExpr.
R"cpp(
struct Foo {
int a[10];
};
constexpr Foo k2 = {
^[[{]]1} // FIXME: why the hover range is 1 character?
};
)cpp",
[](HoverInfo &HI) {
HI.Name = "expression";
HI.Kind = index::SymbolKind::Unknown;
HI.Type = "int [10]";
HI.Value = "{1}";
}}};
for (const auto &Case : Cases) {
SCOPED_TRACE(Case.Code);