mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
AST: Introduce ModuleDecl::ImportFilter::ForLinking
ModuleDecl::forAllVisibleModules() now has a includeLinkOnlyModules parameter. This is intended to be used when computing the set of libraries to autolink.
This commit is contained in:
@@ -345,9 +345,17 @@ public:
|
||||
|
||||
/// \sa getImportedModules
|
||||
enum class ImportFilter {
|
||||
// Everything.
|
||||
All,
|
||||
|
||||
// @_exported only.
|
||||
Public,
|
||||
Private
|
||||
|
||||
// Not @_exported only. Also includes @_usableFromInline.
|
||||
Private,
|
||||
|
||||
// @_usableFromInline and @_exported only.
|
||||
ForLinking
|
||||
};
|
||||
|
||||
/// Looks up which modules are imported by this module.
|
||||
@@ -360,11 +368,16 @@ public:
|
||||
/// Looks up which modules are imported by this module, ignoring any that
|
||||
/// won't contain top-level decls.
|
||||
///
|
||||
/// This is a performance hack. Do not use for anything but name lookup.
|
||||
/// May go away in the future.
|
||||
/// This is a performance hack for the ClangImporter. Do not use for
|
||||
/// anything but name lookup. May go away in the future.
|
||||
void
|
||||
getImportedModulesForLookup(SmallVectorImpl<ImportedModule> &imports) const;
|
||||
|
||||
/// Extension of the above hack. Identical to getImportedModulesForLookup()
|
||||
/// for imported modules, otherwise also includes @usableFromInline imports.
|
||||
void
|
||||
getImportedModulesForLinking(SmallVectorImpl<ImportedModule> &imports) const;
|
||||
|
||||
/// Finds all top-level decls of this module.
|
||||
///
|
||||
/// This does a simple local lookup, not recursively looking through imports.
|
||||
@@ -402,11 +415,16 @@ public:
|
||||
/// results, with the given access path.
|
||||
/// \param fn A callback of type bool(ImportedModule) or void(ImportedModule).
|
||||
/// Return \c false to abort iteration.
|
||||
/// \param includeLinkOnlyModules Include modules that are not visible to
|
||||
/// name lookup but must be linked in because inlinable code can
|
||||
/// reference their symbols.
|
||||
///
|
||||
/// \return True if the traversal ran to completion, false if it ended early
|
||||
/// due to the callback.
|
||||
bool forAllVisibleModules(AccessPathTy topLevelAccessPath,
|
||||
llvm::function_ref<bool(ImportedModule)> fn);
|
||||
llvm::function_ref<bool(ImportedModule)> fn,
|
||||
bool includeLinkOnlyModules = false);
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -638,6 +656,12 @@ public:
|
||||
return getImportedModules(imports, ModuleDecl::ImportFilter::Public);
|
||||
}
|
||||
|
||||
/// \see ModuleDecl::getImportedModulesForLinking
|
||||
virtual void getImportedModulesForLinking(
|
||||
SmallVectorImpl<ModuleDecl::ImportedModule> &imports) const {
|
||||
return getImportedModules(imports, ModuleDecl::ImportFilter::ForLinking);
|
||||
}
|
||||
|
||||
/// Generates the list of libraries needed to link this file, based on its
|
||||
/// imports.
|
||||
virtual void
|
||||
@@ -649,11 +673,15 @@ public:
|
||||
///
|
||||
/// \param fn A callback of type bool(ImportedModule) or void(ImportedModule).
|
||||
/// Return \c false to abort iteration.
|
||||
/// \param includeLinkOnlyModules Include modules that are not visible to
|
||||
/// name lookup but must be linked in because inlinable code can
|
||||
/// reference their symbols.
|
||||
///
|
||||
/// \return True if the traversal ran to completion, false if it ended early
|
||||
/// due to the callback.
|
||||
bool
|
||||
forAllVisibleModules(llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn);
|
||||
forAllVisibleModules(llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn,
|
||||
bool includeLinkOnlyModules = false);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
@@ -97,6 +97,12 @@ public:
|
||||
virtual void getImportedModulesForLookup(
|
||||
SmallVectorImpl<ModuleDecl::ImportedModule> &imports) const override;
|
||||
|
||||
virtual void getImportedModulesForLinking(
|
||||
SmallVectorImpl<ModuleDecl::ImportedModule> &imports) const override {
|
||||
// In C, anything that's linkable is visible to the source language.
|
||||
return getImportedModulesForLookup(imports);
|
||||
}
|
||||
|
||||
virtual void
|
||||
collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const override;
|
||||
|
||||
|
||||
@@ -974,6 +974,11 @@ SourceFile::getImportedModules(SmallVectorImpl<ModuleDecl::ImportedModule> &modu
|
||||
if (importPair.second.contains(ImportFlags::Exported))
|
||||
continue;
|
||||
break;
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
if (!importPair.second.contains(ImportFlags::UsableFromInline) &&
|
||||
!importPair.second.contains(ImportFlags::Exported))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
modules.push_back(importPair.first);
|
||||
@@ -985,6 +990,11 @@ void ModuleDecl::getImportedModulesForLookup(
|
||||
FORWARD(getImportedModulesForLookup, (modules));
|
||||
}
|
||||
|
||||
void ModuleDecl::getImportedModulesForLinking(
|
||||
SmallVectorImpl<ImportedModule> &modules) const {
|
||||
FORWARD(getImportedModulesForLinking, (modules));
|
||||
}
|
||||
|
||||
bool ModuleDecl::isSameAccessPath(AccessPathTy lhs, AccessPathTy rhs) {
|
||||
using AccessPathElem = std::pair<Identifier, SourceLoc>;
|
||||
if (lhs.size() != rhs.size())
|
||||
@@ -1128,10 +1138,14 @@ bool ModuleDecl::isSystemModule() const {
|
||||
}
|
||||
|
||||
bool ModuleDecl::forAllVisibleModules(AccessPathTy thisPath,
|
||||
llvm::function_ref<bool(ImportedModule)> fn) {
|
||||
llvm::function_ref<bool(ImportedModule)> fn,
|
||||
bool includeLinkOnlyModules) {
|
||||
llvm::SmallSet<ImportedModule, 32, ModuleDecl::OrderImportedModules> visited;
|
||||
SmallVector<ImportedModule, 32> stack;
|
||||
|
||||
if (includeLinkOnlyModules)
|
||||
getImportedModules(stack, ModuleDecl::ImportFilter::ForLinking);
|
||||
else
|
||||
getImportedModules(stack, ModuleDecl::ImportFilter::Public);
|
||||
|
||||
// Make sure the top-level module is first; we want pre-order-ish traversal.
|
||||
@@ -1158,6 +1172,9 @@ bool ModuleDecl::forAllVisibleModules(AccessPathTy thisPath,
|
||||
if (!fn(next))
|
||||
return false;
|
||||
|
||||
if (includeLinkOnlyModules)
|
||||
next.second->getImportedModulesForLinking(stack);
|
||||
else
|
||||
next.second->getImportedModulesForLookup(stack);
|
||||
}
|
||||
|
||||
@@ -1165,8 +1182,10 @@ bool ModuleDecl::forAllVisibleModules(AccessPathTy thisPath,
|
||||
}
|
||||
|
||||
bool FileUnit::forAllVisibleModules(
|
||||
llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn) {
|
||||
if (!getParentModule()->forAllVisibleModules(ModuleDecl::AccessPathTy(), fn))
|
||||
llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn,
|
||||
bool includeLinkOnlyModules) {
|
||||
if (!getParentModule()->forAllVisibleModules(ModuleDecl::AccessPathTy(), fn,
|
||||
includeLinkOnlyModules))
|
||||
return false;
|
||||
|
||||
if (auto SF = dyn_cast<SourceFile>(this)) {
|
||||
@@ -1175,7 +1194,8 @@ bool FileUnit::forAllVisibleModules(
|
||||
SmallVector<ModuleDecl::ImportedModule, 4> imports;
|
||||
SF->getImportedModules(imports, ModuleDecl::ImportFilter::Private);
|
||||
for (auto importPair : imports)
|
||||
if (!importPair.second->forAllVisibleModules(importPair.first, fn))
|
||||
if (!importPair.second->forAllVisibleModules(importPair.first, fn,
|
||||
includeLinkOnlyModules))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1198,7 +1218,8 @@ SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const
|
||||
|
||||
next->collectLinkLibraries(callback);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
/*includeLinkOnlyModules=*/true);
|
||||
}
|
||||
|
||||
bool ModuleDecl::walk(ASTWalker &Walker) {
|
||||
|
||||
@@ -3049,6 +3049,7 @@ void ClangModuleUnit::getImportedModules(
|
||||
imports.push_back({ModuleDecl::AccessPathTy(), owner.getStdlibModule()});
|
||||
break;
|
||||
case ModuleDecl::ImportFilter::Public:
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3058,6 +3059,7 @@ void ClangModuleUnit::getImportedModules(
|
||||
switch (filter) {
|
||||
case ModuleDecl::ImportFilter::All:
|
||||
case ModuleDecl::ImportFilter::Public:
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
imported.append(owner.ImportedHeaderExports.begin(),
|
||||
owner.ImportedHeaderExports.end());
|
||||
break;
|
||||
@@ -3106,6 +3108,7 @@ void ClangModuleUnit::getImportedModules(
|
||||
}
|
||||
|
||||
case ModuleDecl::ImportFilter::Public:
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1598,6 +1598,13 @@ void ModuleFile::getImportedModules(
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
// FIXME
|
||||
if (!dep.isExported())
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
assert(dep.isLoaded());
|
||||
|
||||
Reference in New Issue
Block a user