diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 31422e88f92d0..5c623e8719700 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -440,6 +440,66 @@ ClangImporter::~ClangImporter() { #pragma mark Module loading +static Optional getModuleMapFilePath(StringRef name, + SearchPathOptions &Opts, + llvm::Triple triple, + SmallVectorImpl &buffer) { + StringRef platform = swift::getPlatformNameForTriple(triple); + StringRef arch = swift::getMajorArchitectureName(triple); + + StringRef SDKPath = Opts.getSDKPath(); + if (!SDKPath.empty()) { + buffer.clear(); + buffer.append(SDKPath.begin(), SDKPath.end()); + llvm::sys::path::append(buffer, "usr", "lib", "swift"); + llvm::sys::path::append(buffer, platform, arch, name); + + // Only specify the module map if that file actually exists. It may not; + // for example in the case that `swiftc -target x86_64-unknown-linux-gnu + // -emit-ir` is invoked using a Swift compiler not built for Linux targets. + if (llvm::sys::fs::exists(buffer)) + return StringRef(buffer.data(), buffer.size()); + } + + if (!Opts.RuntimeResourcePath.empty()) { + buffer.clear(); + buffer.append(Opts.RuntimeResourcePath.begin(), + Opts.RuntimeResourcePath.end()); + llvm::sys::path::append(buffer, platform, arch, name); + + // Only specify the module map if that file actually exists. It may not; + // for example in the case that `swiftc -target x86_64-unknown-linux-gnu + // -emit-ir` is invoked using a Swift compiler not built for Linux targets. + if (llvm::sys::fs::exists(buffer)) + return StringRef(buffer.data(), buffer.size()); + } + + return None; +} + +/// Finds the glibc.modulemap file relative to the provided resource dir. +/// +/// Note that the module map used for Glibc depends on the target we're +/// compiling for, and is not included in the resource directory with the other +/// implicit module maps. It's at {freebsd|linux}/{arch}/glibc.modulemap. +static Optional +getGlibcModuleMapPath(SearchPathOptions &Opts, llvm::Triple triple, + SmallVectorImpl &buffer) { + return getModuleMapFilePath("glibc.modulemap", Opts, triple, buffer); +} + +static Optional +getLibStdCxxModuleMapPath(SearchPathOptions &opts, llvm::Triple triple, + SmallVectorImpl &buffer) { + return getModuleMapFilePath("libstdcxx.modulemap", opts, triple, buffer); +} + +static Optional +getLibShimCxxModuleMapPath(SearchPathOptions &Opts, llvm::Triple triple, + SmallVectorImpl &buffer) { + return getModuleMapFilePath("libcxxshim.modulemap", Opts, triple, buffer); +} + static bool clangSupportsPragmaAttributeWithSwiftAttr() { clang::AttributeCommonInfo swiftAttrInfo(clang::SourceRange(), clang::AttributeCommonInfo::AT_SwiftAttr, @@ -553,6 +613,11 @@ importer::getNormalInvocationArguments( }); } + SmallString<128> buffer; + if (auto path = getLibShimCxxModuleMapPath(searchPathOpts, triple, buffer)) { + invocationArgStrs.push_back((Twine("-fmodule-map-file=") + *path).str()); + } + // Set C language options. if (triple.isOSDarwin()) { invocationArgStrs.insert(invocationArgStrs.end(), { @@ -4387,10 +4452,12 @@ DeclRefExpr *getInteropStaticCastDeclRefExpr(ASTContext &ctx, derived = derived->wrapInPointer(PTK_UnsafePointer); } - // Lookup our static cast helper function. - // TODO: change this to stdlib or something. - auto wrapperModule = - ctx.getClangModuleLoader()->getWrapperForModule(owningModule); + // Lookup our static cast helper function in the C++ shim module. + auto wrapperModule = ctx.getLoadedModule(ctx.getIdentifier("CxxShim")); + assert(wrapperModule && + "CxxShim module is required when using members of a base class. " + "Make sure you `import CxxShim`."); + SmallVector results; ctx.lookupInModule(wrapperModule, "__swift_interopStaticCast", results); assert( diff --git a/stdlib/public/Cxx/CMakeLists.txt b/stdlib/public/Cxx/CMakeLists.txt index fd0edf4be6971..f574120b6201e 100644 --- a/stdlib/public/Cxx/CMakeLists.txt +++ b/stdlib/public/Cxx/CMakeLists.txt @@ -11,3 +11,4 @@ add_swift_target_library(swiftCxx ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVE INSTALL_IN_COMPONENT sdk-overlay) add_subdirectory(std) +add_subdirectory(cxxshim) diff --git a/stdlib/public/Cxx/cxxshim/CMakeLists.txt b/stdlib/public/Cxx/cxxshim/CMakeLists.txt new file mode 100644 index 0000000000000..0840af9776fe4 --- /dev/null +++ b/stdlib/public/Cxx/cxxshim/CMakeLists.txt @@ -0,0 +1,94 @@ +is_sdk_requested(WINDOWS swift_build_windows) +set(libcxxshim_modulemap_target_list) +foreach(sdk ${SWIFT_SDKS}) + if(swift_build_windows) + continue() + endif() + + foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES}) + set(arch_suffix "${SWIFT_SDK_${sdk}_LIB_SUBDIR}-${arch}") + set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}") + + set(module_dir "${SWIFTLIB_DIR}/${arch_subdir}") + set(module_dir_static "${SWIFTSTATICLIB_DIR}/${arch_subdir}") + + set(libcxxshim_header "libcxxshim.h") + set(libcxxshim_header_out "${module_dir}/libcxxshim.h") + set(libcxxshim_header_out_static "${module_dir_static}/libcxxshim.h") + set(libcxxshim_modulemap "libcxxshim.modulemap") + set(libcxxshim_modulemap_out "${module_dir}/libcxxshim.modulemap") + set(libcxxshim_modulemap_out_static "${module_dir_static}/libcxxshim.modulemap") + + add_custom_command_target( + copy_libcxxshim_modulemap + COMMAND + "${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir} + COMMAND + "${CMAKE_COMMAND}" "-E" "copy_if_different" "${CMAKE_CURRENT_SOURCE_DIR}/${libcxxshim_modulemap}" "${libcxxshim_modulemap_out}" + OUTPUT ${libcxxshim_modulemap_out} + DEPENDS ${libcxxshim_modulemap} + COMMENT "Copying libcxxshim modulemap to resources") + list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_modulemap}) + add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_modulemap}) + + add_custom_command_target( + copy_libcxxshim_header + COMMAND + "${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir} + COMMAND + "${CMAKE_COMMAND}" "-E" "copy_if_different" "${CMAKE_CURRENT_SOURCE_DIR}/${libcxxshim_header}" "${libcxxshim_header_out}" + OUTPUT ${libcxxshim_header_out} + DEPENDS ${libcxxshim_header} + COMMENT "Copying libcxxshim header to resources") + list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_header}) + add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_header}) + + if(SWIFT_BUILD_STATIC_STDLIB) + add_custom_command_target( + copy_libcxxshim_modulemap_static + COMMAND + "${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir_static} + COMMAND + "${CMAKE_COMMAND}" "-E" "copy_if_different" + "${libcxxshim_modulemap_out}" "${libcxxshim_modulemap_out_static}" + OUTPUT ${libcxxshim_modulemap_out_static} + DEPENDS ${copy_libcxxshim_modulemap} + COMMENT "Copying libcxxshim modulemap to static resources") + list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_modulemap_static}) + add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_modulemap_static}) + + add_custom_command_target( + copy_libcxxshim_header_static + COMMAND + "${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir_static} + COMMAND + "${CMAKE_COMMAND}" "-E" "copy_if_different" + "${libcxxshim_header_out}" "${libcxxshim_header_out_static}" + OUTPUT ${libcxxshim_header_out_static} + DEPENDS ${copy_libcxxshim_header} + COMMENT "Copying libcxxshim header to static resources") + list(APPEND libcxxshim_modulemap_target_list ${copy_libcxxshim_header_static}) + add_dependencies(swift-stdlib-${arch_suffix} ${copy_libcxxshim_header_static}) + endif() + + swift_install_in_component(FILES "${libcxxshim_modulemap_out}" + DESTINATION "lib/swift/${arch_subdir}" + COMPONENT sdk-overlay) + swift_install_in_component(FILES "${libcxxshim_header_out}" + DESTINATION "lib/swift/${arch_subdir}" + COMPONENT sdk-overlay) + + if(SWIFT_BUILD_STATIC_STDLIB) + swift_install_in_component(FILES "${libcxxshim_modulemap_out_static}" + DESTINATION "lib/swift_static/${arch_subdir}" + COMPONENT sdk-overlay) + swift_install_in_component(FILES "${libcxxshim_header_out_static}" + DESTINATION "lib/swift_static/${arch_subdir}" + COMPONENT sdk-overlay) + endif() + endforeach() +endforeach() + +add_custom_target(libcxxshim-modulemap DEPENDS ${libcxxshim_modulemap_target_list}) +set_property(TARGET libcxxshim-modulemap PROPERTY FOLDER "Miscellaneous") +add_dependencies(sdk-overlay libcxxshim-modulemap) diff --git a/stdlib/public/Cxx/cxxshim/libcxxshim.h b/stdlib/public/Cxx/cxxshim/libcxxshim.h new file mode 100644 index 0000000000000..102bc1548faa5 --- /dev/null +++ b/stdlib/public/Cxx/cxxshim/libcxxshim.h @@ -0,0 +1,2 @@ +template +To __swift_interopStaticCast(From from) { return static_cast(from); } \ No newline at end of file diff --git a/stdlib/public/Cxx/cxxshim/libcxxshim.modulemap b/stdlib/public/Cxx/cxxshim/libcxxshim.modulemap new file mode 100644 index 0000000000000..807e9218b52e7 --- /dev/null +++ b/stdlib/public/Cxx/cxxshim/libcxxshim.modulemap @@ -0,0 +1,4 @@ +module CxxShim { + header "libcxxshim.h" + requires cplusplus +} \ No newline at end of file diff --git a/stdlib/public/Cxx/cxxshim/libcxxshim.swift b/stdlib/public/Cxx/cxxshim/libcxxshim.swift new file mode 100644 index 0000000000000..ecd332d341ba3 --- /dev/null +++ b/stdlib/public/Cxx/cxxshim/libcxxshim.swift @@ -0,0 +1 @@ +@_exported import CxxShim // Clang module \ No newline at end of file diff --git a/test/Interop/Cxx/class/inheritance/Inputs/fields.h b/test/Interop/Cxx/class/inheritance/Inputs/fields.h index 8706e4a694971..f7f843930bbee 100644 --- a/test/Interop/Cxx/class/inheritance/Inputs/fields.h +++ b/test/Interop/Cxx/class/inheritance/Inputs/fields.h @@ -1,6 +1,3 @@ -template -To __swift_interopStaticCast(From from) { return from; } - struct HasThreeFields { int a = 1; int b = 2; diff --git a/test/Interop/Cxx/class/inheritance/Inputs/functions.h b/test/Interop/Cxx/class/inheritance/Inputs/functions.h index 53f84a47549dc..97e131c651ec7 100644 --- a/test/Interop/Cxx/class/inheritance/Inputs/functions.h +++ b/test/Interop/Cxx/class/inheritance/Inputs/functions.h @@ -1,8 +1,3 @@ -template -To __swift_interopStaticCast(From from) { - return static_cast(from); -} - struct NonTrivial { NonTrivial() {} ~NonTrivial() {} diff --git a/test/Interop/Cxx/class/inheritance/Inputs/type-aliases.h b/test/Interop/Cxx/class/inheritance/Inputs/type-aliases.h index 71ef4444236c5..5f0383c251e29 100644 --- a/test/Interop/Cxx/class/inheritance/Inputs/type-aliases.h +++ b/test/Interop/Cxx/class/inheritance/Inputs/type-aliases.h @@ -1,8 +1,3 @@ -template -To __swift_interopStaticCast(From from) { - return static_cast(from); -} - struct Base { struct Struct {}; diff --git a/test/Interop/Cxx/class/inheritance/fields.swift b/test/Interop/Cxx/class/inheritance/fields.swift index e0d90e732f4e5..8481f7b3083ae 100644 --- a/test/Interop/Cxx/class/inheritance/fields.swift +++ b/test/Interop/Cxx/class/inheritance/fields.swift @@ -6,6 +6,7 @@ // UNSUPPORTED: OS=windows-msvc import StdlibUnittest +import CxxShim import Fields var FieldsTestSuite = TestSuite("Getting and setting fields in base classes") diff --git a/test/Interop/Cxx/class/inheritance/functions.swift b/test/Interop/Cxx/class/inheritance/functions.swift index 63000a810b02e..8be4bb2359b57 100644 --- a/test/Interop/Cxx/class/inheritance/functions.swift +++ b/test/Interop/Cxx/class/inheritance/functions.swift @@ -1,8 +1,11 @@ // RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop) // // REQUIRES: executable_test +// TODO: Fix CxxShim for Windows. +// XFAIL: OS=windows-msvc import StdlibUnittest +import CxxShim import Functions var FunctionsTestSuite = TestSuite("Calling functions in base classes") diff --git a/test/Interop/Cxx/foreign-reference/Inputs/pod.h b/test/Interop/Cxx/foreign-reference/Inputs/pod.h index 471136623ef39..d34dce93a0bef 100644 --- a/test/Interop/Cxx/foreign-reference/Inputs/pod.h +++ b/test/Interop/Cxx/foreign-reference/Inputs/pod.h @@ -10,9 +10,6 @@ inline void *operator new(size_t, void *p) { return p; } #include "visibility.h" -template -To __swift_interopStaticCast(From from) { return from; } - SWIFT_BEGIN_NULLABILITY_ANNOTATIONS struct __attribute__((swift_attr("import_as_ref"))) Empty { diff --git a/test/Interop/Cxx/foreign-reference/pod.swift b/test/Interop/Cxx/foreign-reference/pod.swift index 5cc22a4163b86..883d963726421 100644 --- a/test/Interop/Cxx/foreign-reference/pod.swift +++ b/test/Interop/Cxx/foreign-reference/pod.swift @@ -4,6 +4,7 @@ // XFAIL: OS=windows-msvc import StdlibUnittest +import CxxShim import POD struct StructHoldingPair { diff --git a/test/Interop/Cxx/operators/Inputs/member-inline.h b/test/Interop/Cxx/operators/Inputs/member-inline.h index 6a5cbc7de804b..a0d278161e156 100644 --- a/test/Interop/Cxx/operators/Inputs/member-inline.h +++ b/test/Interop/Cxx/operators/Inputs/member-inline.h @@ -1,9 +1,6 @@ #ifndef TEST_INTEROP_CXX_OPERATORS_INPUTS_MEMBER_INLINE_H #define TEST_INTEROP_CXX_OPERATORS_INPUTS_MEMBER_INLINE_H -template -To __swift_interopStaticCast(From from) { return from; } - struct LoadableIntWrapper { int value; LoadableIntWrapper operator-(LoadableIntWrapper rhs) { diff --git a/test/Interop/Cxx/operators/member-inline.swift b/test/Interop/Cxx/operators/member-inline.swift index 46ab663eb2501..76b0ab94ef2ef 100644 --- a/test/Interop/Cxx/operators/member-inline.swift +++ b/test/Interop/Cxx/operators/member-inline.swift @@ -1,8 +1,11 @@ // RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop) - +// // REQUIRES: executable_test +// TODO: Fix CxxShim for Windows. +// XFAIL: OS=windows-msvc import MemberInline +import CxxShim import StdlibUnittest var OperatorsTestSuite = TestSuite("Operators")