@@ -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+
12621318bool 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