[clang-tools-extra] 72439b6 - [clangd] Add a flag to turn on recovery-expr.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 1 00:18:32 PDT 2020
Author: Haojian Wu
Date: 2020-04-01T09:03:56+02:00
New Revision: 72439b6b9557d5c58ec7f95a14722ef581906a17
URL: https://github.com/llvm/llvm-project/commit/72439b6b9557d5c58ec7f95a14722ef581906a17
DIFF: https://github.com/llvm/llvm-project/commit/72439b6b9557d5c58ec7f95a14722ef581906a17.diff
LOG: [clangd] Add a flag to turn on recovery-expr.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77142
Added:
Modified:
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Compiler.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/tool/ClangdMain.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/TestTU.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 36af6c98d18b..0882784f7031 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -134,7 +134,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
: nullptr),
GetClangTidyOptions(Opts.GetClangTidyOptions),
SuggestMissingIncludes(Opts.SuggestMissingIncludes),
- TweakFilter(Opts.TweakFilter), WorkspaceRoot(Opts.WorkspaceRoot),
+ BuildRecoveryAST(Opts.BuildRecoveryAST), TweakFilter(Opts.TweakFilter),
+ WorkspaceRoot(Opts.WorkspaceRoot),
// Pass a callback into `WorkScheduler` to extract symbols from a newly
// parsed file and rebuild the file index synchronously each time an AST
// is parsed.
@@ -191,6 +192,7 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
Inputs.ForceRebuild = ForceRebuild;
Inputs.Opts = std::move(Opts);
Inputs.Index = Index;
+ Inputs.Opts.BuildRecoveryAST = BuildRecoveryAST;
bool NewFile = WorkScheduler.update(File, Inputs, WantDiags);
// If we loaded Foo.h, we want to make sure Foo.cpp is indexed.
if (NewFile && BackgroundIdx)
diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h
index a0659c7c3d22..f1e981e6c14f 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -118,6 +118,9 @@ class ClangdServer {
/// enabled.
ClangTidyOptionsBuilder GetClangTidyOptions;
+ /// If true, turn on the `-frecovery-ast` clang flag.
+ bool BuildRecoveryAST = false;
+
/// Clangd's workspace root. Relevant for "workspace" operations not bound
/// to a particular file.
/// FIXME: If not set, should use the current working directory.
@@ -345,6 +348,9 @@ class ClangdServer {
// can be caused by missing includes (e.g. member access in incomplete type).
bool SuggestMissingIncludes = false;
+ // If true, preserve expressions in AST for broken code.
+ bool BuildRecoveryAST = false;
+
std::function<bool(const Tweak &)> TweakFilter;
// GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h
index ef5386bb0d17..b7cc174455f3 100644
--- a/clang-tools-extra/clangd/Compiler.h
+++ b/clang-tools-extra/clangd/Compiler.h
@@ -38,6 +38,7 @@ class IgnoreDiagnostics : public DiagnosticConsumer {
struct ParseOptions {
tidy::ClangTidyOptions ClangTidyOpts;
bool SuggestMissingIncludes = false;
+ bool BuildRecoveryAST = false;
};
/// Information required to run clang, e.g. to parse AST or do code completion.
diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index 1d6997f0b4d4..2c7cb5d2b85d 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -253,6 +253,10 @@ ParsedAST::build(llvm::StringRef Version,
const PrecompiledPreamble *PreamblePCH =
Preamble ? &Preamble->Preamble : nullptr;
+ // Recovery expression currently only works for C++.
+ if (CI->getLangOpts()->CPlusPlus)
+ CI->getLangOpts()->RecoveryAST = Opts.BuildRecoveryAST;
+
StoreDiags ASTDiags;
std::string Content = std::string(Buffer->getBuffer());
std::string Filename =
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index fdee71fd2244..48f15420032f 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -132,6 +132,10 @@ buildPreamble(PathRef FileName, CompilerInvocation &CI,
// to read back. We rely on dynamic index for the comments instead.
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
+ // Recovery expression currently only works for C++.
+ if (CI.getLangOpts()->CPlusPlus)
+ CI.getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST;
+
CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback);
if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
log("Couldn't set working directory when building the preamble.");
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 7a7bb9b0718e..9bfc58b55f71 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -281,6 +281,15 @@ opt<bool> CrossFileRename{
Hidden,
};
+opt<bool> RecoveryAST{
+ "recovery-ast",
+ cat(Features),
+ desc("Preserve expressions in AST for broken code (C++ only). Note that "
+ "this feature is experimental and may lead to crashes"),
+ init(false),
+ Hidden,
+};
+
opt<unsigned> WorkerThreadsCount{
"j",
cat(Misc),
@@ -629,6 +638,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
}
Opts.StaticIndex = StaticIdx.get();
Opts.AsyncThreadsCount = WorkerThreadsCount;
+ Opts.BuildRecoveryAST = RecoveryAST;
clangd::CodeCompleteOptions CCOpts;
CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 53d29a236a07..7b6fff292e66 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -132,6 +132,16 @@ TEST_F(TargetDeclTest, Exprs) {
EXPECT_DECLS("CXXOperatorCallExpr", "void operator()(int n)");
}
+TEST_F(TargetDeclTest, Recovery) {
+ Code = R"cpp(
+ // error-ok: testing behavior on broken code
+ int f();
+ int f(int, int);
+ int x = [[f]](42);
+ )cpp";
+ EXPECT_DECLS("UnresolvedLookupExpr", "int f()", "int f(int, int)");
+}
+
TEST_F(TargetDeclTest, UsingDecl) {
Code = R"cpp(
namespace foo {
@@ -685,6 +695,15 @@ TEST_F(FindExplicitReferencesTest, All) {
)cpp",
"0: targets = {x}\n"
"1: targets = {X::a}\n"},
+ {R"cpp(
+ // error-ok: testing with broken code
+ int bar();
+ int foo() {
+ return $0^bar() + $1^bar(42);
+ }
+ )cpp",
+ "0: targets = {bar}\n"
+ "1: targets = {bar}\n"},
// Namespaces and aliases.
{R"cpp(
namespace ns {}
diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp
index dfcdb0884e27..2adcfc338cc2 100644
--- a/clang-tools-extra/clangd/unittests/TestTU.cpp
+++ b/clang-tools-extra/clangd/unittests/TestTU.cpp
@@ -56,6 +56,7 @@ ParseInputs TestTU::inputs() const {
Inputs.Contents = Code;
Inputs.FS = buildTestFS(Files);
Inputs.Opts = ParseOptions();
+ Inputs.Opts.BuildRecoveryAST = true;
Inputs.Opts.ClangTidyOpts.Checks = ClangTidyChecks;
Inputs.Opts.ClangTidyOpts.WarningsAsErrors = ClangTidyWarningsAsErrors;
Inputs.Index = ExternalIndex;
More information about the cfe-commits
mailing list