diff --git a/include/swift/Serialization/Serialization.h b/include/swift/Serialization/Serialization.h new file mode 100644 index 0000000000000..9c7b1ace5cdcf --- /dev/null +++ b/include/swift/Serialization/Serialization.h @@ -0,0 +1,39 @@ +//===--- Serialization.h - Swiftmodule emission -----------------*- C++ -*-===// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022 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 +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SERIALIZATION_H +#define SWIFT_SERIALIZATION_H + +#include "swift/Subsystems.h" + +namespace swift { + +class SILModule; + +namespace serialization { + +/// Serialize a module to the given stream. +void writeToStream( + raw_ostream &os, ModuleOrSourceFile DC, const SILModule *M, + const SerializationOptions &options, + const fine_grained_dependencies::SourceFileDepGraph *DepGraph); + +/// Serialize module documentation to the given stream. +void writeDocToStream(raw_ostream &os, ModuleOrSourceFile DC, + StringRef GroupInfoPath); + +/// Serialize module source info to the given stream. +void writeSourceInfoToStream(raw_ostream &os, ModuleOrSourceFile DC); + +} // end namespace serialization +} // end namespace swift + +#endif // SWIFT_SERIALIZATION_H diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt index ba2de920558dc..215a611c13e7b 100644 --- a/lib/Frontend/CMakeLists.txt +++ b/lib/Frontend/CMakeLists.txt @@ -13,10 +13,12 @@ add_swift_host_library(swiftFrontend STATIC ModuleInterfaceLoader.cpp ModuleInterfaceSupport.cpp PrintingDiagnosticConsumer.cpp + Serialization.cpp SerializedDiagnosticConsumer.cpp) add_dependencies(swiftFrontend SwiftOptions) target_link_libraries(swiftFrontend PRIVATE + swiftAPIDigester swiftAST swiftConstExtract swiftIDE @@ -28,6 +30,6 @@ target_link_libraries(swiftFrontend PRIVATE swiftLocalization swiftSema swiftSerialization - swiftAPIDigester) + swiftSymbolGraphGen) set_swift_llvm_is_available(swiftFrontend) diff --git a/lib/Frontend/Serialization.cpp b/lib/Frontend/Serialization.cpp new file mode 100644 index 0000000000000..3af22d3bf2df0 --- /dev/null +++ b/lib/Frontend/Serialization.cpp @@ -0,0 +1,165 @@ +//===--- Serialization.cpp - Write Swift modules --------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022 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 +// +//===----------------------------------------------------------------------===// + +#include "swift/Serialization/Serialization.h" +#include "swift/APIDigester/ModuleAnalyzerNodes.h" +#include "swift/AST/FileSystem.h" +#include "swift/Subsystems.h" +#include "swift/SymbolGraphGen/SymbolGraphGen.h" +#include "swift/SymbolGraphGen/SymbolGraphOptions.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" + +using namespace swift; + +static ModuleDecl *getModule(ModuleOrSourceFile DC) { + if (auto M = DC.dyn_cast()) + return M; + return DC.get()->getParentModule(); +} + +static ASTContext &getContext(ModuleOrSourceFile DC) { + return getModule(DC)->getASTContext(); +} + +static void emitABIDescriptor(ModuleOrSourceFile DC, + const SerializationOptions &options) { + using namespace swift::ide::api; + if (!options.ABIDescriptorPath.empty()) { + if (DC.is()) { + dumpModuleContent(DC.get(), options.ABIDescriptorPath, true, + options.emptyABIDescriptor); + } + } +} + +void swift::serializeToBuffers( + ModuleOrSourceFile DC, const SerializationOptions &options, + std::unique_ptr *moduleBuffer, + std::unique_ptr *moduleDocBuffer, + std::unique_ptr *moduleSourceInfoBuffer, + const SILModule *M) { + + assert(!options.OutputPath.empty()); + { + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, swiftmodule, to buffer"); + llvm::SmallString<1024> buf; + llvm::raw_svector_ostream stream(buf); + serialization::writeToStream(stream, DC, M, options, + /*dependency info*/ nullptr); + bool hadError = withOutputFile(getContext(DC).Diags, options.OutputPath, + [&](raw_ostream &out) { + out << stream.str(); + return false; + }); + if (hadError) + return; + + emitABIDescriptor(DC, options); + if (moduleBuffer) + *moduleBuffer = std::make_unique( + std::move(buf), options.OutputPath, + /*RequiresNullTerminator=*/false); + } + + if (!options.DocOutputPath.empty()) { + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, swiftdoc, to buffer"); + llvm::SmallString<1024> buf; + llvm::raw_svector_ostream stream(buf); + serialization::writeDocToStream(stream, DC, options.GroupInfoPath); + (void)withOutputFile(getContext(DC).Diags, options.DocOutputPath, + [&](raw_ostream &out) { + out << stream.str(); + return false; + }); + if (moduleDocBuffer) + *moduleDocBuffer = std::make_unique( + std::move(buf), options.DocOutputPath, + /*RequiresNullTerminator=*/false); + } + + if (!options.SourceInfoOutputPath.empty()) { + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, swiftsourceinfo, to buffer"); + llvm::SmallString<1024> buf; + llvm::raw_svector_ostream stream(buf); + serialization::writeSourceInfoToStream(stream, DC); + (void)withOutputFile(getContext(DC).Diags, options.SourceInfoOutputPath, + [&](raw_ostream &out) { + out << stream.str(); + return false; + }); + if (moduleSourceInfoBuffer) + *moduleSourceInfoBuffer = std::make_unique( + std::move(buf), options.SourceInfoOutputPath, + /*RequiresNullTerminator=*/false); + } +} + +void swift::serialize( + ModuleOrSourceFile DC, const SerializationOptions &options, + const symbolgraphgen::SymbolGraphOptions &symbolGraphOptions, + const SILModule *M, + const fine_grained_dependencies::SourceFileDepGraph *DG) { + assert(!options.OutputPath.empty()); + + if (options.OutputPath == "-") { + // Special-case writing to stdout. + serialization::writeToStream(llvm::outs(), DC, M, options, DG); + assert(options.DocOutputPath.empty()); + return; + } + + bool hadError = withOutputFile(getContext(DC).Diags, + options.OutputPath, + [&](raw_ostream &out) { + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, swiftmodule"); + serialization::writeToStream(out, DC, M, options, DG); + return false; + }); + if (hadError) + return; + + if (!options.DocOutputPath.empty()) { + (void)withOutputFile(getContext(DC).Diags, + options.DocOutputPath, + [&](raw_ostream &out) { + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, swiftdoc"); + serialization::writeDocToStream(out, DC, options.GroupInfoPath); + return false; + }); + } + + if (!options.SourceInfoOutputPath.empty()) { + (void)withOutputFile(getContext(DC).Diags, + options.SourceInfoOutputPath, + [&](raw_ostream &out) { + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, swiftsourceinfo"); + serialization::writeSourceInfoToStream(out, DC); + return false; + }); + } + + if (!symbolGraphOptions.OutputDir.empty()) { + if (DC.is()) { + auto *M = DC.get(); + FrontendStatsTracer tracer(getContext(DC).Stats, + "Serialization, symbolgraph"); + symbolgraphgen::emitSymbolGraphForModule(M, symbolGraphOptions); + } + } + emitABIDescriptor(DC, options); +} diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt index 75b185c949bcd..f07472dcb9576 100644 --- a/lib/Serialization/CMakeLists.txt +++ b/lib/Serialization/CMakeLists.txt @@ -16,7 +16,7 @@ add_swift_host_library(swiftSerialization STATIC ) target_link_libraries(swiftSerialization PRIVATE swiftClangImporter - swiftSIL - swiftSymbolGraphGen) + swiftOption + swiftSIL) set_swift_llvm_is_available(swiftSerialization) diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index f6e82e2c76444..0205bf7f0c9df 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -36,7 +36,6 @@ #include "swift/AST/SynthesizedFileUnit.h" #include "swift/AST/TypeCheckRequests.h" #include "swift/AST/TypeVisitor.h" -#include "swift/APIDigester/ModuleAnalyzerNodes.h" #include "swift/Basic/Defer.h" #include "swift/Basic/Dwarf.h" #include "swift/Basic/FileSystem.h" @@ -47,10 +46,9 @@ #include "swift/ClangImporter/ClangModule.h" #include "swift/ClangImporter/SwiftAbstractBasicWriter.h" #include "swift/Demangling/ManglingMacros.h" +#include "swift/Serialization/Serialization.h" #include "swift/Serialization/SerializationOptions.h" #include "swift/Strings.h" -#include "swift/SymbolGraphGen/SymbolGraphGen.h" -#include "swift/SymbolGraphGen/SymbolGraphOptions.h" #include "clang/AST/DeclTemplate.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" @@ -67,7 +65,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/OnDiskHashTable.h" #include "llvm/Support/Path.h" -#include "llvm/Support/SmallVectorMemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include @@ -486,10 +483,6 @@ static ModuleDecl *getModule(ModuleOrSourceFile DC) { return DC.get()->getParentModule(); } -static ASTContext &getContext(ModuleOrSourceFile DC) { - return getModule(DC)->getASTContext(); -} - static bool shouldSerializeAsLocalContext(const DeclContext *DC) { return DC->isLocalContext() && !isa(DC) && !isa(DC) && !isa(DC); @@ -6003,139 +5996,9 @@ bool Serializer::allowCompilerErrors() const { return getASTContext().LangOpts.AllowModuleWithCompilerErrors; } - -static void emitABIDescriptor(ModuleOrSourceFile DC, - const SerializationOptions &options) { - using namespace swift::ide::api; - if (!options.ABIDescriptorPath.empty()) { - if (DC.is()) { - dumpModuleContent(DC.get(), options.ABIDescriptorPath, true, - options.emptyABIDescriptor); - } - } -} - -void swift::serializeToBuffers( - ModuleOrSourceFile DC, const SerializationOptions &options, - std::unique_ptr *moduleBuffer, - std::unique_ptr *moduleDocBuffer, - std::unique_ptr *moduleSourceInfoBuffer, - const SILModule *M) { - - assert(!options.OutputPath.empty()); - { - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, swiftmodule, to buffer"); - llvm::SmallString<1024> buf; - llvm::raw_svector_ostream stream(buf); - Serializer::writeToStream(stream, DC, M, options, - /*dependency info*/ nullptr); - bool hadError = withOutputFile(getContext(DC).Diags, - options.OutputPath, - [&](raw_ostream &out) { - out << stream.str(); - return false; - }); - if (hadError) - return; - emitABIDescriptor(DC, options); - if (moduleBuffer) - *moduleBuffer = std::make_unique( - std::move(buf), options.OutputPath, - /*RequiresNullTerminator=*/false); - } - - if (!options.DocOutputPath.empty()) { - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, swiftdoc, to buffer"); - llvm::SmallString<1024> buf; - llvm::raw_svector_ostream stream(buf); - writeDocToStream(stream, DC, options.GroupInfoPath); - (void)withOutputFile(getContext(DC).Diags, - options.DocOutputPath, - [&](raw_ostream &out) { - out << stream.str(); - return false; - }); - if (moduleDocBuffer) - *moduleDocBuffer = std::make_unique( - std::move(buf), options.DocOutputPath, - /*RequiresNullTerminator=*/false); - } - - if (!options.SourceInfoOutputPath.empty()) { - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, swiftsourceinfo, to buffer"); - llvm::SmallString<1024> buf; - llvm::raw_svector_ostream stream(buf); - writeSourceInfoToStream(stream, DC); - (void)withOutputFile(getContext(DC).Diags, - options.SourceInfoOutputPath, - [&](raw_ostream &out) { - out << stream.str(); - return false; - }); - if (moduleSourceInfoBuffer) - *moduleSourceInfoBuffer = std::make_unique( - std::move(buf), options.SourceInfoOutputPath, - /*RequiresNullTerminator=*/false); - } -} - -void swift::serialize(ModuleOrSourceFile DC, - const SerializationOptions &options, - const symbolgraphgen::SymbolGraphOptions &symbolGraphOptions, - const SILModule *M, - const fine_grained_dependencies::SourceFileDepGraph *DG) { - assert(!options.OutputPath.empty()); - - if (options.OutputPath == "-") { - // Special-case writing to stdout. - Serializer::writeToStream(llvm::outs(), DC, M, options, DG); - assert(options.DocOutputPath.empty()); - return; - } - - bool hadError = withOutputFile(getContext(DC).Diags, - options.OutputPath, - [&](raw_ostream &out) { - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, swiftmodule"); - Serializer::writeToStream(out, DC, M, options, DG); - return false; - }); - if (hadError) - return; - - if (!options.DocOutputPath.empty()) { - (void)withOutputFile(getContext(DC).Diags, - options.DocOutputPath, - [&](raw_ostream &out) { - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, swiftdoc"); - writeDocToStream(out, DC, options.GroupInfoPath); - return false; - }); - } - - if (!options.SourceInfoOutputPath.empty()) { - (void)withOutputFile(getContext(DC).Diags, - options.SourceInfoOutputPath, - [&](raw_ostream &out) { - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, swiftsourceinfo"); - writeSourceInfoToStream(out, DC); - return false; - }); - } - - if (!symbolGraphOptions.OutputDir.empty()) { - if (DC.is()) { - auto *M = DC.get(); - FrontendStatsTracer tracer(getContext(DC).Stats, - "Serialization, symbolgraph"); - symbolgraphgen::emitSymbolGraphForModule(M, symbolGraphOptions); - } - } - emitABIDescriptor(DC, options); +void serialization::writeToStream( + raw_ostream &os, ModuleOrSourceFile DC, const SILModule *M, + const SerializationOptions &options, + const fine_grained_dependencies::SourceFileDepGraph *DepGraph) { + Serializer::writeToStream(os, DC, M, options, DepGraph); } diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h index 6c3632e827e65..f8d8370ed39d5 100644 --- a/lib/Serialization/Serialization.h +++ b/lib/Serialization/Serialization.h @@ -560,12 +560,6 @@ class Serializer : public SerializerBase { bool allowCompilerErrors() const; }; -/// Serialize module documentation to the given stream. -void writeDocToStream(raw_ostream &os, ModuleOrSourceFile DC, - StringRef GroupInfoPath); - -/// Serialize module source info to the given stream. -void writeSourceInfoToStream(raw_ostream &os, ModuleOrSourceFile DC); } // end namespace serialization } // end namespace swift #endif diff --git a/lib/Serialization/SerializeDoc.cpp b/lib/Serialization/SerializeDoc.cpp index 9e4cd6ee370e3..8f25ca5d08365 100644 --- a/lib/Serialization/SerializeDoc.cpp +++ b/lib/Serialization/SerializeDoc.cpp @@ -22,6 +22,7 @@ #include "swift/AST/USRGeneration.h" #include "swift/Basic/Defer.h" #include "swift/Basic/SourceManager.h" +#include "swift/Serialization/Serialization.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/DJB.h" #include "llvm/Support/EndianStream.h" diff --git a/lib/SymbolGraphGen/CMakeLists.txt b/lib/SymbolGraphGen/CMakeLists.txt index 57159b83dc59b..63392f195405e 100644 --- a/lib/SymbolGraphGen/CMakeLists.txt +++ b/lib/SymbolGraphGen/CMakeLists.txt @@ -10,5 +10,5 @@ add_swift_host_library(swiftSymbolGraphGen STATIC target_link_libraries(swiftSymbolGraphGen PRIVATE swiftAST - swiftFrontend + swiftIDE swiftMarkup) diff --git a/tools/swift-dependency-tool/CMakeLists.txt b/tools/swift-dependency-tool/CMakeLists.txt index ab09fa26df4f1..38b409177a91e 100644 --- a/tools/swift-dependency-tool/CMakeLists.txt +++ b/tools/swift-dependency-tool/CMakeLists.txt @@ -7,5 +7,6 @@ target_link_libraries(swift-dependency-tool PRIVATE swiftAST swiftParse + swiftSerialization swiftClangImporter)