Skip to content

Commit ce65b15

Browse files
committed
[Dependency Scanning] Keep track of whether a given Swift 'import' statement is '@_exported'
1 parent a756e21 commit ce65b15

File tree

8 files changed

+74
-52
lines changed

8 files changed

+74
-52
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,14 @@ struct ScannerImportStatementInfo {
152152
uint32_t columnNumber;
153153
};
154154

155-
ScannerImportStatementInfo(std::string importIdentifier)
156-
: importLocations(), importIdentifier(importIdentifier) {}
155+
ScannerImportStatementInfo(std::string importIdentifier, bool isExported)
156+
: importLocations(), importIdentifier(importIdentifier),
157+
isExported(isExported) {}
157158

158-
ScannerImportStatementInfo(std::string importIdentifier,
159+
ScannerImportStatementInfo(std::string importIdentifier, bool isExported,
159160
ImportDiagnosticLocationInfo location)
160-
: importLocations({location}), importIdentifier(importIdentifier) {}
161+
: importLocations({location}), importIdentifier(importIdentifier),
162+
isExported(isExported) {}
161163

162164
void addImportLocation(ImportDiagnosticLocationInfo location) {
163165
importLocations.push_back(location);
@@ -167,6 +169,8 @@ struct ScannerImportStatementInfo {
167169
SmallVector<ImportDiagnosticLocationInfo, 4> importLocations;
168170
/// Imported module string. e.g. "Foo.Bar" in 'import Foo.Bar'
169171
std::string importIdentifier;
172+
/// Is this an @_exported import
173+
bool isExported;
170174
};
171175

172176
/// Base class for the variant storage of ModuleDependencyInfo.
@@ -909,7 +913,7 @@ class ModuleDependencyInfo {
909913

910914
/// Add a dependency on the given module, if it was not already in the set.
911915
void
912-
addOptionalModuleImport(StringRef module,
916+
addOptionalModuleImport(StringRef module, bool isExported,
913917
llvm::StringSet<> *alreadyAddedModules = nullptr);
914918

915919
/// Add all of the module imports in the given source
@@ -919,13 +923,13 @@ class ModuleDependencyInfo {
919923
const SourceManager *sourceManager);
920924

921925
/// Add a dependency on the given module, if it was not already in the set.
922-
void addModuleImport(ImportPath::Module module,
926+
void addModuleImport(ImportPath::Module module, bool isExported,
923927
llvm::StringSet<> *alreadyAddedModules = nullptr,
924928
const SourceManager *sourceManager = nullptr,
925929
SourceLoc sourceLocation = SourceLoc());
926930

927931
/// Add a dependency on the given module, if it was not already in the set.
928-
void addModuleImport(StringRef module,
932+
void addModuleImport(StringRef module, bool isExported,
929933
llvm::StringSet<> *alreadyAddedModules = nullptr,
930934
const SourceManager *sourceManager = nullptr,
931935
SourceLoc sourceLocation = SourceLoc());

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ using IsFrameworkField = BCFixed<1>;
5757
using IsSystemField = BCFixed<1>;
5858
/// A bit that indicates whether or not a module is that of a static archive
5959
using IsStaticField = BCFixed<1>;
60+
/// A bit taht indicates whether or not an import statement is @_exported
61+
using IsExportedImport = BCFixed<1>;
62+
63+
/// Source location fields
64+
using LineNumberField = BCFixed<32>;
65+
using ColumnNumberField = BCFixed<32>;
66+
6067

6168
/// Arrays of various identifiers, distinguished for readability
6269
using IdentifierIDArryField = llvm::BCArray<IdentifierIDField>;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
169169

170170
struct BinaryModuleImports {
171171
llvm::StringSet<> moduleImports;
172+
llvm::StringSet<> exportedModules;
172173
std::string headerImport;
173174
};
174175

@@ -183,7 +184,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
183184

184185
/// If the module has a package name matching the one
185186
/// specified, return a set of package-only imports for this module.
186-
static llvm::ErrorOr<llvm::StringSet<>>
187+
static llvm::ErrorOr<std::vector<ScannerImportStatementInfo>>
187188
getMatchingPackageOnlyImportsOfModule(Twine modulePath,
188189
bool isFramework,
189190
bool isRequiredOSSAModules,

lib/AST/ModuleDependencies.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,16 @@ bool ModuleDependencyInfo::isTestableImport(StringRef moduleName) const {
115115
}
116116

117117
void ModuleDependencyInfo::addOptionalModuleImport(
118-
StringRef module, llvm::StringSet<> *alreadyAddedModules) {
118+
StringRef module, bool isExported, llvm::StringSet<> *alreadyAddedModules) {
119119
if (!alreadyAddedModules || alreadyAddedModules->insert(module).second)
120-
storage->optionalModuleImports.push_back(module.str());
120+
storage->optionalModuleImports.push_back({module.str(), isExported});
121121
}
122122

123123
void ModuleDependencyInfo::addModuleImport(
124-
StringRef module, llvm::StringSet<> *alreadyAddedModules,
124+
StringRef module, bool isExported, llvm::StringSet<> *alreadyAddedModules,
125125
const SourceManager *sourceManager, SourceLoc sourceLocation) {
126126
auto scannerImportLocToDiagnosticLocInfo =
127-
[&sourceManager](SourceLoc sourceLocation) {
127+
[&sourceManager, isExported](SourceLoc sourceLocation) {
128128
auto lineAndColumnNumbers =
129129
sourceManager->getLineAndColumnInBuffer(sourceLocation);
130130
return ScannerImportStatementInfo::ImportDiagnosticLocationInfo(
@@ -135,14 +135,16 @@ void ModuleDependencyInfo::addModuleImport(
135135
sourceManager->isOwning(sourceLocation);
136136

137137
if (alreadyAddedModules && alreadyAddedModules->contains(module)) {
138-
if (validSourceLocation) {
139-
// Find a prior import of this module and add import location
140-
for (auto &existingImport : storage->moduleImports) {
141-
if (existingImport.importIdentifier == module) {
138+
// Find a prior import of this module and add import location
139+
// and adjust whether or not this module is ever imported as exported
140+
for (auto &existingImport : storage->moduleImports) {
141+
if (existingImport.importIdentifier == module) {
142+
if (validSourceLocation) {
142143
existingImport.addImportLocation(
143-
scannerImportLocToDiagnosticLocInfo(sourceLocation));
144-
break;
144+
scannerImportLocToDiagnosticLocInfo(sourceLocation));
145145
}
146+
existingImport.isExported |= isExported;
147+
break;
146148
}
147149
}
148150
} else {
@@ -151,15 +153,15 @@ void ModuleDependencyInfo::addModuleImport(
151153

152154
if (validSourceLocation)
153155
storage->moduleImports.push_back(ScannerImportStatementInfo(
154-
module.str(), scannerImportLocToDiagnosticLocInfo(sourceLocation)));
156+
module.str(), isExported, scannerImportLocToDiagnosticLocInfo(sourceLocation)));
155157
else
156158
storage->moduleImports.push_back(
157-
ScannerImportStatementInfo(module.str()));
159+
ScannerImportStatementInfo(module.str(), isExported));
158160
}
159161
}
160162

161163
void ModuleDependencyInfo::addModuleImport(
162-
ImportPath::Module module, llvm::StringSet<> *alreadyAddedModules,
164+
ImportPath::Module module, bool isExported, llvm::StringSet<> *alreadyAddedModules,
163165
const SourceManager *sourceManager, SourceLoc sourceLocation) {
164166
std::string ImportedModuleName = module.front().Item.str().str();
165167
auto submodulePath = module.getSubmodulePath();
@@ -172,7 +174,7 @@ void ModuleDependencyInfo::addModuleImport(
172174
alreadyAddedModules);
173175
}
174176

175-
addModuleImport(ImportedModuleName, alreadyAddedModules,
177+
addModuleImport(ImportedModuleName, isExported, alreadyAddedModules,
176178
sourceManager, sourceLocation);
177179
}
178180

@@ -201,7 +203,8 @@ void ModuleDependencyInfo::addModuleImports(
201203
importDecl->isExported()))
202204
continue;
203205

204-
addModuleImport(realPath, &alreadyAddedModules, sourceManager,
206+
addModuleImport(realPath, importDecl->isExported(),
207+
&alreadyAddedModules, sourceManager,
205208
importDecl->getLoc());
206209

207210
// Additionally, keep track of which dependencies of a Source

lib/DependencyScan/ModuleDependencyCacheSerialization.cpp

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,6 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
228228
currentContextHashID = contextHashID;
229229
auto importStrings = getStringArray(moduleImportsArrayID);
230230
auto optionalImportStrings = getStringArray(optionalModuleImportsArrayID);
231-
if (importStrings.has_value()) {
232-
for (const auto &is : importStrings.value())
233-
currentModuleImports.push_back(is);
234-
}
235-
236-
if (optionalImportStrings.has_value()) {
237-
for (const auto &ois : optionalImportStrings.value())
238-
currentOptionalModuleImports.push_back(ois);
239-
}
240-
241231
auto optionalCurrentModuleDependencyIDs = getModuleDependencyIDArray(moduleDependencyIDArrayID);
242232
if (!optionalCurrentModuleDependencyIDs)
243233
llvm::report_fatal_error("Bad direct dependencies: no qualified dependencies");
@@ -319,10 +309,10 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
319309

320310
// Add imports of this module
321311
for (const auto &moduleName : currentModuleImports)
322-
moduleDep.addModuleImport(moduleName.importIdentifier);
312+
moduleDep.addModuleImport(moduleName.importIdentifier, false);
323313
// Add optional imports of this module
324314
for (const auto &moduleName : currentOptionalModuleImports)
325-
moduleDep.addOptionalModuleImport(moduleName.importIdentifier);
315+
moduleDep.addOptionalModuleImport(moduleName.importIdentifier, false);
326316

327317
// Add qualified dependencies of this module
328318
std::vector<ModuleDependencyID> swiftDeps;
@@ -442,10 +432,10 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
442432

443433
// Add dependencies of this module
444434
for (const auto &moduleName : currentModuleImports)
445-
moduleDep.addModuleImport(moduleName.importIdentifier);
435+
moduleDep.addModuleImport(moduleName.importIdentifier, false);
446436
// Add optional imports of this module
447437
for (const auto &moduleName : currentOptionalModuleImports)
448-
moduleDep.addOptionalModuleImport(moduleName.importIdentifier);
438+
moduleDep.addOptionalModuleImport(moduleName.importIdentifier, false);
449439

450440
// Add bridging header file path
451441
if (bridgingHeaderFileID != 0) {
@@ -600,10 +590,10 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
600590

601591
// Add dependencies of this module
602592
for (const auto &moduleName : currentModuleImports)
603-
moduleDep.addModuleImport(moduleName.importIdentifier);
593+
moduleDep.addModuleImport(moduleName.importIdentifier, false);
604594
// Add optional imports of this module
605595
for (const auto &moduleName : currentOptionalModuleImports)
606-
moduleDep.addOptionalModuleImport(moduleName.importIdentifier);
596+
moduleDep.addOptionalModuleImport(moduleName.importIdentifier, false);
607597

608598
cache.recordDependency(currentModuleName, std::move(moduleDep),
609599
getContextHash());
@@ -663,10 +653,10 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
663653

664654
// Add dependencies of this module
665655
for (const auto &moduleName : currentModuleImports)
666-
moduleDep.addModuleImport(moduleName.importIdentifier);
656+
moduleDep.addModuleImport(moduleName.importIdentifier, false);
667657
// Add optional imports of this module
668658
for (const auto &moduleName : currentOptionalModuleImports)
669-
moduleDep.addOptionalModuleImport(moduleName.importIdentifier);
659+
moduleDep.addOptionalModuleImport(moduleName.importIdentifier, false);
670660

671661
cache.recordDependency(currentModuleName, std::move(moduleDep),
672662
getContextHash());

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,13 +376,14 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) {
376376
break;
377377

378378
case ImplicitStdlibKind::Stdlib:
379-
mainDependencies.addModuleImport("Swift", &alreadyAddedModules);
379+
mainDependencies.addModuleImport("Swift", false, &alreadyAddedModules);
380380
break;
381381
}
382382

383383
// Add any implicit module names.
384384
for (const auto &import : importInfo.AdditionalUnloadedImports) {
385385
mainDependencies.addModuleImport(import.module.getModulePath(),
386+
import.options.contains(ImportFlags::Exported),
386387
&alreadyAddedModules,
387388
&ScanASTContext.SourceMgr);
388389
}
@@ -391,6 +392,7 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) {
391392
for (const auto &import : importInfo.AdditionalImports) {
392393
mainDependencies.addModuleImport(
393394
import.module.importedModule->getNameStr(),
395+
import.options.contains(ImportFlags::Exported),
394396
&alreadyAddedModules);
395397
}
396398

@@ -403,6 +405,7 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) {
403405
// add a dependency with the same name to trigger the search.
404406
if (importInfo.ShouldImportUnderlyingModule) {
405407
mainDependencies.addModuleImport(mainModule->getName().str(),
408+
/* isExported */ true,
406409
&alreadyAddedModules);
407410
}
408411

@@ -412,6 +415,7 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) {
412415
for (const auto &tbdSymbolModule :
413416
ScanCompilerInvocation.getTBDGenOptions().embedSymbolsFromModules) {
414417
mainDependencies.addModuleImport(tbdSymbolModule,
418+
/* isExported */ false,
415419
&alreadyAddedModules);
416420
}
417421
}
@@ -1278,7 +1282,8 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
12781282
ModuleDependencyInfo::forSwiftSourceModule({}, {}, {}, {});
12791283
std::for_each(newOverlays.begin(), newOverlays.end(),
12801284
[&](Identifier modName) {
1281-
dummyMainDependencies.addModuleImport(modName.str());
1285+
dummyMainDependencies.addModuleImport(modName.str(),
1286+
/* isExported */ false);
12821287
});
12831288

12841289
// Record the dummy main module's direct dependencies. The dummy main module

lib/Serialization/ScanningLoaders.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
269269
auto &imInfo = mainMod->getImplicitImportInfo();
270270
for (auto import : imInfo.AdditionalUnloadedImports) {
271271
Result->addModuleImport(import.module.getModulePath(),
272+
import.options.contains(ImportFlags::Exported),
272273
&alreadyAddedModules, &Ctx.SourceMgr);
273274
}
274275

@@ -294,8 +295,9 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
294295
return adjacentBinaryModulePackageOnlyImports.getError();
295296

296297
for (const auto &requiredImport : *adjacentBinaryModulePackageOnlyImports)
297-
if (!alreadyAddedModules.contains(requiredImport.getKey()))
298-
Result->addModuleImport(requiredImport.getKey(),
298+
if (!alreadyAddedModules.contains(requiredImport.importIdentifier))
299+
Result->addModuleImport(requiredImport.importIdentifier,
300+
requiredImport.isExported,
299301
&alreadyAddedModules);
300302
}
301303
}

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ SerializedModuleLoaderBase::getModuleName(ASTContext &Ctx, StringRef modulePath,
304304
return ModuleFile::getModuleName(Ctx, modulePath, Name);
305305
}
306306

307-
llvm::ErrorOr<llvm::StringSet<>>
307+
llvm::ErrorOr<std::vector<ScannerImportStatementInfo>>
308308
SerializedModuleLoaderBase::getMatchingPackageOnlyImportsOfModule(
309309
Twine modulePath, bool isFramework, bool isRequiredOSSAModules,
310310
StringRef SDKName, StringRef packageName, llvm::vfs::FileSystem *fileSystem,
@@ -313,7 +313,7 @@ SerializedModuleLoaderBase::getMatchingPackageOnlyImportsOfModule(
313313
if (!moduleBuf)
314314
return moduleBuf.getError();
315315

316-
llvm::StringSet<> importedModuleNames;
316+
std::vector<ScannerImportStatementInfo> importedModuleNames;
317317
// Load the module file without validation.
318318
std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
319319
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
@@ -336,7 +336,7 @@ SerializedModuleLoaderBase::getMatchingPackageOnlyImportsOfModule(
336336
if (dotPos != std::string::npos)
337337
moduleName = moduleName.slice(0, dotPos);
338338

339-
importedModuleNames.insert(moduleName);
339+
importedModuleNames.push_back({moduleName.str(), dependency.isExported()});
340340
}
341341

342342
return importedModuleNames;
@@ -442,6 +442,7 @@ SerializedModuleLoaderBase::getImportsOfModule(
442442
ModuleLoadingBehavior transitiveBehavior, StringRef packageName,
443443
bool isTestableImport) {
444444
llvm::StringSet<> importedModuleNames;
445+
llvm::StringSet<> importedExportedModuleNames;
445446
std::string importedHeader = "";
446447
for (const auto &dependency : loadedModuleFile.getDependencies()) {
447448
if (dependency.isHeader()) {
@@ -476,9 +477,12 @@ SerializedModuleLoaderBase::getImportsOfModule(
476477
moduleName = "std";
477478

478479
importedModuleNames.insert(moduleName);
480+
if (dependency.isExported())
481+
importedExportedModuleNames.insert(moduleName);
479482
}
480483

481484
return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames,
485+
importedExportedModuleNames,
482486
importedHeader};
483487
}
484488

@@ -553,17 +557,23 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
553557
auto importedModuleSet = binaryModuleImports->moduleImports;
554558
std::vector<ScannerImportStatementInfo> moduleImports;
555559
moduleImports.reserve(importedModuleSet.size());
556-
llvm::transform(
557-
importedModuleSet.keys(), std::back_inserter(moduleImports),
558-
[](llvm::StringRef N) { return ScannerImportStatementInfo(N.str()); });
560+
llvm::transform(importedModuleSet.keys(), std::back_inserter(moduleImports),
561+
[&binaryModuleImports](llvm::StringRef N) {
562+
return ScannerImportStatementInfo(
563+
N.str(),
564+
binaryModuleImports->exportedModules.contains(N));
565+
});
559566

560567
auto importedHeader = binaryModuleImports->headerImport;
561568
auto &importedOptionalModuleSet = binaryModuleOptionalImports->moduleImports;
569+
auto &importedExportedOptionalModuleSet =
570+
binaryModuleOptionalImports->exportedModules;
562571
std::vector<ScannerImportStatementInfo> optionalModuleImports;
563572
for (const auto optionalImportedModule : importedOptionalModuleSet.keys())
564573
if (!importedModuleSet.contains(optionalImportedModule))
565574
optionalModuleImports.push_back(
566-
ScannerImportStatementInfo(optionalImportedModule.str()));
575+
{optionalImportedModule.str(),
576+
importedExportedOptionalModuleSet.contains(optionalImportedModule)});
567577

568578
std::vector<LinkLibrary> linkLibraries;
569579
{

0 commit comments

Comments
 (0)