This revision was automatically updated to reflect the committed changes. sammccall marked 2 inline comments as done. Closed by commit rG04b419048955: [Driver] Make "upgrade" of -include to include-pch optional; disable in clangd (authored by sammccall).
Changed prior to commit: https://reviews.llvm.org/D124970?vs=427159&id=427323#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D124970/new/ https://reviews.llvm.org/D124970 Files: clang-tools-extra/clangd/Compiler.cpp clang/include/clang/Driver/Driver.h clang/include/clang/Frontend/Utils.h clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CreateInvocationFromCommandLine.cpp clang/unittests/Frontend/UtilsTest.cpp
Index: clang/unittests/Frontend/UtilsTest.cpp =================================================================== --- clang/unittests/Frontend/UtilsTest.cpp +++ clang/unittests/Frontend/UtilsTest.cpp @@ -11,12 +11,15 @@ #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Support/VirtualFileSystem.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace clang { namespace { +using testing::ElementsAre; TEST(BuildCompilerInvocationTest, RecoverMultipleJobs) { // This generates multiple jobs and we recover by using the first. @@ -33,5 +36,31 @@ EXPECT_THAT(CI->TargetOpts->Triple, testing::StartsWith("i386-")); } +// buildInvocationFromCommandLine should not translate -include to -include-pch, +// even if the PCH file exists. +TEST(BuildCompilerInvocationTest, ProbePrecompiled) { + std::vector<const char *> Args = {"clang", "-include", "foo.h", "foo.cpp"}; + auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>(); + FS->addFile("foo.h", 0, llvm::MemoryBuffer::getMemBuffer("")); + FS->addFile("foo.h.pch", 0, llvm::MemoryBuffer::getMemBuffer("")); + + clang::IgnoringDiagConsumer D; + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine = + clang::CompilerInstance::createDiagnostics(new DiagnosticOptions, &D, + false); + // Default: ProbePrecompiled is true. + std::unique_ptr<CompilerInvocation> CI = createInvocationFromCommandLine( + Args, CommandLineDiagsEngine, FS, false, nullptr); + ASSERT_TRUE(CI); + EXPECT_THAT(CI->getPreprocessorOpts().Includes, ElementsAre()); + EXPECT_EQ(CI->getPreprocessorOpts().ImplicitPCHInclude, "foo.h.pch"); + + CI = createInvocationFromCommandLine(Args, CommandLineDiagsEngine, FS, false, + nullptr, /*ProbePrecompiled=*/false); + ASSERT_TRUE(CI); + EXPECT_THAT(CI->getPreprocessorOpts().Includes, ElementsAre("foo.h")); + EXPECT_EQ(CI->getPreprocessorOpts().ImplicitPCHInclude, ""); +} + } // namespace } // namespace clang Index: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp =================================================================== --- clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -48,6 +48,7 @@ // Don't check that inputs exist, they may have been remapped. TheDriver.setCheckInputsExist(false); + TheDriver.setProbePrecompiled(Opts.ProbePrecompiled); std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args)); if (!C) @@ -107,8 +108,8 @@ std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine( ArrayRef<const char *> Args, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool ShouldRecoverOnErrors, - std::vector<std::string> *CC1Args) { + std::vector<std::string> *CC1Args, bool ProbePrecompiled) { return createInvocation( - Args, - CreateInvocationOptions{Diags, VFS, ShouldRecoverOnErrors, CC1Args}); + Args, CreateInvocationOptions{Diags, VFS, ShouldRecoverOnErrors, + ProbePrecompiled, CC1Args}); } Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -1364,7 +1364,8 @@ bool RenderedImplicitInclude = false; for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) { - if (A->getOption().matches(options::OPT_include)) { + if (A->getOption().matches(options::OPT_include) && + D.getProbePrecompiled()) { // Handling of gcc-style gch precompiled headers. bool IsFirstImplicitInclude = !RenderedImplicitInclude; RenderedImplicitInclude = true; @@ -1375,12 +1376,12 @@ // so that replace_extension does the right thing. P += ".dummy"; llvm::sys::path::replace_extension(P, "pch"); - if (llvm::sys::fs::exists(P)) + if (D.getVFS().exists(P)) FoundPCH = true; if (!FoundPCH) { llvm::sys::path::replace_extension(P, "gch"); - if (llvm::sys::fs::exists(P)) { + if (D.getVFS().exists(P)) { FoundPCH = true; } } Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -198,7 +198,8 @@ CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false), CCGenDiagnostics(false), CCPrintProcessStats(false), TargetTriple(TargetTriple), Saver(Alloc), CheckInputsExist(true), - GenReproducer(false), SuppressMissingInputWarning(false) { + ProbePrecompiled(true), GenReproducer(false), + SuppressMissingInputWarning(false) { // Provide a sane fallback if no VFS is specified. if (!this->VFS) this->VFS = llvm::vfs::getRealFileSystem(); Index: clang/include/clang/Frontend/Utils.h =================================================================== --- clang/include/clang/Frontend/Utils.h +++ clang/include/clang/Frontend/Utils.h @@ -202,6 +202,11 @@ /// if any errors were encountered. /// By default, always return null on errors. bool RecoverOnError = false; + /// Allow the driver to probe the filesystem for PCH files. + /// This is used to replace -include with -include-pch in the cc1 args. + /// FIXME: ProbePrecompiled=true is a poor, historical default. + /// It misbehaves if the PCH file is from GCC, has the wrong version, etc. + bool ProbePrecompiled = true; /// If set, the target is populated with the cc1 args produced by the driver. /// This may be populated even if createInvocation returns nullptr. std::vector<std::string> *CC1Args = nullptr; @@ -236,7 +241,7 @@ IntrusiveRefCntPtr<DiagnosticsEngine>(), IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr, bool ShouldRecoverOnErrors = false, - std::vector<std::string> *CC1Args = nullptr); + std::vector<std::string> *CC1Args = nullptr, bool ProbePrecompiled = true); } // namespace clang Index: clang/include/clang/Driver/Driver.h =================================================================== --- clang/include/clang/Driver/Driver.h +++ clang/include/clang/Driver/Driver.h @@ -271,6 +271,9 @@ /// Whether to check that input files exist when constructing compilation /// jobs. unsigned CheckInputsExist : 1; + /// Whether to probe for PCH files on disk, in order to upgrade + /// -include foo.h to -include-pch foo.h.pch. + unsigned ProbePrecompiled : 1; public: /// Force clang to emit reproducer for driver invocation. This is enabled @@ -357,6 +360,9 @@ void setCheckInputsExist(bool Value) { CheckInputsExist = Value; } + bool getProbePrecompiled() const { return ProbePrecompiled; } + void setProbePrecompiled(bool Value) { ProbePrecompiled = Value; } + void setTargetAndMode(const ParsedClangName &TM) { ClangNameParts = TM; } const std::string &getTitle() { return DriverTitle; } Index: clang-tools-extra/clangd/Compiler.cpp =================================================================== --- clang-tools-extra/clangd/Compiler.cpp +++ clang-tools-extra/clangd/Compiler.cpp @@ -97,6 +97,7 @@ CIOpts.RecoverOnError = true; CIOpts.Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions, &D, false); + CIOpts.ProbePrecompiled = false; std::unique_ptr<CompilerInvocation> CI = createInvocation(ArgStrs, CIOpts); if (!CI) return nullptr;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits