-
Notifications
You must be signed in to change notification settings - Fork 10.5k
add support to getTopLevelDecls for clang submodules #76401
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 test |
To aid code review, i'll provide a bit of a writeup of what i changed: ASTI added the IDE@ahoppen @bnbarham @hamishknight @rintaro I had to update the module interface printer to accommodate the change in behavior surrounding Clang modules. Parent Clang modules now no longer report the decls of their submodules, so they will need to be crawled separately. I split out a list of "modules to crawl" and added submodules to it if I also updated the test output for SymbolGraphGenI tweaked the ClangImporter@zoecarver @hyp @egorzhdan @beccadax @ian-twilightcoder To collect decls into the right module when crawling a Clang module, i updated I also updated Finally, i removed the Since the biggest conceptual changes are in the ClangImporter and the module interface printer, i would most appreciate a review from those code owners. Thanks! |
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.
IDE changes look good to me. I don’t understand where the FooHelper
import was coming from before because FooSub.h
doesn’t include anything that might be from FooHelper
and the module map also doesn’t have any mention of FooHelper
. @rintaro @bnbarham @hamishknight Do you know?
@ahoppen IIRC it has to do with how the decls were being collected before. Import decls are filtered separately from other kinds of decls, which means the decl filtering that was being done skipped any import decls. Since printing submodules involved crawling the top-level module, that meant that any import from the top-level module also made its way into the submodule, regardless of whether the submodule actually imported it. That's what happened in this situation. |
I see. In that case: Good fix, thank you! |
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.
IDE changes LGTM
I am not entirely sure but it seems like generating symbol graphs for a top level module doesn't include symbols from submodules. This seems incorrect as unfortunately most ObjC frameworks in SDK have a modulemap that looks something like:
which basically says reexport all the modules it pulled in by the umbrella header (that's the |
9d83f19
to
8299c83
Compare
@swift-ci Please test |
@daniel-grumberg I've just pushed a commit that should fix that. It required some tweaks in the export-import logic and around SymbolGraphGen, but it should automatically treat Clang submodules as re-exported if they were declared with the |
@swift-ci Please test |
lib/AST/Module.cpp
Outdated
if (!ClangModule) | ||
return false; | ||
|
||
while ((ClangModule = ClangModule->Parent)) { |
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.
while ((ClangModule = ClangModule->Parent)) { | |
ClangModule->isSubmoduleOf(ClangParent) |
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 is the implementation of isSubmoduleOf
, and this is a single-equals assignment anyway; i'm checking that ClangModule->Parent
exists, and also assigning it to ClangModule
for the next loop iteration.
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 was referring to using this https://clang.llvm.org/doxygen/classclang_1_1Module.html#ab9ffc11ef69081f60cdc8fabe67f1cbf but maybe I got confused by which types are swift modules vs clang modules.
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! I totally missed that there was an isSubmoduleOf
on Clang modules. I can replace the entire loop with that call, then.
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.
Your change looks good; there's an existing problem in collectExportedImports() you may want to address
@@ -1435,8 +1445,12 @@ collectExportedImports(const ModuleDecl *topLevelModule, | |||
stack.push_back(topLevelModule); |
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.
If the import graph is not a tree, you will push the same node multiple times on the stack and repeat the work of visiting its successors. Eg, suppose we're asked to collectExportedImports() of A
with the import graph below, where A re-exports B and C, B and C both re-export D, etc:
B E H
+ \ + \ + \
/ \ / \ / \
/ + / + / +
A D G J
\ + \ + \ +
\ / \ / \ /
+ / + / + /
C F I
We're going to visit D twice, G four times, J eight times, etc, so this algorithm has a worst case running time of O(2^n)
. You can fix this by adding a visited
set alongside stack
. Before pushing something on the stack, check if it's already been visited, and skip it if 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.
Nice catch! I've just pushed a commit that adds a visited
set to counteract this.
5e1c071
to
936d105
Compare
@swift-ci Please test |
@daniel-grumberg I've pushed an update that handles |
936d105
to
b3348a6
Compare
@swift-ci Please test |
I pushed a new commit that tweaks the behavior of |
rdar://126031510
b3348a6
to
10818f5
Compare
@swift-ci Please test |
I've had to update the PR again to handle an edge case when using this code against some test data offline. It turns out that some modules don't properly add an |
@swift-ci Please test |
@swift-ci Please test |
@swift-ci Please smoke test |
@swift-ci Please test |
Resolves rdar://126031510
This PR adds partial support for Clang submodules in the ClangModuleUnit code. Specifically, it allows
getTopLevelDeclsForDisplay
(and the crawling methods it calls) to correctly load decls when given a submodule.This is a behavior change for this function; specifically, passing in the top-level module now only returns the decls declared specifically in that module, as opposed to adding in the decls from its submodules as well. This broke the module interface printer, which i updated in this PR.
The goal of this was to allow
swift-symbolgraph-extract
to receive the name of a Clang submodule and correctly load its constituent symbols (without tripping an assertion on assertions builds), which this now enables.