-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[InterfaceGen] Print private/internal properties #19127
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
[InterfaceGen] Print private/internal properties #19127
Conversation
All properties which contribute to the storage of a type should be printed, and their names should be hidden from interfaces. Print them with '_' as their name, and teach the parser to recognize these special patterns when parsing interface files. Partially resolves rdar://43810647
c6f6867
to
ba5564a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the second half will be verifying that we generate the same offsets and such, right?
lib/AST/ASTPrinter.cpp
Outdated
@@ -64,13 +64,19 @@ void PrintOptions::clearSynthesizedExtension() { | |||
TransformContext.reset(); | |||
} | |||
|
|||
static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) { | |||
return ASD->getDeclContext()->isTypeContext() && ASD->hasStorage() && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only want this if the type context is non-resilient.
lib/Sema/TypeCheckDecl.cpp
Outdated
if (dc->isTypeContext()) | ||
// Property decls in type context must bind variables unless in a module | ||
// interface, where private members don't bind variables but contribute | ||
// to storage. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still necessary? You are creating the VarDecl now.
// RUN: %empty-directory(%t) | ||
// R UN: %target-swift-frontend -emit-module -o %t/Test~partial.swiftmodule -module-name Test -primary-file %s | ||
// R UN: %target-swift-frontend -merge-modules -emit-module -o %t/Test.swiftmodule %t/Test~partial.swiftmodule | ||
// R UN: %target-swift-ide-test -print-module -module-to-print=Test -source-filename=x -I %t | %FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to re-enable these.
What’s the plan for properties that have internal types? |
"Not covered by this PR" :-) I haven't passed along to Harlan the thing you told me about value witnesses, that if a struct has private types in its fields IRGen just gives up and always uses value witnesses. (Yes? No?) |
Yes that is correct. We still need to know the size and alignment of the type though. I think the best solution for this and the class vtable layout issues is to include any referenced internal types in the interface output. |
Do we want to rename them/their properties to avoid exposing private implementation details? |
We'll have to for |
d7b7c95
to
aaecce9
Compare
I've added a test to make sure the layout doesn't change if the type is declared in this file, in another module, or in an interface file. |
058ad22
to
31b9b4b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
var internalVar: Int64 | ||
|
||
// CHECK-NEXT: internal let _: Bool{{$}} | ||
// RESILIENT-NOT: internal let _: Bool{{$}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious whether this is printed as var
or let
in a resilient-with-@_fixed_contents
context. Do we want to promise that a private let
will stay constant in future versions? cc @slavapestov
(This doesn't have to block this PR.)
// CHECK-EXEC: %[[MYCLASS_INIT:[0-9]+]] = call swiftcc [[MYCLASS]]* @"$S{{[^ ]+}}7MyClassCACycfC"(%swift.type* swiftself %{{[0-9]+}}) | ||
let myClass = MyClass() | ||
|
||
// These are uninteresting as they just call into the standard getter and setter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth CHECKing that they do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed offline, since it ends up just reaching into the table at pretty opaque offsets (in this case, 21, 20, and 11) it's not a super interesting check...
@swift-ci please test |
Build failed |
Build failed |
@swift-ci please test |
Build failed |
Build failed |
⛵ |
All properties which contribute to the storage of a type should be
printed, and their names should be hidden from interfaces. Print them
with '_' as their name, and teach the parser to recognize these special
patterns when parsing interface files.
Partially resolves rdar://43810647