This commit is contained in:
Arnold Schwaighofer
2018-11-08 17:50:25 -08:00
parent e4099d0e88
commit 9feb75806a
5 changed files with 65 additions and 75 deletions

View File

@@ -864,6 +864,19 @@ public:
using ImportOptions = OptionSet<ImportFlags>;
typedef std::pair<ImportOptions, StringRef> ImportOptionsAndFilename;
struct ImportedModuleDesc {
ModuleDecl::ImportedModule module;
ImportOptions importOptions;
StringRef filename;
ImportedModuleDesc(ModuleDecl::ImportedModule module, ImportOptions options)
: module(module), importOptions(options) {}
ImportedModuleDesc(ModuleDecl::ImportedModule module, ImportOptions options,
StringRef filename)
: module(module), importOptions(options), filename(filename) {}
};
private:
std::unique_ptr<LookupCache> Cache;
LookupCache &getCache() const;
@@ -871,8 +884,7 @@ private:
/// This is the list of modules that are imported by this module.
///
/// This is filled in by the Name Binding phase.
ArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptionsAndFilename>>
Imports;
ArrayRef<ImportedModuleDesc> 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
@@ -976,9 +988,7 @@ public:
ImplicitModuleImportKind ModImpKind, bool KeepParsedTokens = false,
bool KeepSyntaxTree = false);
void addImports(
ArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptionsAndFilename>>
IM);
void addImports(ArrayRef<ImportedModuleDesc> IM);
bool hasTestableImport(const ModuleDecl *module) const;

View File

