From cc6a246debb01de59bf776344801ec2322c5b7f9 Mon Sep 17 00:00:00 2001 From: Xi Ge Date: Sun, 1 Sep 2019 09:12:02 -0700 Subject: [PATCH] Revert "Revert "swift-api-digester: teach the tool to find framework-specific baselines from relative path"" --- .../stability-stdlib-abi-with-asserts.swift | 3 +- ...stability-stdlib-abi-without-asserts.swift | 3 +- .../stability-stdlib-source.swift | 3 +- .../ModuleAnalyzerNodes.cpp | 5 +- .../swift-api-digester/ModuleAnalyzerNodes.h | 2 - .../swift-api-digester/swift-api-digester.cpp | 101 ++++++++++++++++-- .../FrameworkABIBaseline/Swift/ABI/macos.json | 0 .../FrameworkABIBaseline/Swift/API/macos.json | 0 8 files changed, 97 insertions(+), 20 deletions(-) rename test/api-digester/Inputs/stdlib-stable-abi.json => utils/api_checker/FrameworkABIBaseline/Swift/ABI/macos.json (100%) rename test/api-digester/Inputs/stdlib-stable.json => utils/api_checker/FrameworkABIBaseline/Swift/API/macos.json (100%) diff --git a/test/api-digester/stability-stdlib-abi-with-asserts.swift b/test/api-digester/stability-stdlib-abi-with-asserts.swift index dd56b03ab14..e5dabff45aa 100644 --- a/test/api-digester/stability-stdlib-abi-with-asserts.swift +++ b/test/api-digester/stability-stdlib-abi-with-asserts.swift @@ -2,8 +2,7 @@ // REQUIRES: swift_stdlib_asserts // RUN: %empty-directory(%t.tmp) // mkdir %t.tmp/module-cache && mkdir %t.tmp/dummy.sdk -// RUN: %api-digester -dump-sdk -module Swift -o %t.tmp/current-stdlib.json -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -abi -avoid-location -// RUN: %api-digester -diagnose-sdk -input-paths %S/Inputs/stdlib-stable-abi.json -input-paths %t.tmp/current-stdlib.json -abi -o %t.tmp/changes.txt -v +// RUN: %api-digester -diagnose-sdk -module Swift -o %t.tmp/changes.txt -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -abi -avoid-location // RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-abi.without.asserts.swift.expected -o - > %t.tmp/stability-stdlib-abi.swift.expected // RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-abi.asserts.additional.swift.expected -o - >> %t.tmp/stability-stdlib-abi.swift.expected // RUN: %clang -E -P -x c %t.tmp/stability-stdlib-abi.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-abi.swift.expected.sorted diff --git a/test/api-digester/stability-stdlib-abi-without-asserts.swift b/test/api-digester/stability-stdlib-abi-without-asserts.swift index 85e823318d6..6f81cd4f557 100644 --- a/test/api-digester/stability-stdlib-abi-without-asserts.swift +++ b/test/api-digester/stability-stdlib-abi-without-asserts.swift @@ -2,8 +2,7 @@ // REQUIRES: swift_stdlib_no_asserts // RUN: %empty-directory(%t.tmp) // mkdir %t.tmp/module-cache && mkdir %t.tmp/dummy.sdk -// RUN: %api-digester -dump-sdk -module Swift -o %t.tmp/current-stdlib.json -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -abi -avoid-location -// RUN: %api-digester -diagnose-sdk -input-paths %S/Inputs/stdlib-stable-abi.json -input-paths %t.tmp/current-stdlib.json -abi -o %t.tmp/changes.txt -v +// RUN: %api-digester -diagnose-sdk -module Swift -o %t.tmp/changes.txt -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -abi -avoid-location -v // RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-abi.without.asserts.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-abi.swift.expected // RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' | sort > %t.tmp/changes.txt.tmp // RUN: diff -u %t.tmp/stability-stdlib-abi.swift.expected %t.tmp/changes.txt.tmp diff --git a/test/api-digester/stability-stdlib-source.swift b/test/api-digester/stability-stdlib-source.swift index a93c306249f..32934342910 100644 --- a/test/api-digester/stability-stdlib-source.swift +++ b/test/api-digester/stability-stdlib-source.swift @@ -1,8 +1,7 @@ // REQUIRES: OS=macosx // RUN: %empty-directory(%t.tmp) // mkdir %t.tmp/module-cache && mkdir %t.tmp/dummy.sdk -// RUN: %api-digester -dump-sdk -module Swift -o %t.tmp/current-stdlib.json -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -avoid-location -// RUN: %api-digester -diagnose-sdk -input-paths %S/Inputs/stdlib-stable.json -input-paths %t.tmp/current-stdlib.json -o %t.tmp/changes.txt -v +// RUN: %api-digester -diagnose-sdk -module Swift -o %t.tmp/changes.txt -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -avoid-location // RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-source.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-source.swift.expected // RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' | sort > %t.tmp/changes.txt.tmp // RUN: diff -u %t.tmp/stability-stdlib-source.swift.expected %t.tmp/changes.txt.tmp diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp index d15d19cc502..984f1e7046c 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp @@ -586,8 +586,8 @@ static StringRef getKeyContent(SDKContext &Ctx, KeyKind Kind) { SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx, llvm::yaml::MappingNode *Node) { static auto GetScalarString = [&](llvm::yaml::Node *N) -> StringRef { - auto WithQuote = cast(N)->getRawValue(); - return WithQuote.substr(1, WithQuote.size() - 2); + SmallString<64> Buffer; + return Ctx.buffer(cast(N)->getValue(Buffer)); }; static auto getAsInt = [&](llvm::yaml::Node *N) -> int { @@ -2102,7 +2102,6 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) { // previously dumped. void SwiftDeclCollector::deSerialize(StringRef Filename) { auto Pair = parseJsonEmit(Ctx, Filename); - OwnedBuffers.push_back(std::move(Pair.first)); RootNode = std::move(Pair.second); } diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.h b/tools/swift-api-digester/ModuleAnalyzerNodes.h index 7c541b8a458..58ab00956a7 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.h +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.h @@ -230,7 +230,6 @@ public: CIs.emplace_back(new CompilerInstance()); return *CIs.back(); } - template void diagnose(YAMLNodeTy node, Diag ID, typename detail::PassArgument::type... args) { @@ -707,7 +706,6 @@ struct TypeInitInfo { class SwiftDeclCollector: public VisibleDeclConsumer { SDKContext &Ctx; - std::vector> OwnedBuffers; SDKNode *RootNode; llvm::SetVector KnownDecls; // Collected and sorted after we get all of them. diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp index 07f6eb10544..b8468b99e60 100644 --- a/tools/swift-api-digester/swift-api-digester.cpp +++ b/tools/swift-api-digester/swift-api-digester.cpp @@ -234,6 +234,11 @@ static llvm::cl::list PreferInterfaceForModules("use-interface-for-module", llvm::cl::ZeroOrMore, llvm::cl::desc("Prefer loading these modules via interface"), llvm::cl::cat(Category)); + +static llvm::cl::opt +BaselineFilePath("baseline-path", + llvm::cl::desc("The path to the Json file that we should use as the baseline"), + llvm::cl::cat(Category)); } // namespace options namespace { @@ -2529,6 +2534,77 @@ static bool hasBaselineInput() { !options::BaselineFrameworkPaths.empty() || !options::BaselineSDK.empty(); } +enum class ComparisonInputMode: uint8_t { + BothJson, + BaselineJson, + BothLoad, +}; + +static ComparisonInputMode checkComparisonInputMode() { + if (options::SDKJsonPaths.size() == 2) + return ComparisonInputMode::BothJson; + else if (hasBaselineInput()) + return ComparisonInputMode::BothLoad; + else + return ComparisonInputMode::BaselineJson; +} + +static SDKNodeRoot *getBaselineFromJson(const char *Main, SDKContext &Ctx) { + SwiftDeclCollector Collector(Ctx); + // If the baseline path has been given, honor that. + if (!options::BaselineFilePath.empty()) { + Collector.deSerialize(options::BaselineFilePath); + return Collector.getSDKRoot(); + } + CompilerInvocation Invok; + llvm::StringSet<> Modules; + // We need to call prepareForDump to parse target triple. + if (prepareForDump(Main, Invok, Modules, true)) + return nullptr; + + assert(Modules.size() == 1 && + "Cannot find builtin baseline for more than one module"); + // The path of the swift-api-digester executable. + std::string ExePath = llvm::sys::fs::getMainExecutable(Main, + reinterpret_cast(&anchorForGetMainExecutable)); + llvm::SmallString<128> BaselinePath(ExePath); + llvm::sys::path::remove_filename(BaselinePath); // Remove /swift-api-digester + llvm::sys::path::remove_filename(BaselinePath); // Remove /bin + llvm::sys::path::append(BaselinePath, "lib", "swift", "FrameworkABIBaseline", + Modules.begin()->getKey()); + // Look for ABI or API baseline + if (Ctx.checkingABI()) + llvm::sys::path::append(BaselinePath, "ABI"); + else + llvm::sys::path::append(BaselinePath, "API"); + // Look for deployment target specific baseline files. + auto Triple = Invok.getLangOptions().Target; + if (Triple.isMacCatalystEnvironment()) + llvm::sys::path::append(BaselinePath, "iosmac.json"); + else if (Triple.isMacOSX()) + llvm::sys::path::append(BaselinePath, "macos.json"); + else if (Triple.isiOS()) + llvm::sys::path::append(BaselinePath, "iphoneos.json"); + else if (Triple.isTvOS()) + llvm::sys::path::append(BaselinePath, "appletvos.json"); + else if (Triple.isWatchOS()) + llvm::sys::path::append(BaselinePath, "watchos.json"); + else { + llvm::errs() << "Unsupported triple target\n"; + exit(1); + } + StringRef Path = BaselinePath.str(); + if (!fs::exists(Path)) { + llvm::errs() << "Baseline at " << Path << " does not exist\n"; + exit(1); + } + if (options::Verbose) { + llvm::errs() << "Using baseline at " << Path << "\n"; + } + Collector.deSerialize(Path); + return Collector.getSDKRoot(); +} + int main(int argc, char *argv[]) { PROGRAM_START(argc, argv); INITIALIZE_LLVM(); @@ -2550,33 +2626,40 @@ int main(int argc, char *argv[]) { dumpSDKContent(InitInvok, Modules, options::OutputFile, Opts); case ActionType::MigratorGen: case ActionType::DiagnoseSDKs: { - bool CompareJson = options::SDKJsonPaths.size() == 2; - if (!CompareJson && !hasBaselineInput()) { - llvm::errs() << "Only two SDK versions can be compared\n"; - llvm::cl::PrintHelpMessage(); - return 1; - } + ComparisonInputMode Mode = checkComparisonInputMode(); llvm::StringSet<> protocolWhitelist; if (!options::ProtReqWhiteList.empty()) { if (readFileLineByLine(options::ProtReqWhiteList, protocolWhitelist)) return 1; } - if (options::Action == ActionType::MigratorGen) + if (options::Action == ActionType::MigratorGen) { + assert(Mode == ComparisonInputMode::BothJson && "Only BothJson mode is supported"); return generateMigrationScript(options::SDKJsonPaths[0], options::SDKJsonPaths[1], options::OutputFile, IgnoredUsrs, Opts); - else if (CompareJson) + } + switch(Mode) { + case ComparisonInputMode::BothJson: { return diagnoseModuleChange(options::SDKJsonPaths[0], options::SDKJsonPaths[1], options::OutputFile, Opts, std::move(protocolWhitelist)); - else { + } + case ComparisonInputMode::BaselineJson: { + SDKContext Ctx(Opts); + return diagnoseModuleChange(Ctx, getBaselineFromJson(argv[0], Ctx), + getSDKRoot(argv[0], Ctx, false), + options::OutputFile, + std::move(protocolWhitelist)); + } + case ComparisonInputMode::BothLoad: { SDKContext Ctx(Opts); return diagnoseModuleChange(Ctx, getSDKRoot(argv[0], Ctx, true), getSDKRoot(argv[0], Ctx, false), options::OutputFile, std::move(protocolWhitelist)); } + } } case ActionType::DeserializeSDK: case ActionType::DeserializeDiffItems: { diff --git a/test/api-digester/Inputs/stdlib-stable-abi.json b/utils/api_checker/FrameworkABIBaseline/Swift/ABI/macos.json similarity index 100% rename from test/api-digester/Inputs/stdlib-stable-abi.json rename to utils/api_checker/FrameworkABIBaseline/Swift/ABI/macos.json diff --git a/test/api-digester/Inputs/stdlib-stable.json b/utils/api_checker/FrameworkABIBaseline/Swift/API/macos.json similarity index 100% rename from test/api-digester/Inputs/stdlib-stable.json rename to utils/api_checker/FrameworkABIBaseline/Swift/API/macos.json