1 //===-- YAMLRemarkSerializer.h - YAML Remark serialization ---*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides an interface for serializing remarks to YAML.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_REMARKS_YAMLREMARKSERIALIZER_H
14 #define LLVM_REMARKS_YAMLREMARKSERIALIZER_H
15 
16 #include "llvm/Remarks/RemarkSerializer.h"
17 #include "llvm/Support/YAMLTraits.h"
18 #include <optional>
19 
20 namespace llvm {
21 namespace remarks {
22 
23 /// Serialize the remarks to YAML. One remark entry looks like this:
24 /// --- !<TYPE>
25 /// Pass:            <PASSNAME>
26 /// Name:            <REMARKNAME>
27 /// DebugLoc:        { File: <SOURCEFILENAME>, Line: <SOURCELINE>,
28 ///                    Column: <SOURCECOLUMN> }
29 /// Function:        <FUNCTIONNAME>
30 /// Args:
31 ///   - <KEY>: <VALUE>
32 ///     DebugLoc:        { File: <FILE>, Line: <LINE>, Column: <COL> }
33 /// ...
34 struct YAMLRemarkSerializer : public RemarkSerializer {
35   /// The YAML streamer.
36   yaml::Output YAMLOutput;
37 
38   YAMLRemarkSerializer(raw_ostream &OS, SerializerMode Mode,
39                        std::optional<StringTable> StrTab = std::nullopt);
40 
41   void emit(const Remark &Remark) override;
42   std::unique_ptr<MetaSerializer> metaSerializer(
43       raw_ostream &OS,
44       std::optional<StringRef> ExternalFilename = std::nullopt) override;
45 
46   static bool classof(const RemarkSerializer *S) {
47     return S->SerializerFormat == Format::YAML;
48   }
49 
50 protected:
51   YAMLRemarkSerializer(Format SerializerFormat, raw_ostream &OS,
52                        SerializerMode Mode,
53                        std::optional<StringTable> StrTab = std::nullopt);
54 };
55 
56 struct YAMLMetaSerializer : public MetaSerializer {
57   std::optional<StringRef> ExternalFilename;
58 
59   YAMLMetaSerializer(raw_ostream &OS, std::optional<StringRef> ExternalFilename)
60       : MetaSerializer(OS), ExternalFilename(ExternalFilename) {}
61 
62   void emit() override;
63 };
64 
65 /// Serialize the remarks to YAML using a string table. An remark entry looks
66 /// like the regular YAML remark but instead of string entries it's using
67 /// numbers that map to an index in the string table.
68 struct YAMLStrTabRemarkSerializer : public YAMLRemarkSerializer {
69   /// Wether we already emitted the metadata in standalone mode.
70   /// This should be set to true after the first invocation of `emit`.
71   bool DidEmitMeta = false;
72 
73   YAMLStrTabRemarkSerializer(raw_ostream &OS, SerializerMode Mode)
74       : YAMLRemarkSerializer(Format::YAMLStrTab, OS, Mode) {
75     // We always need a string table for this type of serializer.
76     StrTab.emplace();
77   }
78   YAMLStrTabRemarkSerializer(raw_ostream &OS, SerializerMode Mode,
79                              StringTable StrTab)
80       : YAMLRemarkSerializer(Format::YAMLStrTab, OS, Mode, std::move(StrTab)) {}
81 
82   /// Override to emit the metadata if necessary.
83   void emit(const Remark &Remark) override;
84 
85   std::unique_ptr<MetaSerializer> metaSerializer(
86       raw_ostream &OS,
87       std::optional<StringRef> ExternalFilename = std::nullopt) override;
88 
89   static bool classof(const RemarkSerializer *S) {
90     return S->SerializerFormat == Format::YAMLStrTab;
91   }
92 };
93 
94 struct YAMLStrTabMetaSerializer : public YAMLMetaSerializer {
95   /// The string table is part of the metadata.
96   const StringTable &StrTab;
97 
98   YAMLStrTabMetaSerializer(raw_ostream &OS,
99                            std::optional<StringRef> ExternalFilename,
100                            const StringTable &StrTab)
101       : YAMLMetaSerializer(OS, ExternalFilename), StrTab(StrTab) {}
102 
103   void emit() override;
104 };
105 
106 } // end namespace remarks
107 } // end namespace llvm
108 
109 #endif // LLVM_REMARKS_YAMLREMARKSERIALIZER_H
110