Skip to content

Commit 9fa720d

Browse files
authored
Merge pull request #25526 from nkcsgexi/compare-sdk-5.1
[5.1] swift-api-digester: teach the tool to compare two SDKs directly
2 parents 28cb627 + 6cd6d80 commit 9fa720d

File tree

14 files changed

+151
-21
lines changed

14 files changed

+151
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#if !defined(__FOOSUB_H__)
2+
#define __FOOSUB_H__ 1
3+
4+
int fooSubFunc1(int a);
5+
6+
enum FooSubEnum1 {
7+
FooSubEnum1X,
8+
FooSubEnum1Y
9+
};
10+
11+
enum {
12+
FooSubUnnamedEnumeratorA1
13+
};
14+
15+
#endif /* ! __FOOSUB_H__ */
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* Foo.h
2+
Copyright (c) 1815, Napoleon Bonaparte. All rights reserved.
3+
*/
4+
#if !defined(__FOO_H__)
5+
#define __FOO_H__ 1
6+
7+
#import <FooSub/FooSub.h>
8+
9+
void removedFunction(void);
10+
11+
#endif /* ! __FOO_H__ */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
framework module Foo {
2+
umbrella header "Foo.h"
3+
export *
4+
framework module FooSub {
5+
umbrella header "FooSub.h"
6+
export *
7+
}
8+
}
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14)
3+
// swift-module-flags: -target x86_64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo
4+
import Swift
5+
public class RemovedClass {
6+
@objc deinit
7+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Foo
2+
SwiftFoo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#if !defined(__FOOSUB_H__)
2+
#define __FOOSUB_H__ 1
3+
4+
int fooSubFunc1(int a);
5+
6+
enum FooSubEnum1 {
7+
FooSubEnum1X,
8+
FooSubEnum1Y
9+
};
10+
11+
enum {
12+
FooSubUnnamedEnumeratorA1
13+
};
14+
15+
#endif /* ! __FOOSUB_H__ */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* Foo.h
2+
Copyright (c) 1815, Napoleon Bonaparte. All rights reserved.
3+
*/
4+
#if !defined(__FOO_H__)
5+
#define __FOO_H__ 1
6+
7+
#import <FooSub/FooSub.h>
8+
9+
#endif /* ! __FOO_H__ */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
framework module Foo {
2+
umbrella header "Foo.h"
3+
export *
4+
framework module FooSub {
5+
umbrella header "FooSub.h"
6+
export *
7+
}
8+
}
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14)
3+
// swift-module-flags: -target x86_64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo
4+
import Swift
5+
public class AddedClass {
6+
@objc deinit
7+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Foo(Foo.h): Func removedFunction() has been removed
2+
SwiftFoo: Class RemovedClass has been removed

test/api-digester/compare-dump-abi-parsable-interface.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod1/cake.swiftinterface %S/Inputs/cake_baseline/cake.swift -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
77
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod2/cake.swiftinterface %S/Inputs/cake_current/cake.swift -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
8-
// RUN: %api-digester -diagnose-sdk -print-module -module cake -BI %t.mod1 -BI %S/Inputs/APINotesLeft -I %t.mod2 -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-cache-path %t.module-cache -o %t.result -abi
8+
// RUN: %api-digester -diagnose-sdk -print-module -module cake -BI %t.mod1 -BI %S/Inputs/APINotesLeft -I %t.mod2 -I %S/Inputs/APINotesRight -sdk %clang-importer-sdk-path -bsdk %clang-importer-sdk-path -module-cache-path %t.module-cache -o %t.result -abi
99

1010
// RUN: %clang -E -P -x c %S/Outputs/Cake-abi.txt -o - | sed '/^\s*$/d' > %t.expected
1111
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
12-
// RUN: diff -u %t.expected %t.result.tmp
12+
// RUN: diff -u %t.expected %t.result.tmp

test/api-digester/compare-dump-parsable-interface.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod1/cake.swiftinterface %S/Inputs/cake_baseline/cake.swift -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
77
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod2/cake.swiftinterface %S/Inputs/cake_current/cake.swift -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
8-
// RUN: %api-digester -diagnose-sdk -print-module -module cake -BI %t.mod1 -BI %S/Inputs/APINotesLeft -I %t.mod2 -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-cache-path %t.module-cache -o %t.result
8+
// RUN: %api-digester -diagnose-sdk -print-module -module cake -BI %t.mod1 -BI %S/Inputs/APINotesLeft -I %t.mod2 -I %S/Inputs/APINotesRight -sdk %clang-importer-sdk-path -bsdk %clang-importer-sdk-path -module-cache-path %t.module-cache -o %t.result
99

1010
// RUN: %clang -E -P -x c %S/Outputs/Cake.txt -o - | sed '/^\s*$/d' > %t.expected
1111
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
12-
// RUN: diff -u %t.expected %t.result.tmp
12+
// RUN: diff -u %t.expected %t.result.tmp
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// REQUIRES: OS=macosx
2+
3+
// RUN: %empty-directory(%t.mod1)
4+
// RUN: %empty-directory(%t.mod2)
5+
// RUN: %empty-directory(%t.sdk)
6+
// RUN: %empty-directory(%t.module-cache)
7+
8+
// RUN: %api-digester -diagnose-sdk -print-module -module-list-file %S/Inputs/mock-sdk-modules.txt -sdk %S/Inputs/mock-sdk.sdk -bsdk %S/Inputs/mock-sdk-baseline.sdk -module-cache-path %t.module-cache -o %t.result -abort-on-module-fail -target x86_64-apple-macos10.14
9+
10+
// RUN: %clang -E -P -x c %S/Outputs/mock-sdk-api.txt -o - | sed '/^\s*$/d' > %t.expected
11+
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
12+
// RUN: diff -u %t.expected %t.result.tmp

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ static llvm::cl::opt<std::string>
8181
SDK("sdk", llvm::cl::desc("path to the SDK to build against"),
8282
llvm::cl::cat(Category));
8383

84+
static llvm::cl::opt<std::string>
85+
BaselineSDK("bsdk", llvm::cl::desc("path to the baseline SDK to import frameworks"),
86+
llvm::cl::cat(Category));
87+
8488
static llvm::cl::opt<std::string>
8589
Triple("target", llvm::cl::desc("target triple"),
8690
llvm::cl::cat(Category));
@@ -98,6 +102,10 @@ static llvm::cl::list<std::string>
98102
FrameworkPaths("F", llvm::cl::desc("add a directory to the framework search path"),
99103
llvm::cl::cat(Category));
100104

105+
static llvm::cl::list<std::string>
106+
BaselineFrameworkPaths("BF", llvm::cl::desc("add a directory to the baseline framework search path"),
107+
llvm::cl::cat(Category));
108+
101109
static llvm::cl::list<std::string>
102110
BaselineModuleInputPaths("BI", llvm::cl::desc("add a module for baseline input"),
103111
llvm::cl::cat(Category));
@@ -2084,6 +2092,10 @@ static int diagnoseModuleChange(SDKContext &Ctx, SDKNodeRoot *LeftModule,
20842092
assert(LeftModule);
20852093
assert(RightModule);
20862094
llvm::raw_ostream *OS = &llvm::errs();
2095+
if (!LeftModule || !RightModule) {
2096+
*OS << "Cannot diagnose null SDKNodeRoot";
2097+
exit(1);
2098+
}
20872099
std::unique_ptr<llvm::raw_ostream> FileOS;
20882100
if (!OutputPath.empty()) {
20892101
std::error_code EC;
@@ -2270,22 +2282,34 @@ static int readFileLineByLine(StringRef Path, llvm::StringSet<> &Lines) {
22702282
// without being given the address of a function in the main executable).
22712283
void anchorForGetMainExecutable() {}
22722284

2285+
static void setSDKPath(CompilerInvocation &InitInvok, bool IsBaseline) {
2286+
if (IsBaseline) {
2287+
// Set baseline SDK
2288+
if (!options::BaselineSDK.empty()) {
2289+
InitInvok.setSDKPath(options::BaselineSDK);
2290+
}
2291+
} else {
2292+
// Set current SDK
2293+
if (!options::SDK.empty()) {
2294+
InitInvok.setSDKPath(options::SDK);
2295+
} else if (const char *SDKROOT = getenv("SDKROOT")) {
2296+
InitInvok.setSDKPath(SDKROOT);
2297+
} else {
2298+
llvm::errs() << "Provide '-sdk <path>' option or run with 'xcrun -sdk <..>\
2299+
swift-api-digester'\n";
2300+
exit(1);
2301+
}
2302+
}
2303+
}
2304+
22732305
static int prepareForDump(const char *Main,
22742306
CompilerInvocation &InitInvok,
22752307
llvm::StringSet<> &Modules,
22762308
bool IsBaseline = false) {
22772309
InitInvok.setMainExecutablePath(fs::getMainExecutable(Main,
22782310
reinterpret_cast<void *>(&anchorForGetMainExecutable)));
22792311
InitInvok.setModuleName("swift_ide_test");
2280-
if (!options::SDK.empty()) {
2281-
InitInvok.setSDKPath(options::SDK);
2282-
} else if (const char *SDKROOT = getenv("SDKROOT")) {
2283-
InitInvok.setSDKPath(SDKROOT);
2284-
} else {
2285-
llvm::errs() << "Provide '-sdk <path>' option or run with 'xcrun -sdk <..>\
2286-
swift-api-digester'\n";
2287-
return 1;
2288-
}
2312+
setSDKPath(InitInvok, IsBaseline);
22892313

22902314
if (!options::Triple.empty())
22912315
InitInvok.setTargetTriple(options::Triple);
@@ -2308,36 +2332,39 @@ static int prepareForDump(const char *Main,
23082332
}
23092333
if (!isValid) {
23102334
llvm::errs() << "Unsupported Swift Version.\n";
2311-
return 1;
2335+
exit(1);
23122336
}
23132337
}
23142338

23152339
if (!options::ResourceDir.empty()) {
23162340
InitInvok.setRuntimeResourcePath(options::ResourceDir);
23172341
}
23182342
std::vector<SearchPathOptions::FrameworkSearchPath> FramePaths;
2319-
for (const auto &path : options::FrameworkPaths) {
2320-
FramePaths.push_back({path, /*isSystem=*/false});
2321-
}
23222343
for (const auto &path : options::CCSystemFrameworkPaths) {
23232344
FramePaths.push_back({path, /*isSystem=*/true});
23242345
}
2325-
InitInvok.setFrameworkSearchPaths(FramePaths);
23262346
if (IsBaseline) {
2347+
for (const auto &path : options::BaselineFrameworkPaths) {
2348+
FramePaths.push_back({path, /*isSystem=*/false});
2349+
}
23272350
InitInvok.setImportSearchPaths(options::BaselineModuleInputPaths);
23282351
} else {
2352+
for (const auto &path : options::FrameworkPaths) {
2353+
FramePaths.push_back({path, /*isSystem=*/false});
2354+
}
23292355
InitInvok.setImportSearchPaths(options::ModuleInputPaths);
23302356
}
2357+
InitInvok.setFrameworkSearchPaths(FramePaths);
23312358
if (!options::ModuleList.empty()) {
23322359
if (readFileLineByLine(options::ModuleList, Modules))
2333-
return 1;
2360+
exit(1);
23342361
}
23352362
for (auto M : options::ModuleNames) {
23362363
Modules.insert(M);
23372364
}
23382365
if (Modules.empty()) {
23392366
llvm::errs() << "Need to specify -include-all or -module <name>\n";
2340-
return 1;
2367+
exit(1);
23412368
}
23422369
return 0;
23432370
}
@@ -2406,6 +2433,11 @@ static SDKNodeRoot *getSDKRoot(const char *Main, SDKContext &Ctx,
24062433
return getSDKNodeRoot(Ctx, Invok, Modules, Opts);
24072434
}
24082435

2436+
static bool hasBaselineInput() {
2437+
return !options::BaselineModuleInputPaths.empty() ||
2438+
!options::BaselineFrameworkPaths.empty() || !options::BaselineSDK.empty();
2439+
}
2440+
24092441
int main(int argc, char *argv[]) {
24102442
PROGRAM_START(argc, argv);
24112443
INITIALIZE_LLVM();
@@ -2428,7 +2460,7 @@ int main(int argc, char *argv[]) {
24282460
case ActionType::MigratorGen:
24292461
case ActionType::DiagnoseSDKs: {
24302462
bool CompareJson = options::SDKJsonPaths.size() == 2;
2431-
if (!CompareJson && options::BaselineModuleInputPaths.empty()) {
2463+
if (!CompareJson && !hasBaselineInput()) {
24322464
llvm::errs() << "Only two SDK versions can be compared\n";
24332465
llvm::cl::PrintHelpMessage();
24342466
return 1;

0 commit comments

Comments
 (0)