-
Notifications
You must be signed in to change notification settings - Fork 10.5k
ClangImporter: use nameless arguments for anonymous struct/unions in constructors #6935
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
ClangImporter: use nameless arguments for anonymous struct/unions in constructors #6935
Conversation
Looks good. @jrose-apple Do we want this for 3.1 as well, to maintain source compatibility between 3.1 and 4.0? |
continue; | ||
bool generateParamName = wantCtorParamNames; | ||
|
||
if (var->hasClangNode()) { |
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.
Nitpick: It seems like we should still honor wantCtorParamNames
being false
, even if no callers do this now with imported structs.
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.
Oh, indeed, good catch. Fixed
Yeah, I agree, @slavapestov. No reason to have this diverge right when it's introduced. |
…constructors. Following a13c134, constructors of structures/unions containing anonymous structures/unions fields include those field in their parameter list, using the generated field name as parameter name: typedef struct foo_t { union { int a; int b; }; } foo_t; Generates: struct foo_t { init(__Anonymous_field0: foo_t.__Unnamed_union__Anonymous_field0) } let foo = foo_t(__Anonymous_field0: .init(a: 1)) One important downside here is that the generated field name get exposed in the API. An idealistic approach would be to generate the constructors that expose the fields indirectly inherited from those structures: struct foo_t { init(a: Int32) init(b: Int32) } However, this approach requires the generation of a constructor per valid combination of indirect fields, which might start having a huge cardinality when we have nested anonymous structures in nested anonymous unions... typedef struct bar_t { union { struct { int a; int b; }; struct { int c; int d; }; }; union { int e; int f; }; } bar_t; In this examples, we have 4 constructors to generates, for (a, b, e), (a, b, f), (c, d, e) and (c, d, f). The proposed approach is to use a nameless parameter for anonymous structures/unions, still forcing the user to build that sub-object by hand, but without exposing the generated field name. This is very similar to what can be done in C: foo_t foo = { { .a = 1 } }; let foo = foo_t(.init(a: 1)) Or bar_t bar = { { { .a = 1, .b = 2 } }, { .e = 1 } }; let bar = bar_t(.init(.init(a: 1, b: 2)), .init(e: 1)) Signed-off-by: Florent Bruneau <[email protected]>
6024b15
to
4c133fc
Compare
This does need to go into master before it can go to the 3.1 branch. (There's no automerge back to master.) The cherry-pick to the 3.1 branch should then follow the template described in the Swift 3.1 Release Process and must be approved by @tkremenek. |
@Fruneau , can you create a PR against |
@swift-ci Please test |
Build failed |
Build failed |
@swift-ci Please test |
This needs to be approved by @tkremenek as release manager before it can be merged, and it still needs to follow the PR format for the release branch. |
@jrose-apple I've updated the PR to match the requested format. Let me know if you think there are missing pieces of information in the description. |
Explanation
This patch follows that discussion: #6816 (review)
Following a13c134, constructors of structures/unions containing
anonymous structures/unions fields include those field in their parameter
list, using the generated field name as parameter name:
Generates:
One important downside here is that the generated field name get exposed
in the API.
An idealistic approach would be to generate the constructors that expose
the fields indirectly inherited from those structures:
However, this approach requires the generation of a constructor per valid
combination of indirect fields, which might start having a huge
cardinality when we have nested anonymous structures in nested anonymous
unions...
In this examples, we have 4 constructors to generates, for
(a, b, e)
,(a, b, f)
,(c, d, e)
and(c, d, f)
.The proposed approach is to use a nameless parameter for anonymous
structures/unions, still forcing the user to build that sub-object by
hand, but without exposing the generated field name. This is very similar
to what can be done in C:
Or
Scope
This patch only impacts the constructor generation of structure/unions containing anonymous structure/union fields. This changes a behavior that was introduced during the development phase of the 3.1 release and as such shouldn't have impact on existing code.
Risk
None, since this patch only changes a behavior introduced in the development phase of the 3.1 release.
Testing
The patch includes the corresponding tests. AFAICT, no further testing is required.