Author: Jan Svoboda Date: 2024-04-09T13:26:45-07:00 New Revision: 2248164a9ab791a3ed1b9586dc340b5303155021
URL: https://github.com/llvm/llvm-project/commit/2248164a9ab791a3ed1b9586dc340b5303155021 DIFF: https://github.com/llvm/llvm-project/commit/2248164a9ab791a3ed1b9586dc340b5303155021.diff LOG: Revert "[clang] Move state out of `PreprocessorOptions` (1/n) (#86358)" This reverts commit 407a2f23 which stopped propagating the callback to module compiles, effectively disabling dependency directive scanning for all modular dependencies. Also added a regression test. Added: clang/test/ClangScanDeps/modules-minimize-extension.c clang/test/ClangScanDeps/modules-minimize-module.c Modified: clang/include/clang/Frontend/FrontendActions.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Lex/PreprocessorOptions.h clang/lib/Frontend/FrontendActions.cpp clang/lib/Lex/PPLexerChange.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp clang/unittests/Lex/PPDependencyDirectivesTest.cpp Removed: clang/test/ClangScanDeps/modules-extension.c ################################################################################ diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index 0518a8823a03ea9..a620ddfc40447d7 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -34,18 +34,12 @@ class InitOnlyAction : public FrontendAction { /// Preprocessor-based frontend action that also loads PCH files. class ReadPCHAndPreprocessAction : public FrontendAction { - llvm::unique_function<void(CompilerInstance &)> AdjustCI; - void ExecuteAction() override; std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; public: - ReadPCHAndPreprocessAction( - llvm::unique_function<void(CompilerInstance &)> AdjustCI) - : AdjustCI(std::move(AdjustCI)) {} - bool usesPreprocessorOnly() const override { return false; } }; @@ -327,15 +321,11 @@ class PrintPreprocessedAction : public PreprocessorFrontendAction { class GetDependenciesByModuleNameAction : public PreprocessOnlyAction { StringRef ModuleName; - llvm::unique_function<void(CompilerInstance &)> AdjustCI; - void ExecuteAction() override; public: - GetDependenciesByModuleNameAction( - StringRef ModuleName, - llvm::unique_function<void(CompilerInstance &)> AdjustCI) - : ModuleName(ModuleName), AdjustCI(std::move(AdjustCI)) {} + GetDependenciesByModuleNameAction(StringRef ModuleName) + : ModuleName(ModuleName) {} }; } // end namespace clang diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 24e146a589a758b..0836b7d439bb049 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -736,19 +736,6 @@ class Preprocessor { State ConditionalStackState = Off; } PreambleConditionalStack; - /// Function for getting the dependency preprocessor directives of a file. - /// - /// These are directives derived from a special form of lexing where the - /// source input is scanned for the preprocessor directives that might have an - /// effect on the dependencies for a compilation unit. - /// - /// Enables a client to cache the directives for a file and provide them - /// across multiple compiler invocations. - /// FIXME: Allow returning an error. - using DependencyDirectivesFn = llvm::unique_function<std::optional< - ArrayRef<dependency_directives_scan::Directive>>(FileEntryRef)>; - DependencyDirectivesFn DependencyDirectivesForFile; - /// The current top of the stack that we're lexing from if /// not expanding a macro and we are lexing directly from source code. /// @@ -1283,11 +1270,6 @@ class Preprocessor { /// false if it is producing tokens to be consumed by Parse and Sema. bool isPreprocessedOutput() const { return PreprocessedOutput; } - /// Set the function used to get dependency directives for a file. - void setDependencyDirectivesFn(DependencyDirectivesFn Fn) { - DependencyDirectivesForFile = std::move(Fn); - } - /// Return true if we are lexing directly from the specified lexer. bool isCurrentLexer(const PreprocessorLexer *L) const { return CurPPLexer == L; diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h index 50b5fba0ff773ec..635971d0ce5ee8c 100644 --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -186,6 +186,19 @@ class PreprocessorOptions { /// with support for lifetime-qualified pointers. ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib; + /// Function for getting the dependency preprocessor directives of a file. + /// + /// These are directives derived from a special form of lexing where the + /// source input is scanned for the preprocessor directives that might have an + /// effect on the dependencies for a compilation unit. + /// + /// Enables a client to cache the directives for a file and provide them + /// across multiple compiler invocations. + /// FIXME: Allow returning an error. + std::function<std::optional<ArrayRef<dependency_directives_scan::Directive>>( + FileEntryRef)> + DependencyDirectivesForFile; + /// Set up preprocessor for RunAnalysis action. bool SetUpStaticAnalyzer = false; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 58fcb2217b05d8c..642b14d8b09d944 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -69,10 +69,7 @@ void InitOnlyAction::ExecuteAction() { // Basically PreprocessOnlyAction::ExecuteAction. void ReadPCHAndPreprocessAction::ExecuteAction() { - CompilerInstance &CI = getCompilerInstance(); - AdjustCI(CI); - - Preprocessor &PP = CI.getPreprocessor(); + Preprocessor &PP = getCompilerInstance().getPreprocessor(); // Ignore unknown pragmas. PP.IgnorePragmas(); @@ -1193,8 +1190,6 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { void GetDependenciesByModuleNameAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); - AdjustCI(CI); - Preprocessor &PP = CI.getPreprocessor(); SourceManager &SM = PP.getSourceManager(); FileID MainFileID = SM.getMainFileID(); diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index a0cc2b516574c19..3b1b6df1dbae4e6 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -93,10 +93,16 @@ bool Preprocessor::EnterSourceFile(FileID FID, ConstSearchDirIterator CurDir, } Lexer *TheLexer = new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile); - if (DependencyDirectivesForFile && FID != PredefinesFileID) - if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID)) - if (auto DepDirectives = DependencyDirectivesForFile(*File)) + if (getPreprocessorOpts().DependencyDirectivesForFile && + FID != PredefinesFileID) { + if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID)) { + if (std::optional<ArrayRef<dependency_directives_scan::Directive>> + DepDirectives = + getPreprocessorOpts().DependencyDirectivesForFile(*File)) { TheLexer->DepDirectives = *DepDirectives; + } + } + } EnterSourceFileWithLexer(TheLexer, CurDir); return false; diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 492b8f1e2b3863d..32850f5eea92a94 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -363,22 +363,17 @@ class DependencyScanningAction : public tooling::ToolAction { PrebuiltModuleVFSMap, ScanInstance.getDiagnostics())) return false; - auto AdjustCI = [&](CompilerInstance &CI) { - // Set up the dependency scanning file system callback if requested. - if (DepFS) { - auto GetDependencyDirectives = [LocalDepFS = DepFS](FileEntryRef File) - -> std::optional<ArrayRef<dependency_directives_scan::Directive>> { - if (llvm::ErrorOr<EntryRef> Entry = - LocalDepFS->getOrCreateFileSystemEntry(File.getName())) - if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry)) - return Entry->getDirectiveTokens(); - return std::nullopt; - }; - - CI.getPreprocessor().setDependencyDirectivesFn( - std::move(GetDependencyDirectives)); - } - }; + // Use the dependency scanning optimized file system if requested to do so. + if (DepFS) + ScanInstance.getPreprocessorOpts().DependencyDirectivesForFile = + [LocalDepFS = DepFS](FileEntryRef File) + -> std::optional<ArrayRef<dependency_directives_scan::Directive>> { + if (llvm::ErrorOr<EntryRef> Entry = + LocalDepFS->getOrCreateFileSystemEntry(File.getName())) + if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry)) + return Entry->getDirectiveTokens(); + return std::nullopt; + }; // Create the dependency collector that will collect the produced // dependencies. @@ -430,11 +425,9 @@ class DependencyScanningAction : public tooling::ToolAction { std::unique_ptr<FrontendAction> Action; if (ModuleName) - Action = std::make_unique<GetDependenciesByModuleNameAction>( - *ModuleName, std::move(AdjustCI)); + Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName); else - Action = - std::make_unique<ReadPCHAndPreprocessAction>(std::move(AdjustCI)); + Action = std::make_unique<ReadPCHAndPreprocessAction>(); if (ScanInstance.getDiagnostics().hasErrorOccurred()) return false; diff --git a/clang/test/ClangScanDeps/modules-extension.c b/clang/test/ClangScanDeps/modules-minimize-extension.c similarity index 100% rename from clang/test/ClangScanDeps/modules-extension.c rename to clang/test/ClangScanDeps/modules-minimize-extension.c diff --git a/clang/test/ClangScanDeps/modules-minimize-module.c b/clang/test/ClangScanDeps/modules-minimize-module.c new file mode 100644 index 000000000000000..fb58c61bc50941e --- /dev/null +++ b/clang/test/ClangScanDeps/modules-minimize-module.c @@ -0,0 +1,24 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + +// This test checks that source files of modules undergo dependency directives +// scan. If a.h would not, the scan would fail when lexing `#error`. + +//--- module.modulemap +module A { header "a.h" } + +//--- a.h +#error blah + +//--- tu.c +#include "a.h" + +//--- cdb.json.in +[{ + "directory": "DIR", + "file": "DIR/tu.c", + "command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache" +}] + +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full > %t/deps.json diff --git a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp index 0c396720ece66d5..6ff87f720a559fd 100644 --- a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp +++ b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp @@ -117,6 +117,11 @@ TEST_F(PPDependencyDirectivesTest, MacroGuard) { }; auto PPOpts = std::make_shared<PreprocessorOptions>(); + PPOpts->DependencyDirectivesForFile = [&](FileEntryRef File) + -> std::optional<ArrayRef<dependency_directives_scan::Directive>> { + return getDependencyDirectives(File); + }; + TrivialModuleLoader ModLoader; HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr, Diags, LangOpts, Target.get()); @@ -125,12 +130,6 @@ TEST_F(PPDependencyDirectivesTest, MacroGuard) { /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); - PP.setDependencyDirectivesFn( - [&](FileEntryRef File) - -> std::optional<ArrayRef<dependency_directives_scan::Directive>> { - return getDependencyDirectives(File); - }); - SmallVector<StringRef> IncludedFiles; PP.addPPCallbacks(std::make_unique<IncludeCollector>(PP, IncludedFiles)); PP.EnterMainSourceFile(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits