Skip to content

Commit ead742b

Browse files
[CAS] Do not create redirect file system when using clang-include-tree
Redirecting file system can canonicalize the file path before forwarding the path to IncludeTreeFileSystem, which is a simplied FS that can only intepret the paths that has been seen by dep-scanner. Since all files that need redirecting already added to underlying FS via DepScan, there is no need for such layer when compiling using clang-include-tree. rdar://119727344
1 parent 2608746 commit ead742b

File tree

8 files changed

+115
-28
lines changed

8 files changed

+115
-28
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,9 +969,12 @@ namespace swift {
969969
/// built and provided to the compiler invocation.
970970
bool DisableImplicitClangModules = false;
971971

972-
/// Enable ClangIncludeTree for explicit module builds.
972+
/// Enable ClangIncludeTree for explicit module builds scanning.
973973
bool UseClangIncludeTree = false;
974974

975+
/// Using ClangIncludeTreeRoot for compilation.
976+
bool HasClangIncludeTreeRoot = false;
977+
975978
/// Return a hash code of any components from these options that should
976979
/// contribute to a Swift Bridging PCH hash.
977980
llvm::hash_code getPCHHashComponents() const {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ std::optional<std::vector<std::string>> ClangImporter::getClangCC1Arguments(
11331133

11341134
std::vector<std::string> FilteredModuleMapFiles;
11351135
for (auto ModuleMapFile : CI->getFrontendOpts().ModuleMapFiles) {
1136-
if (ctx.ClangImporterOpts.UseClangIncludeTree) {
1136+
if (ctx.ClangImporterOpts.HasClangIncludeTreeRoot) {
11371137
// There is no need to add any module map file here. Issue a warning and
11381138
// drop the option.
11391139
importer->Impl.diagnose(SourceLoc(), diag::module_map_ignored,
@@ -1200,27 +1200,33 @@ ClangImporter::create(ASTContext &ctx,
12001200
}
12011201
}
12021202

1203-
auto fileMapping = getClangInvocationFileMapping(ctx);
1204-
// Wrap Swift's FS to allow Clang to override the working directory
12051203
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1206-
llvm::vfs::RedirectingFileSystem::create(
1207-
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1208-
if (!fileMapping.overridenFiles.empty()) {
1209-
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1210-
new llvm::vfs::InMemoryFileSystem();
1211-
for (const auto &file : fileMapping.overridenFiles) {
1212-
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1213-
std::copy(file.second.begin(), file.second.end(), contents.begin());
1214-
// null terminate the buffer.
1215-
contents[contents.size() - 1] = '\0';
1216-
overridenVFS->addFile(file.first, 0,
1217-
llvm::MemoryBuffer::getMemBuffer(
1218-
StringRef(contents.begin(), contents.size() - 1)));
1219-
}
1220-
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1221-
new llvm::vfs::OverlayFileSystem(VFS);
1222-
VFS = overlayVFS;
1223-
overlayVFS->pushOverlay(overridenVFS);
1204+
ctx.SourceMgr.getFileSystem();
1205+
1206+
auto fileMapping = getClangInvocationFileMapping(ctx);
1207+
// Avoid creating indirect file system when using include tree.
1208+
if (!ctx.ClangImporterOpts.HasClangIncludeTreeRoot) {
1209+
// Wrap Swift's FS to allow Clang to override the working directory
1210+
VFS = llvm::vfs::RedirectingFileSystem::create(
1211+
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1212+
1213+
if (!fileMapping.overridenFiles.empty()) {
1214+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1215+
new llvm::vfs::InMemoryFileSystem();
1216+
for (const auto &file : fileMapping.overridenFiles) {
1217+
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1218+
std::copy(file.second.begin(), file.second.end(), contents.begin());
1219+
// null terminate the buffer.
1220+
contents[contents.size() - 1] = '\0';
1221+
overridenVFS->addFile(file.first, 0,
1222+
llvm::MemoryBuffer::getMemBuffer(StringRef(
1223+
contents.begin(), contents.size() - 1)));
1224+
}
1225+
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1226+
new llvm::vfs::OverlayFileSystem(VFS);
1227+
VFS = overlayVFS;
1228+
overlayVFS->pushOverlay(overridenVFS);
1229+
}
12241230
}
12251231

12261232
// Create a new Clang compiler invocation.

lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,7 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args,
16871687
// Only set UseClangIncludeTree when caching is enabled since it is not
16881688
// useful in non-caching context.
16891689
Opts.UseClangIncludeTree = !Args.hasArg(OPT_no_clang_include_tree);
1690+
Opts.HasClangIncludeTreeRoot = Args.hasArg(OPT_clang_include_tree_root);
16901691
}
16911692

16921693
return false;

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ bool CompilerInstance::setUpInputs() {
869869
// There is no input file when building PCM using ClangIncludeTree.
870870
if (Invocation.getFrontendOptions().RequestedAction ==
871871
FrontendOptions::ActionType::EmitPCM &&
872-
Invocation.getClangImporterOptions().UseClangIncludeTree)
872+
Invocation.getClangImporterOptions().HasClangIncludeTreeRoot)
873873
return false;
874874

875875
// Adds to InputSourceCodeBufferIDs, so may need to happen before the
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Usage: BuildCommandExtractor.py file.json ModuleName
4+
5+
import json
6+
import sys
7+
8+
input_json = sys.argv[1]
9+
module_name = sys.argv[2]
10+
11+
mode = 'swift'
12+
13+
if module_name.startswith('clang:'):
14+
mode = 'clang'
15+
module_name = module_name[6:]
16+
elif module_name.startswith('swiftPrebuiltExternal:'):
17+
mode = 'swiftPrebuiltExternal'
18+
module_name = module_name[22:]
19+
20+
with open(input_json, 'r') as file:
21+
deps = json.load(file)
22+
module_names = deps['modules'][::2]
23+
module_details = deps['modules'][1::2]
24+
for name, detail in zip(module_names, module_details):
25+
if name.get(mode, '') != module_name:
26+
continue
27+
28+
cmd = detail['details'][mode]['commandLine']
29+
for c in cmd:
30+
print('"{}"'.format(c))
31+
break

test/CAS/cas-explicit-module-map.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@
110110

111111
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Foo.swiftmodule -disable-implicit-swift-modules -module-cache-path %t.module-cache -explicit-swift-module-map-file @%t/map.casid -Rmodule-loading -Xcc -Rmodule-import %s -cache-compile-job -cas-path %t/cas -allow-unstable-cache-key-for-testing 2>&1 | %FileCheck %s
112112

113-
/// Test that if there are non-existing module-map file passed through -Xcc, this still compiles.
114-
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Foo.swiftmodule -disable-implicit-swift-modules -module-cache-path %t.module-cache -explicit-swift-module-map-file @%t/map.casid -Rmodule-loading -Xcc -Rmodule-import %s -cache-compile-job -cas-path %t/cas -allow-unstable-cache-key-for-testing -Xcc -fmodule-map-file=%t/do-not-exist.modulemap 2>&1 | %FileCheck %s --check-prefix=CHECK --check-prefix=MODULEMAP-IGNORE
115-
116-
// MODULEMAP-IGNORE: warning: module map file '{{.*}}' will be ignored
117-
118113
// RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/Foo.swiftinterface -disable-implicit-swift-modules -module-cache-path %t.module-cache -explicit-swift-module-map-file @%t/map.casid %s -cache-compile-job -cas-path %t/cas -allow-unstable-cache-key-for-testing -swift-version 5 -enable-library-evolution -o %t/Foo.swiftmodule
119114
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
120115
// RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/Foo.swiftinterface -disable-implicit-swift-modules \

test/CAS/include-tree-cxx.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache %t/main.swift -o %t/deps.json -I %t/include -swift-version 4 -cache-compile-job -cas-path %t/cas -cxx-interoperability-mode=default
5+
6+
// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json clang:MyCXX clangIncludeTree | %FileCheck %s
7+
// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json clang:MyCXX moduleCacheKey | %FileCheck %s
8+
9+
// CHECK: llvmcas://
10+
11+
//--- main.swift
12+
import MyCXX
13+
14+
//--- include/module.modulemap
15+
module MyCXX {
16+
header "mycxx.h"
17+
requires cplusplus
18+
}
19+
20+
//--- include/mycxx.h
21+
#pragma once
22+
class A {};
23+
24+
void test(const A& str);

test/CAS/include-tree.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache %t/main.swift -o %t/deps.json -I %t/include -swift-version 4 -cache-compile-job -cas-path %t/cas
5+
// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:DotDot > %t/DotDot.cmd
6+
// RUN: %swift_frontend_plain @%t/DotDot.cmd
7+
8+
// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/SwiftShims.cmd
9+
// RUN: %swift_frontend_plain @%t/SwiftShims.cmd
10+
11+
// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json Swift > %t/Swift.cmd
12+
// RUN: %swift_frontend_plain @%t/Swift.cmd
13+
14+
/// Test that if there are non-existing module-map file passed through -Xcc, this still compiles.
15+
// RUN: %swift_frontend_plain @%t/Swift.cmd -Xcc -fmodule-map-file=%t/do-not-exist.modulemap
16+
17+
//--- main.swift
18+
import DotDot
19+
20+
//--- include/module.modulemap
21+
module DotDot [extern_c] {
22+
header "../dotdot.h"
23+
export *
24+
}
25+
26+
//--- dotdot.h
27+
void test(void);

0 commit comments

Comments
 (0)