-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Clang Importer] Defer module imports to end of bridging-header parse. #7705
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
[Clang Importer] Defer module imports to end of bridging-header parse. #7705
Conversation
Remaining to deal with:
|
lib/ClangImporter/ImporterImpl.h
Outdated
@@ -275,6 +275,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation | |||
|
|||
bool IsReadingBridgingPCH; | |||
llvm::SmallVector<clang::serialization::SubmoduleID, 2> PCHImportedSubmodules; | |||
llvm::SmallVector<const clang::Module*, 2> ImportedModules; |
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 name this DeferredHeaderImports or something? ImportedModules makes it sound like something that stays valid and makes sense to ask for for the lifetime of the ClangImporter.
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.
sure, will 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.
Seems reasonable to me.
There is a subtle incompatibility between the way bridging headers handle module imports and the way clang's normal module-loading works (as done by -emit-pch in bridging PCH, in particular). When importing a submodule, Swift implicitly imports its supermodule. This is part of Swift's treatment of modules and fine, we're not changing it here. But if client code imports a submodule, then tries to use a type that is only defined in its supermodule, not the submodule, this _should_ cause a parse error (and does in clang alone, or when generating a PCH). Unfortunately Swift's "implicit parent import" currently happens eagerly, so the supermodule is imported and its type is defined as soon as the submodule is imported, which in turn suppresses the error. This in turn means that client code thinks their code "works" and then "breaks" when they turn on bridging PCH. What _should_ happen here is that the (actually broken) client code should not be accepted in the first place, neither bridging PCH nor textual bridging-header import. This commit merely changes textual bridging-header import from eager import to deferred parent-import, like bridging PCH does. This reconciles the difference in behaviour between the two, at the cost of a source-compat break. rdar://30615193
845ae28
to
416a12e
Compare
Decision was to land this for swift 4 timeframe, not swift 3.1, but consider it just a bug fix (with release note), not a behaviour to preserve under compat flag. |
@swift-ci please test and merge |
There is a subtle incompatibility between the way bridging headers handle
module imports and the way clang's normal module-loading works (as done
by -emit-pch in bridging PCH, in particular).
When importing a submodule, Swift implicitly imports its supermodule. This
is part of Swift's treatment of modules and fine, we're not changing it
here.
But if client code imports a submodule, then tries to use a type that is
only defined in its supermodule, not the submodule, this should cause
a parse error (and does in clang alone, or when generating a PCH).
Unfortunately Swift's "implicit parent import" currently happens
eagerly, so the supermodule is imported and its type is defined as soon
as the submodule is imported, which in turn suppresses the error.
This in turn means that client code thinks their code "works" and then
"breaks" when they turn on bridging PCH. What should happen here is
that the (actually broken) client code should not be accepted in the first
place, neither bridging PCH nor textual bridging-header import.
This commit merely changes textual bridging-header import from eager
import to deferred parent-import, like bridging PCH does. This reconciles
the difference in behaviour between the two, at the cost of a source-compat
break.
rdar://30615193