@@ -234,6 +234,11 @@ static llvm::cl::list<std::string>
234
234
PreferInterfaceForModules (" use-interface-for-module" , llvm::cl::ZeroOrMore,
235
235
llvm::cl::desc (" Prefer loading these modules via interface" ),
236
236
llvm::cl::cat(Category));
237
+
238
+ static llvm::cl::opt<std::string>
239
+ BaselineFilePath (" baseline-path" ,
240
+ llvm::cl::desc (" The path to the Json file that we should use as the baseline" ),
241
+ llvm::cl::cat(Category));
237
242
} // namespace options
238
243
239
244
namespace {
@@ -2529,6 +2534,77 @@ static bool hasBaselineInput() {
2529
2534
!options::BaselineFrameworkPaths.empty () || !options::BaselineSDK.empty ();
2530
2535
}
2531
2536
2537
+ enum class ComparisonInputMode : uint8_t {
2538
+ BothJson,
2539
+ BaselineJson,
2540
+ BothLoad,
2541
+ };
2542
+
2543
+ static ComparisonInputMode checkComparisonInputMode () {
2544
+ if (options::SDKJsonPaths.size () == 2 )
2545
+ return ComparisonInputMode::BothJson;
2546
+ else if (hasBaselineInput ())
2547
+ return ComparisonInputMode::BothLoad;
2548
+ else
2549
+ return ComparisonInputMode::BaselineJson;
2550
+ }
2551
+
2552
+ static SDKNodeRoot *getBaselineFromJson (const char *Main, SDKContext &Ctx) {
2553
+ SwiftDeclCollector Collector (Ctx);
2554
+ // If the baseline path has been given, honor that.
2555
+ if (!options::BaselineFilePath.empty ()) {
2556
+ Collector.deSerialize (options::BaselineFilePath);
2557
+ return Collector.getSDKRoot ();
2558
+ }
2559
+ CompilerInvocation Invok;
2560
+ llvm::StringSet<> Modules;
2561
+ // We need to call prepareForDump to parse target triple.
2562
+ if (prepareForDump (Main, Invok, Modules, true ))
2563
+ return nullptr ;
2564
+
2565
+ assert (Modules.size () == 1 &&
2566
+ " Cannot find builtin baseline for more than one module" );
2567
+ // The path of the swift-api-digester executable.
2568
+ std::string ExePath = llvm::sys::fs::getMainExecutable (Main,
2569
+ reinterpret_cast <void *>(&anchorForGetMainExecutable));
2570
+ llvm::SmallString<128 > BaselinePath (ExePath);
2571
+ llvm::sys::path::remove_filename (BaselinePath); // Remove /swift-api-digester
2572
+ llvm::sys::path::remove_filename (BaselinePath); // Remove /bin
2573
+ llvm::sys::path::append (BaselinePath, " lib" , " swift" , " FrameworkABIBaseline" ,
2574
+ Modules.begin ()->getKey ());
2575
+ // Look for ABI or API baseline
2576
+ if (Ctx.checkingABI ())
2577
+ llvm::sys::path::append (BaselinePath, " ABI" );
2578
+ else
2579
+ llvm::sys::path::append (BaselinePath, " API" );
2580
+ // Look for deployment target specific baseline files.
2581
+ auto Triple = Invok.getLangOptions ().Target ;
2582
+ if (Triple.isMacCatalystEnvironment ())
2583
+ llvm::sys::path::append (BaselinePath, " iosmac.json" );
2584
+ else if (Triple.isMacOSX ())
2585
+ llvm::sys::path::append (BaselinePath, " macos.json" );
2586
+ else if (Triple.isiOS ())
2587
+ llvm::sys::path::append (BaselinePath, " iphoneos.json" );
2588
+ else if (Triple.isTvOS ())
2589
+ llvm::sys::path::append (BaselinePath, " appletvos.json" );
2590
+ else if (Triple.isWatchOS ())
2591
+ llvm::sys::path::append (BaselinePath, " watchos.json" );
2592
+ else {
2593
+ llvm::errs () << " Unsupported triple target\n " ;
2594
+ exit (1 );
2595
+ }
2596
+ StringRef Path = BaselinePath.str ();
2597
+ if (!fs::exists (Path)) {
2598
+ llvm::errs () << " Baseline at " << Path << " does not exist\n " ;
2599
+ exit (1 );
2600
+ }
2601
+ if (options::Verbose) {
2602
+ llvm::errs () << " Using baseline at " << Path << " \n " ;
2603
+ }
2604
+ Collector.deSerialize (Path);
2605
+ return Collector.getSDKRoot ();
2606
+ }
2607
+
2532
2608
int main (int argc, char *argv[]) {
2533
2609
PROGRAM_START (argc, argv);
2534
2610
INITIALIZE_LLVM ();
@@ -2550,33 +2626,40 @@ int main(int argc, char *argv[]) {
2550
2626
dumpSDKContent (InitInvok, Modules, options::OutputFile, Opts);
2551
2627
case ActionType::MigratorGen:
2552
2628
case ActionType::DiagnoseSDKs: {
2553
- bool CompareJson = options::SDKJsonPaths.size () == 2 ;
2554
- if (!CompareJson && !hasBaselineInput ()) {
2555
- llvm::errs () << " Only two SDK versions can be compared\n " ;
2556
- llvm::cl::PrintHelpMessage ();
2557
- return 1 ;
2558
- }
2629
+ ComparisonInputMode Mode = checkComparisonInputMode ();
2559
2630
llvm::StringSet<> protocolWhitelist;
2560
2631
if (!options::ProtReqWhiteList.empty ()) {
2561
2632
if (readFileLineByLine (options::ProtReqWhiteList, protocolWhitelist))
2562
2633
return 1 ;
2563
2634
}
2564
- if (options::Action == ActionType::MigratorGen)
2635
+ if (options::Action == ActionType::MigratorGen) {
2636
+ assert (Mode == ComparisonInputMode::BothJson && " Only BothJson mode is supported" );
2565
2637
return generateMigrationScript (options::SDKJsonPaths[0 ],
2566
2638
options::SDKJsonPaths[1 ],
2567
2639
options::OutputFile, IgnoredUsrs, Opts);
2568
- else if (CompareJson)
2640
+ }
2641
+ switch (Mode) {
2642
+ case ComparisonInputMode::BothJson: {
2569
2643
return diagnoseModuleChange (options::SDKJsonPaths[0 ],
2570
2644
options::SDKJsonPaths[1 ],
2571
2645
options::OutputFile, Opts,
2572
2646
std::move (protocolWhitelist));
2573
- else {
2647
+ }
2648
+ case ComparisonInputMode::BaselineJson: {
2649
+ SDKContext Ctx (Opts);
2650
+ return diagnoseModuleChange (Ctx, getBaselineFromJson (argv[0 ], Ctx),
2651
+ getSDKRoot (argv[0 ], Ctx, false ),
2652
+ options::OutputFile,
2653
+ std::move (protocolWhitelist));
2654
+ }
2655
+ case ComparisonInputMode::BothLoad: {
2574
2656
SDKContext Ctx (Opts);
2575
2657
return diagnoseModuleChange (Ctx, getSDKRoot (argv[0 ], Ctx, true ),
2576
2658
getSDKRoot (argv[0 ], Ctx, false ),
2577
2659
options::OutputFile,
2578
2660
std::move (protocolWhitelist));
2579
2661
}
2662
+ }
2580
2663
}
2581
2664
case ActionType::DeserializeSDK:
2582
2665
case ActionType::DeserializeDiffItems: {
0 commit comments