diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp index 957d7c382125ef..04d48b08865d9d 100644 --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -41,8 +41,7 @@ void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, } std::unique_ptr -buildCompilerInvocation(const ParseInputs &Inputs, - clang::DiagnosticConsumer &D, +buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector *CC1Args) { std::vector ArgStrs; for (const auto &S : Inputs.CompileCommand.CommandLine) @@ -74,6 +73,15 @@ buildCompilerInvocation(const ParseInputs &Inputs, CI->getDependencyOutputOpts().HeaderIncludeOutputFile.clear(); CI->getDependencyOutputOpts().DOTOutputFile.clear(); CI->getDependencyOutputOpts().ModuleDependencyOutputDir.clear(); + + // Disable any pch generation/usage operations. Since serialized preamble + // format is unstable, using an incompatible one might result in unexpected + // behaviours, including crashes. + CI->getPreprocessorOpts().ImplicitPCHInclude.clear(); + CI->getPreprocessorOpts().PrecompiledPreambleBytes = {0, false}; + CI->getPreprocessorOpts().PCHThroughHeader.clear(); + CI->getPreprocessorOpts().PCHWithHdrStop = false; + CI->getPreprocessorOpts().PCHWithHdrStopCreate = false; return CI; } diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index cccb3ce7308a14..a1f6af6747f4e1 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -34,6 +34,7 @@ add_unittest(ClangdUnitTests ClangdTests CodeCompletionStringsTests.cpp CollectMacrosTests.cpp CompileCommandsTests.cpp + CompilerTests.cpp DexTests.cpp DiagnosticsTests.cpp DraftStoreTests.cpp diff --git a/clang-tools-extra/clangd/unittests/CompilerTests.cpp b/clang-tools-extra/clangd/unittests/CompilerTests.cpp new file mode 100644 index 00000000000000..a12a7b9ce9af88 --- /dev/null +++ b/clang-tools-extra/clangd/unittests/CompilerTests.cpp @@ -0,0 +1,55 @@ +//===-- CompilerTests.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Compiler.h" +#include "TestTU.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace { + +using testing::IsEmpty; + +TEST(BuildCompilerInvocation, DropsPCH) { + IgnoreDiagnostics Diags; + TestTU TU; + TU.AdditionalFiles["test.h.pch"] = ""; + + TU.ExtraArgs = {"-include-pch", "test.h.pch"}; + EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags) + ->getPreprocessorOpts() + .ImplicitPCHInclude, + IsEmpty()); + + // Transparent include translation + TU.ExtraArgs = {"-include", "test.h"}; + EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags) + ->getPreprocessorOpts() + .ImplicitPCHInclude, + IsEmpty()); + + // CL mode parsing. + TU.AdditionalFiles["test.pch"] = ""; + TU.ExtraArgs = {"--driver-mode=cl"}; + TU.ExtraArgs.push_back("/Yutest.h"); + EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags) + ->getPreprocessorOpts() + .ImplicitPCHInclude, + IsEmpty()); + EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags) + ->getPreprocessorOpts() + .PCHThroughHeader, + IsEmpty()); +} + +} // namespace +} // namespace clangd +} // namespace clang