/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Remarks/YAMLRemarkSerializer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- YAMLRemarkSerializer.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-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file provides the implementation of the YAML remark serializer using |
10 | | // LLVM's YAMLTraits. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/Remarks/YAMLRemarkSerializer.h" |
15 | | #include "llvm/Support/CommandLine.h" |
16 | | |
17 | | using namespace llvm; |
18 | | using namespace llvm::remarks; |
19 | | |
20 | | // Use the same keys whether we use a string table or not (respectively, T is an |
21 | | // unsigned or a StringRef). |
22 | | template <typename T> |
23 | | static void mapRemarkHeader(yaml::IO &io, T PassName, T RemarkName, |
24 | | Optional<RemarkLocation> RL, T FunctionName, |
25 | | Optional<uint64_t> Hotness, |
26 | 427 | ArrayRef<Argument> Args) { |
27 | 427 | io.mapRequired("Pass", PassName); |
28 | 427 | io.mapRequired("Name", RemarkName); |
29 | 427 | io.mapOptional("DebugLoc", RL); |
30 | 427 | io.mapRequired("Function", FunctionName); |
31 | 427 | io.mapOptional("Hotness", Hotness); |
32 | 427 | io.mapOptional("Args", Args); |
33 | 427 | } YAMLRemarkSerializer.cpp:void mapRemarkHeader<unsigned int>(llvm::yaml::IO&, unsigned int, unsigned int, llvm::Optional<llvm::remarks::RemarkLocation>, unsigned int, llvm::Optional<unsigned long long>, llvm::ArrayRef<llvm::remarks::Argument>) Line | Count | Source | 26 | 3 | ArrayRef<Argument> Args) { | 27 | 3 | io.mapRequired("Pass", PassName); | 28 | 3 | io.mapRequired("Name", RemarkName); | 29 | 3 | io.mapOptional("DebugLoc", RL); | 30 | 3 | io.mapRequired("Function", FunctionName); | 31 | 3 | io.mapOptional("Hotness", Hotness); | 32 | 3 | io.mapOptional("Args", Args); | 33 | 3 | } |
YAMLRemarkSerializer.cpp:void mapRemarkHeader<llvm::StringRef>(llvm::yaml::IO&, llvm::StringRef, llvm::StringRef, llvm::Optional<llvm::remarks::RemarkLocation>, llvm::StringRef, llvm::Optional<unsigned long long>, llvm::ArrayRef<llvm::remarks::Argument>) Line | Count | Source | 26 | 424 | ArrayRef<Argument> Args) { | 27 | 424 | io.mapRequired("Pass", PassName); | 28 | 424 | io.mapRequired("Name", RemarkName); | 29 | 424 | io.mapOptional("DebugLoc", RL); | 30 | 424 | io.mapRequired("Function", FunctionName); | 31 | 424 | io.mapOptional("Hotness", Hotness); | 32 | 424 | io.mapOptional("Args", Args); | 33 | 424 | } |
|
34 | | |
35 | | namespace llvm { |
36 | | namespace yaml { |
37 | | |
38 | | template <> struct MappingTraits<remarks::Remark *> { |
39 | 427 | static void mapping(IO &io, remarks::Remark *&Remark) { |
40 | 427 | assert(io.outputting() && "input not yet implemented"); |
41 | 427 | |
42 | 427 | if (io.mapTag("!Passed", (Remark->RemarkType == Type::Passed))) |
43 | 121 | ; |
44 | 306 | else if (io.mapTag("!Missed", (Remark->RemarkType == Type::Missed))) |
45 | 112 | ; |
46 | 194 | else if (io.mapTag("!Analysis", (Remark->RemarkType == Type::Analysis))) |
47 | 183 | ; |
48 | 11 | else if (io.mapTag("!AnalysisFPCommute", |
49 | 11 | (Remark->RemarkType == Type::AnalysisFPCommute))) |
50 | 0 | ; |
51 | 11 | else if (io.mapTag("!AnalysisAliasing", |
52 | 11 | (Remark->RemarkType == Type::AnalysisAliasing))) |
53 | 1 | ; |
54 | 10 | else if (io.mapTag("!Failure", (Remark->RemarkType == Type::Failure))) |
55 | 10 | ; |
56 | 10 | else |
57 | 10 | llvm_unreachable0 ("Unknown remark type"); |
58 | 427 | |
59 | 427 | if (Optional<StringTable> &StrTab = |
60 | 3 | reinterpret_cast<YAMLSerializer *>(io.getContext())->StrTab) { |
61 | 3 | unsigned PassID = StrTab->add(Remark->PassName).first; |
62 | 3 | unsigned NameID = StrTab->add(Remark->RemarkName).first; |
63 | 3 | unsigned FunctionID = StrTab->add(Remark->FunctionName).first; |
64 | 3 | mapRemarkHeader(io, PassID, NameID, Remark->Loc, FunctionID, |
65 | 3 | Remark->Hotness, Remark->Args); |
66 | 424 | } else { |
67 | 424 | mapRemarkHeader(io, Remark->PassName, Remark->RemarkName, Remark->Loc, |
68 | 424 | Remark->FunctionName, Remark->Hotness, Remark->Args); |
69 | 424 | } |
70 | 427 | } |
71 | | }; |
72 | | |
73 | | template <> struct MappingTraits<RemarkLocation> { |
74 | 230 | static void mapping(IO &io, RemarkLocation &RL) { |
75 | 230 | assert(io.outputting() && "input not yet implemented"); |
76 | 230 | |
77 | 230 | StringRef File = RL.SourceFilePath; |
78 | 230 | unsigned Line = RL.SourceLine; |
79 | 230 | unsigned Col = RL.SourceColumn; |
80 | 230 | |
81 | 230 | if (Optional<StringTable> &StrTab = |
82 | 2 | reinterpret_cast<YAMLSerializer *>(io.getContext())->StrTab) { |
83 | 2 | unsigned FileID = StrTab->add(File).first; |
84 | 2 | io.mapRequired("File", FileID); |
85 | 228 | } else { |
86 | 228 | io.mapRequired("File", File); |
87 | 228 | } |
88 | 230 | |
89 | 230 | io.mapRequired("Line", Line); |
90 | 230 | io.mapRequired("Column", Col); |
91 | 230 | } |
92 | | |
93 | | static const bool flow = true; |
94 | | }; |
95 | | |
96 | | /// Helper struct for multiline string block literals. Use this type to preserve |
97 | | /// newlines in strings. |
98 | | struct StringBlockVal { |
99 | | StringRef Value; |
100 | 0 | StringBlockVal(const std::string &Value) : Value(Value) {} |
101 | | }; |
102 | | |
103 | | template <> struct BlockScalarTraits<StringBlockVal> { |
104 | 0 | static void output(const StringBlockVal &S, void *Ctx, raw_ostream &OS) { |
105 | 0 | return ScalarTraits<StringRef>::output(S.Value, Ctx, OS); |
106 | 0 | } |
107 | | |
108 | 0 | static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S) { |
109 | 0 | return ScalarTraits<StringRef>::input(Scalar, Ctx, S.Value); |
110 | 0 | } |
111 | | }; |
112 | | |
113 | | /// ArrayRef is not really compatible with the YAMLTraits. Everything should be |
114 | | /// immutable in an ArrayRef, while the SequenceTraits expect a mutable version |
115 | | /// for inputting, but we're only using the outputting capabilities here. |
116 | | /// This is a hack, but still nicer than having to manually call the YAMLIO |
117 | | /// internal methods. |
118 | | /// Keep this in this file so that it doesn't get misused from YAMLTraits.h. |
119 | | template <typename T> struct SequenceTraits<ArrayRef<T>> { |
120 | 427 | static size_t size(IO &io, ArrayRef<T> &seq) { return seq.size(); } |
121 | 1.43k | static Argument &element(IO &io, ArrayRef<T> &seq, size_t index) { |
122 | 1.43k | assert(io.outputting() && "input not yet implemented"); |
123 | 1.43k | // The assert above should make this "safer" to satisfy the YAMLTraits. |
124 | 1.43k | return const_cast<T &>(seq[index]); |
125 | 1.43k | } |
126 | | }; |
127 | | |
128 | | /// Implement this as a mapping for now to get proper quotation for the value. |
129 | | template <> struct MappingTraits<Argument> { |
130 | 1.43k | static void mapping(IO &io, Argument &A) { |
131 | 1.43k | assert(io.outputting() && "input not yet implemented"); |
132 | 1.43k | |
133 | 1.43k | if (Optional<StringTable> &StrTab = |
134 | 6 | reinterpret_cast<YAMLSerializer *>(io.getContext())->StrTab) { |
135 | 6 | auto ValueID = StrTab->add(A.Val).first; |
136 | 6 | io.mapRequired(A.Key.data(), ValueID); |
137 | 1.43k | } else if (StringRef(A.Val).count('\n') > 1) { |
138 | 0 | StringBlockVal S(A.Val); |
139 | 0 | io.mapRequired(A.Key.data(), S); |
140 | 1.43k | } else { |
141 | 1.43k | io.mapRequired(A.Key.data(), A.Val); |
142 | 1.43k | } |
143 | 1.43k | io.mapOptional("DebugLoc", A.Loc); |
144 | 1.43k | } |
145 | | }; |
146 | | |
147 | | } // end namespace yaml |
148 | | } // end namespace llvm |
149 | | |
150 | | LLVM_YAML_IS_SEQUENCE_VECTOR(Argument) |
151 | | |
152 | | YAMLSerializer::YAMLSerializer(raw_ostream &OS) |
153 | 93 | : Serializer(OS), YAMLOutput(OS, reinterpret_cast<void *>(this)) {} |
154 | | |
155 | 427 | void YAMLSerializer::emit(const Remark &Remark) { |
156 | 427 | // Again, YAMLTraits expect a non-const object for inputting, but we're not |
157 | 427 | // using that here. |
158 | 427 | auto R = const_cast<remarks::Remark *>(&Remark); |
159 | 427 | YAMLOutput << R; |
160 | 427 | } |