Skip to content

Commit f5e2b24

Browse files
committed
[Dependency Scanning] Filter out '-Xcc' search paths from Swift module compilation commands
These search paths will not get used during Swift module compilation and can only hinder module sharing among different targets. Resolves rdar://119217774
1 parent 452c624 commit f5e2b24

File tree

4 files changed

+123
-28
lines changed

4 files changed

+123
-28
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,16 @@ namespace swift {
10011001

10021002
std::vector<std::string> getRemappedExtraArgs(
10031003
std::function<std::string(StringRef)> pathRemapCallback) const;
1004+
1005+
/// For a swift module dependency, interface build command generation must
1006+
/// inherit
1007+
/// `-Xcc` flags used for configuration of the building instance's
1008+
/// `ClangImporter`. However, we can ignore Clang search path flags because
1009+
/// explicit Swift module build tasks will not rely on them and they may be
1010+
/// source-target-context-specific and hinder module sharing across
1011+
/// compilation source targets.
1012+
std::vector<std::string>
1013+
getReducedExtraArgsForSwiftModuleDependency() const;
10041014
};
10051015

10061016
} // end namespace swift

lib/Basic/LangOptions.cpp

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -672,26 +672,30 @@ DiagnosticBehavior LangOptions::getAccessNoteFailureLimit() const {
672672
llvm_unreachable("covered switch");
673673
}
674674

