Skip to content

Commit a90d3e2

Browse files
committed
Factor out reading flags/version from an interface from setting up a Compiler sub-instance
1 parent 7fd2a29 commit a90d3e2

File tree

4 files changed

+106
-67
lines changed

4 files changed

+106
-67
lines changed

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
453453
const StringRef backupInterfaceDir, const StringRef prebuiltCachePath,
454454
const StringRef ABIDescriptorPath, StringRef interfacePath,
455455
StringRef outputPath, bool ShouldSerializeDeps,
456-
ArrayRef<std::string> CompiledCandidates, StringRef CompilerVersion,
456+
ArrayRef<std::string> CompiledCandidates,
457457
DependencyTracker *tracker = nullptr);
458458
};
459459

@@ -473,13 +473,8 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
473473
InFlightDiagnostic diagnose(StringRef interfacePath,
474474
SourceLoc diagnosticLoc,
475475
Diag<ArgTypes...> ID,
476-
typename detail::PassArgument<ArgTypes>::type... Args) {
477-
SourceLoc loc = diagnosticLoc;
478-
if (diagnosticLoc.isInvalid()) {
479-
// Diagnose this inside the interface file, if possible.
480-
loc = SM.getLocFromExternalSource(interfacePath, 1, 1);
481-
}
482-
return Diags->diagnose(loc, ID, std::move(Args)...);
476+
typename detail::PassArgument<ArgTypes>::type... Args) {
477+
return InterfaceSubContextDelegateImpl::diagnose(interfacePath, diagnosticLoc, SM, Diags, ID, std::move(Args)...);
483478
}
484479
void
485480
inheritOptionsForBuildingInterface(const SearchPathOptions &SearchPathOpts,
@@ -500,6 +495,22 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
500495
StringRef backupModuleInterfaceDir,
501496
bool serializeDependencyHashes, bool trackSystemDependencies,
502497
RequireOSSAModules_t requireOSSAModules);
498+
499+
template<typename ...ArgTypes>
500+
static InFlightDiagnostic diagnose(StringRef interfacePath,
501+
SourceLoc diagnosticLoc,
502+
SourceManager &SM,
503+
DiagnosticEngine *Diags,
504+
Diag<ArgTypes...> ID,
505+
typename detail::PassArgument<ArgTypes>::type... Args) {
506+
SourceLoc loc = diagnosticLoc;
507+
if (diagnosticLoc.isInvalid()) {
508+
// Diagnose this inside the interface file, if possible.
509+
loc = SM.getLocFromExternalSource(interfacePath, 1, 1);
510+
}
511+
return Diags->diagnose(loc, ID, std::move(Args)...);
512+
}
513+
503514
std::error_code runInSubContext(StringRef moduleName,
504515
StringRef interfacePath,
505516
StringRef outputPath,

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ bool ArgsToFrontendOptionsConverter::convert(
9393
if (Args.hasArg(OPT_track_system_dependencies)) {
9494
Opts.IntermoduleDependencyTracking =
9595
IntermoduleDepTrackingMode::IncludeSystem;
96+
} else if (Args.hasArg(OPT_explicit_interface_module_build)) {
97+
// Always track at least the non-system dependencies for interface building.
98+
Opts.IntermoduleDependencyTracking =
99+
IntermoduleDepTrackingMode::ExcludeSystem;
96100
}
97101

98102
if (const Arg *A = Args.getLastArg(OPT_bad_file_descriptor_retry_count)) {
@@ -624,7 +628,7 @@ bool ArgsToFrontendOptionsConverter::checkBuildFromInterfaceOnlyOptions()
624628
if (Opts.RequestedAction != FrontendOptions::ActionType::CompileModuleFromInterface &&
625629
Opts.ExplicitInterfaceBuild) {
626630
Diags.diagnose(SourceLoc(),
627-
diag::error_cannot_ignore_interface_options_in_mode);
631+
diag::error_cannot_explicit_interface_build_in_mode);
628632
return true;
629633
}
630634
return false;

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,32 +181,29 @@ bool ExplicitModuleInterfaceBuilder::collectDepsForSerialization(
181181
}
182182

183183
std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
184-
StringRef interfacePath, StringRef outputPath, bool ShouldSerializeDeps,
184+
StringRef InterfacePath, StringRef OutputPath, bool ShouldSerializeDeps,
185185
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
186-
ArrayRef<std::string> compiledCandidates,
186+
ArrayRef<std::string> CompiledCandidates,
187187
StringRef CompilerVersion) {
188188
auto Invocation = Instance.getInvocation();
189189
// Try building forwarding module first. If succeed, return.
190190
if (Instance.getASTContext()
191191
.getModuleInterfaceChecker()
192-
->tryEmitForwardingModule(Invocation.getModuleName(), interfacePath,
193-
compiledCandidates, outputPath)) {
192+
->tryEmitForwardingModule(Invocation.getModuleName(), InterfacePath,
193+
CompiledCandidates, OutputPath)) {
194194
return std::error_code();
195195
}
196196
FrontendOptions &FEOpts = Invocation.getFrontendOptions();
197197
bool isTypeChecking =
198198
(FEOpts.RequestedAction == FrontendOptions::ActionType::Typecheck);
199199
const auto &InputInfo = FEOpts.InputsAndOutputs.firstInput();
200200
StringRef InPath = InputInfo.getFileName();
201-
const auto &OutputInfo =
202-
InputInfo.getPrimarySpecificPaths().SupplementaryOutputs;
203-
StringRef OutPath = OutputInfo.ModuleOutputPath;
204201

205202
// Build the .swiftmodule; this is a _very_ abridged version of the logic
206203
// in performCompile in libFrontendTool, specialized, to just the one
207204
// module-serialization task we're trying to do here.
208205
LLVM_DEBUG(llvm::dbgs() << "Setting up instance to compile " << InPath
209-
<< " to " << OutPath << "\n");
206+
<< " to " << OutputPath << "\n");
210207

211208
LLVM_DEBUG(llvm::dbgs() << "Performing sema\n");
212209
if (isTypeChecking && FEOpts.DowngradeInterfaceVerificationError) {
@@ -262,7 +259,7 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
262259
// Setup the callbacks for serialization, which can occur during the
263260
// optimization pipeline.
264261
SerializationOptions SerializationOpts;
265-
std::string OutPathStr = OutPath.str();
262+
std::string OutPathStr = OutputPath.str();
266263
SerializationOpts.OutputPath = OutPathStr.c_str();
267264
SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
268265
SerializationOpts.AutolinkForceLoad =
@@ -277,8 +274,8 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
277274
SerializationOpts.SDKName = Instance.getASTContext().LangOpts.SDKName;
278275
SerializationOpts.ABIDescriptorPath = ABIDescriptorPath.str();
279276
SmallVector<FileDependency, 16> Deps;
280-
bool serializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes;
281-
if (collectDepsForSerialization(Deps, interfacePath, serializeHashes)) {
277+
bool SerializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes;
278+
if (collectDepsForSerialization(Deps, InterfacePath, SerializeHashes)) {
282279
return std::make_error_code(std::errc::not_supported);
283280
}
284281
if (ShouldSerializeDeps)

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,13 +1259,83 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
12591259
SearchPathOpts.CandidateCompiledModules);
12601260
}
12611261

1262+
static bool readSwiftInterfaceVersionAndArgs(
1263+
SourceManager &SM, DiagnosticEngine &Diags, llvm::StringSaver &ArgSaver,
1264+
SmallVectorImpl<const char *> &SubArgs, std::string &CompilerVersion,
1265+
StringRef interfacePath, SourceLoc diagnosticLoc) {
1266+
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
1267+
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
1268+
if (!FileOrError) {
1269+
// Don't use this->diagnose() because it'll just try to re-open
1270+
// interfacePath.
1271+
Diags.diagnose(diagnosticLoc, diag::error_open_input_file, interfacePath,
1272+
FileOrError.getError().message());
1273+
return true;
1274+
}
1275+
auto SB = FileOrError.get()->getBuffer();
1276+
auto VersRe = getSwiftInterfaceFormatVersionRegex();
1277+
auto CompRe = getSwiftInterfaceCompilerVersionRegex();
1278+
SmallVector<StringRef, 1> VersMatches, CompMatches;
1279+
1280+
if (!VersRe.match(SB, &VersMatches)) {
1281+
InterfaceSubContextDelegateImpl::diagnose(
1282+
interfacePath, diagnosticLoc, SM, &Diags,
1283+
diag::error_extracting_version_from_module_interface);
1284+
return true;
1285+
}
1286+
1287+
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver, SubArgs)) {
1288+
InterfaceSubContextDelegateImpl::diagnose(
1289+
interfacePath, diagnosticLoc, SM, &Diags,
1290+
diag::error_extracting_version_from_module_interface);
1291+
return true;
1292+
}
1293+
1294+
assert(VersMatches.size() == 2);
1295+
// FIXME We should diagnose this at a location that makes sense:
1296+
auto Vers = swift::version::Version(VersMatches[1], SourceLoc(), &Diags);
1297+
1298+
if (CompRe.match(SB, &CompMatches)) {
1299+
assert(CompMatches.size() == 2);
1300+
CompilerVersion = ArgSaver.save(CompMatches[1]).str();
1301+
} else {
1302+
// Don't diagnose; handwritten module interfaces don't include this field.
1303+
CompilerVersion = "(unspecified, file possibly handwritten)";
1304+
}
1305+
1306+
// For now: we support anything with the same "major version" and assume
1307+
// minor versions might be interesting for debugging, or special-casing a
1308+
// compatible field variant.
1309+
if (Vers.asMajorVersion() != InterfaceFormatVersion.asMajorVersion()) {
1310+
InterfaceSubContextDelegateImpl::diagnose(
1311+
interfacePath, diagnosticLoc, SM, &Diags,
1312+
diag::unsupported_version_of_module_interface, interfacePath, Vers);
1313+
return true;
1314+
}
1315+
return false;
1316+
}
1317+
12621318
bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface(
12631319
CompilerInstance &Instance, const StringRef moduleCachePath,
12641320
const StringRef backupInterfaceDir, const StringRef prebuiltCachePath,
12651321
const StringRef ABIDescriptorPath, StringRef interfacePath,
12661322
StringRef outputPath, bool ShouldSerializeDeps,
1267-
ArrayRef<std::string> CompiledCandidates, StringRef CompilerVersion,
1323+
ArrayRef<std::string> CompiledCandidates,
12681324
DependencyTracker *tracker) {
1325+
1326+
// Read out the compiler version.
1327+
llvm::BumpPtrAllocator alloc;
1328+
llvm::StringSaver ArgSaver(alloc);
1329+
std::string CompilerVersion;
1330+
SmallVector<const char *, 64> InterfaceArgs;
1331+
readSwiftInterfaceVersionAndArgs(Instance.getSourceMgr(),
1332+
Instance.getDiags(),
1333+
ArgSaver,
1334+
InterfaceArgs,
1335+
CompilerVersion,
1336+
interfacePath,
1337+
SourceLoc());
1338+
12691339
auto Builder = ExplicitModuleInterfaceBuilder(
12701340
Instance, &Instance.getDiags(), Instance.getSourceMgr(),
12711341
moduleCachePath, backupInterfaceDir, prebuiltCachePath,
@@ -1382,53 +1452,10 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
13821452
std::string &CompilerVersion,
13831453
StringRef interfacePath,
13841454
SourceLoc diagnosticLoc) {
1385-
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
1386-
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
1387-
if (!FileOrError) {
1388-
// Don't use this->diagnose() because it'll just try to re-open
1389-
// interfacePath.
1390-
Diags->diagnose(diagnosticLoc, diag::error_open_input_file,
1391-
interfacePath, FileOrError.getError().message());
1392-
return true;
1393-
}
1394-
auto SB = FileOrError.get()->getBuffer();
1395-
auto VersRe = getSwiftInterfaceFormatVersionRegex();
1396-
auto CompRe = getSwiftInterfaceCompilerVersionRegex();
1397-
SmallVector<StringRef, 1> VersMatches, CompMatches;
1398-
1399-
if (!VersRe.match(SB, &VersMatches)) {
1400-
diagnose(interfacePath, diagnosticLoc,
1401-
diag::error_extracting_version_from_module_interface);
1402-
return true;
1403-
}
1404-
1405-
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver, SubArgs)) {
1406-
diagnose(interfacePath, diagnosticLoc,
1407-
diag::error_extracting_version_from_module_interface);
1455+
if (readSwiftInterfaceVersionAndArgs(SM, *Diags, ArgSaver, SubArgs,
1456+
CompilerVersion, interfacePath,
1457+
diagnosticLoc))
14081458
return true;
1409-
}
1410-
1411-
assert(VersMatches.size() == 2);
1412-
// FIXME We should diagnose this at a location that makes sense:
1413-
auto Vers = swift::version::Version(VersMatches[1], SourceLoc(), Diags);
1414-
1415-
if (CompRe.match(SB, &CompMatches)) {
1416-
assert(CompMatches.size() == 2);
1417-
CompilerVersion = ArgSaver.save(CompMatches[1]).str();
1418-
}
1419-
else {
1420-
// Don't diagnose; handwritten module interfaces don't include this field.
1421-
CompilerVersion = "(unspecified, file possibly handwritten)";
1422-
}
1423-
1424-
// For now: we support anything with the same "major version" and assume
1425-
// minor versions might be interesting for debugging, or special-casing a
1426-
// compatible field variant.
1427-
if (Vers.asMajorVersion() != InterfaceFormatVersion.asMajorVersion()) {
1428-
diagnose(interfacePath, diagnosticLoc,
1429-
diag::unsupported_version_of_module_interface, interfacePath, Vers);
1430-
return true;
1431-
}
14321459

14331460
SmallString<32> ExpectedModuleName = subInvocation.getModuleName();
14341461
if (subInvocation.parseArgs(SubArgs, *Diags)) {

0 commit comments

Comments
 (0)