Index: clang-query/QueryParser.cpp =================================================================== --- clang-query/QueryParser.cpp +++ clang-query/QueryParser.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include +#include using namespace llvm; using namespace clang::ast_matchers::dynamic; @@ -210,13 +211,27 @@ if (CompletionPos) return completeMatcherExpression(); - Diagnostics Diag; - Optional Matcher = Parser::parseMatcherExpression( - StringRef(Begin, End - Begin), nullptr, &QS.NamedValues, &Diag); - if (!Matcher) { - return makeInvalidQueryFromDiagnostics(Diag); + Diagnostics FirstDiag; + std::string Query = StringRef(Begin, End - Begin).str(); + while (true) { + Diagnostics Diag; + Diagnostics* CurrentDiag = FirstDiag.errors().empty() ? &FirstDiag : &Diag; + Optional Matcher = Parser::parseMatcherExpression( + Query, nullptr, &QS.NamedValues, CurrentDiag); + if (Matcher) { + return new MatchQuery(*Matcher); + } + for (const auto& Error : CurrentDiag->errors()) { + for (const auto &Message : Error.Messages) { + if (Message.Type == Diagnostics::ET_ParserNoCloseParen) { + Query += ")"; + } else { + // Report the first error before we mucked with the query. + return makeInvalidQueryFromDiagnostics(FirstDiag); + } + } + } } - return new MatchQuery(*Matcher); } case PQK_Set: { Index: test/clang-query/missing-parens.c =================================================================== --- /dev/null +++ test/clang-query/missing-parens.c @@ -0,0 +1,4 @@ +// RUN: clang-query -c "match functionDecl(" %s -- | FileCheck %s + +// CHECK: function-decl.c:4:1: note: "root" binds here +void foo(void) {}