Skip to content

Commit 5246372

Browse files
authored
Merge pull request #59754 from zoecarver/fix-static-down-cast-shim
2 parents 0277971 + 8cf4d3b commit 5246372

File tree

15 files changed

+182
-24
lines changed

15 files changed

+182
-24
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(), {
@@ -4387,10 +4452,12 @@ DeclRefExpr *getInteropStaticCastDeclRefExpr(ASTContext &ctx,
43874452
derived = derived->wrapInPointer(PTK_UnsafePointer);
43884453
}
43894454

4390-
// Lookup our static cast helper function.
4391-
// TODO: change this to stdlib or something.
4392-
auto wrapperModule =
4393-
ctx.getClangModuleLoader()->getWrapperForModule(owningModule);
4455+
// Lookup our static cast helper function in the C++ shim module.
4456+
auto wrapperModule = ctx.getLoadedModule(ctx.getIdentifier("CxxShim"));
4457+
assert(wrapperModule &&
4458+
"CxxShim module is required when using members of a base class. "
4459+
"Make sure you `import CxxShim`.");
4460+
43944461
SmallVector<ValueDecl *, 1> results;
43954462
ctx.lookupInModule(wrapperModule, "__swift_interopStaticCast", results);
43964463
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: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
is_sdk_requested(WINDOWS swift_build_windows)
2+
set(libcxxshim_modulemap_target_list)
3+
foreach(sdk ${SWIFT_SDKS})
4+
if(swift_build_windows)
5+
continue()
6+
endif()
7+
8+
foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
9+
set(arch_suffix "${SWIFT_SDK_${sdk}_LIB_SUBDIR}-${arch}")
10+
set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}")
11+
12+
set(module_dir "${SWIFTLIB_DIR}/${arch_subdir}")
13+
set(module_dir_static "${SWIFTSTATICLIB_DIR}/${arch_subdir}")
14+
15+
set(libcxxshim_header "libcxxshim.h")
16+
set(libcxxshim_header_out "${module_dir}/libcxxshim.h")
17+
set(libcxxshim_header_out_static "${module_dir_static}/libcxxshim.h")
18+
set(libcxxshim_modulemap "libcxxshim.modulemap")
19+
set(libcxxshim_modulemap_out "${module_dir}/libcxxshim.modulemap")
20+
set(libcxxshim_modulemap_out_static "${module_dir_static}/libcxxshim.modulemap")
21+
22+
add_custom_command_target(
23+
copy_libcxxshim_modulemap
24+
COMMAND
25+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir}
26+
COMMAND
27+
"${CMAKE_COMMAND}" "-E" "copy_if_different" "${CMAKE_CURRENT_SOURCE_DIR}/${libcxxshim_modulemap}" "${libcxxshim_modulemap_out}"
28+
OUTPUT ${libcxxshim_modulemap_out}
29+
DEPENDS ${libcxxshim_modulemap}
30+
COMMENT "Copying libcxxshim modulemap to resources")
31+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_modulemap})
32+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_modulemap})
33+
34+
add_custom_command_target(
35+
copy_libcxxshim_header
36+
COMMAND
37+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir}
38+
COMMAND
39+
"${CMAKE_COMMAND}" "-E" "copy_if_different" "${CMAKE_CURRENT_SOURCE_DIR}/${libcxxshim_header}" "${libcxxshim_header_out}"
40+
OUTPUT ${libcxxshim_header_out}
41+
DEPENDS ${libcxxshim_header}
42+
COMMENT "Copying libcxxshim header to resources")
43+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_header})
44+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_header})
45+
46+
if(SWIFT_BUILD_STATIC_STDLIB)
47+
add_custom_command_target(
48+
copy_libcxxshim_modulemap_static
49+
COMMAND
50+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir_static}
51+
COMMAND
52+
"${CMAKE_COMMAND}" "-E" "copy_if_different"
53+
"${libcxxshim_modulemap_out}" "${libcxxshim_modulemap_out_static}"
54+
OUTPUT ${libcxxshim_modulemap_out_static}
55+
DEPENDS ${copy_libcxxshim_modulemap}
56+
COMMENT "Copying libcxxshim modulemap to static resources")
57+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_modulemap_static})
58+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_modulemap_static})
59+
60+
add_custom_command_target(
61+
copy_libcxxshim_header_static
62+
COMMAND
63+
"${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir_static}
64+
COMMAND
65+
"${CMAKE_COMMAND}" "-E" "copy_if_different"
66+
"${libcxxshim_header_out}" "${libcxxshim_header_out_static}"
67+
OUTPUT ${libcxxshim_header_out_static}
68+
DEPENDS ${copy_libcxxshim_header}
69+
COMMENT "Copying libcxxshim header to static resources")
70+
list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_header_static})
71+
add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_header_static})
72+
endif()
73+
74+
swift_install_in_component(FILES "${libcxxshim_modulemap_out}"
75+
DESTINATION "lib/swift/${arch_subdir}"
76+
COMPONENT sdk-overlay)
77+
swift_install_in_component(FILES "${libcxxshim_header_out}"
78+
DESTINATION "lib/swift/${arch_subdir}"
79+
COMPONENT sdk-overlay)
80+
81+
if(SWIFT_BUILD_STATIC_STDLIB)
82+
swift_install_in_component(FILES "${libcxxshim_modulemap_out_static}"
83+
DESTINATION "lib/swift_static/${arch_subdir}"
84+
COMPONENT sdk-overlay)
85+
swift_install_in_component(FILES "${libcxxshim_header_out_static}"
86+
DESTINATION "lib/swift_static/${arch_subdir}"
87+
COMPONENT sdk-overlay)
88+
endif()
89+
endforeach()
90+
endforeach()
91+
92+
add_custom_target(libcxxshim-modulemap DEPENDS ${libcxxshim_modulemap_target_list})
93+
set_property(TARGET libcxxshim-modulemap PROPERTY FOLDER "Miscellaneous")
94+
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop)
22
//
33
// REQUIRES: executable_test
4+
// TODO: Fix CxxShim for Windows.
5+
// XFAIL: OS=windows-msvc
46

57
import StdlibUnittest
8+
import CxxShim
69
import Functions
710

811
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
@@ -10,9 +10,6 @@ inline void *operator new(size_t, void *p) { return p; }
1010

1111
#include "visibility.h"
1212

13-
template <class From, class To>
14-
To __swift_interopStaticCast(From from) { return from; }
15-
1613
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
1714

1815
struct __attribute__((swift_attr("import_as_ref"))) Empty {

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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop)
2-
2+
//
33
// REQUIRES: executable_test
4+
// TODO: Fix CxxShim for Windows.
5+
// XFAIL: OS=windows-msvc
46

57
import MemberInline
8+
import CxxShim
69
import StdlibUnittest
710

811
var OperatorsTestSuite = TestSuite("Operators")

0 commit comments

Comments
 (0)