[clang] c12577c - [clang][driver] Introduce new -fdriver-only flag

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 13 04:31:04 PDT 2022


Author: Jan Svoboda
Date: 2022-06-13T13:30:56+02:00
New Revision: c12577c61dbf37b1b6ae25ed422a900ac71f18fe

URL: https://github.com/llvm/llvm-project/commit/c12577c61dbf37b1b6ae25ed422a900ac71f18fe
DIFF: https://github.com/llvm/llvm-project/commit/c12577c61dbf37b1b6ae25ed422a900ac71f18fe.diff

LOG: [clang][driver] Introduce new -fdriver-only flag

This patch introduces the new -fdriver-only flag which instructs Clang to only execute the driver logic without running individual jobs. In a way, this is very similar to -###, with the following differences:
 * it doesn't automatically print all jobs,
 * it doesn't avoid side effects (e.g. it will generate compilation database when -MJ is specified).

This flag will be useful in testing D121997.

Reviewed By: dexonsmith, egorzhdan

Differential Revision: https://reviews.llvm.org/D127408

Added: 
    clang/test/Driver/driver-only.c

Modified: 
    clang/include/clang/Driver/Compilation.h
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/Compilation.cpp
    clang/lib/Driver/Driver.cpp
    clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
    clang/test/Driver/cc-print-options.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Compilation.h b/clang/include/clang/Driver/Compilation.h
