Skip to content

Commit 7abd265

Browse files
committed
[cxx-interop] revert back to old address-only heuristic for MSVC
1 parent 988f373 commit 7abd265

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
@@ -2427,9 +2427,39 @@ namespace {
24272427
}
24282428

24292429
if (cxxRecordDecl) {
2430+
// FIXME: Swift right now uses AddressOnly type layout
2431+
// in a way that conflates C++ types
2432+
// that need to be destroyed or copied explicitly with C++
2433+
// types that have to be passed indirectly, because
2434+
// only AddressOnly types can be copied or destroyed using C++
2435+
// semantics. However, in actuality these two concepts are
2436+
// separate and don't map to one notion of AddressOnly type
2437+
// layout cleanly. We should reserve the use of AddressOnly
2438+
// type layout when types have to use C++ copy/move/destroy
2439+
// operations, but allow AddressOnly types to be passed
2440+
// directly as well. This will help unify the MSVC and
2441+
// Itanium difference here, and will allow us to support
2442+
// trivial_abi C++ types as well.
2443+
auto isNonTrivialForPurposeOfCalls =
2444+
[](const clang::CXXRecordDecl *decl) -> bool {
2445+
return decl->hasNonTrivialCopyConstructor() ||
2446+
decl->hasNonTrivialMoveConstructor() ||
2447+
!decl->hasTrivialDestructor();
2448+
};
2449+
auto isAddressOnlySwiftStruct =
2450+
[&](const clang::CXXRecordDecl *decl) -> bool {
2451+
// MSVC ABI allows non-trivially destroyed C++ types
2452+
// to be passed in register. This is not supported, as such
2453+
// type wouldn't be destroyed in Swift correctly. Therefore,
2454+
// force AddressOnly type layout using the old heuristic.
2455+
// FIXME: Support can pass in registers for MSVC correctly.
2456+
if (Impl.SwiftContext.LangOpts.Target.isWindowsMSVCEnvironment())
2457+
return isNonTrivialForPurposeOfCalls(decl);
2458+
return !decl->canPassInRegisters();
2459+
};
24302460
if (auto structResult = dyn_cast<StructDecl>(result))
24312461
structResult->setIsCxxNonTrivial(
2432-
!cxxRecordDecl->canPassInRegisters());
2462+
isAddressOnlySwiftStruct(cxxRecordDecl));
24332463

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

0 commit comments

Comments
 (0)