-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[ClangImporter] Do not import enum when already imported via DeclContext #85424
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
base: main
Are you sure you want to change the base?
Conversation
|
@swift-ci please test |
lib/ClangImporter/ImportDecl.cpp
Outdated
| if (!HadForwardDeclaration) { | ||
| auto it = ImportedDecls.try_emplace({Canon, version}, Result); | ||
| if (!it.second && Result != it.first->second) { | ||
| ABORT([&](auto &out) { |
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.
nice, didn't know about this macro
lib/ClangImporter/ImportDecl.cpp
Outdated
| Canon->getSourceRange().print(out, Instance->getSourceManager()); | ||
| } | ||
| out << "\nImported as Swift Decl:\n"; | ||
| Result->dump(out, 4); |
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.
there's an indentation parameter to dump?? is that true for all of them or just decls?
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.
Appears to be available for all swift::Decls
6c51588 to
b1aa927
Compare
|
@swift-ci please test |
It works 🥳 |
Before we import an enum, we import its DeclContext. If that DeclContext
gets resolved to a struct that contains that field of that enum type,
e.g.:
typedef CF_OPTIONS(uint32_t, MyFlags) {
...
} CF_SWIFT_NAME(MyCtx.Flags);
struct MyStruct {
MyFlags flags;
...
} CF_SWIFT_NAME(MyCtx);
We end up with a cycle, i.e., MyFlags -> MyCtx -> MyStruct -> MyFlags.
Existing cycle-breaking mechanisms seem to prevent this from looping
infinitely, but it leads to us importing two copies of the enum, which
can cause errors later during CodeGen.
This patch breaks the cycle by checking the cache again.
N.B. as of this commit, the circular-import-as-member.swift test doesn't
actually fail *without* the fix, because ClangImporter is quite
lenient about importing the same clang::Decl multiple times. An earlier
attempt at this patch ABORT()'d the compiler as soon as a duplicate is
detected, but that led to more isseus beyond the scope of this patch.
rdar://162317760
b1aa927 to
005acc4
Compare
|
@swift-ci please test |
If we try to import this in ObjC interop mode:
ClangImporter tries to import
MyCtx/MyStructbefore it importsMyFlags(viaimportDeclContextOf()), which in turn tries to importMyFlagsagain due to theflagsfield. The existing cycle-breaking mechanism prevents us from looping infinitely, but leads us to import two copies of the SwiftEnumDecl, which can cause errors later during CodeGen.This patch adds an assertion to catch such issues earlier, and breaks the cycle by checking the cache again.This patch no longer does so because that caused issues beyond the scope of this patch.rdar://162317760