[ScanDependency] Add -experimental-clang-importer-direct-cc1-scan

Add an experimental option to tell dependency scanner to report clang
cc1 args should be used to construct clang importer in all constructed
swift-frontend tasks.
This commit is contained in:
Steven Wu
2024-02-23 12:15:57 -08:00
parent fb3c268abc
commit cb17ea8e66
7 changed files with 50 additions and 3 deletions

View File

@@ -969,6 +969,10 @@ namespace swift {
/// Using ClangIncludeTreeRoot for compilation. /// Using ClangIncludeTreeRoot for compilation.
bool HasClangIncludeTreeRoot = false; bool HasClangIncludeTreeRoot = false;
/// Whether the dependency scanner should construct all swift-frontend
/// invocations directly from clang cc1 args.
bool ClangImporterDirectCC1Scan = false;
/// Return a hash code of any components from these options that should /// Return a hash code of any components from these options that should
/// contribute to a Swift Bridging PCH hash. /// contribute to a Swift Bridging PCH hash.
llvm::hash_code getPCHHashComponents() const { llvm::hash_code getPCHHashComponents() const {

View File

@@ -1894,6 +1894,11 @@ def gcc_toolchain: Separate<["-"], "gcc-toolchain">,
MetaVarName<"<path>">, MetaVarName<"<path>">,
HelpText<"Specify a directory where the clang importer and clang linker can find headers and libraries">; HelpText<"Specify a directory where the clang importer and clang linker can find headers and libraries">;
def experimental_clang_importer_direct_cc1_scan:
Flag<["-"], "experimental-clang-importer-direct-cc1-scan">,
Flags<[FrontendOption, NewDriverOnlyOption, HelpHidden]>,
HelpText<"Enables swift driver to construct swift-frontend invocations using -direct-clang-cc1-module-build">;
def cache_compile_job: Flag<["-"], "cache-compile-job">, def cache_compile_job: Flag<["-"], "cache-compile-job">,
Flags<[FrontendOption, NewDriverOnlyOption]>, Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Enable compiler caching">; HelpText<"Enable compiler caching">;

View File

@@ -347,6 +347,8 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(
std::string rootID; std::string rootID;
std::vector<std::string> buildArgs; std::vector<std::string> buildArgs;
auto clangImporter =
static_cast<ClangImporter *>(ScanASTContext.getClangModuleLoader());
if (tracker) { if (tracker) {
tracker->startTracking(); tracker->startTracking();
for (auto fileUnit : mainModule->getFiles()) { for (auto fileUnit : mainModule->getFiles()) {
@@ -359,8 +361,6 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(
ScanCompilerInvocation.getSearchPathOptions()); ScanCompilerInvocation.getSearchPathOptions());
// Fetch some dependency files from clang importer. // Fetch some dependency files from clang importer.
std::vector<std::string> clangDependencyFiles; std::vector<std::string> clangDependencyFiles;
auto clangImporter =
static_cast<ClangImporter *>(ScanASTContext.getClangModuleLoader());
clangImporter->addClangInvovcationDependencies(clangDependencyFiles); clangImporter->addClangInvovcationDependencies(clangDependencyFiles);
llvm::for_each(clangDependencyFiles, llvm::for_each(clangDependencyFiles,
[&](std::string &file) { tracker->trackFile(file); }); [&](std::string &file) { tracker->trackFile(file); });
@@ -372,7 +372,9 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(
return std::make_error_code(std::errc::io_error); return std::make_error_code(std::errc::io_error);
} }
rootID = root->getID().toString(); rootID = root->getID().toString();
}
if (ScanASTContext.ClangImporterOpts.ClangImporterDirectCC1Scan) {
buildArgs.push_back("-direct-clang-cc1-module-build"); buildArgs.push_back("-direct-clang-cc1-module-build");
for (auto &arg : clangImporter->getSwiftExplicitModuleDirectCC1Args()) { for (auto &arg : clangImporter->getSwiftExplicitModuleDirectCC1Args()) {
buildArgs.push_back("-Xcc"); buildArgs.push_back("-Xcc");

View File

@@ -1709,6 +1709,8 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args,
Opts.DisableSourceImport |= Opts.DisableSourceImport |=
Args.hasArg(OPT_disable_clangimporter_source_import); Args.hasArg(OPT_disable_clangimporter_source_import);
Opts.ClangImporterDirectCC1Scan |=
Args.hasArg(OPT_experimental_clang_importer_direct_cc1_scan);
// Forward the FrontendOptions to clang importer option so it can be // Forward the FrontendOptions to clang importer option so it can be
// accessed when creating clang module compilation invocation. // accessed when creating clang module compilation invocation.
if (CASOpts.EnableCaching) { if (CASOpts.EnableCaching) {
@@ -1716,6 +1718,8 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args,
// useful in non-caching context. // useful in non-caching context.
Opts.UseClangIncludeTree |= !Args.hasArg(OPT_no_clang_include_tree); Opts.UseClangIncludeTree |= !Args.hasArg(OPT_no_clang_include_tree);
Opts.HasClangIncludeTreeRoot |= Args.hasArg(OPT_clang_include_tree_root); Opts.HasClangIncludeTreeRoot |= Args.hasArg(OPT_clang_include_tree_root);
// Caching requires direct clang import cc1 scanning.
Opts.ClangImporterDirectCC1Scan = true;
} }
// If in direct clang cc1 module build mode, return early. // If in direct clang cc1 module build mode, return early.

View File

@@ -1677,6 +1677,8 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
genericSubInvocation.getClangImporterOptions().DirectClangCC1ModuleBuild = genericSubInvocation.getClangImporterOptions().DirectClangCC1ModuleBuild =
clangImporterOpts.DirectClangCC1ModuleBuild; clangImporterOpts.DirectClangCC1ModuleBuild;
genericSubInvocation.getClangImporterOptions().ClangImporterDirectCC1Scan =
clangImporterOpts.ClangImporterDirectCC1Scan;
// Validate Clang modules once per-build session flags must be consistent // Validate Clang modules once per-build session flags must be consistent
// across all module sub-invocations // across all module sub-invocations

View File

@@ -160,7 +160,7 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
// Handle clang arguments. For caching build, all arguments are passed // Handle clang arguments. For caching build, all arguments are passed
// with `-direct-clang-cc1-module-build`. // with `-direct-clang-cc1-module-build`.
if (Ctx.CASOpts.EnableCaching) { if (Ctx.ClangImporterOpts.ClangImporterDirectCC1Scan) {
Args.push_back("-direct-clang-cc1-module-build"); Args.push_back("-direct-clang-cc1-module-build");
auto *importer = auto *importer =
static_cast<ClangImporter *>(Ctx.getClangModuleLoader()); static_cast<ClangImporter *>(Ctx.getClangModuleLoader());

View File

@@ -0,0 +1,30 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-frontend -emit-module %t/A.swift -module-name A \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
// RUN: -enable-library-evolution -swift-version 5 \
// RUN: -emit-module-interface-path %t/A.swiftinterface \
// RUN: -o %t/A.swiftmodule
// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json -I %t \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
// RUN: %t/test.swift -module-name Test -swift-version 5
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json A | %FileCheck %s --check-prefix CHECK-NO-DIRECT-CC1
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json Test | %FileCheck %s --allow-empty --check-prefix CHECK-NO-DIRECT-CC1
// RUN: %target-swift-frontend -scan-dependencies -o %t/deps2.json -I %t \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
// RUN: %t/test.swift -module-name Test -swift-version 5 -experimental-clang-importer-direct-cc1-scan
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps2.json A | %FileCheck %s --check-prefix CHECK-DIRECT-CC1-SCAN
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps2.json Test | %FileCheck %s --check-prefix CHECK-DIRECT-CC1-SCAN
// CHECK-NO-DIRECT-CC1-NOT: -direct-clang-cc1-module-build
// CHECK-DIRECT-CC1-SCAN: -direct-clang-cc1-module-build
//--- A.swift
func a() {}
//--- test.swift
import A
func test() {}