-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[ClangImporter] Suffix ambiguous protocol names if C++ interop is enabled #41410
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
Conversation
@swift-ci please smoke test |
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.
This seems reasonable. Thanks for fixing it!
Would you mind adding a module-interface test too? It would be good to make sure the imported names are correct (i.e., the "Protocol" suffix is actually added).
lib/ClangImporter/ImportName.cpp
Outdated
if (std::any_of(lookupResult.begin(), lookupResult.end(), conflicts)) | ||
return true; | ||
} | ||
|
||
lookupResult.clear(clang::Sema::LookupTagName); | ||
if (clangSema.LookupName(lookupResult, /*scope=*/nullptr)) { | ||
if (clangSema.LookupName(lookupResult, /*scope=*/clangSema.TUScope)) { |
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.
The second lookup performs a LookupTagName
, which I believe should not produce more lookup results in C++ (In C it can though). In that case , do we really need to adjust the scope here? Also, if this lookup isn't needed in C++, can we just wrap it in an if
when clang's lang options have C++ on to remove the redundant lookup?
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 can try both theories and I see if it changes any result.
I found the problem with the first, and I thought that keeping both with the same scope made sense, but it might not be so.
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.
Neither changing back to nullptr
, nor wrapping the lookup for a check of C++ changed the result of the test, or the results in the rest of the test suite, so it seems safe to assume that LookupTagName
is not necessary. Thanks for the help!
355c518
to
8c931c0
Compare
@swift-ci please smoke test |
Good intuition. It doesn't seem that the protocol gets imported. I am still trying to figure out why. For some reason the name requests for the class name end up in the machinery that I would expect, but the request for the |
@drodriguez is it okay to land this now? Maybe we can investigate after the fact? |
@bulbazord was looking at little bit more into this problem and I think he was close to find out the reason. He might be able to determine if this is going to be good, or going to be discarded in the final solution. |
lib/ClangImporter/ImportName.cpp
Outdated
if (std::any_of(lookupResult.begin(), lookupResult.end(), conflicts)) | ||
return true; | ||
// No need to lookup tags if we are using C++ mode. | ||
if (clang::LangStandard::getLangStandardForKind( |
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.
The check is the opposite of what it should be.
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.
Yep. Noted.
if (clangSema.LookupName(lookupResult, /*scope=*/nullptr)) { | ||
if (std::any_of(lookupResult.begin(), lookupResult.end(), conflicts)) | ||
return true; | ||
// No need to lookup tags if we are using C++ mode. |
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.
You can also use ASTContext.LangOpts.EnableCXXInterop
, either way.
I believe I have discovered the root cause of the bug(s). Effectively, the function being modified Scenario 1: We are looking for the right Scenario 2:
To recap: How do we fix this? I have 3 general routes in mind: I think option 3 is probably not the right thing to do. I experimented with option 2, but I didn’t get very far and I’m not familiar enough with clang to know how viable this option even is. I’d like to say 1 is the better option here, but I’m not sure. What do y’all think? |
I think that |
Here's what I think we should do. Basically, the failure mode that you're investigating is when |
@swift-ci please test. |
lib/ClangImporter/ImportName.cpp
Outdated
if (std::any_of(lookupResult.begin(), lookupResult.end(), conflicts)) | ||
return true; | ||
// No need to lookup tags if we are using C++ mode. | ||
if (clang::LangStandard::getLangStandardForKind( |
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.
Once this is fixed, my approval stands. Let's land this!
@swift-ci please test. |
…bled The Clang Importer when C++ interop is not enabled, disambigate an Obj-C class and protocol that are named the same by appending `Protocol` to the protocol. This was not happening when C++ interop was enabled, but should also apply to Obj-C++ modules. The fix is providing an starting scope for the search, which the C++ name lookup need to actually find the similarly named counterpart. Includes a test to avoid this problem creeping in again, and locally it did not break any other tests.
8c931c0
to
746080d
Compare
@swift-ci please smoke test and merge |
Something interesting I noticed while flipping the condition: it doesn't seem to matter in any of the tests of the suite. I was running those tests to check that nothing broke, and in both negated and not negated all tests pass. |
The Clang Importer when C++ interop is not enabled, disambigate an Obj-C
class and protocol that are named the same by appending
Protocol
tothe protocol. This was not happening when C++ interop was enabled, but
should also apply to Obj-C++ modules.
The fix is providing an starting scope for the search, which the C++
name lookup need to actually find the similarly named counterpart.
Includes a test to avoid this problem creeping in again, and locally it
did not break any other tests.