//===- RemarkConvert.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Convert remarks from bitstream to yaml and the other way around. // //===----------------------------------------------------------------------===// #include "RemarkUtilHelpers.h" #include "RemarkUtilRegistry.h" using namespace llvm; using namespace remarks; using namespace llvm::remarkutil; extern ExitOnError ExitOnErr; static cl::SubCommand YAML2Bitstream("yaml2bitstream", "Convert YAML remarks to bitstream remarks"); static cl::SubCommand Bitstream2YAML("bitstream2yaml", "Convert bitstream remarks to YAML remarks"); namespace yaml2bitstream { /// Remark format to parse. static constexpr Format InputFormat = Format::YAML; /// Remark format to output. static constexpr Format OutputFormat = Format::Bitstream; INPUT_OUTPUT_COMMAND_LINE_OPTIONS(YAML2Bitstream) } // namespace yaml2bitstream namespace bitstream2yaml { /// Remark format to parse. static constexpr Format InputFormat = Format::Bitstream; /// Remark format to output. static constexpr Format OutputFormat = Format::YAML; INPUT_OUTPUT_COMMAND_LINE_OPTIONS(Bitstream2YAML) } // namespace bitstream2yaml namespace yaml2bitstream { /// Parses all remarks in the input YAML file. /// \p [out] ParsedRemarks - Filled with remarks parsed from the input file. /// \p [out] StrTab - A string table populated for later remark serialization. /// \returns Error::success() if all remarks were successfully parsed, and an /// Error otherwise. static Error tryParseRemarksFromYAMLFile(std::vector> &ParsedRemarks, StringTable &StrTab) { auto MaybeBuf = getInputMemoryBuffer(InputFileName); if (!MaybeBuf) return MaybeBuf.takeError(); auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer()); if (!MaybeParser) return MaybeParser.takeError(); auto &Parser = **MaybeParser; auto MaybeRemark = Parser.next(); for (; MaybeRemark; MaybeRemark = Parser.next()) { StrTab.internalize(**MaybeRemark); ParsedRemarks.push_back(std::move(*MaybeRemark)); } auto E = MaybeRemark.takeError(); if (!E.isA()) return E; consumeError(std::move(E)); return Error::success(); } /// Reserialize a list of parsed YAML remarks into bitstream remarks. /// \p ParsedRemarks - A list of remarks. /// \p StrTab - The string table for the remarks. /// \returns Error::success() on success. static Error tryReserializeYAML2Bitstream( const std::vector> &ParsedRemarks, StringTable &StrTab) { auto MaybeOF = getOutputFileForRemarks(OutputFileName, OutputFormat); if (!MaybeOF) return MaybeOF.takeError(); auto OF = std::move(*MaybeOF); auto MaybeSerializer = createRemarkSerializer( OutputFormat, SerializerMode::Standalone, OF->os(), std::move(StrTab)); if (!MaybeSerializer) return MaybeSerializer.takeError(); auto Serializer = std::move(*MaybeSerializer); for (const auto &Remark : ParsedRemarks) Serializer->emit(*Remark); OF->keep(); return Error::success(); } /// Parse YAML remarks and reserialize as bitstream remarks. /// \returns Error::success() on success, and an Error otherwise. static Error tryYAML2Bitstream() { StringTable StrTab; std::vector> ParsedRemarks; ExitOnErr(tryParseRemarksFromYAMLFile(ParsedRemarks, StrTab)); return tryReserializeYAML2Bitstream(ParsedRemarks, StrTab); } } // namespace yaml2bitstream namespace bitstream2yaml { /// Parse bitstream remarks and reserialize as YAML remarks. /// \returns An Error if reserialization fails, or Error::success() on success. static Error tryBitstream2YAML() { // Create the serializer. auto MaybeOF = getOutputFileForRemarks(OutputFileName, OutputFormat); if (!MaybeOF) return MaybeOF.takeError(); auto OF = std::move(*MaybeOF); auto MaybeSerializer = createRemarkSerializer( OutputFormat, SerializerMode::Standalone, OF->os()); if (!MaybeSerializer) return MaybeSerializer.takeError(); // Create the parser. auto MaybeBuf = getInputMemoryBuffer(InputFileName); if (!MaybeBuf) return MaybeBuf.takeError(); auto Serializer = std::move(*MaybeSerializer); auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer()); if (!MaybeParser) return MaybeParser.takeError(); auto &Parser = **MaybeParser; // Parse + reserialize all remarks. auto MaybeRemark = Parser.next(); for (; MaybeRemark; MaybeRemark = Parser.next()) Serializer->emit(**MaybeRemark); auto E = MaybeRemark.takeError(); if (!E.isA()) return E; consumeError(std::move(E)); return Error::success(); } } // namespace bitstream2yaml static CommandRegistration Bitstream2YamlReg(&Bitstream2YAML, bitstream2yaml::tryBitstream2YAML); static CommandRegistration Yaml2Bitstream(&YAML2Bitstream, yaml2bitstream::tryYAML2Bitstream);