mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[APIDigester] Build the API digester as a frontend tool instead of a standalone executable
This commit is contained in:
@@ -167,7 +167,8 @@ public:
|
||||
AutolinkExtract, // swift-autolink-extract
|
||||
SwiftIndent, // swift-indent
|
||||
SymbolGraph, // swift-symbolgraph
|
||||
APIExtract // swift-api-extract
|
||||
APIExtract, // swift-api-extract
|
||||
APIDigester // swift-api-digester
|
||||
};
|
||||
|
||||
class InputInfoMap;
|
||||
|
||||
10
lib/APIDigester/CMakeLists.txt
Normal file
10
lib/APIDigester/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
set_swift_llvm_is_available()
|
||||
|
||||
add_swift_host_library(swiftAPIDigester STATIC
|
||||
ModuleAnalyzerNodes.cpp
|
||||
ModuleDiagsConsumer.cpp)
|
||||
|
||||
target_link_libraries(swiftAPIDigester PRIVATE
|
||||
swiftFrontend
|
||||
swiftSIL
|
||||
swiftIDE)
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "swift/Basic/Defer.h"
|
||||
#include "swift/SIL/SILDeclRef.h"
|
||||
#include <ModuleAnalyzerNodes.h>
|
||||
#include <swift/APIDigester/ModuleAnalyzerNodes.h>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace swift;
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "swift/AST/DiagnosticEngine.h"
|
||||
#include "swift/AST/DiagnosticsModuleDiffer.h"
|
||||
#include "ModuleDiagsConsumer.h"
|
||||
#include "swift/APIDigester/ModuleDiagsConsumer.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
@@ -14,6 +14,7 @@ list(APPEND LLVM_COMMON_DEPENDS intrinsics_gen clang-tablegen-targets)
|
||||
list(APPEND LLVM_COMMON_DEPENDS swift-syntax-generated-headers)
|
||||
list(APPEND LLVM_COMMON_DEPENDS swift-parse-syntax-generated-headers)
|
||||
|
||||
add_subdirectory(APIDigester)
|
||||
add_subdirectory(AST)
|
||||
add_subdirectory(ASTSectionImporter)
|
||||
add_subdirectory(Basic)
|
||||
|
||||
@@ -103,6 +103,7 @@ void Driver::parseDriverKind(ArrayRef<const char *> Args) {
|
||||
.Case("swift-indent", DriverKind::SwiftIndent)
|
||||
.Case("swift-symbolgraph-extract", DriverKind::SymbolGraph)
|
||||
.Case("swift-api-extract", DriverKind::APIExtract)
|
||||
.Case("swift-api-digester", DriverKind::APIDigester)
|
||||
.Default(None);
|
||||
|
||||
if (Kind.hasValue())
|
||||
@@ -3497,6 +3498,7 @@ void Driver::printHelp(bool ShowHidden) const {
|
||||
case DriverKind::SwiftIndent:
|
||||
case DriverKind::SymbolGraph:
|
||||
case DriverKind::APIExtract:
|
||||
case DriverKind::APIDigester:
|
||||
ExcludedFlagsBitmask |= options::NoBatchOption;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ function(get_test_dependencies SDK result_var_name)
|
||||
sil-opt
|
||||
sil-passpipeline-dumper
|
||||
swift-frontend
|
||||
swift-api-digester
|
||||
swift-demangle
|
||||
swift-demangle-yamldump
|
||||
swift-dependency-tool
|
||||
|
||||
@@ -25,7 +25,6 @@ add_swift_tool_subdirectory(sil-llvm-gen)
|
||||
add_swift_tool_subdirectory(sil-nm)
|
||||
add_swift_tool_subdirectory(sil-passpipeline-dumper)
|
||||
add_swift_tool_subdirectory(swift-llvm-opt)
|
||||
add_swift_tool_subdirectory(swift-api-digester)
|
||||
add_swift_tool_subdirectory(swift-ast-script)
|
||||
add_swift_tool_subdirectory(swift-refactor)
|
||||
add_swift_tool_subdirectory(libSwiftScan)
|
||||
|
||||
@@ -2,6 +2,7 @@ add_swift_host_tool(swift-frontend
|
||||
driver.cpp
|
||||
autolink_extract_main.cpp
|
||||
modulewrap_main.cpp
|
||||
swift_api_digester_main.cpp
|
||||
swift_indent_main.cpp
|
||||
swift_symbolgraph_extract_main.cpp
|
||||
swift_api_extract_main.cpp
|
||||
@@ -9,6 +10,7 @@ add_swift_host_tool(swift-frontend
|
||||
)
|
||||
target_link_libraries(swift-frontend
|
||||
PRIVATE
|
||||
swiftAPIDigester
|
||||
swiftDriver
|
||||
swiftFrontendTool
|
||||
swiftSymbolGraphGen
|
||||
@@ -44,12 +46,18 @@ swift_create_post_build_symlink(swift-frontend
|
||||
DESTINATION "swift-autolink-extract${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
WORKING_DIRECTORY "${SWIFT_RUNTIME_OUTPUT_INTDIR}")
|
||||
|
||||
swift_create_post_build_symlink(swift-frontend
|
||||
SOURCE "swift-frontend${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
DESTINATION "swift-api-digester${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
WORKING_DIRECTORY "${SWIFT_RUNTIME_OUTPUT_INTDIR}")
|
||||
|
||||
add_swift_tool_symlink(swift swift-frontend compiler)
|
||||
add_swift_tool_symlink(swiftc swift-frontend compiler)
|
||||
add_swift_tool_symlink(swift-symbolgraph-extract swift-frontend compiler)
|
||||
add_swift_tool_symlink(swift-api-extract swift-frontend compiler)
|
||||
add_swift_tool_symlink(swift-autolink-extract swift-frontend autolink-driver)
|
||||
add_swift_tool_symlink(swift-indent swift-frontend editor-integration)
|
||||
add_swift_tool_symlink(swift-api-digester swift-frontend compiler)
|
||||
|
||||
# If building as part of clang, make sure the headers are installed.
|
||||
if(NOT SWIFT_BUILT_STANDALONE)
|
||||
@@ -69,6 +77,9 @@ swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-symbolgra
|
||||
swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-api-extract${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
DESTINATION "bin"
|
||||
COMPONENT compiler)
|
||||
swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-api-digester${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
DESTINATION "bin"
|
||||
COMPONENT compiler)
|
||||
add_dependencies(autolink-driver swift-frontend)
|
||||
swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-autolink-extract${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
DESTINATION "bin"
|
||||
|
||||
@@ -75,6 +75,10 @@ extern int swift_indent_main(ArrayRef<const char *> Args, const char *Argv0,
|
||||
extern int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv0,
|
||||
void *MainAddr);
|
||||
|
||||
/// Run 'swift-api-digester'
|
||||
extern int swift_api_digester_main(ArrayRef<const char *> Args,
|
||||
const char *Argv0, void *MainAddr);
|
||||
|
||||
/// Run 'swift-api-extract'
|
||||
extern int swift_api_extract_main(ArrayRef<const char *> Args,
|
||||
const char *Argv0, void *MainAddr);
|
||||
@@ -238,6 +242,10 @@ static int run_driver(StringRef ExecName,
|
||||
return swift_api_extract_main(
|
||||
TheDriver.getArgsWithoutProgramNameAndDriverMode(argv), argv[0],
|
||||
(void *)(intptr_t)getExecutablePath);
|
||||
case Driver::DriverKind::APIDigester:
|
||||
return swift_api_digester_main(
|
||||
TheDriver.getArgsWithoutProgramNameAndDriverMode(argv), argv[0],
|
||||
(void *)(intptr_t)getExecutablePath);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
#include "swift/AST/DiagnosticsModuleDiffer.h"
|
||||
#include "swift/IDE/APIDigesterData.h"
|
||||
#include <functional>
|
||||
#include "ModuleAnalyzerNodes.h"
|
||||
#include "ModuleDiagsConsumer.h"
|
||||
#include "swift/APIDigester/ModuleAnalyzerNodes.h"
|
||||
#include "swift/APIDigester/ModuleDiagsConsumer.h"
|
||||
|
||||
using namespace swift;
|
||||
using namespace ide;
|
||||
@@ -2551,13 +2551,6 @@ static int generateMigrationScript(StringRef LeftPath, StringRef RightPath,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function isn't referenced outside its translation unit, but it
|
||||
// can't use the "static" keyword because its address is used for
|
||||
// getMainExecutable (since some platforms don't support taking the
|
||||
// address of main, and some platforms can't implement getMainExecutable
|
||||
// without being given the address of a function in the main executable).
|
||||
void anchorForGetMainExecutable() {}
|
||||
|
||||
static void setSDKPath(CompilerInvocation &InitInvok, bool IsBaseline) {
|
||||
if (IsBaseline) {
|
||||
// Set baseline SDK
|
||||
@@ -2578,12 +2571,10 @@ static void setSDKPath(CompilerInvocation &InitInvok, bool IsBaseline) {
|
||||
}
|
||||
}
|
||||
|
||||
static int prepareForDump(const char *Main,
|
||||
static int prepareForDump(std::string MainExecutablePath,
|
||||
CompilerInvocation &InitInvok,
|
||||
llvm::StringSet<> &Modules,
|
||||
bool IsBaseline = false) {
|
||||
InitInvok.setMainExecutablePath(fs::getMainExecutable(Main,
|
||||
reinterpret_cast<void *>(&anchorForGetMainExecutable)));
|
||||
llvm::StringSet<> &Modules, bool IsBaseline = false) {
|
||||
InitInvok.setMainExecutablePath(MainExecutablePath);
|
||||
InitInvok.setModuleName("swift_ide_test");
|
||||
setSDKPath(InitInvok, IsBaseline);
|
||||
|
||||
@@ -2692,7 +2683,7 @@ static int deserializeNameCorrection(APIDiffItemStore &Store,
|
||||
return EC.value();
|
||||
}
|
||||
|
||||
static CheckerOptions getCheckOpts(int argc, char *argv[]) {
|
||||
static CheckerOptions getCheckOpts(ArrayRef<const char *> Args) {
|
||||
CheckerOptions Opts;
|
||||
Opts.AvoidLocation = options::AvoidLocation;
|
||||
Opts.AvoidToolArgs = options::AvoidToolArgs;
|
||||
@@ -2708,8 +2699,8 @@ static CheckerOptions getCheckOpts(int argc, char *argv[]) {
|
||||
Opts.SkipOSCheck = options::DisableOSChecks;
|
||||
Opts.CompilerStyle = options::CompilerStyleDiags ||
|
||||
!options::SerializedDiagPath.empty();
|
||||
for (int i = 1; i < argc; ++i)
|
||||
Opts.ToolArgs.push_back(argv[i]);
|
||||
for (auto Arg : Args)
|
||||
Opts.ToolArgs.push_back(Arg);
|
||||
|
||||
if (!options::SDK.empty()) {
|
||||
auto Ver = getSDKBuildVersion(options::SDK);
|
||||
@@ -2721,10 +2712,11 @@ static CheckerOptions getCheckOpts(int argc, char *argv[]) {
|
||||
return Opts;
|
||||
}
|
||||
|
||||
static SDKNodeRoot *getSDKRoot(const char *Main, SDKContext &Ctx, bool IsBaseline) {
|
||||
static SDKNodeRoot *getSDKRoot(std::string MainExecutablePath, SDKContext &Ctx,
|
||||
bool IsBaseline) {
|
||||
CompilerInvocation Invok;
|
||||
llvm::StringSet<> Modules;
|
||||
if (prepareForDump(Main, Invok, Modules, IsBaseline))
|
||||
if (prepareForDump(MainExecutablePath, Invok, Modules, IsBaseline))
|
||||
return nullptr;
|
||||
return getSDKNodeRoot(Ctx, Invok, Modules);
|
||||
}
|
||||
@@ -2749,20 +2741,18 @@ static ComparisonInputMode checkComparisonInputMode() {
|
||||
return ComparisonInputMode::BaselineJson;
|
||||
}
|
||||
|
||||
static std::string getDefaultBaselineDir(const char *Main) {
|
||||
static std::string getDefaultBaselineDir(std::string MainExecutablePath) {
|
||||
llvm::SmallString<128> BaselineDir;
|
||||
// The path of the swift-api-digester executable.
|
||||
std::string ExePath = llvm::sys::fs::getMainExecutable(Main,
|
||||
reinterpret_cast<void *>(&anchorForGetMainExecutable));
|
||||
BaselineDir.append(ExePath);
|
||||
BaselineDir.append(MainExecutablePath);
|
||||
llvm::sys::path::remove_filename(BaselineDir); // Remove /swift-api-digester
|
||||
llvm::sys::path::remove_filename(BaselineDir); // Remove /bin
|
||||
llvm::sys::path::append(BaselineDir, "lib", "swift", "FrameworkABIBaseline");
|
||||
return BaselineDir.str().str();
|
||||
}
|
||||
|
||||
static std::string getEmptyBaselinePath(const char *Main) {
|
||||
llvm::SmallString<128> BaselinePath(getDefaultBaselineDir(Main));
|
||||
static std::string getEmptyBaselinePath(std::string MainExecutablePath) {
|
||||
llvm::SmallString<128> BaselinePath(
|
||||
getDefaultBaselineDir(MainExecutablePath));
|
||||
llvm::sys::path::append(BaselinePath, "nil.json");
|
||||
return BaselinePath.str().str();
|
||||
}
|
||||
@@ -2788,10 +2778,11 @@ static StringRef getBaselineFilename(llvm::Triple Triple) {
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getDefaultBaselinePath(const char *Main, StringRef Module,
|
||||
llvm::Triple Triple,
|
||||
static std::string getDefaultBaselinePath(std::string MainExecutablePath,
|
||||
StringRef Module, llvm::Triple Triple,
|
||||
bool ABI) {
|
||||
llvm::SmallString<128> BaselinePath(getDefaultBaselineDir(Main));
|
||||
llvm::SmallString<128> BaselinePath(
|
||||
getDefaultBaselineDir(MainExecutablePath));
|
||||
llvm::sys::path::append(BaselinePath, Module);
|
||||
// Look for ABI or API baseline
|
||||
llvm::sys::path::append(BaselinePath, ABI? "ABI": "API");
|
||||
@@ -2807,12 +2798,13 @@ static std::string getCustomBaselinePath(llvm::Triple Triple, bool ABI) {
|
||||
return BaselinePath.str().str();
|
||||
}
|
||||
|
||||
static SDKNodeRoot *getBaselineFromJson(const char *Main, SDKContext &Ctx) {
|
||||
static SDKNodeRoot *getBaselineFromJson(std::string MainExecutablePath,
|
||||
SDKContext &Ctx) {
|
||||
SwiftDeclCollector Collector(Ctx);
|
||||
CompilerInvocation Invok;
|
||||
llvm::StringSet<> Modules;
|
||||
// We need to call prepareForDump to parse target triple.
|
||||
if (prepareForDump(Main, Invok, Modules, true))
|
||||
if (prepareForDump(MainExecutablePath, Invok, Modules, true))
|
||||
return nullptr;
|
||||
|
||||
assert(Modules.size() == 1 &&
|
||||
@@ -2825,9 +2817,9 @@ static SDKNodeRoot *getBaselineFromJson(const char *Main, SDKContext &Ctx) {
|
||||
Path = getCustomBaselinePath(Invok.getLangOptions().Target,
|
||||
Ctx.checkingABI());
|
||||
} else if (options::UseEmptyBaseline) {
|
||||
Path = getEmptyBaselinePath(Main);
|
||||
Path = getEmptyBaselinePath(MainExecutablePath);
|
||||
} else {
|
||||
Path = getDefaultBaselinePath(Main, Modules.begin()->getKey(),
|
||||
Path = getDefaultBaselinePath(MainExecutablePath, Modules.begin()->getKey(),
|
||||
Invok.getLangOptions().Target,
|
||||
Ctx.checkingABI());
|
||||
}
|
||||
@@ -2860,26 +2852,37 @@ static std::string getJsonOutputFilePath(llvm::Triple Triple, bool ABI) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
PROGRAM_START(argc, argv);
|
||||
int swift_api_digester_main(ArrayRef<const char *> Args, const char *Argv0,
|
||||
void *MainAddr) {
|
||||
INITIALIZE_LLVM();
|
||||
|
||||
// LLVM Command Line parsing expects to trim off argv[0].
|
||||
SmallVector<const char *, 8> ArgsWithArgv0{Argv0};
|
||||
ArgsWithArgv0.append(Args.begin(), Args.end());
|
||||
|
||||
std::string MainExecutablePath = fs::getMainExecutable(Argv0, MainAddr);
|
||||
|
||||
llvm::cl::HideUnrelatedOptions(options::Category);
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SDK Digester\n");
|
||||
llvm::cl::ParseCommandLineOptions(ArgsWithArgv0.size(),
|
||||
llvm::makeArrayRef(ArgsWithArgv0).data(),
|
||||
"Swift SDK Digester\n");
|
||||
CompilerInvocation InitInvok;
|
||||
|
||||
llvm::StringSet<> Modules;
|
||||
std::vector<std::string> PrintApis;
|
||||
llvm::StringSet<> IgnoredUsrs;
|
||||
readIgnoredUsrs(IgnoredUsrs);
|
||||
CheckerOptions Opts = getCheckOpts(argc, argv);
|
||||
CheckerOptions Opts = getCheckOpts(Args);
|
||||
for (auto Name : options::ApisPrintUsrs)
|
||||
PrintApis.push_back(Name);
|
||||
switch (options::Action) {
|
||||
case ActionType::DumpSDK:
|
||||
return (prepareForDump(argv[0], InitInvok, Modules)) ? 1 :
|
||||
dumpSDKContent(InitInvok, Modules,
|
||||
getJsonOutputFilePath(InitInvok.getLangOptions().Target, Opts.ABI),
|
||||
return (prepareForDump(MainExecutablePath, InitInvok, Modules))
|
||||
? 1
|
||||
: dumpSDKContent(
|
||||
InitInvok, Modules,
|
||||
getJsonOutputFilePath(InitInvok.getLangOptions().Target,
|
||||
Opts.ABI),
|
||||
Opts);
|
||||
case ActionType::MigratorGen:
|
||||
case ActionType::DiagnoseSDKs: {
|
||||
@@ -2904,16 +2907,16 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
case ComparisonInputMode::BaselineJson: {
|
||||
SDKContext Ctx(Opts);
|
||||
return diagnoseModuleChange(Ctx, getBaselineFromJson(argv[0], Ctx),
|
||||
getSDKRoot(argv[0], Ctx, false),
|
||||
options::OutputFile,
|
||||
return diagnoseModuleChange(
|
||||
Ctx, getBaselineFromJson(MainExecutablePath, Ctx),
|
||||
getSDKRoot(MainExecutablePath, Ctx, false), options::OutputFile,
|
||||
std::move(protocolAllowlist));
|
||||
}
|
||||
case ComparisonInputMode::BothLoad: {
|
||||
SDKContext Ctx(Opts);
|
||||
return diagnoseModuleChange(Ctx, getSDKRoot(argv[0], Ctx, true),
|
||||
getSDKRoot(argv[0], Ctx, false),
|
||||
options::OutputFile,
|
||||
return diagnoseModuleChange(
|
||||
Ctx, getSDKRoot(MainExecutablePath, Ctx, true),
|
||||
getSDKRoot(MainExecutablePath, Ctx, false), options::OutputFile,
|
||||
std::move(protocolAllowlist));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
add_swift_host_tool(swift-api-digester
|
||||
swift-api-digester.cpp
|
||||
ModuleAnalyzerNodes.cpp
|
||||
ModuleDiagsConsumer.cpp
|
||||
SWIFT_COMPONENT toolchain-tools
|
||||
)
|
||||
target_link_libraries(swift-api-digester
|
||||
PRIVATE
|
||||
swiftFrontend
|
||||
swiftSIL
|
||||
swiftIDE)
|
||||
Reference in New Issue
Block a user