index 260e2a34ed5a7..c5714d3208884 100644
--- a/clang/include/clang/Driver/Compilation.h
+++ b/clang/include/clang/Driver/Compilation.h
@@ -295,16 +295,22 @@ class Compilation {
   ///
   /// \param FailingCommand - For non-zero results, this will be set to the
   /// Command which failed, if any.
+  /// \param LogOnly - When true, only tries to log the command, not actually
+  /// execute it.
   /// \return The result code of the subprocess.
-  int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
+  int ExecuteCommand(const Command &C, const Command *&FailingCommand,
+                     bool LogOnly = false) const;
 
   /// ExecuteJob - Execute a single job.
   ///
   /// \param FailingCommands - For non-zero results, this will be a vector of
   /// failing commands and their associated result code.
-  void ExecuteJobs(
-      const JobList &Jobs,
-      SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
+  /// \param LogOnly - When true, only tries to log the command, not actually
+  /// execute it.
+  void
+  ExecuteJobs(const JobList &Jobs,
+              SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands,
+              bool LogOnly = false) const;
 
   /// initCompilationForDiagnostics - Remove stale state and suppress output
   /// so compilation can be reexecuted to generate additional diagnostic

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 002cd6cc8cb17..5d650534ce07f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2751,6 +2751,8 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
             " overwriting polymorphic C++ objects">,
   NegFlag<SetFalse>>;
 def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
+def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption, CoreOption]>,
+  Group<Action_Group>, HelpText<"Only run the driver.">;
 def fsyntax_only : Flag<["-"], "fsyntax-only">,
   Flags<[NoXarchOption,CoreOption,CC1Option,FC1Option]>, Group<Action_Group>;
 def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group<f_Group>;

diff  --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index 67d941c6c2ab9..b4367a0af81ee 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -162,7 +162,8 @@ bool Compilation::CleanupFileMap(const ArgStringMap &Files,
 }
 
 int Compilation::ExecuteCommand(const Command &C,
-                                const Command *&FailingCommand) const {
+                                const Command *&FailingCommand,
+                                bool LogOnly) const {
   if ((getDriver().CCPrintOptions ||
        getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) {
     raw_ostream *OS = &llvm::errs();
@@ -191,6 +192,9 @@ int Compilation::ExecuteCommand(const Command &C,
     C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions);
   }
 
+  if (LogOnly)
+    return 0;
+
   std::string Error;
   bool ExecutionFailed;
   int Res = C.Execute(Redirects, &Error, &ExecutionFailed);
@@ -237,7 +241,8 @@ static bool InputsOk(const Command &C,
 }
 
 void Compilation::ExecuteJobs(const JobList &Jobs,
-                              FailingCommandList &FailingCommands) const {
+                              FailingCommandList &FailingCommands,
+                              bool LogOnly) const {
   // According to UNIX standard, driver need to continue compiling all the
   // inputs on the command line even one of them failed.
   // In all but CLMode, execute all the jobs unless the necessary inputs for the
@@ -246,7 +251,7 @@ void Compilation::ExecuteJobs(const JobList &Jobs,
     if (!InputsOk(Job, FailingCommands))
       continue;
     const Command *FailingCommand = nullptr;
-    if (int Res = ExecuteCommand(Job, FailingCommand)) {
+    if (int Res = ExecuteCommand(Job, FailingCommand, LogOnly)) {
       FailingCommands.push_back(std::make_pair(Res, FailingCommand));
       // Bail as soon as one command fails in cl driver mode.
       if (TheDriver.IsCLMode())

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8f7e411696e2c..bb879805ae79e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1689,6 +1689,19 @@ void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) {
 int Driver::ExecuteCompilation(
     Compilation &C,
     SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) {
+  if (C.getArgs().hasArg(options::OPT_fdriver_only)) {
+    if (C.getArgs().hasArg(options::OPT_v))
+      C.getJobs().Print(llvm::errs(), "\n", true);
+
+    C.ExecuteJobs(C.getJobs(), FailingCommands, /*LogOnly=*/true);
+
+    // If there were errors building the compilation, quit now.
+    if (!FailingCommands.empty() || Diags.hasErrorOccurred())
+      return 1;
+
+    return 0;
+  }
+
   // Just print if -### was present.
   if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
     C.getJobs().Print(llvm::errs(), "\n", true);
@@ -4761,6 +4774,8 @@ void Driver::BuildJobs(Compilation &C) const {
       C.getArgs().hasArg(options::OPT_Qunused_arguments))
     return;
 
+  // Claim -fdriver-only here.
+  (void)C.getArgs().hasArg(options::OPT_fdriver_only);
   // Claim -### here.
   (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
 

diff  --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
index 49e814b31b439..35b5e2144e6d3 100644
--- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -54,6 +54,9 @@ clang::createInvocation(ArrayRef<const char *> ArgList,
   if (!C)
     return nullptr;
 
+  if (C->getArgs().hasArg(driver::options::OPT_fdriver_only))
+    return nullptr;
+
   // Just print the cc1 options if -### was present.
   if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
     C->getJobs().Print(llvm::errs(), "\n", true);

diff  --git a/clang/test/Driver/cc-print-options.c b/clang/test/Driver/cc-print-options.c
index 5a1781008337f..58375fa7327cc 100644
--- a/clang/test/Driver/cc-print-options.c
+++ b/clang/test/Driver/cc-print-options.c
@@ -1,8 +1,14 @@
+// RUN: rm -f %t.log
 // RUN: env CC_PRINT_OPTIONS=1 \
 // RUN:     CC_PRINT_OPTIONS_FILE=%t.log \
 // RUN: %clang -S -o %t.s %s
 // RUN: FileCheck %s < %t.log
 
-// CHECK: [Logging clang options]
-// CHECK: {{.*}} "-S"
+// RUN: rm -f %t.log
+// RUN: env CC_PRINT_OPTIONS=1 \
+// RUN:     CC_PRINT_OPTIONS_FILE=%t.log \
+// RUN: %clang -fdriver-only -o %t.s %s
+// RUN: FileCheck %s < %t.log
 
+// CHECK: [Logging clang options]
+// CHECK: {{.*}} "-cc1"

diff  --git a/clang/test/Driver/driver-only.c b/clang/test/Driver/driver-only.c
new file mode 100644
index 0000000000000..067f174a3cf45
--- /dev/null
+++ b/clang/test/Driver/driver-only.c
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// Check that -fdriver-only doesn't actually run the generated -cc1 job.
+//
+// RUN: %clang -c %s -o %t/a.o -fdriver-only
+// RUN: not cat %t/a.o
+
+// Check that -fdriver-only respects errors.
+//
+// RUN: not %clang -c %s -fdriver-only -target i386-apple-darwin9 -m32 -Xarch_i386 -o
+
+// Check that -fdriver-only respects -v.
+//
+// RUN: %clang -c %s -fdriver-only -v 2>&1 | FileCheck %s --check-prefix=CHECK-V
+// CHECK-V: {{.*}} "-cc1"
+//
+// RUN: %clang -c %s -fdriver-only    2>&1 | FileCheck %s --check-prefix=CHECK-NO-V --allow-empty
+// CHECK-NO-V-NOT: {{.*}} "-cc1"


        


More information about the cfe-commits mailing list