Skip to content

Commit 800bd74

Browse files
committed
[cxx-interop] Add CxxShim library; move __swift_interopStaticCast into it.
1 parent 374c7a3 commit 800bd74

File tree

15 files changed

+172
-23
lines changed

15 files changed

+172
-23
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,66 @@ ClangImporter::~ClangImporter() {
440440

441441
#pragma mark Module loading
442442

443+
static Optional<StringRef> getModuleMapFilePath(StringRef name,
444+
SearchPathOptions &Opts,
445+
llvm::Triple triple,
446+
SmallVectorImpl<char> &buffer) {
447+
StringRef platform = swift::getPlatformNameForTriple(triple);
448+
StringRef arch = swift::getMajorArchitectureName(triple);
449+
450+
StringRef SDKPath = Opts.getSDKPath();
451+
if (!SDKPath.empty()) {
452+
buffer.clear();
453+
buffer.append(SDKPath.begin(), SDKPath.end());
454+
llvm::sys::path::append(buffer, "usr", "lib", "swift");
455+
llvm::sys::path::append(buffer, platform, arch, name);
456+
457+
// Only specify the module map if that file actually exists. It may not;
458+
// for example in the case that `swiftc -target x86_64-unknown-linux-gnu
459+
// -emit-ir` is invoked using a Swift compiler not built for Linux targets.
460+
if (llvm::sys::fs::exists(buffer))
461+
return StringRef(buffer.data(), buffer.size());
462+
}
463+
464+
if (!Opts.RuntimeResourcePath.empty()) {
465+
buffer.clear();
466+
buffer.append(Opts.RuntimeResourcePath.begin(),
467+
Opts.RuntimeResourcePath.end());
468+
llvm::sys::path::append(buffer, platform, arch, name);
469+
470+
// Only specify the module map if that file actually exists. It may not;
471+
// for example in the case that `swiftc -target x86_64-unknown-linux-gnu
472+
// -emit-ir` is invoked using a Swift compiler not built for Linux targets.
473+
if (llvm::sys::fs::exists(buffer))
474+
return StringRef(buffer.data(), buffer.size());
475+
}
476+
477+
return None;
478+
}
479+
480+
/// Finds the glibc.modulemap file relative to the provided resource dir.
481+
///
482+
/// Note that the module map used for Glibc depends on the target we're
483+
/// compiling for, and is not included in the resource directory with the other
484+
/// implicit module maps. It's at {freebsd|linux}/{arch}/glibc.modulemap.
485+
static Optional<StringRef>
486+
getGlibcModuleMapPath(SearchPathOptions &Opts, llvm::Triple triple,
487+
SmallVectorImpl<char> &buffer) {
488+
return getModuleMapFilePath("glibc.modulemap", Opts, triple, buffer);
489+
}
490+
491+
static Optional<StringRef>
492+
getLibStdCxxModuleMapPath(SearchPathOptions &opts, llvm::Triple triple,
493+
SmallVectorImpl<char> &buffer) {
494+
return getModuleMapFilePath("libstdcxx.modulemap", opts, triple, buffer);
495+
}
496+
497+
static Optional<StringRef>
498+
getLibShimCxxModuleMapPath(SearchPathOptions &Opts, llvm::Triple triple,
499+
SmallVectorImpl<char> &buffer) {
500+
return getModuleMapFilePath("libcxxshim.modulemap", Opts, triple, buffer);
501+
}
502+
443503
static bool clangSupportsPragmaAttributeWithSwiftAttr() {
444504
clang::AttributeCommonInfo swiftAttrInfo(clang::SourceRange(),
445505
clang::AttributeCommonInfo::AT_SwiftAttr,
@@ -553,6 +613,11 @@ importer::getNormalInvocationArguments(
553613
});
554614
}
555615

616+
SmallString<128> buffer;
617+
if (auto path = getLibShimCxxModuleMapPath(searchPathOpts, triple, buffer)) {
618+
invocationArgStrs.push_back((Twine("-fmodule-map-file=") + *path).str());
619+
}
620+
556621
// Set C language options.
557622
if (triple.isOSDarwin()) {
558623
invocationArgStrs.insert(invocationArgStrs.end(), {
@@ -4394,10 +4459,12 @@ DeclRefExpr *getInteropStaticCastDeclRefExpr(ASTContext &ctx,
43944459
derived = derived->wrapInPointer(PTK_UnsafePointer);
43954460
}
43964461

4397-
// Lookup our static cast helper function.
4398-
// TODO: change this to stdlib or something.
4399-
auto wrapperModule =
4400-
ctx.getClangModuleLoader()->getWrapperForModule(owningModule);
4462+
// Lookup our static cast helper function in the C++ shim module.
4463+
auto wrapperModule = ctx.getLoadedModule(ctx.getIdentifier("CxxShim"));
4464+
assert(wrapperModule &&
4465+
"CxxShim module is required when using members of a base class. "
4466+
"Make sure you `import CxxShim`.");
4467+
44014468
SmallVector<ValueDecl *, 1> results;
44024469
ctx.lookupInModule(wrapperModule, "__swift_interopStaticCast", results);
44034470
assert(

stdlib/public/Cxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ add_swift_target_library(swiftCxx ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVE
1111
INSTALL_IN_COMPONENT sdk-overlay)
1212

1313
add_subdirectory(std)
14+
add_subdirectory(cxxshim)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
set(libcxxshim_modulemap_target_list)
2+
foreach(sdk ${SWIFT_SDKS})
3+
foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
4+
set(arch_suffix "${SWIFT_SDK_${sdk}_LIB_SUBDIR}-${arch}")
5+
set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}")
6+
7+
set(module_dir "${SWIFTLIB_DIR}/${arch_subdir}")
8+
set(module_dir_static "${SWIFTSTATICLIB_DIR}/${arch_subdir}")
9+
10+
set(libcxxshim_header "libcxxshim.h")
11+
set(libcxxshim_header_out "${module_dir}/libcxxshim.h")
12+
set(libcxxshim_header_out_static "${module_dir_static}/libcxxshim.h")
13+
set(libcxxshim_modulemap "libcxxshim.modulemap")
14+
set(libcxxshim_modulemap_out "${module_dir}/libcxxshim.modulemap")
15+
set(libcxxshim_modulemap_out_static "${module_dir_static}/libcxxshim.modulemap")
16+
17+
add_custom_command_target(
18+
copy_libcxxshim_modulemap
19+
COMMAND
20+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir}
21+
COMMAND
22+
"${CMAKE_COMMAND}" "-E" "copy_if_different" "${CMAKE_CURRENT_SOURCE_DIR}/${libcxxshim_modulemap}" "${libcxxshim_modulemap_out}"
23+
OUTPUT ${libcxxshim_modulemap_out}
24+
DEPENDS ${libcxxshim_modulemap}
25+
COMMENT "Copying libcxxshim modulemap to resources")
26+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_modulemap})
27+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_modulemap})
28+
29+
add_custom_command_target(
30+
copy_libcxxshim_header
31+
COMMAND
32+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir}
33+
COMMAND
34+
"${CMAKE_COMMAND}" "-E" "copy_if_different" "${CMAKE_CURRENT_SOURCE_DIR}/${libcxxshim_header}" "${libcxxshim_header_out}"
35+
OUTPUT ${libcxxshim_header_out}
36+
DEPENDS ${libcxxshim_header}
37+
COMMENT "Copying libcxxshim header to resources")
38+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_header})
39+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_header})
40+
41+
if(SWIFT_BUILD_STATIC_STDLIB)
42+
add_custom_command_target(
43+
copy_libcxxshim_modulemap_static
44+
COMMAND
45+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir_static}
46+
COMMAND
47+
"${CMAKE_COMMAND}" "-E" "copy_if_different"
48+
"${libcxxshim_modulemap_out}" "${libcxxshim_modulemap_out_static}"
49+
OUTPUT ${libcxxshim_modulemap_out_static}
50+
DEPENDS ${copy_libcxxshim_modulemap}
51+
COMMENT "Copying libcxxshim modulemap to static resources")
52+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_modulemap_static})
53+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_modulemap_static})
54+
55+
add_custom_command_target(
56+
copy_libcxxshim_header_static
57+
COMMAND
58+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir_static}
59+
COMMAND
60+
"${CMAKE_COMMAND}" "-E" "copy_if_different"
61+
"${libcxxshim_header_out}" "${libcxxshim_header_out_static}"
62+
OUTPUT ${libcxxshim_header_out_static}
63+
DEPENDS ${copy_libcxxshim_header}
64+
COMMENT "Copying libcxxshim header to static resources")
65+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_header_static})
66+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_header_static})
67+
endif()
68+
69+
swift_install_in_component(FILES "${libcxxshim_modulemap_out}"
70+
DESTINATION "lib/swift/${arch_subdir}"
71+
COMPONENT sdk-overlay)
72+
swift_install_in_component(FILES "${libcxxshim_header_out}"
73+
DESTINATION "lib/swift/${arch_subdir}"
74+
COMPONENT sdk-overlay)
75+
76+
if(SWIFT_BUILD_STATIC_STDLIB)
77+
swift_install_in_component(FILES "${libcxxshim_modulemap_out_static}"
78+
DESTINATION "lib/swift_static/${arch_subdir}"
79+
COMPONENT sdk-overlay)
80+
swift_install_in_component(FILES "${libcxxshim_header_out_static}"
81+
DESTINATION "lib/swift_static/${arch_subdir}"
82+
COMPONENT sdk-overlay)
83+
endif()
84+
endforeach()
85+
endforeach()
86+
87+
add_custom_target(libcxxshim-modulemap DEPENDS ${libcxxshim_modulemap_target_list})
88+
set_property(TARGET libcxxshim-modulemap PROPERTY FOLDER "Miscellaneous")
89+
add_dependencies(sdk-overlay libcxxshim-modulemap)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
template <class From, class To>
2+
To __swift_interopStaticCast(From from) { return static_cast<To>(from); }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module CxxShim {
2+
header "libcxxshim.h"
3+
requires cplusplus
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@_exported import CxxShim // Clang module

test/Interop/Cxx/class/inheritance/Inputs/fields.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
template <class From, class To>
2-
To __swift_interopStaticCast(From from) { return from; }
3-
41
struct HasThreeFields {
52
int a = 1;
63
int b = 2;

test/Interop/Cxx/class/inheritance/Inputs/functions.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
template <class From, class To>
2-
To __swift_interopStaticCast(From from) {
3-
return static_cast<To>(from);
4-
}
5-
61
struct NonTrivial {
72
NonTrivial() {}
83
~NonTrivial() {}

test/Interop/Cxx/class/inheritance/Inputs/type-aliases.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
template <class From, class To>
2-
To __swift_interopStaticCast(From from) {
3-
return static_cast<To>(from);
4-
}
5-
61
struct Base {
72
struct Struct {};
83

test/Interop/Cxx/class/inheritance/fields.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// UNSUPPORTED: OS=windows-msvc
77

88
import StdlibUnittest
9+
import CxxShim
910
import Fields
1011

1112
var FieldsTestSuite = TestSuite("Getting and setting fields in base classes")

test/Interop/Cxx/class/inheritance/functions.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// REQUIRES: executable_test
44

55
import StdlibUnittest
6+
import CxxShim
67
import Functions
78

89
var FunctionsTestSuite = TestSuite("Calling functions in base classes")

test/Interop/Cxx/foreign-reference/Inputs/pod.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
#include "visibility.h"
77

8-
template <class From, class To>
9-
To __swift_interopStaticCast(From from) { return from; }
10-
118
inline void *operator new(size_t, void *p) { return p; }
129

1310
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS

test/Interop/Cxx/foreign-reference/pod.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// XFAIL: OS=windows-msvc
55

66
import StdlibUnittest
7+
import CxxShim
78
import POD
89

910
struct StructHoldingPair {

test/Interop/Cxx/operators/Inputs/member-inline.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#ifndef TEST_INTEROP_CXX_OPERATORS_INPUTS_MEMBER_INLINE_H
22
#define TEST_INTEROP_CXX_OPERATORS_INPUTS_MEMBER_INLINE_H
33

4-
template <class From, class To>
5-
To __swift_interopStaticCast(From from) { return from; }
6-
74
struct LoadableIntWrapper {
85
int value;
96
LoadableIntWrapper operator-(LoadableIntWrapper rhs) {

test/Interop/Cxx/operators/member-inline.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// REQUIRES: executable_test
44

55
import MemberInline
6+
import CxxShim
67
import StdlibUnittest
78

89
var OperatorsTestSuite = TestSuite("Operators")

0 commit comments

Comments
 (0)