Skip to content

Commit e80b9aa

Browse files
committed
[cxx-interop] revert back to old address-only heuristic for MSVC
(cherry picked from commit 7abd265)
1 parent 45da5fa commit e80b9aa

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2447,9 +2447,39 @@ namespace {
24472447
}
24482448

24492449
if (cxxRecordDecl) {
2450+
// FIXME: Swift right now uses AddressOnly type layout
2451+
// in a way that conflates C++ types
2452+
// that need to be destroyed or copied explicitly with C++
2453+
// types that have to be passed indirectly, because
2454+
// only AddressOnly types can be copied or destroyed using C++
2455+
// semantics. However, in actuality these two concepts are
2456+
// separate and don't map to one notion of AddressOnly type
2457+
// layout cleanly. We should reserve the use of AddressOnly
2458+
// type layout when types have to use C++ copy/move/destroy
2459+
// operations, but allow AddressOnly types to be passed
2460+
// directly as well. This will help unify the MSVC and
2461+
// Itanium difference here, and will allow us to support
2462+
// trivial_abi C++ types as well.
2463+
auto isNonTrivialForPurposeOfCalls =
2464+
[](const clang::CXXRecordDecl *decl) -> bool {
2465+
return decl->hasNonTrivialCopyConstructor() ||
2466+
decl->hasNonTrivialMoveConstructor() ||
2467+
!decl->hasTrivialDestructor();
2468+
};
2469+
auto isAddressOnlySwiftStruct =
2470+
[&](const clang::CXXRecordDecl *decl) -> bool {
2471+
// MSVC ABI allows non-trivially destroyed C++ types
2472+
// to be passed in register. This is not supported, as such
2473+
// type wouldn't be destroyed in Swift correctly. Therefore,
2474+
// force AddressOnly type layout using the old heuristic.
2475+
// FIXME: Support can pass in registers for MSVC correctly.
2476+
if (Impl.SwiftContext.LangOpts.Target.isWindowsMSVCEnvironment())
2477+
return isNonTrivialForPurposeOfCalls(decl);
2478+
return !decl->canPassInRegisters();
2479+
};
24502480
if (auto structResult = dyn_cast<StructDecl>(result))
24512481
structResult->setIsCxxNonTrivial(
2452-
!cxxRecordDecl->canPassInRegisters());
2482+
isAddressOnlySwiftStruct(cxxRecordDecl));
24532483

24542484
for (auto &getterAndSetter : Impl.GetterSetterMap[result]) {
24552485
auto getter = getterAndSetter.second.first;

0 commit comments

Comments
 (0)