Skip to content

Commit 2840f4f

Browse files
authored
Merge pull request #33264 from nkcsgexi/onone-import-scanner
DependenciesScanner: add implicitly imported modules to dependencies of Swift module interfaces
2 parents 9f6f93a + f0cf220 commit 2840f4f

File tree

5 files changed

+80
-42
lines changed

5 files changed

+80
-42
lines changed

include/swift/AST/ModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ struct InterfaceSubContextDelegate {
107107
StringRef interfacePath,
108108
StringRef outputPath,
109109
SourceLoc diagLoc,
110-
llvm::function_ref<bool(ASTContext&,ArrayRef<StringRef>,
110+
llvm::function_ref<bool(ASTContext&, ModuleDecl*, ArrayRef<StringRef>,
111111
ArrayRef<StringRef>, StringRef)> action) = 0;
112112
virtual bool runInSubCompilerInstance(StringRef moduleName,
113113
StringRef interfacePath,

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
359359
llvm::BumpPtrAllocator Allocator;
360360
llvm::StringSaver ArgSaver;
361361
std::vector<StringRef> GenericArgs;
362-
CompilerInvocation subInvocation;
362+
CompilerInvocation genericSubInvocation;
363363

364364
template<typename ...ArgTypes>
365365
InFlightDiagnostic diagnose(StringRef interfacePath,
@@ -375,7 +375,8 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
375375
}
376376
void inheritOptionsForBuildingInterface(const SearchPathOptions &SearchPathOpts,
377377
const LangOptions &LangOpts);
378-
bool extractSwiftInterfaceVersionAndArgs(SmallVectorImpl<const char *> &SubArgs,
378+
bool extractSwiftInterfaceVersionAndArgs(CompilerInvocation &subInvocation,
379+
SmallVectorImpl<const char *> &SubArgs,
379380
std::string &CompilerVersion,
380381
StringRef interfacePath,
381382
SourceLoc diagnosticLoc);
@@ -395,7 +396,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
395396
StringRef interfacePath,
396397
StringRef outputPath,
397398
SourceLoc diagLoc,
398-
llvm::function_ref<bool(ASTContext&, ArrayRef<StringRef>,
399+
llvm::function_ref<bool(ASTContext&, ModuleDecl*, ArrayRef<StringRef>,
399400
ArrayRef<StringRef>, StringRef)> action) override;
400401
bool runInSubCompilerInstance(StringRef moduleName,
401402
StringRef interfacePath,

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ class ModuleInterfaceLoaderImpl {
852852
/*serializeDependencyHashes*/false,
853853
trackSystemDependencies);
854854
// Set up a builder if we need to build the module. It'll also set up
855-
// the subinvocation we'll need to use to compute the cache paths.
855+
// the genericSubInvocation we'll need to use to compute the cache paths.
856856
ModuleInterfaceBuilder builder(
857857
ctx.SourceMgr, ctx.Diags, astDelegate, interfacePath, moduleName, cacheDir,
858858
prebuiltCacheDir,
@@ -1118,68 +1118,69 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
11181118
const SearchPathOptions &SearchPathOpts,
11191119
const LangOptions &LangOpts) {
11201120
GenericArgs.push_back("-frontend");
1121-
// Start with a SubInvocation that copies various state from our
1121+
// Start with a genericSubInvocation that copies various state from our
11221122
// invoking ASTContext.
11231123
GenericArgs.push_back("-compile-module-from-interface");
1124-
subInvocation.setTargetTriple(LangOpts.Target);
1124+
genericSubInvocation.setTargetTriple(LangOpts.Target);
11251125

1126-
auto triple = ArgSaver.save(subInvocation.getTargetTriple());
1126+
auto triple = ArgSaver.save(genericSubInvocation.getTargetTriple());
11271127
if (!triple.empty()) {
11281128
GenericArgs.push_back("-target");
11291129
GenericArgs.push_back(triple);
11301130
}
11311131

11321132
// Inherit the Swift language version
1133-
subInvocation.getLangOptions().EffectiveLanguageVersion =
1133+
genericSubInvocation.getLangOptions().EffectiveLanguageVersion =
11341134
LangOpts.EffectiveLanguageVersion;
11351135
GenericArgs.push_back("-swift-version");
1136-
GenericArgs.push_back(ArgSaver.save(subInvocation.getLangOptions()
1136+
GenericArgs.push_back(ArgSaver.save(genericSubInvocation.getLangOptions()
11371137
.EffectiveLanguageVersion.asAPINotesVersionString()));
11381138

1139-
subInvocation.setImportSearchPaths(SearchPathOpts.ImportSearchPaths);
1139+
genericSubInvocation.setImportSearchPaths(SearchPathOpts.ImportSearchPaths);
11401140
llvm::for_each(SearchPathOpts.ImportSearchPaths,
11411141
[&](const std::string &path) {
11421142
GenericArgs.push_back("-I");
11431143
GenericArgs.push_back(path);
11441144
});
1145-
subInvocation.setFrameworkSearchPaths(SearchPathOpts.FrameworkSearchPaths);
1145+
genericSubInvocation.setFrameworkSearchPaths(SearchPathOpts.FrameworkSearchPaths);
11461146
llvm::for_each(SearchPathOpts.FrameworkSearchPaths,
11471147
[&](const SearchPathOptions::FrameworkSearchPath &path) {
11481148
GenericArgs.push_back(path.IsSystem? "-Fsystem": "-F");
11491149
GenericArgs.push_back(path.Path);
11501150
});
11511151
if (!SearchPathOpts.SDKPath.empty()) {
1152-
subInvocation.setSDKPath(SearchPathOpts.SDKPath);
1152+
genericSubInvocation.setSDKPath(SearchPathOpts.SDKPath);
11531153
GenericArgs.push_back("-sdk");
11541154
GenericArgs.push_back(SearchPathOpts.SDKPath);
11551155
}
11561156

1157-
subInvocation.setInputKind(InputFileKind::SwiftModuleInterface);
1157+
genericSubInvocation.setInputKind(InputFileKind::SwiftModuleInterface);
11581158
if (!SearchPathOpts.RuntimeResourcePath.empty()) {
1159-
subInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
1159+
genericSubInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
11601160
GenericArgs.push_back("-resource-dir");
11611161
GenericArgs.push_back(SearchPathOpts.RuntimeResourcePath);
11621162
}
11631163

1164-
// Inhibit warnings from the SubInvocation since we are assuming the user
1164+
// Inhibit warnings from the genericSubInvocation since we are assuming the user
11651165
// is not in a position to fix them.
1166-
subInvocation.getDiagnosticOptions().SuppressWarnings = true;
1166+
genericSubInvocation.getDiagnosticOptions().SuppressWarnings = true;
11671167
GenericArgs.push_back("-suppress-warnings");
11681168

11691169
// Inherit this setting down so that it can affect error diagnostics (mostly
11701170
// by making them non-fatal).
1171-
subInvocation.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
1171+
genericSubInvocation.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
11721172
if (LangOpts.DebuggerSupport) {
11731173
GenericArgs.push_back("-debugger-support");
11741174
}
11751175

11761176
// Disable this; deinitializers always get printed with `@objc` even in
11771177
// modules that don't import Foundation.
1178-
subInvocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
1178+
genericSubInvocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
11791179
GenericArgs.push_back("-disable-objc-attr-requires-foundation-module");
11801180
}
11811181

11821182
bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
1183+
CompilerInvocation &subInvocation,
11831184
SmallVectorImpl<const char *> &SubArgs,
11841185
std::string &CompilerVersion,
11851186
StringRef interfacePath,
@@ -1251,7 +1252,7 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
12511252
}
12521253

12531254
void InterfaceSubContextDelegateImpl::addExtraClangArg(StringRef arg) {
1254-
subInvocation.getClangImporterOptions().ExtraArgs.push_back(arg);
1255+
genericSubInvocation.getClangImporterOptions().ExtraArgs.push_back(arg);
12551256
GenericArgs.push_back("-Xcc");
12561257
GenericArgs.push_back(ArgSaver.save(arg));
12571258
}
@@ -1268,36 +1269,36 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
12681269
StringRef prebuiltCachePath,
12691270
bool serializeDependencyHashes,
12701271
bool trackSystemDependencies): SM(SM), Diags(Diags), ArgSaver(Allocator) {
1271-
subInvocation.setMainExecutablePath(LoaderOpts.mainExecutablePath);
1272+
genericSubInvocation.setMainExecutablePath(LoaderOpts.mainExecutablePath);
12721273
inheritOptionsForBuildingInterface(searchPathOpts, langOpts);
12731274
// Configure front-end input.
1274-
auto &SubFEOpts = subInvocation.getFrontendOptions();
1275+
auto &SubFEOpts = genericSubInvocation.getFrontendOptions();
12751276
SubFEOpts.RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
12761277
if (!moduleCachePath.empty()) {
1277-
subInvocation.setClangModuleCachePath(moduleCachePath);
1278+
genericSubInvocation.setClangModuleCachePath(moduleCachePath);
12781279
GenericArgs.push_back("-module-cache-path");
12791280
GenericArgs.push_back(moduleCachePath);
12801281
}
12811282
if (!prebuiltCachePath.empty()) {
1282-
subInvocation.getFrontendOptions().PrebuiltModuleCachePath =
1283+
genericSubInvocation.getFrontendOptions().PrebuiltModuleCachePath =
12831284
prebuiltCachePath.str();
12841285
GenericArgs.push_back("-prebuilt-module-cache-path");
12851286
GenericArgs.push_back(prebuiltCachePath);
12861287
}
12871288
if (trackSystemDependencies) {
1288-
subInvocation.getFrontendOptions().IntermoduleDependencyTracking =
1289+
genericSubInvocation.getFrontendOptions().IntermoduleDependencyTracking =
12891290
IntermoduleDepTrackingMode::IncludeSystem;
12901291
GenericArgs.push_back("-track-system-dependencies");
12911292
} else {
12921293
// Always track at least the non-system dependencies for interface building.
1293-
subInvocation.getFrontendOptions().IntermoduleDependencyTracking =
1294+
genericSubInvocation.getFrontendOptions().IntermoduleDependencyTracking =
12941295
IntermoduleDepTrackingMode::ExcludeSystem;
12951296
}
12961297
if (LoaderOpts.disableImplicitSwiftModule) {
1297-
subInvocation.getFrontendOptions().DisableImplicitModules = true;
1298+
genericSubInvocation.getFrontendOptions().DisableImplicitModules = true;
12981299
GenericArgs.push_back("-disable-implicit-swift-modules");
12991300
}
1300-
subInvocation.getSearchPathOptions().ExplicitSwiftModules =
1301+
genericSubInvocation.getSearchPathOptions().ExplicitSwiftModules =
13011302
searchPathOpts.ExplicitSwiftModules;
13021303
// Dependencies scanner shouldn't know any explict Swift modules to use.
13031304
// Adding these argumnets may not be necessary.
@@ -1309,7 +1310,7 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
13091310
// Pass down -explicit-swift-module-map-file
13101311
// FIXME: we shouldn't need this. Remove it?
13111312
StringRef explictSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
1312-
subInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
1313+
genericSubInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
13131314
explictSwiftModuleMap;
13141315
if (!explictSwiftModuleMap.empty()) {
13151316
GenericArgs.push_back("-explicit-swift-module-map-file");
@@ -1329,19 +1330,19 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
13291330
// required by sourcekitd.
13301331
auto &Opts = clangImporter->getClangInstance().getPreprocessorOpts();
13311332
if (Opts.DetailedRecord) {
1332-
subInvocation.getClangImporterOptions().DetailedPreprocessingRecord = true;
1333+
genericSubInvocation.getClangImporterOptions().DetailedPreprocessingRecord = true;
13331334
}
13341335
}
13351336

1336-
// Tell the subinvocation to serialize dependency hashes if asked to do so.
1337-
auto &frontendOpts = subInvocation.getFrontendOptions();
1337+
// Tell the genericSubInvocation to serialize dependency hashes if asked to do so.
1338+
auto &frontendOpts = genericSubInvocation.getFrontendOptions();
13381339
frontendOpts.SerializeModuleInterfaceDependencyHashes =
13391340
serializeDependencyHashes;
13401341
if (serializeDependencyHashes) {
13411342
GenericArgs.push_back("-serialize-module-interface-dependency-hashes");
13421343
}
13431344

1344-
// Tell the subinvocation to remark on rebuilds from an interface if asked
1345+
// Tell the genericSubInvocation to remark on rebuilds from an interface if asked
13451346
// to do so.
13461347
frontendOpts.RemarkOnRebuildFromModuleInterface =
13471348
LoaderOpts.remarkOnRebuildFromInterface;
@@ -1355,14 +1356,14 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
13551356
(void)llvm::sys::fs::create_directories(moduleCachePath);
13561357
}
13571358

1358-
/// Calculate an output filename in \p SubInvocation's cache path that
1359+
/// Calculate an output filename in \p genericSubInvocation's cache path that
13591360
/// includes a hash of relevant key data.
13601361
StringRef InterfaceSubContextDelegateImpl::computeCachedOutputPath(
13611362
StringRef moduleName,
13621363
StringRef useInterfacePath,
13631364
llvm::SmallString<256> &OutPath,
13641365
StringRef &CacheHash) {
1365-
OutPath = subInvocation.getClangModuleCachePath();
1366+
OutPath = genericSubInvocation.getClangModuleCachePath();
13661367
llvm::sys::path::append(OutPath, moduleName);
13671368
OutPath.append("-");
13681369
auto hashStart = OutPath.size();
@@ -1387,7 +1388,7 @@ StringRef InterfaceSubContextDelegateImpl::computeCachedOutputPath(
13871388
std::string
13881389
InterfaceSubContextDelegateImpl::getCacheHash(StringRef useInterfacePath) {
13891390
auto normalizedTargetTriple =
1390-
getTargetSpecificModuleTriple(subInvocation.getLangOptions().Target);
1391+
getTargetSpecificModuleTriple(genericSubInvocation.getLangOptions().Target);
13911392

13921393
llvm::hash_code H = hash_combine(
13931394
// Start with the compiler version (which will be either tag names or
@@ -1411,11 +1412,11 @@ InterfaceSubContextDelegateImpl::getCacheHash(StringRef useInterfacePath) {
14111412

14121413
// The SDK path is going to affect how this module is imported, so
14131414
// include it.
1414-
subInvocation.getSDKPath(),
1415+
genericSubInvocation.getSDKPath(),
14151416

14161417
// Whether or not we're tracking system dependencies affects the
14171418
// invalidation behavior of this cache item.
1418-
subInvocation.getFrontendOptions().shouldTrackSystemDependencies());
1419+
genericSubInvocation.getFrontendOptions().shouldTrackSystemDependencies());
14191420

14201421
return llvm::APInt(64, H).toString(36, /*Signed=*/false);
14211422
}
@@ -1424,11 +1425,13 @@ bool InterfaceSubContextDelegateImpl::runInSubContext(StringRef moduleName,
14241425
StringRef interfacePath,
14251426
StringRef outputPath,
14261427
SourceLoc diagLoc,
1427-
llvm::function_ref<bool(ASTContext&, ArrayRef<StringRef>,
1428+
llvm::function_ref<bool(ASTContext&, ModuleDecl*, ArrayRef<StringRef>,
14281429
ArrayRef<StringRef>, StringRef)> action) {
14291430
return runInSubCompilerInstance(moduleName, interfacePath, outputPath, diagLoc,
14301431
[&](SubCompilerInstanceInfo &info){
1431-
return action(info.Instance->getASTContext(), info.BuildArguments,
1432+
return action(info.Instance->getASTContext(),
1433+
info.Instance->getMainModule(),
1434+
info.BuildArguments,
14321435
info.ExtraPCMArgs,
14331436
info.Hash);
14341437
});
@@ -1439,6 +1442,10 @@ bool InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleN
14391442
StringRef outputPath,
14401443
SourceLoc diagLoc,
14411444
llvm::function_ref<bool(SubCompilerInstanceInfo&)> action) {
1445+
// We are about to mess up the compiler invocation by using the compiler
1446+
// arguments in the textual interface file. So copy to use a new compiler
1447+
// invocation.
1448+
CompilerInvocation subInvocation = genericSubInvocation;
14421449
std::vector<StringRef> BuildArgs(GenericArgs.begin(), GenericArgs.end());
14431450
assert(BuildArgs.size() == GenericArgs.size());
14441451
// Configure inputs
@@ -1473,7 +1480,8 @@ bool InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleN
14731480
std::string CompilerVersion;
14741481
// Extract compiler arguments from the interface file and use them to configure
14751482
// the compiler invocation.
1476-
if (extractSwiftInterfaceVersionAndArgs(SubArgs,
1483+
if (extractSwiftInterfaceVersionAndArgs(subInvocation,
1484+
SubArgs,
14771485
CompilerVersion,
14781486
interfacePath,
14791487
diagLoc)) {

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "swift/AST/DiagnosticsFrontend.h"
1616
#include "swift/AST/ModuleDependencies.h"
1717
#include "swift/AST/SourceFile.h"
18+
#include "swift/AST/TypeCheckRequests.h"
1819
#include "swift/Basic/FileTypes.h"
1920
#include "swift/Frontend/ModuleInterfaceLoader.h"
2021
#include "swift/Serialization/SerializedModuleLoader.h"
@@ -184,8 +185,10 @@ ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
184185
moduleInterfacePath.str(),
185186
StringRef(),
186187
SourceLoc(),
187-
[&](ASTContext &Ctx, ArrayRef<StringRef> Args,
188+
[&](ASTContext &Ctx, ModuleDecl *mainMod,
189+
ArrayRef<StringRef> Args,
188190
ArrayRef<StringRef> PCMArgs, StringRef Hash) {
191+
assert(mainMod);
189192
std::string InPath = moduleInterfacePath.str();
190193
auto compiledCandidates = getCompiledCandidates(Ctx, moduleName.str(),
191194
InPath);
@@ -211,6 +214,13 @@ ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
211214
// Walk the source file to find the import declarations.
212215
llvm::StringSet<> alreadyAddedModules;
213216
Result->addModuleDependencies(*sourceFile, alreadyAddedModules);
217+
218+
// Collect implicitly imported modules in case they are not explicitly
219+
// printed in the interface file, e.g. SwiftOnoneSupport.
220+
auto &imInfo = mainMod->getImplicitImportInfo();
221+
for (auto name: imInfo.ModuleNames) {
222+
Result->addModuleDependency(name.str(), &alreadyAddedModules);
223+
}
214224
return false;
215225
});
216226

test/ScanDependencies/module_deps.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ import SubE
122122
// CHECK-NEXT: },
123123
// CHECK-NEXT: {
124124
// CHECK-NEXT: "clang": "G"
125+
// CHECK-NEXT: },
126+
// CHECK-NEXT: {
127+
// CHECK-NEXT: "swift": "SwiftOnoneSupport"
125128
// CHECK-NEXT: }
126129
// CHECK-NEXT: ],
127130
// CHECK-NEXT: "details": {
@@ -148,6 +151,22 @@ import SubE
148151
// CHECK-NEXT: {
149152
// CHECK-NEXT: "clang": "SwiftShims"
150153

154+
/// --------Swift module F
155+
// CHECK: "modulePath": "F.swiftmodule",
156+
// CHECK-NEXT: "sourceFiles": [
157+
// CHECK-NEXT: ],
158+
// CHECK-NEXT: "directDependencies": [
159+
// CHECK-NEXT: {
160+
// CHECK-NEXT: "swift": "Swift"
161+
// CHECK-NEXT: },
162+
// CHECK-NEXT: {
163+
// CHECK-NEXT: "clang": "F"
164+
// CHECK-NEXT: },
165+
// CHECK-NEXT: {
166+
// CHECK-NEXT: "swift": "SwiftOnoneSupport"
167+
// CHECK-NEXT: }
168+
// CHECK-NEXT: ],
169+
151170
/// --------Swift module A
152171
// CHECK-LABEL: "modulePath": "A.swiftmodule",
153172

0 commit comments

Comments
 (0)