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