diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 446d69a3757..5e506712e23 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -184,6 +184,7 @@ public: APIDigester, // swift-api-digester CacheTool, // swift-cache-tool ParseTest, // swift-parse-test + SynthesizeInterface, // swift-synthesize-interface }; class InputInfoMap; diff --git a/include/swift/Option/Options.h b/include/swift/Option/Options.h index 898899f78ee..af74c80580d 100644 --- a/include/swift/Option/Options.h +++ b/include/swift/Option/Options.h @@ -33,7 +33,7 @@ namespace options { DoesNotAffectIncrementalBuild = (1 << 8), AutolinkExtractOption = (1 << 9), ModuleWrapOption = (1 << 10), - // 1 << 11 was previously `SwiftIndentOption` + SwiftSynthesizeInterfaceOption = (1 << 11), ArgumentIsPath = (1 << 12), ModuleInterfaceOption = (1 << 13), SupplementaryOutput = (1 << 14), diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index bca177b1e10..de05a8392ba 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -60,6 +60,9 @@ def SupplementaryOutput : OptionFlag; // The option should be accepted by swift-symbolgraph-extract. def SwiftSymbolGraphExtractOption : OptionFlag; +// The option should be accepted by swift-synthesize-interface. +def SwiftSynthesizeInterfaceOption : OptionFlag; + // The option should be accepted by swift-api-digester. def SwiftAPIDigesterOption : OptionFlag; @@ -215,7 +218,8 @@ def driver_mode : Joined<["--"], "driver-mode=">, Flags<[HelpHidden]>, def help : Flag<["-", "--"], "help">, Flags<[FrontendOption, AutolinkExtractOption, ModuleWrapOption, - SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Display available options">; def h : Flag<["-"], "h">, Alias; def help_hidden : Flag<["-", "--"], "help-hidden">, @@ -223,7 +227,8 @@ def help_hidden : Flag<["-", "--"], "help-hidden">, HelpText<"Display available options, including hidden options">; def v : Flag<["-"], "v">, - Flags<[DoesNotAffectIncrementalBuild, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + Flags<[DoesNotAffectIncrementalBuild, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Show commands to run and use verbose output">; def version : Flag<["-", "--"], "version">, Flags<[FrontendOption]>, HelpText<"Print version information and exit">; @@ -236,26 +241,30 @@ def parseable_output : Flag<["-"], "parseable-output">, def windows_sdk_root : Separate<["-"], "windows-sdk-root">, Flags<[ArgumentIsPath, FrontendOption, - SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Windows SDK Root">, MetaVarName<"">; def windows_sdk_version : Separate<["-"], "windows-sdk-version">, Flags<[FrontendOption, - SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Windows SDK Version">, MetaVarName<"">; def visualc_tools_root : Separate<["-"], "visualc-tools-root">, Flags<[ArgumentIsPath, FrontendOption, - SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"VisualC++ Tools Root">, MetaVarName<"">; def visualc_tools_version : Separate<["-"], "visualc-tools-version">, Flags<[FrontendOption, - SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"VisualC++ ToolSet Version">, MetaVarName<"">; // Android Options def sysroot : Separate<["-"], "sysroot">, Flags<[ArgumentIsPath, FrontendOption, SwiftSymbolGraphExtractOption, - SwiftAPIDigesterOption]>, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Native Platform sysroot">, MetaVarName<"">; // Standard Options @@ -265,7 +274,7 @@ def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>, def o : JoinedOrSeparate<["-"], "o">, Flags<[FrontendOption, AutolinkExtractOption, ModuleWrapOption, NoInteractiveOption, ArgumentIsPath, SwiftAPIDigesterOption, - CacheInvariant]>, + SwiftSynthesizeInterfaceOption, CacheInvariant]>, HelpText<"Write output to ">, MetaVarName<"">; def j : JoinedOrSeparate<["-"], "j">, Flags<[DoesNotAffectIncrementalBuild]>, @@ -273,18 +282,18 @@ def j : JoinedOrSeparate<["-"], "j">, Flags<[DoesNotAffectIncrementalBuild]>, def sdk : Separate<["-"], "sdk">, Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, - SwiftAPIDigesterOption]>, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Compile against ">, MetaVarName<"">; def swift_version : Separate<["-"], "swift-version">, Flags<[FrontendOption, ModuleInterfaceOption, SwiftSymbolGraphExtractOption, - SwiftAPIDigesterOption]>, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Interpret input according to a specific Swift language version number">, MetaVarName<"">; def language_mode : Separate<["-"], "language-mode">, Flags<[FrontendOption, ModuleInterfaceOption, SwiftSymbolGraphExtractOption, - SwiftAPIDigesterOption]>, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Interpret input according to a specific Swift language mode">, MetaVarName<"">, Alias; @@ -306,17 +315,20 @@ def e : Separate<["-"], "e">, Flags<[NewDriverOnlyOption]>, HelpText<"Executes a line of code provided on the command line">; def F : JoinedOrSeparate<["-"], "F">, - Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Add directory to framework search path">; def F_EQ : Joined<["-"], "F=">, Flags<[FrontendOption, ArgumentIsPath]>, Alias; def Fsystem : Separate<["-"], "Fsystem">, - Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption]>, + Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Add directory to system framework search path">; def I : JoinedOrSeparate<["-"], "I">, - Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Add directory to the import search path">; def I_EQ : Joined<["-"], "I=">, Flags<[FrontendOption, ArgumentIsPath]>, Alias; @@ -495,7 +507,8 @@ def localization_path : Separate<["-"], "localization-path">, def module_cache_path : Separate<["-"], "module-cache-path">, Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath, - SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Specifies the module cache path">; def enable_library_evolution : Flag<["-"], "enable-library-evolution">, @@ -559,11 +572,11 @@ def library_level_EQ : Joined<["-"], "library-level=">, def module_name : Separate<["-"], "module-name">, Flags<[FrontendOption, ModuleInterfaceOption, - SwiftSymbolGraphExtractOption]>, + SwiftSymbolGraphExtractOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Name of the module to build">; def project_name : Separate<["-"], "project-name">, Flags<[FrontendOption, ModuleInterfaceOptionIgnorable, - SwiftSymbolGraphExtractOption]>, + SwiftSymbolGraphExtractOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Name of the project this module to build belongs to">; def module_name_EQ : Joined<["-"], "module-name=">, Flags<[FrontendOption]>, @@ -790,7 +803,8 @@ def enable_experimental_cxx_interop : def cxx_interoperability_mode : Joined<["-"], "cxx-interoperability-mode=">, - Flags<[FrontendOption, ModuleInterfaceOption, SwiftSymbolGraphExtractOption]>, + Flags<[FrontendOption, ModuleInterfaceOption, SwiftSymbolGraphExtractOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Enables C++ interoperability; pass 'default' to enable or 'off' to disable">; def experimental_c_foreign_reference_types : @@ -1384,7 +1398,9 @@ def num_threads : Separate<["-"], "num-threads">, def Xfrontend : Separate<["-"], "Xfrontend">, Flags<[HelpHidden]>, MetaVarName<"">, HelpText<"Pass to the Swift frontend">; -def Xcc : Separate<["-"], "Xcc">, Flags<[FrontendOption, SwiftSymbolGraphExtractOption]>, +def Xcc : Separate<["-"], "Xcc">, + Flags<[FrontendOption, SwiftSymbolGraphExtractOption, + SwiftSynthesizeInterfaceOption]>, MetaVarName<"">, HelpText<"Pass to the C/C++/Objective-C compiler">; @@ -1396,13 +1412,16 @@ def Xllvm : Separate<["-"], "Xllvm">, MetaVarName<"">, HelpText<"Pass to LLVM.">; def resource_dir : Separate<["-"], "resource-dir">, - Flags<[FrontendOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, HelpHidden, ArgumentIsPath]>, + Flags<[FrontendOption, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption, + HelpHidden, ArgumentIsPath]>, MetaVarName<"">, HelpText<"The directory that holds the compiler resource files">; def target : Separate<["-"], "target">, - Flags<[FrontendOption, ModuleWrapOption, ModuleInterfaceOption, SwiftSymbolGraphExtractOption, - SwiftAPIDigesterOption]>, + Flags<[FrontendOption, ModuleWrapOption, ModuleInterfaceOption, + SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, + SwiftSynthesizeInterfaceOption]>, HelpText<"Generate code for the given target , such as x86_64-apple-macos10.9">, MetaVarName<"">; def target_legacy_spelling : Joined<["--"], "target=">, Flags<[FrontendOption]>, Alias; @@ -1419,7 +1438,8 @@ def target_variant : Separate<["-"], "target-variant">, " variant target triple in addition to the main -target triple">; def clang_target : Separate<["-"], "clang-target">, - Flags<[FrontendOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + Flags<[FrontendOption, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Separately set the target we should use for internal Clang instance">; def disable_clang_target : Flag<["-"], "disable-clang-target">, diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index b5dcad87181..38811145ca4 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -112,6 +112,7 @@ void Driver::parseDriverKind(ArrayRef Args) { .Case("swift-api-digester", DriverKind::APIDigester) .Case("swift-cache-tool", DriverKind::CacheTool) .Case("swift-parse-test", DriverKind::ParseTest) + .Case("swift-synthesize-interface", DriverKind::SynthesizeInterface) .Default(std::nullopt); if (Kind.has_value()) @@ -3122,6 +3123,7 @@ void Driver::printHelp(bool ShowHidden) const { case DriverKind::APIDigester: case DriverKind::CacheTool: case DriverKind::ParseTest: + case DriverKind::SynthesizeInterface: ExcludedFlagsBitmask |= options::NoBatchOption; break; } diff --git a/lib/DriverTool/CMakeLists.txt b/lib/DriverTool/CMakeLists.txt index 19ae4196fb6..5a04c738876 100644 --- a/lib/DriverTool/CMakeLists.txt +++ b/lib/DriverTool/CMakeLists.txt @@ -13,6 +13,7 @@ set(driver_sources_and_options swift_cache_tool_main.cpp swift_indent_main.cpp swift_symbolgraph_extract_main.cpp + swift_synthesize_interface_main.cpp swift_parse_test_main.cpp) set(driver_common_libs diff --git a/lib/DriverTool/driver.cpp b/lib/DriverTool/driver.cpp index e7abcf51b9a..df125f5c738 100644 --- a/lib/DriverTool/driver.cpp +++ b/lib/DriverTool/driver.cpp @@ -98,6 +98,10 @@ extern int modulewrap_main(ArrayRef Args, const char *Argv0, extern int swift_symbolgraph_extract_main(ArrayRef Args, const char *Argv0, void *MainAddr); +/// Run 'swift-synthesize-interface' +extern int swift_synthesize_interface_main(ArrayRef Args, + const char *Argv0, void *MainAddr); + /// Run 'swift-api-digester' extern int swift_api_digester_main(ArrayRef Args, const char *Argv0, void *MainAddr); @@ -387,6 +391,10 @@ static int run_driver(StringRef ExecName, argv[0], (void *)(intptr_t)getExecutablePath); case Driver::DriverKind::SymbolGraph: return swift_symbolgraph_extract_main(TheDriver.getArgsWithoutProgramNameAndDriverMode(argv), argv[0], (void *)(intptr_t)getExecutablePath); + case Driver::DriverKind::SynthesizeInterface: + return swift_synthesize_interface_main( + TheDriver.getArgsWithoutProgramNameAndDriverMode(argv), argv[0], + (void *)(intptr_t)getExecutablePath); case Driver::DriverKind::APIDigester: return swift_api_digester_main( TheDriver.getArgsWithoutProgramNameAndDriverMode(argv), argv[0], diff --git a/lib/DriverTool/swift_synthesize_interface_main.cpp b/lib/DriverTool/swift_synthesize_interface_main.cpp new file mode 100644 index 00000000000..fbb0f2e7348 --- /dev/null +++ b/lib/DriverTool/swift_synthesize_interface_main.cpp @@ -0,0 +1,211 @@ +//===--- swift_synthesize_interface_main.cpp - Swift interface synthesis --===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Prints the synthesized Swift interface for a Clang module. +// +//===----------------------------------------------------------------------===// + +#include "swift/AST/ASTPrinter.h" +#include "swift/AST/DiagnosticsFrontend.h" +#include "swift/Basic/LLVM.h" +#include "swift/Basic/LLVMInitialize.h" +#include "swift/Basic/Version.h" +#include "swift/Frontend/Frontend.h" +#include "swift/Frontend/PrintingDiagnosticConsumer.h" +#include "swift/IDE/ModuleInterfacePrinting.h" +#include "swift/Option/Options.h" +#include "swift/Parse/ParseVersion.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/raw_ostream.h" + +using namespace swift; +using namespace options; + +int swift_synthesize_interface_main(ArrayRef Args, + const char *Argv0, void *MainAddr) { + INITIALIZE_LLVM(); + + CompilerInvocation Invocation; + CompilerInstance CI; + PrintingDiagnosticConsumer DiagPrinter; + auto &Diags = CI.getDiags(); + Diags.addConsumer(DiagPrinter); + + std::unique_ptr Table = createSwiftOptTable(); + unsigned MissingIndex; + unsigned MissingCount; + llvm::opt::InputArgList ParsedArgs = Table->ParseArgs( + Args, MissingIndex, MissingCount, SwiftSynthesizeInterfaceOption); + if (MissingCount) { + Diags.diagnose(SourceLoc(), diag::error_missing_arg_value, + ParsedArgs.getArgString(MissingIndex), MissingCount); + return EXIT_FAILURE; + } + + if (ParsedArgs.hasArg(OPT_UNKNOWN)) { + for (const auto *A : ParsedArgs.filtered(OPT_UNKNOWN)) { + Diags.diagnose(SourceLoc(), diag::error_unknown_arg, + A->getAsString(ParsedArgs)); + } + return EXIT_FAILURE; + } + + auto MainExecutablePath = llvm::sys::fs::getMainExecutable(Argv0, MainAddr); + + if (ParsedArgs.getLastArg(OPT_help) || Args.empty()) { + std::string ExecutableName = + llvm::sys::path::stem(MainExecutablePath).str(); + Table->printHelp(llvm::outs(), ExecutableName.c_str(), + "Swift Interface Synthesizer", + SwiftSynthesizeInterfaceOption, 0, + /*ShowAllAliases*/ false); + return EXIT_FAILURE; + } + + std::string ModuleName; + if (auto *A = ParsedArgs.getLastArg(OPT_module_name)) { + ModuleName = A->getValue(); + } else { + Diags.diagnose(SourceLoc(), diag::error_option_required, "-module-name"); + return EXIT_FAILURE; + } + + llvm::Triple Target; + if (auto *A = ParsedArgs.getLastArg(OPT_target)) { + Target = llvm::Triple(A->getValue()); + } else { + Diags.diagnose(SourceLoc(), diag::error_option_required, "-target"); + return EXIT_FAILURE; + } + + std::string OutputFile; + if (auto *A = ParsedArgs.getLastArg(OPT_o)) { + OutputFile = A->getValue(); + } else { + OutputFile = "-"; + } + + Invocation.setMainExecutablePath(MainExecutablePath); + Invocation.setModuleName("swift_synthesize_interface"); + + if (auto *A = ParsedArgs.getLastArg(OPT_resource_dir)) { + Invocation.setRuntimeResourcePath(A->getValue()); + } + + std::string SDK = ""; + if (auto *A = ParsedArgs.getLastArg(OPT_sdk)) { + SDK = A->getValue(); + } + Invocation.setSDKPath(SDK); + Invocation.setTargetTriple(Target); + + for (const auto *A : ParsedArgs.filtered(OPT_Xcc)) { + Invocation.getClangImporterOptions().ExtraArgs.push_back(A->getValue()); + } + + std::vector FrameworkSearchPaths; + for (const auto *A : ParsedArgs.filtered(OPT_F)) { + FrameworkSearchPaths.push_back({A->getValue(), /*isSystem*/ false}); + } + for (const auto *A : ParsedArgs.filtered(OPT_Fsystem)) { + FrameworkSearchPaths.push_back({A->getValue(), /*isSystem*/ true}); + } + Invocation.setFrameworkSearchPaths(FrameworkSearchPaths); + Invocation.getSearchPathOptions().LibrarySearchPaths = + ParsedArgs.getAllArgValues(OPT_L); + Invocation.setImportSearchPaths(ParsedArgs.getAllArgValues(OPT_I)); + + Invocation.getLangOptions().EnableObjCInterop = Target.isOSDarwin(); + Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags); + + std::string ModuleCachePath = ""; + if (auto *A = ParsedArgs.getLastArg(OPT_module_cache_path)) { + ModuleCachePath = A->getValue(); + } + Invocation.setClangModuleCachePath(ModuleCachePath); + Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath; + Invocation.getClangImporterOptions().ImportForwardDeclarations = true; + Invocation.setDefaultPrebuiltCacheIfNecessary(); + + if (auto *A = ParsedArgs.getLastArg(OPT_swift_version)) { + using version::Version; + auto SwiftVersion = A->getValue(); + bool isValid = false; + if (auto Version = VersionParser::parseVersionString( + SwiftVersion, SourceLoc(), nullptr)) { + if (auto Effective = Version.value().getEffectiveLanguageVersion()) { + Invocation.getLangOptions().EffectiveLanguageVersion = *Effective; + isValid = true; + } + } + if (!isValid) { + Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, + "-swift-version", SwiftVersion); + return EXIT_FAILURE; + } + } + + std::string InstanceSetupError; + if (CI.setup(Invocation, InstanceSetupError)) { + llvm::outs() << InstanceSetupError << '\n'; + return EXIT_FAILURE; + } + + auto M = CI.getASTContext().getModuleByName(ModuleName); + if (!M) { + llvm::errs() << "Couldn't load module '" << ModuleName << '\'' + << " in the current SDK and search paths.\n"; + + SmallVector VisibleModuleNames; + CI.getASTContext().getVisibleTopLevelModuleNames(VisibleModuleNames); + + if (VisibleModuleNames.empty()) { + llvm::errs() << "Could not find any modules.\n"; + } else { + std::sort(VisibleModuleNames.begin(), VisibleModuleNames.end(), + [](const Identifier &A, const Identifier &B) -> bool { + return A.str() < B.str(); + }); + llvm::errs() << "Current visible modules:\n"; + for (const auto &ModuleName : VisibleModuleNames) { + llvm::errs() << ModuleName.str() << "\n"; + } + } + return EXIT_FAILURE; + } + + if (M->failedToLoad()) { + llvm::errs() << "Error: Failed to load the module '" << ModuleName + << "'. Are you missing build dependencies or " + "include/framework directories?\n" + << "See the previous error messages for details. Aborting.\n"; + + return EXIT_FAILURE; + } + + std::error_code EC; + llvm::raw_fd_ostream fs(OutputFile, EC); + if (EC) { + llvm::errs() << "Cannot open output file: " << OutputFile << "\n"; + return EXIT_FAILURE; + } + + StreamPrinter printer(fs); + PrintOptions printOpts = + PrintOptions::printModuleInterface(/*printFullConvention=*/true); + ide::printModuleInterface(M, /*GroupNames=*/{}, + /*TraversalOptions=*/std::nullopt, printer, + printOpts, /*PrintSynthesizedExtensions=*/false); + + return EXIT_SUCCESS; +} diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index bb243a92104..163c93d5d79 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -1076,6 +1076,7 @@ static void printSingleFrontendOpt(llvm::opt::OptTable &table, options::ID id, table.getOption(id).hasFlag(options::AutolinkExtractOption) || table.getOption(id).hasFlag(options::ModuleWrapOption) || table.getOption(id).hasFlag(options::SwiftSymbolGraphExtractOption) || + table.getOption(id).hasFlag(options::SwiftSynthesizeInterfaceOption) || table.getOption(id).hasFlag(options::SwiftAPIDigesterOption)) { auto name = StringRef(table.getOptionName(id)); if (!name.empty()) { diff --git a/test/SynthesizeInterfaceTool/Inputs/m1.h b/test/SynthesizeInterfaceTool/Inputs/m1.h new file mode 100644 index 00000000000..056df8f87c6 --- /dev/null +++ b/test/SynthesizeInterfaceTool/Inputs/m1.h @@ -0,0 +1,6 @@ +struct MyStruct { + int value; +}; + +void printvalue_mystruct(const struct MyStruct *m) + __attribute__((swift_name("MyStruct.printValue(self:)"))); diff --git a/test/SynthesizeInterfaceTool/Inputs/mcxx.h b/test/SynthesizeInterfaceTool/Inputs/mcxx.h new file mode 100644 index 00000000000..2e092b3379b --- /dev/null +++ b/test/SynthesizeInterfaceTool/Inputs/mcxx.h @@ -0,0 +1,10 @@ +class MyClass { +private: + int value; + +public: + MyClass(int v) : value(v) {} + MyClass() : MyClass(0) {} + + void printValue() const {} +}; diff --git a/test/SynthesizeInterfaceTool/Inputs/module.modulemap b/test/SynthesizeInterfaceTool/Inputs/module.modulemap new file mode 100644 index 00000000000..51fb805cd4e --- /dev/null +++ b/test/SynthesizeInterfaceTool/Inputs/module.modulemap @@ -0,0 +1,8 @@ +module m1 { + header "m1.h" +} + +module mcxx { + requires cplusplus + header "mcxx.h" +} diff --git a/test/SynthesizeInterfaceTool/synthesize-interface-cxx.swift b/test/SynthesizeInterfaceTool/synthesize-interface-cxx.swift new file mode 100644 index 00000000000..5b0d7aafc5b --- /dev/null +++ b/test/SynthesizeInterfaceTool/synthesize-interface-cxx.swift @@ -0,0 +1,7 @@ +// RUN: %target-swift-synthesize-interface -cxx-interoperability-mode=default -module-name mcxx -I %S/Inputs -o - | %FileCheck %s + +// CHECK: public struct MyClass { +// CHECK-DAG: public init(_ v: Int32) +// CHECK-DAG: public init() +// CHECK-DAG: public func printValue() +// CHECK-DAG: } diff --git a/test/SynthesizeInterfaceTool/synthesize-interface-pcm.swift b/test/SynthesizeInterfaceTool/synthesize-interface-pcm.swift new file mode 100644 index 00000000000..73c632d714e --- /dev/null +++ b/test/SynthesizeInterfaceTool/synthesize-interface-pcm.swift @@ -0,0 +1,15 @@ +// Emit the explicit module. +// RUN: %empty-directory(%t) +// RUN: %target-swift-emit-pcm -module-name m1 -o %t/m1.pcm %S/Inputs/module.modulemap + +// Invoke the frontend with the PCM as an input. +// RUN: %target-swift-synthesize-interface %windows_vfs_overlay_opt -module-name m1 -Xcc -fmodule-file=%t/m1.pcm -o - | %FileCheck %s + +// CHECK: public struct MyStruct { +// CHECK-DAG: public init() +// CHECK-DAG: public init(value: Int32) +// CHECK-DAG: public var value: Int32 +// CHECK-DAG: } +// CHECK-DAG: extension MyStruct { +// CHECK-DAG: public func printValue() +// CHECK-DAG: } diff --git a/test/SynthesizeInterfaceTool/synthesize-interface-swift.swift b/test/SynthesizeInterfaceTool/synthesize-interface-swift.swift new file mode 100644 index 00000000000..3c4c6492ead --- /dev/null +++ b/test/SynthesizeInterfaceTool/synthesize-interface-swift.swift @@ -0,0 +1,23 @@ +// Emit the Swift module. +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module -module-name MyModule -o %t/MyModule.swiftmodule %s + +// Invoke the frontend with the module on the import path. +// RUN: %target-swift-synthesize-interface -module-name MyModule -I %t -o - | %FileCheck %s + +public struct MyStruct { +// CHECK: public struct MyStruct { + public private(set) var value: Int + // CHECK-DAG: public private(set) var value: Int { get } + + public init(value: Int = 0) { + // CHECK-DAG: public init(value: Int = 0) + self.value = value + } + + public func printValue() { + // CHECK-DAG: public func printValue() + print(self.value) + } +} +// CHECK-DAG: } diff --git a/test/SynthesizeInterfaceTool/synthesize-interface.swift b/test/SynthesizeInterfaceTool/synthesize-interface.swift new file mode 100644 index 00000000000..426094d5429 --- /dev/null +++ b/test/SynthesizeInterfaceTool/synthesize-interface.swift @@ -0,0 +1,10 @@ +// RUN: %target-swift-synthesize-interface -module-name m1 -I %S/Inputs -o - | %FileCheck %s + +// CHECK: public struct MyStruct { +// CHECK-DAG: public init() +// CHECK-DAG: public init(value: Int32) +// CHECK-DAG: public var value: Int32 +// CHECK-DAG: } +// CHECK-DAG: extension MyStruct { +// CHECK-DAG: public func printValue() +// CHECK-DAG: } diff --git a/test/lit.cfg b/test/lit.cfg index 9eee54f141b..6bb8a2bf0c3 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -324,6 +324,7 @@ config.swift_dependency_tool = inferSwiftBinary('swift-dependency-tool') config.swift_reflection_dump = inferSwiftBinary('swift-reflection-dump') config.swift_remoteast_test = inferSwiftBinary('swift-remoteast-test') config.swift_symbolgraph_extract = inferSwiftBinary('swift-symbolgraph-extract') +config.swift_synthesize_interface = inferSwiftBinary('swift-synthesize-interface') config.clang = inferSwiftBinary('clang') config.clangxx = inferSwiftBinary('clang++') config.llvm_link = inferSwiftBinary('llvm-link') @@ -1546,6 +1547,9 @@ if run_vendor == 'apple': config.target_swift_symbolgraph_extract = ( "%s %s %s" % (xcrun_prefix, config.swift_symbolgraph_extract, target_options)) + config.target_swift_synthesize_interface = ( + "%s %s %s" % + (xcrun_prefix, config.swift_synthesize_interface, target_options)) config.target_swift_ide_test = ( "%s %s %s %s %s" % (xcrun_prefix, config.swift_ide_test, target_options, ccp_opt, @@ -1689,6 +1693,10 @@ elif run_os in ['windows-msvc']: ('%r -target %s %s' % (config.swift_symbolgraph_extract, \ config.variant_triple, \ mcp_opt)) + config.target_swift_synthesize_interface = \ + ('%r -target %s %s' % (config.swift_synthesize_interface, \ + config.variant_triple, \ + mcp_opt)) config.target_swift_ide_test = \ ('%r -target %s %s %s %s %s' % (config.swift_ide_test, \ config.variant_triple, \ @@ -1820,6 +1828,9 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows- config.target_swift_symbolgraph_extract = ( '%s -target %s %s' % (config.swift_symbolgraph_extract, config.variant_triple, mcp_opt)) + config.target_swift_synthesize_interface = ( + '%s -target %s %s' % + (config.swift_synthesize_interface, config.variant_triple, mcp_opt)) config.target_swift_ide_test = ( '%s -target %s %s %s %s %s' % (config.swift_ide_test, config.variant_triple, config.resource_dir_opt, @@ -1928,6 +1939,10 @@ elif run_os == 'linux-androideabi' or run_os == 'linux-android': config.swift_symbolgraph_extract, '-target', config.variant_triple, mcp_opt]) + config.target_swift_synthesize_interface = ' '.join([ + config.swift_synthesize_interface, + '-target', config.variant_triple, + mcp_opt]) config.target_swift_ide_test = ' '.join([ 'env', 'SDKROOT={}'.format(shell_quote(config.variant_sdk)), config.swift_ide_test, @@ -2007,6 +2022,10 @@ elif run_os == 'wasi': config.swift_symbolgraph_extract, '-target', config.variant_triple, mcp_opt]) + config.target_swift_synthesize_interface = ' '.join([ + config.swift_synthesize_interface, + '-target', config.variant_triple, + mcp_opt]) config.target_swift_ide_test = ( '%s -target %s %s %s %s %s' % (config.swift_ide_test, config.variant_triple, config.resource_dir_opt, @@ -2768,6 +2787,7 @@ config.substitutions.append(('%target-swift-ide-test', config.clang_system_overlay_opt))) config.substitutions.append(('%target-swift-symbolgraph-extract', config.target_swift_symbolgraph_extract)) +config.substitutions.append(('%target-swift-synthesize-interface', config.target_swift_synthesize_interface)) config.substitutions.append(('%empty-directory\(([^)]+)\)', SubstituteCaptures(r'rm -rf "\1" && mkdir -p "\1"'))) diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index 4eced05f4c7..1726f14d885 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -173,6 +173,11 @@ swift_create_post_build_symlink(swift-frontend DESTINATION "swift-parse-test${CMAKE_EXECUTABLE_SUFFIX}" WORKING_DIRECTORY "${SWIFT_RUNTIME_OUTPUT_INTDIR}") +swift_create_post_build_symlink(swift-frontend + SOURCE "swift-frontend${CMAKE_EXECUTABLE_SUFFIX}" + DESTINATION "swift-synthesize-interface${CMAKE_EXECUTABLE_SUFFIX}" + WORKING_DIRECTORY "${SWIFT_RUNTIME_OUTPUT_INTDIR}") + add_dependencies(compiler swift-frontend) swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION "bin" @@ -189,6 +194,9 @@ swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-api-diges swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-cache-tool${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION "bin" COMPONENT compiler) +swift_install_in_component(FILES "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-synthesize-interface${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"