675+
namespace {
676+
static constexpr std::array<std::string_view, 16> knownSearchPathPrefiexes =
677+
{"-I",
678+
"-F",
679+
"-fmodule-map-file=",
680+
"-iquote",
681+
"-idirafter",
682+
"-iframeworkwithsysroot",
683+
"-iframework",
684+
"-iprefix",
685+
"-iwithprefixbefore",
686+
"-iwithprefix",
687+
"-isystemafter",
688+
"-isystem",
689+
"-isysroot",
690+
"-ivfsoverlay",
691+
"-working-directory=",
692+
"-working-directory"};
693+
}
694+
675695
std::vector<std::string> ClangImporterOptions::getRemappedExtraArgs(
676696
std::function<std::string(StringRef)> pathRemapCallback) const {
677697
auto consumeIncludeOption = [](StringRef &arg, StringRef &prefix) {
678-
static StringRef options[] = {"-I",
679-
"-F",
680-
"-fmodule-map-file=",
681-
"-iquote",
682-
"-idirafter",
683-
"-iframeworkwithsysroot",
684-
"-iframework",
685-
"-iprefix",
686-
"-iwithprefixbefore",
687-
"-iwithprefix",
688-
"-isystemafter",
689-
"-isystem",
690-
"-isysroot",
691-
"-ivfsoverlay",
692-
"-working-directory=",
693-
"-working-directory"};
694-
for (StringRef &option : options)
698+
for (const auto &option : knownSearchPathPrefiexes)
695699
if (arg.consume_front(option)) {
696700
prefix = option;
697701
return true;
@@ -724,3 +728,34 @@ std::vector<std::string> ClangImporterOptions::getRemappedExtraArgs(
724728
}
725729
return args;
726730
}
731+
732+
std::vector<std::string>
733+
ClangImporterOptions::getReducedExtraArgsForSwiftModuleDependency() const {
734+
auto matchIncludeOption = [](StringRef &arg) {
735+
for (const auto &option : knownSearchPathPrefiexes)
736+
if (arg.consume_front(option))
737+
return true;
738+
return false;
739+
};
740+
741+
std::vector<std::string> filtered_args;
742+
bool skip_next = false;
743+
std::vector<std::string> args;
744+
for (auto A : ExtraArgs) {
745+
StringRef arg(A);
746+
if (skip_next) {
747+
skip_next = false;
748+
continue;
749+
} else if (matchIncludeOption(arg)) {
750+
if (arg.empty()) {
751+
// Option pair
752+
skip_next = true;
753+
} // else non-pair option e.g. '-I/search/path'
754+
continue;
755+
} else {
756+
filtered_args.push_back(A);
757+
}
758+
}
759+
760+
return filtered_args;
761+
}

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,17 +1756,32 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
17561756
clangImporterOpts.DetailedPreprocessingRecord;
17571757
subClangImporterOpts.CASOpts = clangImporterOpts.CASOpts;
17581758

1759-
// If the compiler has been asked to be strict with ensuring downstream dependencies
1760-
// get the parent invocation's context, or this is an Explicit build, inherit the
1761-
// extra Clang arguments also.
1762-
if (LoaderOpts.strictImplicitModuleContext || LoaderOpts.disableImplicitSwiftModule ||
1763-
LoaderOpts.requestedAction == FrontendOptions::ActionType::ScanDependencies) {
1764-
// Inherit any clang-specific state of the compilation (macros, clang flags, etc.)
1765-
subClangImporterOpts.ExtraArgs = clangImporterOpts.ExtraArgs;
1766-
for (auto arg : subClangImporterOpts.ExtraArgs) {
1767-
GenericArgs.push_back("-Xcc");
1768-
GenericArgs.push_back(ArgSaver.save(arg));
1769-
}
1759+
std::vector<std::string> inheritedParentContextClangArgs;
1760+
if (LoaderOpts.requestedAction ==
1761+
FrontendOptions::ActionType::ScanDependencies) {
1762+
// For a dependency scanning action, interface build command generation must
1763+
// inherit
1764+
// `-Xcc` flags used for configuration of the building instance's
1765+
// `ClangImporter`. However, we can ignore Clang search path flags because
1766+
// explicit Swift module build tasks will not rely on them and they may be
1767+
// source-target-context-specific and hinder module sharing across
1768+
// compilation source targets.
1769+
// Clang module dependecies of this Swift dependency will be distinguished by
1770+
// their context hash for different variants, so would still cause a difference
1771+
// in the Swift compile commands, when different.
1772+
inheritedParentContextClangArgs =
1773+
clangImporterOpts.getReducedExtraArgsForSwiftModuleDependency();
1774+
} else if (LoaderOpts.strictImplicitModuleContext) {
1775+
// If the compiler has been asked to be strict with ensuring downstream
1776+
// dependencies get the parent invocation's context, inherit the extra Clang
1777+
// arguments also. Inherit any clang-specific state of the compilation
1778+
// (macros, clang flags, etc.)
1779+
inheritedParentContextClangArgs = clangImporterOpts.ExtraArgs;
1780+
}
1781+
subClangImporterOpts.ExtraArgs = inheritedParentContextClangArgs;
1782+
for (auto arg : subClangImporterOpts.ExtraArgs) {
1783+
GenericArgs.push_back("-Xcc");
1784+
GenericArgs.push_back(ArgSaver.save(arg));
17701785
}
17711786

17721787
subClangImporterOpts.EnableClangSPI = clangImporterOpts.EnableClangSPI;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/clang-module-cache)
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -Xcc -fobjc-disable-direct-methods-for-testing -Xcc -I -Xcc /tmp/foo -Xcc -I/tmp/bar
5+
// Check the contents of the JSON output
6+
// RUN: %validate-json %t/deps.json | %FileCheck %s
7+
8+
// REQUIRES: executable_test
9+
// REQUIRES: objc_interop
10+
11+
import C
12+
13+
// CHECK: "mainModuleName": "deps"
14+
/// --------Main module
15+
// CHECK-LABEL: "modulePath": "deps.swiftmodule",
16+
// CHECK-NEXT: sourceFiles
17+
// CHECK-NEXT: FilterClangSearchPaths.swift
18+
// CHECK-NEXT: ],
19+
// CHECK-NEXT: "directDependencies": [
20+
// CHECK-DAG: "clang": "C"
21+
// CHECK-DAG: "swift": "Swift"
22+
// CHECK-DAG: "swift": "SwiftOnoneSupport"
23+
// CHECK-DAG: "swift": "_Concurrency"
24+
// CHECK: ],
25+
26+
// CHECK: "swift": "A"
27+
// CHECK: "swift": {
28+
// CHECK-NEXT: "moduleInterfacePath": "{{.*}}{{/|\\}}Inputs{{/|\\}}Swift{{/|\\}}A.swiftinterface",
29+
// CHECK: "commandLine": [
30+
// CHECK: "-fobjc-disable-direct-methods-for-testing"
31+
// CHECK: "-o",
32+
// CHECK-NEXT: "{{.*}}{{/|\\}}A-{{.*}}.swiftmodule",
33+
// CHECK-NOT: "/tmp/foo"
34+
// CHECK-NOT: "-I/tmp/bar"
35+
// CHECK: ]

0 commit comments

Comments
 (0)