kadircet created this revision. kadircet added a reviewer: ilya-biryukov. Herald added subscribers: cfe-commits, arphaman, jkorous, MaskRay, ioeric.
Some projects make use of clang plugins when building, but clangd is not aware of those plugins therefore can't work with the same compile command arguments. We invoke clang in two different codepaths one in backgroundindex and another when building asts. This patch adds the filtering logic to their intersection. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D56841 Files: clangd/ClangdUnit.cpp unittests/clangd/ClangdTests.cpp Index: unittests/clangd/ClangdTests.cpp =================================================================== --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -1037,6 +1037,27 @@ } #endif +TEST_F(ClangdVFSTest, FlagsWithPlugins) { + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + CDB.ExtraClangFlags = { + "-Xclang", + "-add-plugin", + "-Xclang", + "random-plugin", + }; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + auto FooCpp = testPath("foo.cpp"); + const auto SourceContents = "int main() { return 0; }"; + FS.Files[FooCpp] = FooCpp; + Server.addDocument(FooCpp, SourceContents); + auto Result = dumpASTWithoutMemoryLocs(Server, FooCpp); + EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics"; + EXPECT_NE(Result, "<no-ast>"); +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/ClangdUnit.cpp =================================================================== --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -425,8 +425,21 @@ std::unique_ptr<CompilerInvocation> buildCompilerInvocation(const ParseInputs &Inputs) { std::vector<const char *> ArgStrs; - for (const auto &S : Inputs.CompileCommand.CommandLine) - ArgStrs.push_back(S.c_str()); + const auto &CommandLine = Inputs.CompileCommand.CommandLine; + for (size_t I = 0, E = CommandLine.size(); I != E; I++) { + // According to https://clang.llvm.org/docs/ClangPlugins.html + // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin} -Xclang + // <arbitrary-argument> + if (I + 4 < E && CommandLine[I] == "-Xclang" && + (CommandLine[I + 1] == "-load" || CommandLine[I + 1] == "-plugin" || + llvm::StringRef(CommandLine[I + 1]).startswith("-plugin-arg-") || + CommandLine[I + 1] == "-add-plugin") && + CommandLine[I + 2] == "-Xclang") { + I += 3; + continue; + } + ArgStrs.push_back(CommandLine[I].c_str()); + } if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { log("Couldn't set working directory when creating compiler invocation.");
Index: unittests/clangd/ClangdTests.cpp =================================================================== --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -1037,6 +1037,27 @@ } #endif +TEST_F(ClangdVFSTest, FlagsWithPlugins) { + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + CDB.ExtraClangFlags = { + "-Xclang", + "-add-plugin", + "-Xclang", + "random-plugin", + }; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + auto FooCpp = testPath("foo.cpp"); + const auto SourceContents = "int main() { return 0; }"; + FS.Files[FooCpp] = FooCpp; + Server.addDocument(FooCpp, SourceContents); + auto Result = dumpASTWithoutMemoryLocs(Server, FooCpp); + EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics"; + EXPECT_NE(Result, "<no-ast>"); +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/ClangdUnit.cpp =================================================================== --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -425,8 +425,21 @@ std::unique_ptr<CompilerInvocation> buildCompilerInvocation(const ParseInputs &Inputs) { std::vector<const char *> ArgStrs; - for (const auto &S : Inputs.CompileCommand.CommandLine) - ArgStrs.push_back(S.c_str()); + const auto &CommandLine = Inputs.CompileCommand.CommandLine; + for (size_t I = 0, E = CommandLine.size(); I != E; I++) { + // According to https://clang.llvm.org/docs/ClangPlugins.html + // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin} -Xclang + // <arbitrary-argument> + if (I + 4 < E && CommandLine[I] == "-Xclang" && + (CommandLine[I + 1] == "-load" || CommandLine[I + 1] == "-plugin" || + llvm::StringRef(CommandLine[I + 1]).startswith("-plugin-arg-") || + CommandLine[I + 1] == "-add-plugin") && + CommandLine[I + 2] == "-Xclang") { + I += 3; + continue; + } + ArgStrs.push_back(CommandLine[I].c_str()); + } if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { log("Couldn't set working directory when creating compiler invocation.");
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits