[clang] d8bab69 - [clang][deps] Move invocation adjustments from `clang-scan-deps` to `DependencyScanning` library

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 14 03:23:40 PDT 2021


Author: Jan Svoboda
Date: 2021-06-14T12:23:33+02:00
New Revision: d8bab69ead22a10dc4cdb2e36f6ea6fdfe774e2e

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

LOG: [clang][deps] Move invocation adjustments from `clang-scan-deps` to `DependencyScanning` library

The `clang-scan-deps` tool has some logic that parses and modifies the original Clang command-line. The goal is to setup `DependencyOutputOptions` by injecting `-M -MT <target>` and prevent the creation of output files.

This patch moves the logic into the `DependencyScanning` library, and uses the parsed `CompilerInvocation` instead of the raw command-line. The code simpler and can be used from the C++ API as well.

The `-o /dev/null` arguments are not necessary, since the `DependencyScanning` library only runs a preprocessing action, so there's no way it'll produce an actual object file.

Related: The `-M` argument implies `-w`, which would appear on the command-line of modular dependencies even though it was not on the original TU command line (see D104036).

Some related tests were updated.

Reviewed By: arphaman

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

Added: 
    

Modified: 
    clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
    clang/test/ClangScanDeps/modules-pch.c
    clang/test/ClangScanDeps/modules.cpp
    clang/test/ClangScanDeps/regular_cdb.cpp
    clang/tools/clang-scan-deps/ClangScanDeps.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 40466b00f0e5..e9392ee824a6 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -62,6 +62,26 @@ class ImportCollectingListener : public ASTReaderListener {
   std::map<std::string, std::string> &PrebuiltModuleFiles;
 };
 
