Skip to content

Commit 0220b02

Browse files
authored
Merge pull request #74336 from artemcm/60CacheVisibleClangModulesInModules
[6.0 🍒] Cache visible Clang modules for interface printing in 'ModuleDecl'
2 parents e7c2412 + 1c2e9e0 commit 0220b02

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
@@ -5725,8 +5725,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57255725

57265726
ASTPrinter &Printer;
57275727
const PrintOptions &Options;
5728-
std::optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
5729-
VisibleClangModules;
57305728

57315729
void printGenericArgs(ArrayRef<Type> flatArgs) {
57325730
Printer << "<";
@@ -5800,56 +5798,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
58005798
return T->hasSimpleTypeRepr();
58015799
}
58025800

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

58675812
template <typename T>

lib/AST/Module.cpp

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

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

0 commit comments

Comments
 (0)