-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AST] scan @_exported import
modules of source files for display decls
#40810
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 |
@swift-ci Please build toolchain macOS platform |
This PR builds on top of #40696 so that i can use its test. |
@swift-ci Please test windows |
:-/ I realize I'm well away from being a compiler contributor by now, and that |
Build failed |
@belkadan My assumption is that because i'm pulling the imports directly from the file, it will only pull when a file has the ...however, i'll need to double-check about the imports added by |
Build failed |
lib/AST/Module.cpp
Outdated
void SourceFile::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const { | ||
if (Imports.hasValue()) { | ||
for (auto import : *Imports) { | ||
if (import.options.contains(ImportFlags::Exported)) { |
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.
Will this potentially include the same decl more than once if it's imported via two different paths, eg
// C.swift:
public class Class {}
// A.swift:
@_exported import C
// B.swift
@_exported import C
// Foo.swift
import A
import B
// does this visit 'C.Class' twice?
Perhaps a better way is to get the 'flat' list of transitively-imported modules from the ImportCache, and then just get the top-level decls of each one?
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.
It looks like it will, based on how the -import-underlying-module
case works (it currently crawls those modules for each file). I'll work on an alternative method to collect these modules ahead of time.
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.
Try something like this
auto &importCache = sf.getASTContext().getImportCache();
auto &importSet = importCache.getImportSet(sf);
auto modules = importSet.getTransitiveImports();
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.
Are the transitive imports what we want? I'm concerned about collecting decls that aren't actually part of the file/module, since they wouldn't be @_exported
.
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 transitive imports are the @_exported ones only, I think.
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.
It looks like that includes much more than the @_exported
imports; the framework from the test case seems to be including all of Foundation.
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 think i have a solution, but i'm not sure where/how to test it. The symbol graph deduplicated these symbols anyway, and i'm not sure where else uses getDisplayDecls()
that we could slot a test into.
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.
What about something like this in getDisplayDecls()
:
#ifndef NDEBUG
llvm::DenseSet<Decl *> visited;
for (auto *decl : decls) {
auto inserted = visited.insert(decl).second;
assert(inserted);
}
#endif
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.
That seemed to work! I've pushed a commit with my implementation and this assertion. I've updated the test to use two Swift files, which previously caused the underlying Clang module to be scanned twice.
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.
Excellent, thanks. The PR looks good to me.
7a9c7bd
to
8a896a7
Compare
@swift-ci Please test |
@swift-ci Please build toolchain macOS platform |
@_exported
imports@_exported import
modules of source files
@_exported import
modules of source files@_exported import
modules of source files for display decls
Build failed |
@swift-ci Please test Linux |
Build failed |
macOS Toolchain Install command |
8a896a7
to
e04092d
Compare
@swift-ci Please smoke test |
Resolves rdar://85230067
When collecting decls for SourceFile modules, decls from
@_exported import
modules (including those added with-import-underlying-module
) are not collected. This causes SymbolGraphGen to miss Clang symbols when building in-emit-module
mode. This PR adds an override forSourceFile::getDisplayDecls
(called indirectly by SymbolGraphGen) that also collects symbols from these exported modules.