[clang] 2248164 - Revert "[clang] Move state out of `PreprocessorOptions` (1/n) (#86358)"

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 9 13:26:52 PDT 2024


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();


        


More information about the cfe-commits mailing list