Author: Haojian Wu Date: 2020-05-19T15:21:57+02:00 New Revision: 0320ce8916a815d10a0449f5581e0f3ca7183922
URL: https://github.com/llvm/llvm-project/commit/0320ce8916a815d10a0449f5581e0f3ca7183922 DIFF: https://github.com/llvm/llvm-project/commit/0320ce8916a815d10a0449f5581e0f3ca7183922.diff LOG: [clangd] Add a flag to preserve type for recovery expression. Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D79938 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/Compiler.cpp clang-tools-extra/clangd/Compiler.h clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.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 9231296e729d..910c591c1f1e 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -135,8 +135,9 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, : nullptr), GetClangTidyOptions(Opts.GetClangTidyOptions), SuggestMissingIncludes(Opts.SuggestMissingIncludes), - BuildRecoveryAST(Opts.BuildRecoveryAST), TweakFilter(Opts.TweakFilter), - WorkspaceRoot(Opts.WorkspaceRoot), + BuildRecoveryAST(Opts.BuildRecoveryAST), + PreserveRecoveryASTType(Opts.PreserveRecoveryASTType), + 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. @@ -194,6 +195,7 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, Inputs.Opts = std::move(Opts); Inputs.Index = Index; Inputs.Opts.BuildRecoveryAST = BuildRecoveryAST; + Inputs.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType; 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 76fa64b5a314..68344eb8f51e 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -120,6 +120,9 @@ class ClangdServer { /// If true, turn on the `-frecovery-ast` clang flag. bool BuildRecoveryAST = false; + /// If true, turn on the `-frecovery-ast-type` clang flag. + bool PreserveRecoveryASTType = 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. @@ -349,6 +352,8 @@ class ClangdServer { // If true, preserve expressions in AST for broken code. bool BuildRecoveryAST = false; + // If true, preserve the type for recovery AST. + bool PreserveRecoveryASTType = false; std::function<bool(const Tweak &)> TweakFilter; diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 03c1cb1e2e13..f2bdadb0ad9d 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1069,6 +1069,7 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer, ParseInput.CompileCommand = Input.Command; ParseInput.FS = VFS; ParseInput.Contents = std::string(Input.Contents); + // FIXME: setup the recoveryAST and recoveryASTType in ParseInput properly. IgnoreDiagnostics IgnoreDiags; auto CI = buildCompilerInvocation(ParseInput, IgnoreDiags); diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp index ee9b187258b2..9eb86a4265b4 100644 --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -84,8 +84,10 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, CI->getPreprocessorOpts().PCHWithHdrStopCreate = false; // Recovery expression currently only works for C++. - if (CI->getLangOpts()->CPlusPlus) + if (CI->getLangOpts()->CPlusPlus) { CI->getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST; + CI->getLangOpts()->RecoveryASTType = Inputs.Opts.PreserveRecoveryASTType; + } return CI; } diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h index b7cc174455f3..5c4cf39fac77 100644 --- a/clang-tools-extra/clangd/Compiler.h +++ b/clang-tools-extra/clangd/Compiler.h @@ -39,6 +39,7 @@ struct ParseOptions { tidy::ClangTidyOptions ClangTidyOpts; bool SuggestMissingIncludes = false; bool BuildRecoveryAST = false; + bool PreserveRecoveryASTType = false; }; /// Information required to run clang, e.g. to parse AST or do code completion. diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index e59aecb2d752..031f57f954cb 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -289,6 +289,14 @@ opt<bool> RecoveryAST{ init(false), Hidden, }; +opt<bool> RecoveryASTType{ + "recovery-ast-type", + cat(Features), + desc("Preserve the type for recovery AST. Note that " + "this feature is experimental and may lead to crashes"), + init(false), + Hidden, +}; opt<unsigned> WorkerThreadsCount{ "j", @@ -641,6 +649,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var Opts.StaticIndex = StaticIdx.get(); Opts.AsyncThreadsCount = WorkerThreadsCount; Opts.BuildRecoveryAST = RecoveryAST; + Opts.PreserveRecoveryASTType = RecoveryASTType; clangd::CodeCompleteOptions CCOpts; CCOpts.IncludeIneligibleResults = IncludeIneligibleResults; diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 77b5c5ac386c..d2b9661fc47d 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -753,6 +753,19 @@ TEST(CompletionTest, CompletionInPreamble) { EXPECT_THAT(Results, ElementsAre(Named("ifndef"))); } +// FIXME: enable it. +TEST(CompletionTest, DISABLED_CompletionRecoveryASTType) { + auto Results = completions(R"cpp( + struct S { int member; }; + S overloaded(int); + void foo() { + // No overload matches, but we have recovery-expr with the correct type. + overloaded().^ + })cpp") + .Completions; + EXPECT_THAT(Results, ElementsAre(Named("member"))); +} + TEST(CompletionTest, DynamicIndexIncludeInsertion) { MockFSProvider FS; MockCompilationDatabase CDB; diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 03cdc02fbb18..94d0402af640 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -158,6 +158,19 @@ TEST_F(TargetDeclTest, Recovery) { EXPECT_DECLS("UnresolvedLookupExpr", "int f()", "int f(int, int)"); } +TEST_F(TargetDeclTest, RecoveryType) { + Code = R"cpp( + // error-ok: testing behavior on broken code + struct S { int member; }; + S overloaded(int); + void foo() { + // No overload matches, but we have recovery-expr with the correct type. + overloaded().[[member]]; + } + )cpp"; + EXPECT_DECLS("MemberExpr", "int member"); +} + TEST_F(TargetDeclTest, UsingDecl) { Code = R"cpp( namespace foo { diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp index 8ff1120452fc..6d9de48f23dc 100644 --- a/clang-tools-extra/clangd/unittests/TestTU.cpp +++ b/clang-tools-extra/clangd/unittests/TestTU.cpp @@ -57,6 +57,7 @@ ParseInputs TestTU::inputs() const { Inputs.FS = buildTestFS(Files); Inputs.Opts = ParseOptions(); Inputs.Opts.BuildRecoveryAST = true; + Inputs.Opts.PreserveRecoveryASTType = true; Inputs.Opts.ClangTidyOpts.Checks = ClangTidyChecks; Inputs.Opts.ClangTidyOpts.WarningsAsErrors = ClangTidyWarningsAsErrors; Inputs.Index = ExternalIndex; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits