Skip to content

[cxx-interop] [IRGen] TypeInfo for address-only types. #32973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 10, 2020

Conversation

zoecarver
Copy link
Contributor

The current "ClangRecordTypeInfo" derives from "LoadableTypeInfo" and is only meant for loadable types. While we have not yet run into problems, this may cause issues in the future and as more logic is needed around copying, moving, and destroying C++ objects, this should be fixed.

I'm not aware of any behavior changes so, it's a bit difficult for me to come up with tests. But, that may just be a consequence of my lack of knowledge around this part of the codebase. Please chime in with test ideas if you have any :)

Refs #32291.

@zoecarver zoecarver requested a review from gribozavr July 18, 2020 03:42


class ClangRecordAddressOnlyTypeInfo final
: public StructTypeInfoBase<ClangRecordAddressOnlyTypeInfo, FixedTypeInfo,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can someone more familiar with this part of IRGen confirm that FixedTypeInfo is what should go here?

Copy link
Contributor

@gribozavr gribozavr Jul 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use IndirectTypeInfo as the base type? Depending on the capabilities of the Clang type, we might need to use ImmovableTypeInfo (or imitate it appropriately). I'd suggest to try using IndirectTypeInfo in this PR, while leaving the immovable issue as a TODO for future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean use IndirectTypeInfo instead of StructTypeInfoBase? Even address-only types should be imported as structs, so I think we should keep StructTypeInfoBase. IndirectTypeInfo takes two template parameters so, I think one of those would still have to be FixedTypeInfo or something.

@zoecarver zoecarver added the c++ interop Feature: Interoperability with C++ label Jul 18, 2020
if (SwiftType.getStructOrBoundGenericStruct()
->isCxxNotTriviallyCopyable()) {
return ClangRecordAddressOnlyTypeInfo::create(
FieldInfos, llvmType, TotalStride, std::move(SpareBits),
Copy link
Contributor

@gribozavr gribozavr Jul 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FieldInfos vector will contain private data members that we're not importing. It would be good to skip private data members in ClangRecordLowering (in a future PR).

Currently for skipping non-importable fields ClangRecordLowering has addOpaqueField(), which should form the correct layout but avoid informing the rest of the system about the specific type of fields that we can't ever access. However, it uses IRGenModule::getOpaqueStorageTypeInfo which returns LoadableTypeInfo which is not correct for some fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make a follow up PR for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM!

void addFieldInfo(VarDecl *swiftField, const LoadableTypeInfo &fieldType) {
unsigned explosionSize = fieldType.getExplosionSize();
void addFieldInfo(VarDecl *swiftField, const FixedTypeInfo &fieldType) {
unsigned explosionSize = SwiftDecl->getStoredProperties().size();
Copy link
Contributor

@gribozavr gribozavr Jul 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand it correctly, the concept of explosion does not make sense for address-only types (explosion is a list of LLVM values into which an aggregate value was loaded), so it is not a surprise that we don't have an appropriate API to call here to calculate the size of the explosion. Just counting the number of stored properties is not correct, since we decided to not import private member variables in C++ classes.

This information about explosion size is eventually written into RecordField::Begin / ::End. Note that only ClangFieldInfo is setting these fields. Even StructFieldInfo (the subclass for native Swift structs) is not setting them. Since this data is not correct for native Swift structs, I suspect that users of this data are dead code. Could you take a look? It is quite possible you would be able to delete some/all of the users, as well as this code that calculates this information.

If this data is used, I think we should change ClangFieldInfo to be like StructFieldInfo and not set the explosion begin/end, at least when we have an address-only type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right! With a small amount of refactoring, I was able to get this working without begin/end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out after running all the tests there are some things which rely on begin/end. At first, I was confused by this because, as you said, it doesn't appear that StructFieldInfo sets them. But, after further investigation, it appears they are set for StructFieldInfo. Just in a more convoluted way.

I'll have to add back the old path, too.

Copy link
Contributor

@gribozavr gribozavr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fixes!

@zoecarver zoecarver force-pushed the cxx/address-only-type-info branch from 798f0f9 to 0fcd3e9 Compare July 31, 2020 03:15
@zoecarver zoecarver force-pushed the cxx/address-only-type-info branch 2 times, most recently from 0548e7c to d921b11 Compare August 1, 2020 05:10
@zoecarver
Copy link
Contributor Author

@swift-ci please smoke test

@zoecarver zoecarver requested a review from gribozavr August 1, 2020 05:11

import TypeClassification

// TODO: C++ objects with destructors should be tested here once we fully
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfortunate (but also unrelated to this change). I was meaning to submit a fix for this and forgot. Maybe I'll have time this weekend. Otherwise, I'll do it next week.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #32591.

// TODO: C++ objects with destructors should be tested here once we fully
// support them.

// CHECK-LABEL: define {{.*}}i1 @"$s4main37testStructWithCopyConstructorAndValueSbyF"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add an explanation of what these tests are verifying, so that future when IRGen patterns change people can update the CHECK lines appropriately, and not accidentally eliminate the part that we're thinking we are testing here.

@zoecarver zoecarver force-pushed the cxx/address-only-type-info branch 2 times, most recently from 49482b0 to 064d9ff Compare August 8, 2020 22:13
@zoecarver
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Aug 8, 2020

Build failed
Swift Test Linux Platform
Git Sha - d921b11b14fac039a0a55a002f71c155c71feef8

@swift-ci
Copy link
Contributor

swift-ci commented Aug 8, 2020

Build failed
Swift Test OS X Platform
Git Sha - d921b11b14fac039a0a55a002f71c155c71feef8

@zoecarver zoecarver force-pushed the cxx/address-only-type-info branch from 064d9ff to 6b55bd7 Compare August 9, 2020 17:05
@zoecarver
Copy link
Contributor Author

@swift-ci please test

1 similar comment
@zoecarver
Copy link
Contributor Author

@swift-ci please test

@zoecarver
Copy link
Contributor Author

@swift-ci please test Windows Platform

@swift-ci
Copy link
Contributor

swift-ci commented Aug 9, 2020

Build failed
Swift Test Linux Platform
Git Sha - 6b55bd765901d6fa1d68aba7fc131817aff7c18b

The current "ClangRecordTypeInfo" derives from "LoadableTypeInfo" and is
only meant for loadable types. While we have not yet run into problems,
this may cause issues in the future and as more logic is needed around
copying, moving, and destroying C++ objects, this needs to be fixed.
@zoecarver
Copy link
Contributor Author

@swift-ci please test

@zoecarver zoecarver force-pushed the cxx/address-only-type-info branch from 6b55bd7 to 0cef2ce Compare August 10, 2020 04:08
@zoecarver
Copy link
Contributor Author

@swift-ci please test

@zoecarver zoecarver merged commit 63875e9 into swiftlang:master Aug 10, 2020
@gribozavr
Copy link
Contributor

@zoecarver Congrats!

@meg-gupta
Copy link
Contributor

This is causing a Filecheck mismatch error with Interop/Cxx/class/type-classification-non-trivial-irgen.swift in https://ci.swift.org/job/oss-swift_tools-R_stdlib-RD_test-simulator/5307/
@zoecarver can you take a look ?

@zoecarver
Copy link
Contributor Author

@meg-gupta thanks for bringing my attention to the issue. I have a fix, running the tests locally now. I'll make a PR shortly.

@zoecarver
Copy link
Contributor Author

See #33474.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ interop Feature: Interoperability with C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants