@@ -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