Skip to content

Commit 3dfeb5f

Browse files
authored
Merge pull request #74307 from artemcm/CacheVisibleClangModulesInModules
Cache visible Clang modules for interface printing in `ModuleDecl`
2 parents 3aca85b + 71ec06e commit 3dfeb5f

File tree

3 files changed

+63
-56
lines changed

3 files changed

+63
-56
lines changed

include/swift/AST/Module.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "llvm/Support/ErrorHandling.h"
4040
#include "llvm/Support/MD5.h"
4141
#include <optional>
42+
#include <unordered_map>
4243
#include <set>
4344

4445
namespace clang {
@@ -537,6 +538,11 @@ class ModuleDecl
537538
std::optional<std::pair<ModuleDecl *, Identifier>>
538539
declaringModuleAndBystander;
539540

541+
/// A cache of this module's visible Clang modules
542+
/// parameterized by the Swift interface print mode.
543+
using VisibleClangModuleSet = llvm::DenseMap<const clang::Module *, ModuleDecl *>;
544+
std::unordered_map<PrintOptions::InterfaceMode, VisibleClangModuleSet> CachedVisibleClangModuleSet;
545+
540546
/// If this module is an underscored cross import overlay, gets the underlying
541547
/// module that declared it (which may itself be a cross-import overlay),
542548
/// along with the name of the required bystander module. Used by tooling to
@@ -578,6 +584,14 @@ class ModuleDecl
578584
bool getRequiredBystandersIfCrossImportOverlay(
579585
ModuleDecl *declaring, SmallVectorImpl<Identifier> &bystanderNames);
580586

587+
/// Computes all Clang modules that are visible from this moule.
588+
/// This includes any modules that are imported transitively through public
589+
/// (`@_exported`) imports.
590+
///
591+
/// The computed map associates each visible Clang module with the
592+
/// corresponding Swift module.
593+
const VisibleClangModuleSet &
594+
getVisibleClangModules(PrintOptions::InterfaceMode contentMode);
581595

582596
/// Walks and loads the declared, underscored cross-import overlays of this
583597
/// module and its underlying clang module, transitively, to find all cross

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5724,8 +5724,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57245724

57255725
ASTPrinter &Printer;
57265726
const PrintOptions &Options;
5727-
std::optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
5728-
VisibleClangModules;
57295727

57305728
void printGenericArgs(ArrayRef<Type> flatArgs) {
57315729
Printer << "<";
@@ -5799,56 +5797,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57995797
return T->hasSimpleTypeRepr();
58005798
}
58015799

5802-
/// Computes the map that is cached by `getVisibleClangModules()`.
5803-
/// Do not call directly.
5804-
llvm::DenseMap<const clang::Module *, ModuleDecl *>
5805-
computeVisibleClangModules() {
5806-
assert(Options.CurrentModule &&
5807-
"CurrentModule needs to be set to determine imported Clang modules");
5808-
5809-
llvm::DenseMap<const clang::Module *, ModuleDecl *> Result;
5810-
5811-
// For the current module, consider both private and public imports.
5812-
ModuleDecl::ImportFilter Filter = ModuleDecl::ImportFilterKind::Exported;
5813-
Filter |= ModuleDecl::ImportFilterKind::Default;
5814-
5815-
// For private or package swiftinterfaces, also look through @_spiOnly imports.
5816-
if (!Options.printPublicInterface())
5817-
Filter |= ModuleDecl::ImportFilterKind::SPIOnly;
5818-
// Consider package import for package interface
5819-
if (Options.printPackageInterface())
5820-
Filter |= ModuleDecl::ImportFilterKind::PackageOnly;
5821-
5822-
SmallVector<ImportedModule, 4> Imports;
5823-
Options.CurrentModule->getImportedModules(Imports, Filter);
5824-
5825-
SmallVector<ModuleDecl *, 4> ModulesToProcess;
5826-
for (const auto &Import : Imports) {
5827-
ModulesToProcess.push_back(Import.importedModule);
5828-
}
5829-
5830-
SmallPtrSet<ModuleDecl *, 4> Processed;
5831-
while (!ModulesToProcess.empty()) {
5832-
ModuleDecl *Mod = ModulesToProcess.back();
5833-
ModulesToProcess.pop_back();
5834-
5835-
if (!Processed.insert(Mod).second)
5836-
continue;
5837-
5838-
if (const clang::Module *ClangModule = Mod->findUnderlyingClangModule())
5839-
Result[ClangModule] = Mod;
5840-
5841-
// For transitive imports, consider only public imports.
5842-
Imports.clear();
5843-
Mod->getImportedModules(Imports, ModuleDecl::ImportFilterKind::Exported);
5844-
for (const auto &Import : Imports) {
5845-
ModulesToProcess.push_back(Import.importedModule);
5846-
}
5847-
}
5848-
5849-
return Result;
5850-
}
5851-
58525800
/// Returns all Clang modules that are visible from `Options.CurrentModule`.
58535801
/// This includes any modules that are imported transitively through public
58545802
/// (`@_exported`) imports.
@@ -5857,10 +5805,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
58575805
/// corresponding Swift module.
58585806
const llvm::DenseMap<const clang::Module *, ModuleDecl *> &
58595807
getVisibleClangModules() {
5860-
if (!VisibleClangModules) {
5861-
VisibleClangModules = computeVisibleClangModules();
5862-
}
5863-
return *VisibleClangModules;
5808+
return Options.CurrentModule->getVisibleClangModules(Options.InterfaceContentKind);
58645809
}
58655810

58665811
template <typename T>

lib/AST/Module.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,54 @@ void ModuleDecl::getMissingImportedModules(
17191719
FORWARD(getMissingImportedModules, (imports));
17201720
}
17211721

1722+
const llvm::DenseMap<const clang::Module *, ModuleDecl *> &
1723+
ModuleDecl::getVisibleClangModules(PrintOptions::InterfaceMode contentMode) {
1724+
if (CachedVisibleClangModuleSet.find(contentMode) != CachedVisibleClangModuleSet.end())
1725+
return CachedVisibleClangModuleSet[contentMode];
1726+
else
1727+
CachedVisibleClangModuleSet.emplace(contentMode, VisibleClangModuleSet{});
1728+
VisibleClangModuleSet &result = CachedVisibleClangModuleSet[contentMode];
1729+
1730+
// For the current module, consider both private and public imports.
1731+
ModuleDecl::ImportFilter Filter = ModuleDecl::ImportFilterKind::Exported;
1732+
Filter |= ModuleDecl::ImportFilterKind::Default;
1733+
1734+
// For private or package swiftinterfaces, also look through @_spiOnly imports.
1735+
if (contentMode != PrintOptions::InterfaceMode::Public)
1736+
Filter |= ModuleDecl::ImportFilterKind::SPIOnly;
1737+
// Consider package import for package interface
1738+
if (contentMode == PrintOptions::InterfaceMode::Package)
1739+
Filter |= ModuleDecl::ImportFilterKind::PackageOnly;
1740+
1741+
SmallVector<ImportedModule, 32> Imports;
1742+
getImportedModules(Imports, Filter);
1743+
1744+
SmallVector<ModuleDecl *, 32> ModulesToProcess;
1745+
for (const auto &Import : Imports)
1746+
ModulesToProcess.push_back(Import.importedModule);
1747+
1748+
SmallPtrSet<ModuleDecl *, 32> Processed;
1749+
while (!ModulesToProcess.empty()) {
1750+
ModuleDecl *Mod = ModulesToProcess.back();
1751+
ModulesToProcess.pop_back();
1752+
1753+
if (!Processed.insert(Mod).second)
1754+
continue;
1755+
1756+
if (const clang::Module *ClangModule = Mod->findUnderlyingClangModule())
1757+
result[ClangModule] = Mod;
1758+
1759+
// For transitive imports, consider only public imports.
1760+
Imports.clear();
1761+
Mod->getImportedModules(Imports, ModuleDecl::ImportFilterKind::Exported);
1762+
for (const auto &Import : Imports) {
1763+
ModulesToProcess.push_back(Import.importedModule);
1764+
}
1765+
}
1766+
1767+
return result;
1768+
}
1769+
17221770
void
17231771
SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
17241772
ModuleDecl::ImportFilter filter) const {

0 commit comments

Comments
 (0)