Skip to content

Just autolink everything #16349

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

Merged
merged 7 commits into from
May 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 0 additions & 9 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1549,19 +1549,10 @@ class ImportDecl final : public Decl,
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; }

Expand Down
82 changes: 41 additions & 41 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,17 +353,9 @@ class ModuleDecl : public DeclContext, public TypeDecl {

/// \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.
Expand All @@ -376,16 +368,11 @@ class ModuleDecl : public DeclContext, public TypeDecl {
/// 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.
Expand Down Expand Up @@ -423,16 +410,28 @@ class ModuleDecl : public DeclContext, public TypeDecl {
/// 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);
}

/// @}

Expand Down Expand Up @@ -664,12 +663,6 @@ class FileUnit : public DeclContext {
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
Expand All @@ -681,15 +674,28 @@ class FileUnit : public DeclContext {
///
/// \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);
}

/// @}

Expand Down Expand Up @@ -768,17 +774,13 @@ class SourceFile final : public FileUnit {
};

/// 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
Expand All @@ -791,7 +793,7 @@ class SourceFile final : public FileUnit {
/// 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
Expand Down Expand Up @@ -897,8 +899,6 @@ class SourceFile final : public FileUnit {

bool hasTestableImport(const ModuleDecl *module) const;

void markUsableFromInlineImport(const ModuleDecl *module);

void clearLookupCache();

void cacheVisibleDecls(SmallVectorImpl<ValueDecl *> &&globals) const;
Expand Down
6 changes: 0 additions & 6 deletions include/swift/ClangImporter/ClangModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,6 @@ class ClangModuleUnit final : public LoadedFile {
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;

Expand Down
27 changes: 7 additions & 20 deletions include/swift/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,40 +132,27 @@ class ModuleFile
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 {
return Import.second != nullptr;
}

bool isExported() const { return IsExported; }
bool isUsableFromInline() const { return IsUsableFromInline; }
bool isHeader() const { return IsHeader; }
bool isScoped() const { return IsScoped; }

Expand Down
3 changes: 1 addition & 2 deletions include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion lib/AST/LookupVisibleDecls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,6 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer,
CurrDC->getParentSourceFile()->forAllVisibleModules(
[&](ModuleDecl::ImportedModule Import) {
Import.second->lookupClassMembers(Import.first, ConsumerWrapper);
return true;
});
}

Expand Down
Loading