+/// Transform arbitrary file name into an object-like file name.
+static std::string makeObjFileName(StringRef FileName) {
+  SmallString<128> ObjFileName(FileName);
+  llvm::sys::path::replace_extension(ObjFileName, "o");
+  return std::string(ObjFileName.str());
+}
+
+/// Deduce the dependency target based on the output file and input files.
+static std::string
+deduceDepTarget(const std::string &OutputFile,
+                const SmallVectorImpl<FrontendInputFile> &InputFiles) {
+  if (OutputFile != "-")
+    return OutputFile;
+
+  if (InputFiles.empty() || !InputFiles.front().isFile())
+    return "clang-scan-deps\\ dependency";
+
+  return makeObjFileName(InputFiles.front().getFile());
+}
+
 /// A clang tool that runs the preprocessor in a mode that's optimized for
 /// dependency scanning for the given compiler invocation.
 class DependencyScanningAction : public tooling::ToolAction {
@@ -150,9 +170,11 @@ class DependencyScanningAction : public tooling::ToolAction {
     // and thus won't write out the extra '.d' files to disk.
     auto Opts = std::make_unique<DependencyOutputOptions>(
         std::move(Compiler.getInvocation().getDependencyOutputOpts()));
-    // We need at least one -MT equivalent for the generator to work.
+    // We need at least one -MT equivalent for the generator of make dependency
+    // files to work.
     if (Opts->Targets.empty())
-      Opts->Targets = {"clang-scan-deps dependency"};
+      Opts->Targets = {deduceDepTarget(Compiler.getFrontendOpts().OutputFile,
+                                       Compiler.getFrontendOpts().Inputs)};
 
     switch (Format) {
     case ScanningOutputFormat::Make:

diff  --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c
index 34a0043acd5c..8b8b75310adb 100644
--- a/clang/test/ClangScanDeps/modules-pch.c
+++ b/clang/test/ClangScanDeps/modules-pch.c
@@ -9,6 +9,9 @@
 // RUN:   -generate-modules-path-args -module-files-dir %t/build -mode preprocess >> %t/result_pch.json
 // RUN: cat %t/result_pch.json | sed 's:\\\\\?:/:g' | FileCheck %s -check-prefix=CHECK-PCH
 //
+// Check we didn't build the PCH during dependency scanning.
+// RUN: not cat %/t/pch.h.gch
+//
 // CHECK-PCH:      -[[PREFIX:.*]]
 // CHECK-PCH-NEXT: {
 // CHECK-PCH-NEXT:   "modules": [

diff  --git a/clang/test/ClangScanDeps/modules.cpp b/clang/test/ClangScanDeps/modules.cpp
index f0d97dc0c5c2..b7daf51b4a80 100644
--- a/clang/test/ClangScanDeps/modules.cpp
+++ b/clang/test/ClangScanDeps/modules.cpp
@@ -42,13 +42,14 @@
 
 #include "header.h"
 
-// CHECK1: modules_cdb_input2.cpp
+// CHECK1: modules_cdb_input2.o:
 // CHECK1-NEXT: modules_cdb_input2.cpp
 // CHECK1-NEXT: Inputs{{/|\\}}module.modulemap
 // CHECK1-NEXT: Inputs{{/|\\}}header2.h
 // CHECK1: Inputs{{/|\\}}header.h
 
-// CHECK2: modules_cdb_input.cpp
+// CHECK2: {{.*}}.o:
+// CHECK2-NEXT: modules_cdb_input.cpp
 // CHECK2-NEXT: Inputs{{/|\\}}module.modulemap
 // CHECK2-NEXT: Inputs{{/|\\}}header.h
 // CHECK2NO-NOT: header2

diff  --git a/clang/test/ClangScanDeps/regular_cdb.cpp b/clang/test/ClangScanDeps/regular_cdb.cpp
index d7ba2519067e..ee986005f97e 100644
--- a/clang/test/ClangScanDeps/regular_cdb.cpp
+++ b/clang/test/ClangScanDeps/regular_cdb.cpp
@@ -58,14 +58,14 @@
 
 #include "header.h"
 
-// CHECK1: regular_cdb_input2.cpp
+// CHECK1: regular_cdb_input2.o:
 // CHECK1-NEXT: regular_cdb_input2.cpp
 // CHECK1-NEXT: Inputs{{/|\\}}header.h
 // CHECK1-NEXT: Inputs{{/|\\}}header2.h
 
-// CHECK3: regular_cdb_input.o
-// CHECK2: regular_cdb_input.cpp
+// CHECK2: regular_cdb_input.o:
+// CHECK2-NEXT: regular_cdb_input.cpp
 // CHECK2-NEXT: Inputs{{/|\\}}header.h
 // CHECK2NO-NOT: header2
 
-// CHECK3: adena.o
+// CHECK3: adena.o:

diff  --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 625a4c1ef923..d9f1b586d71a 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -201,13 +201,6 @@ llvm::cl::opt<bool> Verbose("v", llvm::cl::Optional,
 
 } // end anonymous namespace
 
-/// \returns object-file path derived from source-file path.
-static std::string getObjFilePath(StringRef SrcFile) {
-  SmallString<128> ObjFileName(SrcFile);
-  llvm::sys::path::replace_extension(ObjFileName, "o");
-  return std::string(ObjFileName.str());
-}
-
 class SingleCommandCompilationDatabase : public tooling::CompilationDatabase {
 public:
   SingleCommandCompilationDatabase(tooling::CompileCommand Cmd)
@@ -463,16 +456,10 @@ int main(int argc, const char **argv) {
           std::move(Compilations));
   ResourceDirectoryCache ResourceDirCache;
 
-  // FIXME: Adjust the resulting CompilerInvocation in DependencyScanningAction
-  // instead of parsing and adjusting the raw command-line. This will make it
-  // possible to remove some code specific to clang-cl and Windows.
   AdjustingCompilations->appendArgumentsAdjuster(
       [&ResourceDirCache](const tooling::CommandLineArguments &Args,
                           StringRef FileName) {
         std::string LastO = "";
-        bool HasMT = false;
-        bool HasMQ = false;
-        bool HasMD = false;
         bool HasResourceDir = false;
         bool ClangCLMode = false;
         auto FlagsEnd = llvm::find(Args, "--");
@@ -503,58 +490,17 @@ int main(int argc, const char **argv) {
                 if (!LastO.empty() && !llvm::sys::path::has_extension(LastO))
                   LastO.append(".obj");
               }
-              if (Arg == "/clang:-MT")
-                HasMT = true;
-              if (Arg == "/clang:-MQ")
-                HasMQ = true;
-              if (Arg == "/clang:-MD")
-                HasMD = true;
-            } else {
-              if (LastO.empty()) {
-                if (Arg == "-o" && I != R)
-                  LastO = I[-1]; // Next argument (reverse iterator)
-                else if (Arg.startswith("-o"))
-                  LastO = Arg.drop_front(2).str();
-              }
-              if (Arg == "-MT")
-                HasMT = true;
-              if (Arg == "-MQ")
-                HasMQ = true;
-              if (Arg == "-MD")
-                HasMD = true;
             }
             if (Arg == "-resource-dir")
               HasResourceDir = true;
           }
         }
-        // If there's no -MT/-MQ Driver would add -MT with the value of the last
-        // -o option.
         tooling::CommandLineArguments AdjustedArgs(Args.begin(), FlagsEnd);
-        AdjustedArgs.push_back("-o");
-#ifdef _WIN32
-        AdjustedArgs.push_back("nul");
-#else
-        AdjustedArgs.push_back("/dev/null");
-#endif
-        if (!HasMT && !HasMQ && Format == ScanningOutputFormat::Make) {
-          // We're interested in source dependencies of an object file.
-          std::string FileNameArg;
-          if (!HasMD) {
-            // FIXME: We are missing the directory unless the -o value is an
-            // absolute path.
-            FileNameArg = !LastO.empty() ? LastO : getObjFilePath(FileName);
-          } else {
-            FileNameArg = std::string(FileName);
-          }
-          if (ClangCLMode) {
-            AdjustedArgs.push_back("/clang:-M");
-            AdjustedArgs.push_back("/clang:-MT");
-            AdjustedArgs.push_back(Twine("/clang:", FileNameArg).str());
-          } else {
-            AdjustedArgs.push_back("-M");
-            AdjustedArgs.push_back("-MT");
-            AdjustedArgs.push_back(std::move(FileNameArg));
-          }
+        // The clang-cl driver passes "-o -" to the frontend. Inject the real
+        // file here to ensure "-MT" can be deduced if need be.
+        if (ClangCLMode && !LastO.empty()) {
+          AdjustedArgs.push_back("/clang:-o");
+          AdjustedArgs.push_back("/clang:" + LastO);
         }
         AdjustedArgs.push_back("-Xclang");
         AdjustedArgs.push_back("-sys-header-deps");


        


More information about the cfe-commits mailing list