144 lines · cpp
1//===- RemarkConvert.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Convert remarks from bitstream to yaml and the other way around.10//11//===----------------------------------------------------------------------===//12 13#include "RemarkUtilHelpers.h"14#include "RemarkUtilRegistry.h"15 16using namespace llvm;17using namespace remarks;18using namespace llvm::remarkutil;19 20extern ExitOnError ExitOnErr;21static cl::SubCommand22 YAML2Bitstream("yaml2bitstream",23 "Convert YAML remarks to bitstream remarks");24static cl::SubCommand25 Bitstream2YAML("bitstream2yaml",26 "Convert bitstream remarks to YAML remarks");27 28namespace yaml2bitstream {29/// Remark format to parse.30static constexpr Format InputFormat = Format::YAML;31/// Remark format to output.32static constexpr Format OutputFormat = Format::Bitstream;33INPUT_OUTPUT_COMMAND_LINE_OPTIONS(YAML2Bitstream)34} // namespace yaml2bitstream35 36namespace bitstream2yaml {37/// Remark format to parse.38static constexpr Format InputFormat = Format::Bitstream;39/// Remark format to output.40static constexpr Format OutputFormat = Format::YAML;41INPUT_OUTPUT_COMMAND_LINE_OPTIONS(Bitstream2YAML)42} // namespace bitstream2yaml43 44namespace yaml2bitstream {45/// Parses all remarks in the input YAML file.46/// \p [out] ParsedRemarks - Filled with remarks parsed from the input file.47/// \p [out] StrTab - A string table populated for later remark serialization.48/// \returns Error::success() if all remarks were successfully parsed, and an49/// Error otherwise.50static Error51tryParseRemarksFromYAMLFile(std::vector<std::unique_ptr<Remark>> &ParsedRemarks,52 StringTable &StrTab) {53 auto MaybeBuf = getInputMemoryBuffer(InputFileName);54 if (!MaybeBuf)55 return MaybeBuf.takeError();56 auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());57 if (!MaybeParser)58 return MaybeParser.takeError();59 auto &Parser = **MaybeParser;60 auto MaybeRemark = Parser.next();61 for (; MaybeRemark; MaybeRemark = Parser.next()) {62 StrTab.internalize(**MaybeRemark);63 ParsedRemarks.push_back(std::move(*MaybeRemark));64 }65 auto E = MaybeRemark.takeError();66 if (!E.isA<EndOfFileError>())67 return E;68 consumeError(std::move(E));69 return Error::success();70}71 72/// Reserialize a list of parsed YAML remarks into bitstream remarks.73/// \p ParsedRemarks - A list of remarks.74/// \p StrTab - The string table for the remarks.75/// \returns Error::success() on success.76static Error tryReserializeYAML2Bitstream(77 const std::vector<std::unique_ptr<Remark>> &ParsedRemarks,78 StringTable &StrTab) {79 auto MaybeOF = getOutputFileForRemarks(OutputFileName, OutputFormat);80 if (!MaybeOF)81 return MaybeOF.takeError();82 auto OF = std::move(*MaybeOF);83 auto MaybeSerializer =84 createRemarkSerializer(OutputFormat, OF->os(), std::move(StrTab));85 if (!MaybeSerializer)86 return MaybeSerializer.takeError();87 auto Serializer = std::move(*MaybeSerializer);88 for (const auto &Remark : ParsedRemarks)89 Serializer->emit(*Remark);90 OF->keep();91 return Error::success();92}93 94/// Parse YAML remarks and reserialize as bitstream remarks.95/// \returns Error::success() on success, and an Error otherwise.96static Error tryYAML2Bitstream() {97 StringTable StrTab;98 std::vector<std::unique_ptr<Remark>> ParsedRemarks;99 ExitOnErr(tryParseRemarksFromYAMLFile(ParsedRemarks, StrTab));100 return tryReserializeYAML2Bitstream(ParsedRemarks, StrTab);101}102} // namespace yaml2bitstream103 104namespace bitstream2yaml {105/// Parse bitstream remarks and reserialize as YAML remarks.106/// \returns An Error if reserialization fails, or Error::success() on success.107static Error tryBitstream2YAML() {108 // Create the serializer.109 auto MaybeOF = getOutputFileForRemarks(OutputFileName, OutputFormat);110 if (!MaybeOF)111 return MaybeOF.takeError();112 auto OF = std::move(*MaybeOF);113 auto MaybeSerializer = createRemarkSerializer(OutputFormat, OF->os());114 if (!MaybeSerializer)115 return MaybeSerializer.takeError();116 117 // Create the parser.118 auto MaybeBuf = getInputMemoryBuffer(InputFileName);119 if (!MaybeBuf)120 return MaybeBuf.takeError();121 auto Serializer = std::move(*MaybeSerializer);122 auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());123 if (!MaybeParser)124 return MaybeParser.takeError();125 auto &Parser = **MaybeParser;126 127 // Parse + reserialize all remarks.128 auto MaybeRemark = Parser.next();129 for (; MaybeRemark; MaybeRemark = Parser.next())130 Serializer->emit(**MaybeRemark);131 auto E = MaybeRemark.takeError();132 if (!E.isA<EndOfFileError>())133 return E;134 consumeError(std::move(E));135 OF->keep();136 return Error::success();137}138} // namespace bitstream2yaml139 140static CommandRegistration Bitstream2YamlReg(&Bitstream2YAML,141 bitstream2yaml::tryBitstream2YAML);142static CommandRegistration Yaml2Bitstream(&YAML2Bitstream,143 yaml2bitstream::tryYAML2Bitstream);144