mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
Merge pull request #16349 from jrose-apple/just-autolink-everything
Just autolink everything that's imported, publicly or privately. rdar://problem/39338239
This commit is contained in:
@@ -372,9 +372,6 @@ SIMPLE_DECL_ATTR(_frozen, Frozen,
|
||||
OnEnum |
|
||||
UserInaccessible,
|
||||
76)
|
||||
SIMPLE_DECL_ATTR(_usableFromInline, UsableFromInlineImport,
|
||||
OnImport | UserInaccessible,
|
||||
77)
|
||||
|
||||
#undef TYPE_ATTR
|
||||
#undef DECL_ATTR_ALIAS
|
||||
|
||||
@@ -1549,19 +1549,10 @@ public:
|
||||
return static_cast<ImportKind>(Bits.ImportDecl.ImportKind);
|
||||
}
|
||||
|
||||
// An exported import is visible to name lookup from other modules, and is
|
||||
// autolinked when the containing module is autolinked.
|
||||
bool isExported() const {
|
||||
return getAttrs().hasAttribute<ExportedAttr>();
|
||||
}
|
||||
|
||||
// A usable from inline import is autolinked but not visible to name lookup.
|
||||
// This attribute is inferred when type checking inlinable and default
|
||||
// argument bodies.
|
||||
bool isUsableFromInline() const {
|
||||
return getAttrs().hasAttribute<UsableFromInlineImportAttr>();
|
||||
}
|
||||
|
||||
ModuleDecl *getModule() const { return Mod; }
|
||||
void setModule(ModuleDecl *M) { Mod = M; }
|
||||
|
||||
|
||||
+41
-41
@@ -353,17 +353,9 @@ public:
|
||||
|
||||
/// \sa getImportedModules
|
||||
enum class ImportFilter {
|
||||
// Everything.
|
||||
All,
|
||||
|
||||
// @_exported only.
|
||||
Public,
|
||||
|
||||
// Not @_exported only. Also includes @_usableFromInline.
|
||||
Private,
|
||||
|
||||
// @_usableFromInline and @_exported only.
|
||||
ForLinking
|
||||
Private
|
||||
};
|
||||
|
||||
/// Looks up which modules are imported by this module.
|
||||
@@ -376,16 +368,11 @@ public:
|
||||
/// Looks up which modules are imported by this module, ignoring any that
|
||||
/// won't contain top-level decls.
|
||||
///
|
||||
/// This is a performance hack for the ClangImporter. Do not use for
|
||||
/// anything but name lookup. May go away in the future.
|
||||
/// This is a performance hack. 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.
|
||||
@@ -423,16 +410,28 @@ 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,
|
||||
bool includeLinkOnlyModules = false);
|
||||
llvm::function_ref<bool(ImportedModule)> fn);
|
||||
|
||||
bool forAllVisibleModules(AccessPathTy topLevelAccessPath,
|
||||
llvm::function_ref<void(ImportedModule)> fn) {
|
||||
return forAllVisibleModules(topLevelAccessPath,
|
||||
[=](const ImportedModule &import) -> bool {
|
||||
fn(import);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
bool forAllVisibleModules(AccessPathTy topLevelAccessPath,
|
||||
Fn &&fn) {
|
||||
using RetTy = typename std::result_of<Fn(ImportedModule)>::type;
|
||||
llvm::function_ref<RetTy(ImportedModule)> wrapped{std::forward<Fn>(fn)};
|
||||
return forAllVisibleModules(topLevelAccessPath, wrapped);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -664,12 +663,6 @@ 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
|
||||
@@ -681,15 +674,28 @@ 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,
|
||||
bool includeLinkOnlyModules = false);
|
||||
forAllVisibleModules(llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn);
|
||||
|
||||
bool
|
||||
forAllVisibleModules(llvm::function_ref<void(ModuleDecl::ImportedModule)> fn) {
|
||||
return forAllVisibleModules([=](ModuleDecl::ImportedModule import) -> bool {
|
||||
fn(import);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
bool forAllVisibleModules(Fn &&fn) {
|
||||
using RetTy = typename std::result_of<Fn(ModuleDecl::ImportedModule)>::type;
|
||||
llvm::function_ref<RetTy(ModuleDecl::ImportedModule)> wrapped{
|
||||
std::forward<Fn>(fn)
|
||||
};
|
||||
return forAllVisibleModules(wrapped);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -768,17 +774,13 @@ public:
|
||||
};
|
||||
|
||||
/// Possible attributes for imports in source files.
|
||||
enum class ImportFlags : uint8_t {
|
||||
enum class ImportFlags {
|
||||
/// The imported module is exposed to anyone who imports the parent module.
|
||||
Exported = 0x1,
|
||||
|
||||
/// This source file has access to testable declarations in the imported
|
||||
/// module.
|
||||
Testable = 0x2,
|
||||
|
||||
/// Modules that depend on the module containing this source file will
|
||||
/// autolink this dependency.
|
||||
UsableFromInline = 0x4,
|
||||
Testable = 0x2
|
||||
};
|
||||
|
||||
/// \see ImportFlags
|
||||
@@ -791,7 +793,7 @@ private:
|
||||
/// This is the list of modules that are imported by this module.
|
||||
///
|
||||
/// This is filled in by the Name Binding phase.
|
||||
MutableArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptions>> Imports;
|
||||
ArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptions>> Imports;
|
||||
|
||||
/// A unique identifier representing this file; used to mark private decls
|
||||
/// within the file to keep them from conflicting with other files in the
|
||||
@@ -897,8 +899,6 @@ public:
|
||||
|
||||
bool hasTestableImport(const ModuleDecl *module) const;
|
||||
|
||||
void markUsableFromInlineImport(const ModuleDecl *module);
|
||||
|
||||
void clearLookupCache();
|
||||
|
||||
void cacheVisibleDecls(SmallVectorImpl<ValueDecl *> &&globals) const;
|
||||
|
||||
@@ -97,12 +97,6 @@ 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;
|
||||
|
||||
|
||||
@@ -132,32 +132,20 @@ public:
|
||||
const StringRef RawPath;
|
||||
|
||||
private:
|
||||
unsigned IsExported : 1;
|
||||
const unsigned IsHeader : 1;
|
||||
const unsigned IsExported : 1;
|
||||
const unsigned IsUsableFromInline : 1;
|
||||
const unsigned IsScoped : 1;
|
||||
|
||||
Dependency(bool isHeader,
|
||||
StringRef path, bool exported,
|
||||
bool isUsableFromInline, bool isScoped)
|
||||
: RawPath(path),
|
||||
IsHeader(isHeader),
|
||||
IsExported(exported),
|
||||
IsUsableFromInline(isUsableFromInline),
|
||||
IsScoped(isScoped) {
|
||||
assert(!(IsExported && IsUsableFromInline));
|
||||
assert(!(IsHeader && IsScoped));
|
||||
}
|
||||
Dependency(StringRef path, bool isHeader, bool exported, bool isScoped)
|
||||
: RawPath(path), IsExported(exported), IsHeader(isHeader),
|
||||
IsScoped(isScoped) {}
|
||||
|
||||
public:
|
||||
Dependency(StringRef path, bool exported, bool isUsableFromInline,
|
||||
bool isScoped)
|
||||
: Dependency(false, path, exported, isUsableFromInline, isScoped) {}
|
||||
Dependency(StringRef path, bool exported, bool isScoped)
|
||||
: Dependency(path, false, exported, isScoped) {}
|
||||
|
||||
static Dependency forHeader(StringRef headerPath, bool exported) {
|
||||
return Dependency(true, headerPath, exported,
|
||||
/*isUsableFromInline=*/false,
|
||||
/*isScoped=*/false);
|
||||
return Dependency(headerPath, true, exported, false);
|
||||
}
|
||||
|
||||
bool isLoaded() const {
|
||||
@@ -165,7 +153,6 @@ public:
|
||||
}
|
||||
|
||||
bool isExported() const { return IsExported; }
|
||||
bool isUsableFromInline() const { return IsUsableFromInline; }
|
||||
bool isHeader() const { return IsHeader; }
|
||||
bool isScoped() const { return IsScoped; }
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
|
||||
/// describe what change you made. The content of this comment isn't important;
|
||||
/// it just ensures a conflict if two people change the module format.
|
||||
/// Don't worry about adhering to the 80-column limit for this line.
|
||||
const uint16_t VERSION_MINOR = 416; // Last change: remove substitutions
|
||||
const uint16_t VERSION_MINOR = 417; // Last change: revert @usableFromInline imports
|
||||
|
||||
using DeclIDField = BCFixed<31>;
|
||||
|
||||
@@ -595,7 +595,6 @@ namespace input_block {
|
||||
using ImportedModuleLayout = BCRecordLayout<
|
||||
IMPORTED_MODULE,
|
||||
BCFixed<1>, // exported?
|
||||
BCFixed<1>, // usable from inlinable functions?
|
||||
BCFixed<1>, // scoped?
|
||||
BCBlob // module name, with submodule path pieces separated by \0s.
|
||||
// If the 'scoped' flag is set, the final path piece is an access
|
||||
|
||||
@@ -2331,7 +2331,6 @@ void ASTContext::diagnoseAttrsRequiringFoundation(SourceFile &SF) {
|
||||
SF.forAllVisibleModules([&](ModuleDecl::ImportedModule import) {
|
||||
if (import.second->getName() == Id_Foundation)
|
||||
ImportsFoundationModule = true;
|
||||
return true;
|
||||
});
|
||||
|
||||
if (ImportsFoundationModule)
|
||||
|
||||
@@ -387,7 +387,6 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer,
|
||||
CurrDC->getParentSourceFile()->forAllVisibleModules(
|
||||
[&](ModuleDecl::ImportedModule Import) {
|
||||
Import.second->lookupClassMembers(Import.first, ConsumerWrapper);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+38
-49
@@ -974,11 +974,6 @@ 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);
|
||||
@@ -990,11 +985,6 @@ 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())
|
||||
@@ -1137,29 +1127,35 @@ bool ModuleDecl::isSystemModule() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModuleDecl::forAllVisibleModules(AccessPathTy thisPath,
|
||||
llvm::function_ref<bool(ImportedModule)> fn,
|
||||
bool includeLinkOnlyModules) {
|
||||
template<bool respectVisibility>
|
||||
static bool
|
||||
forAllImportedModules(ModuleDecl *topLevel, ModuleDecl::AccessPathTy thisPath,
|
||||
llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn) {
|
||||
using ImportedModule = ModuleDecl::ImportedModule;
|
||||
using AccessPathTy = ModuleDecl::AccessPathTy;
|
||||
|
||||
llvm::SmallSet<ImportedModule, 32, ModuleDecl::OrderImportedModules> visited;
|
||||
SmallVector<ImportedModule, 32> stack;
|
||||
|
||||
if (includeLinkOnlyModules)
|
||||
getImportedModules(stack, ModuleDecl::ImportFilter::ForLinking);
|
||||
else
|
||||
getImportedModules(stack, ModuleDecl::ImportFilter::Public);
|
||||
auto filter = respectVisibility ? ModuleDecl::ImportFilter::Public
|
||||
: ModuleDecl::ImportFilter::All;
|
||||
topLevel->getImportedModules(stack, filter);
|
||||
|
||||
// Make sure the top-level module is first; we want pre-order-ish traversal.
|
||||
stack.push_back(ImportedModule(thisPath, this));
|
||||
AccessPathTy overridingPath;
|
||||
if (respectVisibility)
|
||||
overridingPath = thisPath;
|
||||
stack.push_back(ImportedModule(overridingPath, topLevel));
|
||||
|
||||
while (!stack.empty()) {
|
||||
auto next = stack.pop_back_val();
|
||||
|
||||
// Filter any whole-module imports, and skip specific-decl imports if the
|
||||
// import path doesn't match exactly.
|
||||
if (next.first.empty())
|
||||
next.first = thisPath;
|
||||
else if (!thisPath.empty() &&
|
||||
!ModuleDecl::isSameAccessPath(next.first, thisPath)) {
|
||||
if (next.first.empty() || !respectVisibility)
|
||||
next.first = overridingPath;
|
||||
else if (!overridingPath.empty() &&
|
||||
!ModuleDecl::isSameAccessPath(next.first, overridingPath)) {
|
||||
// If we ever allow importing non-top-level decls, it's possible the rule
|
||||
// above isn't what we want.
|
||||
assert(next.first.size() == 1 && "import of non-top-level decl");
|
||||
@@ -1172,20 +1168,24 @@ bool ModuleDecl::forAllVisibleModules(AccessPathTy thisPath,
|
||||
if (!fn(next))
|
||||
return false;
|
||||
|
||||
if (includeLinkOnlyModules)
|
||||
next.second->getImportedModulesForLinking(stack);
|
||||
else
|
||||
if (respectVisibility)
|
||||
next.second->getImportedModulesForLookup(stack);
|
||||
else
|
||||
next.second->getImportedModules(stack, filter);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleDecl::forAllVisibleModules(AccessPathTy thisPath,
|
||||
llvm::function_ref<bool(ImportedModule)> fn) {
|
||||
return forAllImportedModules<true>(this, thisPath, fn);
|
||||
}
|
||||
|
||||
bool FileUnit::forAllVisibleModules(
|
||||
llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn,
|
||||
bool includeLinkOnlyModules) {
|
||||
if (!getParentModule()->forAllVisibleModules(ModuleDecl::AccessPathTy(), fn,
|
||||
includeLinkOnlyModules))
|
||||
llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn) {
|
||||
if (!getParentModule()->forAllVisibleModules(ModuleDecl::AccessPathTy(), fn))
|
||||
return false;
|
||||
|
||||
if (auto SF = dyn_cast<SourceFile>(this)) {
|
||||
@@ -1194,8 +1194,7 @@ 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,
|
||||
includeLinkOnlyModules))
|
||||
if (!importPair.second->forAllVisibleModules(importPair.first, fn))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1209,17 +1208,15 @@ void ModuleDecl::collectLinkLibraries(LinkLibraryCallback callback) {
|
||||
|
||||
void
|
||||
SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const {
|
||||
|
||||
const_cast<SourceFile *>(this)->forAllVisibleModules(
|
||||
[&](swift::ModuleDecl::ImportedModule import) {
|
||||
swift::ModuleDecl *next = import.second;
|
||||
if (next->getName() == getParentModule()->getName())
|
||||
return true;
|
||||
|
||||
next->collectLinkLibraries(callback);
|
||||
forAllImportedModules<false>(getParentModule(), /*thisPath*/{},
|
||||
[=](ModuleDecl::ImportedModule import) -> bool {
|
||||
swift::ModuleDecl *next = import.second;
|
||||
if (next->getName() == getParentModule()->getName())
|
||||
return true;
|
||||
},
|
||||
/*includeLinkOnlyModules=*/true);
|
||||
|
||||
next->collectLinkLibraries(callback);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool ModuleDecl::walk(ASTWalker &Walker) {
|
||||
@@ -1287,14 +1284,6 @@ bool SourceFile::hasTestableImport(const swift::ModuleDecl *module) const {
|
||||
});
|
||||
}
|
||||
|
||||
void SourceFile::markUsableFromInlineImport(const ModuleDecl *module) {
|
||||
for (auto &Import : Imports) {
|
||||
if (Import.first.second == module) {
|
||||
Import.second |= ImportFlags::UsableFromInline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SourceFile::clearLookupCache() {
|
||||
if (!Cache)
|
||||
return;
|
||||
|
||||
@@ -1865,7 +1865,6 @@ bool DeclContext::lookupQualified(Type type,
|
||||
SmallVector<ValueDecl *, 4> allDecls;
|
||||
forAllVisibleModules(this, [&](ModuleDecl::ImportedModule import) {
|
||||
import.second->lookupClassMember(import.first, member, allDecls);
|
||||
return true;
|
||||
});
|
||||
|
||||
// For each declaration whose context is not something we've
|
||||
@@ -1928,7 +1927,6 @@ void DeclContext::lookupAllObjCMethods(
|
||||
// Collect all of the methods with this selector.
|
||||
forAllVisibleModules(this, [&](ModuleDecl::ImportedModule import) {
|
||||
import.second->lookupObjCMethods(selector, results);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Filter out duplicates.
|
||||
|
||||
@@ -1580,9 +1580,7 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
|
||||
// FIXME: This forces the creation of wrapper modules for all imports as
|
||||
// well, and may do unnecessary work.
|
||||
cacheEntry.setInt(true);
|
||||
result->forAllVisibleModules({}, [&](ModuleDecl::ImportedModule import) {
|
||||
return true;
|
||||
});
|
||||
result->forAllVisibleModules({}, [&](ModuleDecl::ImportedModule import) {});
|
||||
}
|
||||
} else {
|
||||
// Build the representation of the Clang module in Swift.
|
||||
@@ -1602,9 +1600,7 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
|
||||
// Force load adapter modules for all imported modules.
|
||||
// FIXME: This forces the creation of wrapper modules for all imports as
|
||||
// well, and may do unnecessary work.
|
||||
result->forAllVisibleModules({}, [](ModuleDecl::ImportedModule import) {
|
||||
return true;
|
||||
});
|
||||
result->forAllVisibleModules({}, [](ModuleDecl::ImportedModule import) {});
|
||||
}
|
||||
|
||||
if (clangModule->isSubModule()) {
|
||||
@@ -3055,7 +3051,6 @@ void ClangModuleUnit::getImportedModules(
|
||||
imports.push_back({ModuleDecl::AccessPathTy(), owner.getStdlibModule()});
|
||||
break;
|
||||
case ModuleDecl::ImportFilter::Public:
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3065,7 +3060,6 @@ 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;
|
||||
@@ -3114,7 +3108,6 @@ void ClangModuleUnit::getImportedModules(
|
||||
}
|
||||
|
||||
case ModuleDecl::ImportFilter::Public:
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3334,8 +3334,6 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
return results;
|
||||
}
|
||||
@@ -5609,11 +5607,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
||||
|
||||
// FIXME: actually check imports.
|
||||
const_cast<ModuleDecl*>(Request.TheModule)
|
||||
->forAllVisibleModules({},
|
||||
[&](ModuleDecl::ImportedModule Import) {
|
||||
handleImport(Import);
|
||||
return true;
|
||||
});
|
||||
->forAllVisibleModules({}, handleImport);
|
||||
} else {
|
||||
// Add results from current module.
|
||||
Lookup.getToplevelCompletions(Request.OnlyTypes);
|
||||
@@ -5627,11 +5621,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
||||
for (auto Imported : Imports) {
|
||||
ModuleDecl *TheModule = Imported.second;
|
||||
ModuleDecl::AccessPathTy AccessPath = Imported.first;
|
||||
TheModule->forAllVisibleModules(AccessPath,
|
||||
[&](ModuleDecl::ImportedModule Import) {
|
||||
handleImport(Import);
|
||||
return true;
|
||||
});
|
||||
TheModule->forAllVisibleModules(AccessPath, handleImport);
|
||||
}
|
||||
}
|
||||
Lookup.RequestedCachedResults.reset();
|
||||
|
||||
@@ -235,8 +235,6 @@ void NameBinder::addImport(
|
||||
ImportOptions options;
|
||||
if (ID->isExported())
|
||||
options |= SourceFile::ImportFlags::Exported;
|
||||
if (ID->isUsableFromInline())
|
||||
options |= SourceFile::ImportFlags::UsableFromInline;
|
||||
if (testableAttr)
|
||||
options |= SourceFile::ImportFlags::Testable;
|
||||
imports.push_back({ { ID->getDeclPath(), M }, options });
|
||||
|
||||
@@ -113,7 +113,6 @@ public:
|
||||
IGNORED_ATTR(UIApplicationMain)
|
||||
IGNORED_ATTR(UnsafeNoObjCTaggedPointer)
|
||||
IGNORED_ATTR(UsableFromInline)
|
||||
IGNORED_ATTR(UsableFromInlineImport)
|
||||
IGNORED_ATTR(WeakLinked)
|
||||
#undef IGNORED_ATTR
|
||||
|
||||
@@ -834,7 +833,6 @@ public:
|
||||
IGNORED_ATTR(SynthesizedProtocol)
|
||||
IGNORED_ATTR(Testable)
|
||||
IGNORED_ATTR(Transparent)
|
||||
IGNORED_ATTR(UsableFromInlineImport)
|
||||
IGNORED_ATTR(WarnUnqualifiedAccess)
|
||||
IGNORED_ATTR(WeakLinked)
|
||||
#undef IGNORED_ATTR
|
||||
|
||||
@@ -2509,19 +2509,12 @@ bool AvailabilityWalker::diagAvailability(const ValueDecl *D, SourceRange R,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FragileKind) {
|
||||
if (R.isValid()) {
|
||||
if (FragileKind)
|
||||
if (R.isValid())
|
||||
if (TC.diagnoseInlinableDeclRef(R.Start, D, DC, *FragileKind,
|
||||
TreatUsableFromInlineAsPublic))
|
||||
return true;
|
||||
|
||||
auto *SF = cast<SourceFile>(DC->getModuleScopeContext());
|
||||
auto *M = D->getDeclContext()->getParentModule();
|
||||
if (SF->getParentModule() != M)
|
||||
SF->markUsableFromInlineImport(M);
|
||||
}
|
||||
}
|
||||
|
||||
if (TC.diagnoseExplicitUnavailability(D, R, DC, call))
|
||||
return true;
|
||||
|
||||
|
||||
@@ -5794,8 +5794,6 @@ public:
|
||||
UNINTERESTING_ATTR(ClangImporterSynthesizedType)
|
||||
UNINTERESTING_ATTR(WeakLinked)
|
||||
UNINTERESTING_ATTR(Frozen)
|
||||
UNINTERESTING_ATTR(UsableFromInlineImport)
|
||||
|
||||
#undef UNINTERESTING_ATTR
|
||||
|
||||
void visitAvailableAttr(AvailableAttr *attr) {
|
||||
|
||||
@@ -655,8 +655,6 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
||||
bindExtensionDecl(ED, TC);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Type check the top-level elements of the source file.
|
||||
|
||||
@@ -1140,12 +1140,10 @@ ModuleFile::ModuleFile(
|
||||
unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
|
||||
switch (kind) {
|
||||
case input_block::IMPORTED_MODULE: {
|
||||
bool exported, usableFromInline, scoped;
|
||||
bool exported, scoped;
|
||||
input_block::ImportedModuleLayout::readRecord(scratch,
|
||||
exported,
|
||||
usableFromInline,
|
||||
scoped);
|
||||
Dependencies.push_back({blobData, exported, usableFromInline, scoped});
|
||||
exported, scoped);
|
||||
Dependencies.push_back({blobData, exported, scoped});
|
||||
break;
|
||||
}
|
||||
case input_block::LINK_LIBRARY: {
|
||||
@@ -1607,13 +1605,6 @@ void ModuleFile::getImportedModules(
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case ModuleDecl::ImportFilter::ForLinking:
|
||||
// Only include @_exported and @usableFromInline imports.
|
||||
if (!dep.isExported() && !dep.isUsableFromInline())
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
assert(dep.isLoaded());
|
||||
@@ -1682,9 +1673,6 @@ void ModuleFile::getImportDecls(SmallVectorImpl<Decl *> &Results) {
|
||||
if (Dep.isExported())
|
||||
ID->getAttrs().add(
|
||||
new (Ctx) ExportedAttr(/*IsImplicit=*/false));
|
||||
if (Dep.isUsableFromInline())
|
||||
ID->getAttrs().add(
|
||||
new (Ctx) UsableFromInlineImportAttr(/*IsImplicit=*/true));
|
||||
ImportDecls.push_back(ID);
|
||||
}
|
||||
Bits.ComputedImportDecls = true;
|
||||
|
||||
@@ -1071,11 +1071,9 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
|
||||
// FIXME: Having to deal with private imports as a superset of public imports
|
||||
// is inefficient.
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> publicImports;
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> linkImports;
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> allImports;
|
||||
for (auto file : M->getFiles()) {
|
||||
file->getImportedModules(publicImports, ModuleDecl::ImportFilter::Public);
|
||||
file->getImportedModules(linkImports, ModuleDecl::ImportFilter::ForLinking);
|
||||
file->getImportedModules(allImports, ModuleDecl::ImportFilter::All);
|
||||
}
|
||||
|
||||
@@ -1083,10 +1081,6 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
|
||||
publicImportSet;
|
||||
publicImportSet.insert(publicImports.begin(), publicImports.end());
|
||||
|
||||
llvm::SmallSet<ModuleDecl::ImportedModule, 8, ModuleDecl::OrderImportedModules>
|
||||
linkImportSet;
|
||||
linkImportSet.insert(linkImports.begin(), linkImports.end());
|
||||
|
||||
removeDuplicateImports(allImports);
|
||||
auto clangImporter =
|
||||
static_cast<ClangImporter *>(M->getASTContext().getClangModuleLoader());
|
||||
@@ -1115,10 +1109,7 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
|
||||
|
||||
ImportPathBlob importPath;
|
||||
flattenImportPath(import, importPath);
|
||||
ImportedModule.emit(ScratchRecord,
|
||||
publicImportSet.count(import),
|
||||
(linkImportSet.count(import) &&
|
||||
!publicImportSet.count(import)),
|
||||
ImportedModule.emit(ScratchRecord, publicImportSet.count(import),
|
||||
!import.first.empty(), importPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// RUN: %FileCheck %s < %t/with-adapter.ll
|
||||
// RUN: %FileCheck -check-prefix CHECK-WITH-SWIFT %s < %t/with-adapter.ll
|
||||
|
||||
// RUN: %target-swift-frontend %s -sdk %S/Inputs -I %S/Inputs/custom-modules -emit-ir -disable-autolink-framework LinkFramework -o - | %FileCheck -check-prefix CHECK-WITH-DISABLED %s
|
||||
// RUN: %target-swift-frontend %s -sdk %S/Inputs -I %S/Inputs/custom-modules -emit-ir -disable-autolink-framework LinkFramework -o - > %t/with-disabled.ll
|
||||
// RUN: %FileCheck -check-prefix CHECK-WITH-DISABLED %s < %t/with-disabled.ll
|
||||
// RUN: %FileCheck -check-prefix NEGATIVE-WITH-DISABLED %s < %t/with-disabled.ll
|
||||
|
||||
// Linux uses a different autolinking mechanism, based on
|
||||
// swift-autolink-extract. This file tests the Darwin mechanism.
|
||||
@@ -37,6 +39,6 @@ UsesSubmodule.useSomethingFromSubmodule()
|
||||
|
||||
// CHECK-WITH-SWIFT: !{{[0-9]+}} = !{!"-lSwiftAdapter"}
|
||||
|
||||
// CHECK-WITH-DISABLED: !{!"-framework", !"Barrel"}
|
||||
// CHECK-WITH-DISABLED-NOT: !{!"-framework", !"LinkFramework"}
|
||||
// CHECK-WITH-DISABLED: !{!"-framework", !"Indirect"}
|
||||
// CHECK-WITH-DISABLED-DAG: !{!"-framework", !"Barrel"}
|
||||
// CHECK-WITH-DISABLED-DAG: !{!"-framework", !"Indirect"}
|
||||
// NEGATIVE-WITH-DISABLED-NOT: !"LinkFramework"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
@_usableFromInline import InlinableImport
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
// Empty module
|
||||
@@ -1,13 +0,0 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend -emit-module -o %t/InlinableImport.swiftmodule %S/Inputs/InlinableImport.swift
|
||||
// RUN: %target-swift-frontend -I %t -emit-module -o %t/HasInlinableImport.swiftmodule %S/Inputs/HasInlinableImport.swift
|
||||
// RUN: %target-swift-ide-test -I %t -print-module -source-filename %s -module-to-print=HasInlinableImport -function-definitions=false | %FileCheck %s
|
||||
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
import HasInlinableImport
|
||||
|
||||
// For now, don't print anything special for inlinable imports.
|
||||
|
||||
// CHECK: {{^}}import InlinableImport
|
||||
@@ -1,11 +1,13 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -enable-objc-interop -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -O -disable-sil-perf-optzns -disable-llvm-optzns -emit-ir -Xcc -fstack-protector | %FileCheck %s
|
||||
// RUN: %build-irgen-test-overlays
|
||||
// RUN: %target-swift-frontend -enable-objc-interop -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -O -disable-sil-perf-optzns -disable-llvm-optzns -emit-ir -Xcc -fstack-protector -I %t | %FileCheck %s
|
||||
|
||||
// RUN: %empty-directory(%t/Empty.framework/Modules/Empty.swiftmodule)
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module-path %t/Empty.framework/Modules/Empty.swiftmodule/%target-swiftmodule-name %S/../Inputs/empty.swift -module-name Empty
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -F %t -DIMPORT_EMPTY -O -disable-sil-perf-optzns -disable-llvm-optzns -emit-ir -Xcc -fstack-protector -enable-objc-interop | %FileCheck %s
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module-path %t/Empty.framework/Modules/Empty.swiftmodule/%target-swiftmodule-name %S/../Inputs/empty.swift -module-name Empty -I %t
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -I %t -F %t -DIMPORT_EMPTY -O -disable-sil-perf-optzns -disable-llvm-optzns -emit-ir -Xcc -fstack-protector -enable-objc-interop | %FileCheck %s
|
||||
|
||||
// REQUIRES: CPU=i386 || CPU=x86_64
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
#if IMPORT_EMPTY
|
||||
import Empty
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// Same test as clang_inline.swift, but with the order swapped.
|
||||
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -enable-objc-interop -emit-ir -module-name clang_inline | %FileCheck %s
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %build-irgen-test-overlays
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -enable-objc-interop -emit-ir -module-name clang_inline -I %t | %FileCheck %s
|
||||
|
||||
// REQUIRES: CPU=i386 || CPU=x86_64
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
import gizmo
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -gnone -enable-objc-interop -sdk %S/Inputs %s -emit-ir | %FileCheck %s
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %build-irgen-test-overlays
|
||||
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -gnone -enable-objc-interop -sdk %S/Inputs -I %t %s -emit-ir | %FileCheck %s
|
||||
|
||||
// REQUIRES: CPU=x86_64
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
sil_stage canonical
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
@_exported import autolinking_other2
|
||||
@@ -1,7 +0,0 @@
|
||||
@_exported import autolinking_public
|
||||
@_usableFromInline import autolinking_other
|
||||
import autolinking_private
|
||||
|
||||
public func bfunc(x: Int = afunc()) {
|
||||
cfunc()
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
@_exported import autolinking_public
|
||||
import autolinking_other // inferred as @_usableFromInline
|
||||
import autolinking_other
|
||||
import autolinking_indirect
|
||||
import autolinking_private
|
||||
|
||||
public func bfunc(x: Int = afunc()) {
|
||||
public func bfunc(x: Int = afunc(), y: Int = afunc2()) {
|
||||
cfunc()
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
public func afunc2() -> Int { return 0 }
|
||||
@@ -3,12 +3,12 @@
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_public.swift -emit-module-path %t/autolinking_public.swiftmodule -module-link-name autolinking_public -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_other.swift -emit-module-path %t/autolinking_other.swiftmodule -module-link-name autolinking_other -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_private.swift -emit-module-path %t/autolinking_private.swiftmodule -module-link-name autolinking_private -I %t -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_other2.swift -emit-module-path %t/autolinking_other2.swiftmodule -module-link-name autolinking_other2 -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_indirect.swift -emit-module-path %t/autolinking_indirect.swiftmodule -module-link-name autolinking_indirect -I %t -swift-version 4
|
||||
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_module_inferred.swift -emit-module-path %t/autolinking_module_inferred.swiftmodule -module-link-name autolinking_module_inferred -I %t -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-ir %s -I %t -swift-version 4 | %FileCheck %s
|
||||
|
||||
// This test is identical to autolinking-inlinable, except we also rely on the
|
||||
// '@_usableFromInline' attribute getting inferred correctly on the import.
|
||||
|
||||
// Linux uses a different autolinking mechanism, based on
|
||||
// swift-autolink-extract. This file tests the Darwin mechanism.
|
||||
// UNSUPPORTED: OS=linux-gnu
|
||||
@@ -20,13 +20,17 @@ import autolinking_module_inferred
|
||||
|
||||
bfunc()
|
||||
|
||||
// Note: we don't autolink autolinking_private even though autolinking_module imports it also.
|
||||
// CHECK: !llvm.linker.options = !{[[MODULE:![0-9]+]], [[PUBLIC:![0-9]+]], [[SWIFTONONESUPPORT:![0-9]+]], [[SWIFTCORE:![0-9]+]], [[PRIVATE:![0-9]+]], [[OTHER:![0-9]+]], [[INDIRECT:![0-9]+]], [[OTHER2:![0-9]+]], [[OBJC:![0-9]+]]}
|
||||
|
||||
// CHECK: !llvm.linker.options = !{[[SWIFTCORE:![0-9]+]], [[SWIFTONONESUPPORT:![0-9]+]], [[MODULE:![0-9]+]], [[PUBLIC:![0-9]+]], [[OTHER:![0-9]+]], [[OBJC:![0-9]+]]}
|
||||
// CHECK-DAG: [[SWIFTCORE]] = !{!"-lswiftCore"}
|
||||
// CHECK-DAG: [[SWIFTONONESUPPORT]] = !{!"-lswiftSwiftOnoneSupport"}
|
||||
// CHECK-DAG: [[MODULE]] = !{!"-lautolinking_module_inferred"}
|
||||
// CHECK-DAG: [[PUBLIC]] = !{!"-lautolinking_public"}
|
||||
// CHECK-DAG: [[OTHER]] = !{!"-lautolinking_other"}
|
||||
// CHECK-DAG: [[OTHER2]] = !{!"-lautolinking_other2"}
|
||||
// CHECK-DAG: [[OBJC]] = !{!"-lobjc"}
|
||||
|
||||
// CHECK: [[SWIFTCORE]] = !{!"-lswiftCore"}
|
||||
// CHECK: [[SWIFTONONESUPPORT]] = !{!"-lswiftSwiftOnoneSupport"}
|
||||
// CHECK: [[MODULE]] = !{!"-lautolinking_module_inferred"}
|
||||
// CHECK: [[PUBLIC]] = !{!"-lautolinking_public"}
|
||||
// CHECK: [[OTHER]] = !{!"-lautolinking_other"}
|
||||
// CHECK: [[OBJC]] = !{!"-lobjc"}
|
||||
// We don't actually care about these two. As long as we autolink the libraries
|
||||
// that get used, we're okay.
|
||||
// CHECK-DAG: [[PRIVATE]] = !{!"-lautolinking_private"}
|
||||
// CHECK-DAG: [[INDIRECT]] = !{!"-lautolinking_indirect"}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_public.swift -emit-module-path %t/autolinking_public.swiftmodule -module-link-name autolinking_public -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_other.swift -emit-module-path %t/autolinking_other.swiftmodule -module-link-name autolinking_other -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_private.swift -emit-module-path %t/autolinking_private.swiftmodule -module-link-name autolinking_private -I %t -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_module.swift -emit-module-path %t/autolinking_module.swiftmodule -module-link-name autolinking_module -I %t -swift-version 4
|
||||
// RUN: %target-swift-frontend -emit-ir %s -I %t -swift-version 4 | %FileCheck %s
|
||||
|
||||
// Linux uses a different autolinking mechanism, based on
|
||||
// swift-autolink-extract. This file tests the Darwin mechanism.
|
||||
// UNSUPPORTED: OS=linux-gnu
|
||||
// UNSUPPORTED: OS=linux-gnueabihf
|
||||
// UNSUPPORTED: OS=freebsd
|
||||
// UNSUPPORTED: OS=linux-androideabi
|
||||
|
||||
import autolinking_module
|
||||
|
||||
bfunc()
|
||||
|
||||
// Note: we don't autolink autolinking_private even though autolinking_module imports it also.
|
||||
|
||||
// CHECK: !llvm.linker.options = !{[[SWIFTCORE:![0-9]+]], [[SWIFTONONESUPPORT:![0-9]+]], [[MODULE:![0-9]+]], [[PUBLIC:![0-9]+]], [[OTHER:![0-9]+]], [[OBJC:![0-9]+]]}
|
||||
|
||||
// CHECK: [[SWIFTCORE]] = !{!"-lswiftCore"}
|
||||
// CHECK: [[SWIFTONONESUPPORT]] = !{!"-lswiftSwiftOnoneSupport"}
|
||||
// CHECK: [[MODULE]] = !{!"-lautolinking_module"}
|
||||
// CHECK: [[PUBLIC]] = !{!"-lautolinking_public"}
|
||||
// CHECK: [[OTHER]] = !{!"-lautolinking_other"}
|
||||
// CHECK: [[OBJC]] = !{!"-lobjc"}
|
||||
@@ -2449,8 +2449,6 @@ static int doPrintModuleImports(const CompilerInvocation &InitInvok,
|
||||
llvm::outs() << " (Clang)";
|
||||
llvm::outs() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user