-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix effective context construction for NS_OPTIONS in linkage spec #62236
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
Fix effective context construction for NS_OPTIONS in linkage spec #62236
Conversation
@swift-ci please test |
ba232be
to
79d7484
Compare
@swift-ci please test |
Very nice work @NuriAmari. I think I overlooked the possibility of nesting LinkageSpecDecls when I previously did the fix for EffectiveClangContext. I suspect that this would be the case in UIKit because the |
@swift-ci please test source compatibility |
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.
Can you add a test with multiple extern "C" blocks? (That seems to be why you added the while loop, right?)
This LGTM though |
The existing test already has two nested, one explicit and one introduced by |
I think in practice the double extern C happens implicitly by having an extern C both in code and in the module specifier in the modulemap. I think for testing there should probably be a doubly nested extern C in code case and an extern C from module map plus an extern C from code case. |
Alright, I'll add a test to cover the "extern C from module map" case. |
When the ClangImporter imports a name, it associates it with a an EffectiveClangContext. An EffectiveClangContext can be thought of as the Clang scope the declaration will reside in, as far as importing into Swift is concerned. This helps API notes and NS_SWIFT_NAME to manipulate the SDK interface presented to Swift users. When a entry is added to the Swift lookup table, it is associated with a context. This context is a type and a name, used to effectively namespace entries in the table. This context is derived from the EffectiveClangContext associated with the name. This translation is handled by SwiftLookupTable::translateContextDecl among other machinery. This method in particular, understands only how to translate a set of Clang nodes, and fails to create a context in other cases. Prior to this patch, the EffectiveClangContext of declarations annotated with UIKIT_EXTERN, with cxx-interop turned on, was a LinkageSpecDecl. This results in context translation failure, and warnings produced in SwiftLookupTable::finalizeLookupTable. This patch corrects name import behavior to skip over the LinkageSpecDecl, and use the enclosing TranslationUnit instead. This is appropriate and performed by `determineEffectiveContext` as a LinkageSpecDecl is a so called "transparent" context. That is its members are semantically declared and accessible outside the context without additional qualification. This patch tests using API notes, as that is the method UIKit uses. The issue could just as easily be surface with a NS_SWIFT_NAME annotation. Even without any annotation at all, the we would still fail to translate, though there would likely be no corresponding warnings.
48308b8
to
3a555bd
Compare
@swift-ci please test |
This patch is motivated by more errors produced when finalizing the SwiftLookupTable with cxx-interop enabled. In particular,
SwiftLookupTable::translateContextDecl
only knows how to convert a small set of decls into aStoredContext
. When cxx-interop is turned on, we get moreLinkageSpecDecl
nodes that ordinary.If we ever created an
EffectiveClangContext
which holds reference to aLinkageSpecDecl
we'll get mapping errors such those shown in the added test.In this patch, we have modified the constructor of
EffectiveClangContext
to skip over anyLinkageSpecDecl
s. We have noticed thatdetermineEffectiveContext
includes some of the same behavior. In particular, it dispatches togetRedeclContext
which will skip so called "transparent" contexts,LinkageSpecDecls
included:This particular error, can also be fixed by calling
determineEffectiveContext
on produced contexts like so:We could use some input on if this unwrapping should occur at all times, and the best place for it (
determineEffectiveContext
vsEffectiveClangContext::EffectiveClangContext
) as the logic seems split between the two at the moment.