4141#include " llvm/Support/MemoryBuffer.h"
4242#include " llvm/Support/Path.h"
4343#include " llvm/Support/CommandLine.h"
44+ #include < optional>
4445#include < system_error>
4546
4647using namespace swift ;
@@ -1389,17 +1390,33 @@ static bool tripleNeedsSubarchitectureAdjustment(const llvm::Triple &lhs, const
13891390 lhs.getEnvironment () == rhs.getEnvironment ());
13901391}
13911392
1393+ static std::optional<StringRef> getFlagsFromInterfaceFile (StringRef &file,
1394+ StringRef prefix) {
1395+ StringRef line, buffer = file;
1396+ while (!buffer.empty ()) {
1397+ std::tie (line, buffer) = buffer.split (' \n ' );
1398+ // If the line is no longer comments, return not found.
1399+ if (!line.consume_front (" // " ))
1400+ return std::nullopt ;
1401+
1402+ if (line.consume_front (prefix) && line.consume_front (" :" )) {
1403+ file = buffer;
1404+ return line;
1405+ }
1406+ }
1407+
1408+ return std::nullopt ;
1409+ }
1410+
13921411bool swift::extractCompilerFlagsFromInterface (
13931412 StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
13941413 SmallVectorImpl<const char *> &SubArgs,
13951414 std::optional<llvm::Triple> PreferredTarget,
13961415 std::optional<llvm::Triple> PreferredTargetVariant) {
1397- SmallVector<StringRef, 1 > FlagMatches;
1398- auto FlagRe = llvm::Regex (" ^// swift-module-flags:(.*)$" , llvm::Regex::Newline);
1399- if (!FlagRe.match (buffer, &FlagMatches))
1416+ auto FlagMatch = getFlagsFromInterfaceFile (buffer, SWIFT_MODULE_FLAGS_KEY);
1417+ if (!FlagMatch)
14001418 return true ;
1401- assert (FlagMatches.size () == 2 );
1402- llvm::cl::TokenizeGNUCommandLine (FlagMatches[1 ], ArgSaver, SubArgs);
1419+ llvm::cl::TokenizeGNUCommandLine (*FlagMatch, ArgSaver, SubArgs);
14031420
14041421 // If the target triple parsed from the Swift interface file differs
14051422 // only in subarchitecture from the compatible target triple, then
@@ -1421,28 +1438,22 @@ bool swift::extractCompilerFlagsFromInterface(
14211438 }
14221439 }
14231440
1424- SmallVector<StringRef, 1 > IgnFlagMatches;
1425- // Cherry-pick supported options from the ignorable list.
1426- auto IgnFlagRe = llvm::Regex (" ^// swift-module-flags-ignorable:(.*)$" ,
1427- llvm::Regex::Newline);
1428- auto hasIgnorableFlags = IgnFlagRe.match (buffer, &IgnFlagMatches);
1429-
1430- // Check for ignorable-private flags
1431- SmallVector<StringRef, 1 > IgnPrivateFlagMatches;
1432- auto IgnPrivateFlagRe = llvm::Regex (" ^// swift-module-flags-ignorable-private:(.*)$" ,
1433- llvm::Regex::Newline);
1434- auto hasIgnorablePrivateFlags = IgnPrivateFlagRe.match (buffer, &IgnPrivateFlagMatches);
1441+ auto IgnFlagMatch =
1442+ getFlagsFromInterfaceFile (buffer, SWIFT_MODULE_FLAGS_IGNORABLE_KEY);
1443+ auto IgnPrivateFlagMatch = getFlagsFromInterfaceFile (
1444+ buffer, SWIFT_MODULE_FLAGS_IGNORABLE_PRIVATE_KEY);
14351445
14361446 // It's OK the interface doesn't have the ignorable list (private or not), we just
14371447 // ignore them all.
1438- if (!hasIgnorableFlags && !hasIgnorablePrivateFlags )
1448+ if (!IgnFlagMatch && !IgnPrivateFlagMatch )
14391449 return false ;
14401450
14411451 SmallVector<const char *, 8 > IgnSubArgs;
1442- if (hasIgnorableFlags)
1443- llvm::cl::TokenizeGNUCommandLine (IgnFlagMatches[1 ], ArgSaver, IgnSubArgs);
1444- if (hasIgnorablePrivateFlags)
1445- llvm::cl::TokenizeGNUCommandLine (IgnPrivateFlagMatches[1 ], ArgSaver, IgnSubArgs);
1452+ if (IgnFlagMatch)
1453+ llvm::cl::TokenizeGNUCommandLine (*IgnFlagMatch, ArgSaver, IgnSubArgs);
1454+ if (IgnPrivateFlagMatch)
1455+ llvm::cl::TokenizeGNUCommandLine (*IgnPrivateFlagMatch, ArgSaver,
1456+ IgnSubArgs);
14461457
14471458 std::unique_ptr<llvm::opt::OptTable> table = swift::createSwiftOptTable ();
14481459 unsigned missingArgIdx = 0 ;
0 commit comments