@@ -778,8 +778,7 @@ namespace {
class SourceFile::Impl {
public:
/// Only intended for use by lookupOperatorDeclForName.
static ArrayRef<std::pair<ModuleDecl::ImportedModule,
std::pair<SourceFile::ImportOptions, StringRef>>>
static ArrayRef<SourceFile::ImportedModuleDesc>
getImportsForSourceFile(const SourceFile &SF) {
return SF.Imports;
}
@@ -889,16 +888,16 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc, Identifier Name,
ImportedOperatorsMap<OP_DECL> importedOperators;
for (auto &imported : SourceFile::Impl::getImportsForSourceFile(SF)) {
// Protect against source files that contrive to import their own modules.
if (imported.first.second == ownModule)
if (imported.module.second == ownModule)
continue;
bool isExported =
imported.second.first.contains(SourceFile::ImportFlags::Exported);
imported.importOptions.contains(SourceFile::ImportFlags::Exported);
if (!includePrivate && !isExported)
continue;
Optional<OP_DECL *> maybeOp
= lookupOperatorDeclForName(imported.first.second, Loc, Name, OP_MAP);
Optional<OP_DECL *> maybeOp =
lookupOperatorDeclForName(imported.module.second, Loc, Name, OP_MAP);
if (!maybeOp)
return None;
@@ -990,21 +989,21 @@ void
SourceFile::getImportedModules(SmallVectorImpl<ModuleDecl::ImportedModule> &modules,
ModuleDecl::ImportFilter filter) const {
assert(ASTStage >= Parsed || Kind == SourceFileKind::SIL);
for (auto importPair : Imports) {
for (auto desc : Imports) {
switch (filter) {
case ModuleDecl::ImportFilter::All:
break;
case ModuleDecl::ImportFilter::Public:
if (!importPair.second.first.contains(ImportFlags::Exported))
if (!desc.importOptions.contains(ImportFlags::Exported))
continue;
break;
case ModuleDecl::ImportFilter::Private:
if (importPair.second.first.contains(ImportFlags::Exported))
if (desc.importOptions.contains(ImportFlags::Exported))
continue;
break;
}
modules.push_back(importPair.first);
modules.push_back(desc.module);
}
}
@@ -1374,17 +1373,12 @@ void SourceFile::print(ASTPrinter &Printer, const PrintOptions &PO) {
}
}
void SourceFile::addImports(
ArrayRef<std::pair<ModuleDecl::ImportedModule,
std::pair<ImportOptions, StringRef>>>
IM) {
using ImportPair = std::pair<ModuleDecl::ImportedModule,
std::pair<ImportOptions, StringRef>>;
void SourceFile::addImports(ArrayRef<ImportedModuleDesc> IM) {
if (IM.empty())
return;
ASTContext &ctx = getASTContext();
auto newBuf =
ctx.AllocateUninitialized<ImportPair>(Imports.size() + IM.size());
ctx.AllocateUninitialized<ImportedModuleDesc>(Imports.size() + IM.size());
auto iter = newBuf.begin();
iter = std::uninitialized_copy(Imports.begin(), Imports.end(), iter);
@@ -1395,20 +1389,16 @@ void SourceFile::addImports(
}
bool SourceFile::hasTestableImport(const swift::ModuleDecl *module) const {
using ImportPair = std::pair<ModuleDecl::ImportedModule,
std::pair<ImportOptions, StringRef>>;
return std::any_of(
Imports.begin(), Imports.end(), [module](ImportPair importPair) -> bool {
return importPair.first.second == module &&
importPair.second.first.contains(ImportFlags::Testable);
Imports.begin(), Imports.end(),
[module](ImportedModuleDesc desc) -> bool {
return desc.module.second == module &&
desc.importOptions.contains(ImportFlags::Testable);
});
}
bool SourceFile::hasPrivateImport(AccessLevel accessLevel,
const swift::ValueDecl *ofDecl) const {
using ImportPair = std::pair<ModuleDecl::ImportedModule,
std::pair<ImportOptions, StringRef>>;
auto *module = ofDecl->getModuleContext();
switch (accessLevel) {
case AccessLevel::Internal:
@@ -1417,9 +1407,9 @@ bool SourceFile::hasPrivateImport(AccessLevel accessLevel,
// filename does not need to match (and we don't serialize it for such
// decls).
return std::any_of(Imports.begin(), Imports.end(),
[module](ImportPair importPair) -> bool {
return importPair.first.second == module &&
importPair.second.first.contains(
[module](ImportedModuleDesc desc) -> bool {
return desc.module.second == module &&
desc.importOptions.contains(
ImportFlags::PrivateImport);
});
case AccessLevel::Open:
@@ -1447,11 +1437,11 @@ bool SourceFile::hasPrivateImport(AccessLevel accessLevel,
return false;
return std::any_of(Imports.begin(), Imports.end(),
[module, filename](ImportPair importPair) -> bool {
return importPair.first.second == module &&
importPair.second.first.contains(
[module, filename](ImportedModuleDesc desc) -> bool {
return desc.module.second == module &&
desc.importOptions.contains(
ImportFlags::PrivateImport) &&
importPair.second.second == filename;
desc.filename == filename;
});
}
@@ -1500,9 +1490,8 @@ static void performAutoImport(
// FIXME: These will be the same for most source files, but we copy them
// over and over again.
auto Imports =
std::make_pair(ModuleDecl::ImportedModule({}, M),
std::make_pair(SourceFile::ImportOptions(), StringRef()));
auto Imports = SourceFile::ImportedModuleDesc(
ModuleDecl::ImportedModule({}, M), SourceFile::ImportOptions());
SF.addImports(Imports);
}

View File

@@ -497,23 +497,24 @@ ModuleDecl *CompilerInstance::getMainModule() {
static void addAdditionalInitialImportsTo(
SourceFile *SF, const CompilerInstance::ImplicitImports &implicitImports) {
using ImportPair = std::pair<ModuleDecl::ImportedModule,
std::pair<SourceFile::ImportOptions, StringRef>>;
SmallVector<ImportPair, 4> additionalImports;
SmallVector<SourceFile::ImportedModuleDesc, 4> additionalImports;
if (implicitImports.objCModuleUnderlyingMixedFramework)
additionalImports.push_back(
{{/*accessPath=*/{},
implicitImports.objCModuleUnderlyingMixedFramework},
{SourceFile::ImportFlags::Exported, StringRef()}});
additionalImports.push_back(SourceFile::ImportedModuleDesc(
ModuleDecl::ImportedModule(
/*accessPath=*/{},
implicitImports.objCModuleUnderlyingMixedFramework),
SourceFile::ImportFlags::Exported));
if (implicitImports.headerModule)
additionalImports.push_back(
{{/*accessPath=*/{}, implicitImports.headerModule},
{SourceFile::ImportFlags::Exported, StringRef()}});
additionalImports.push_back(SourceFile::ImportedModuleDesc(
ModuleDecl::ImportedModule(/*accessPath=*/{},
implicitImports.headerModule),
SourceFile::ImportFlags::Exported));
if (!implicitImports.modules.empty()) {
for (auto &importModule : implicitImports.modules) {
additionalImports.push_back(
{{/*accessPath=*/{}, importModule}, {{}, StringRef()}});
additionalImports.push_back(SourceFile::ImportedModuleDesc(
ModuleDecl::ImportedModule(/*accessPath=*/{}, importModule),
SourceFile::ImportOptions()));
}
}

View File

@@ -171,22 +171,17 @@ typeCheckREPLInput(ModuleDecl *MostRecentModule, StringRef Name,
ModuleDecl::ImportedModule ImportOfMostRecentModule{
/*AccessPath*/{}, MostRecentModule};
REPLInputFile.addImports(
std::make_pair(ImportOfMostRecentModule,
std::make_pair(SourceFile::ImportOptions(), StringRef())));
REPLInputFile.addImports(SourceFile::ImportedModuleDesc(
ImportOfMostRecentModule, SourceFile::ImportOptions()));
SmallVector<ModuleDecl::ImportedModule, 8> Imports;
MostRecentModule->getImportedModules(Imports,
ModuleDecl::ImportFilter::Private);
if (!Imports.empty()) {
SmallVector<std::pair<ModuleDecl::ImportedModule,
std::pair<SourceFile::ImportOptions, StringRef>>,
8>
ImportsWithOptions;
SmallVector<SourceFile::ImportedModuleDesc, 8> ImportsWithOptions;
for (auto Import : Imports) {
ImportsWithOptions.emplace_back(
Import,
std::make_pair(SourceFile::ImportFlags::Exported, StringRef()));
ImportsWithOptions.emplace_back(SourceFile::ImportedModuleDesc(
Import, SourceFile::ImportFlags::Exported));
}
REPLInputFile.addImports(ImportsWithOptions);
}

View File

@@ -53,10 +53,7 @@ namespace {
return Context.Diags.diagnose(std::forward<ArgTypes>(Args)...);
}
void addImport(
SmallVectorImpl<
std::pair<ImportedModule, std::pair<ImportOptions, StringRef>>>
&imports,
void addImport(SmallVectorImpl<SourceFile::ImportedModuleDesc> &imports,
ImportDecl *ID);
/// Load a module referenced by an import statement.
@@ -170,9 +167,7 @@ static bool shouldImportSelfImportClang(const ImportDecl *ID,
}
void NameBinder::addImport(
SmallVectorImpl<std::pair<ImportedModule,
std::pair<ImportOptions, StringRef>>> &imports,
ImportDecl *ID) {
SmallVectorImpl<SourceFile::ImportedModuleDesc> &imports, ImportDecl *ID) {
if (ID->getModulePath().front().first == SF.getParentModule()->getName() &&
ID->getModulePath().size() == 1 && !shouldImportSelfImportClang(ID, SF)) {
// If the imported module name is the same as the current module,
@@ -257,11 +252,12 @@ void NameBinder::addImport(
if (privateImportAttr)
options |= SourceFile::ImportFlags::PrivateImport;
imports.push_back({{ID->getDeclPath(), M}, {options, privateImportFileName}});
imports.push_back(SourceFile::ImportedModuleDesc(
{ID->getDeclPath(), M}, options, privateImportFileName));
if (topLevelModule != M)
imports.push_back({{ID->getDeclPath(), topLevelModule},
{options, privateImportFileName}});
imports.push_back(SourceFile::ImportedModuleDesc(
{ID->getDeclPath(), topLevelModule}, options, privateImportFileName));
if (ID->getImportKind() != ImportKind::Module) {
// If we're importing a specific decl, validate the import kind.
@@ -387,8 +383,7 @@ void swift::performNameBinding(SourceFile &SF, unsigned StartElem) {
NameBinder Binder(SF);
SmallVector<std::pair<ImportedModule, std::pair<ImportOptions, StringRef>>, 8>
ImportedModules;
SmallVector<SourceFile::ImportedModuleDesc, 8> ImportedModules;
// Do a prepass over the declarations to find and load the imported modules
// and map operator decls.