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