1 //===- unittest/Support/YAMLRemarksSerializerTest.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 #include "llvm/Remarks/Remark.h"
10 #include "llvm/Remarks/RemarkParser.h"
11 #include "llvm/Remarks/YAMLRemarkSerializer.h"
12 #include "llvm/Support/Error.h"
13 #include "gtest/gtest.h"
14
15 // We need to supprt Windows paths as well. In order to have paths with the same
16 // length, use a different path according to the platform.
17 #ifdef _WIN32
18 #define EXTERNALFILETESTPATH "C:/externalfi"
19 #else
20 #define EXTERNALFILETESTPATH "/externalfile"
21 #endif
22
23 using namespace llvm;
24
check(remarks::Format SerializerFormat,remarks::SerializerMode Mode,ArrayRef<remarks::Remark> Rs,StringRef ExpectedR,Optional<StringRef> ExpectedMeta,Optional<remarks::StringTable> StrTab=None)25 static void check(remarks::Format SerializerFormat,
26 remarks::SerializerMode Mode, ArrayRef<remarks::Remark> Rs,
27 StringRef ExpectedR, Optional<StringRef> ExpectedMeta,
28 Optional<remarks::StringTable> StrTab = None) {
29 std::string Buf;
30 raw_string_ostream OS(Buf);
31 Expected<std::unique_ptr<remarks::RemarkSerializer>> MaybeS = [&] {
32 if (StrTab)
33 return createRemarkSerializer(SerializerFormat, Mode, OS,
34 std::move(*StrTab));
35 else
36 return createRemarkSerializer(SerializerFormat, Mode, OS);
37 }();
38 EXPECT_FALSE(errorToBool(MaybeS.takeError()));
39 std::unique_ptr<remarks::RemarkSerializer> S = std::move(*MaybeS);
40
41 for (const remarks::Remark &R : Rs)
42 S->emit(R);
43 EXPECT_EQ(OS.str(), ExpectedR);
44
45 if (ExpectedMeta) {
46 Buf.clear();
47 std::unique_ptr<remarks::MetaSerializer> MS =
48 S->metaSerializer(OS, StringRef(EXTERNALFILETESTPATH));
49 MS->emit();
50 EXPECT_EQ(OS.str(), *ExpectedMeta);
51 }
52 }
53
check(remarks::Format SerializerFormat,const remarks::Remark & R,StringRef ExpectedR,StringRef ExpectedMeta,Optional<remarks::StringTable> StrTab=None)54 static void check(remarks::Format SerializerFormat, const remarks::Remark &R,
55 StringRef ExpectedR, StringRef ExpectedMeta,
56 Optional<remarks::StringTable> StrTab = None) {
57 return check(SerializerFormat, remarks::SerializerMode::Separate,
58 makeArrayRef(&R, &R + 1), ExpectedR, ExpectedMeta,
59 std::move(StrTab));
60 }
61
checkStandalone(remarks::Format SerializerFormat,const remarks::Remark & R,StringRef ExpectedR,Optional<remarks::StringTable> StrTab=None)62 static void checkStandalone(remarks::Format SerializerFormat,
63 const remarks::Remark &R, StringRef ExpectedR,
64 Optional<remarks::StringTable> StrTab = None) {
65 return check(SerializerFormat, remarks::SerializerMode::Standalone,
66 makeArrayRef(&R, &R + 1), ExpectedR,
67 /*ExpectedMeta=*/None, std::move(StrTab));
68 }
69
TEST(YAMLRemarks,SerializerRemark)70 TEST(YAMLRemarks, SerializerRemark) {
71 remarks::Remark R;
72 R.RemarkType = remarks::Type::Missed;
73 R.PassName = "pass";
74 R.RemarkName = "name";
75 R.FunctionName = "func";
76 R.Loc = remarks::RemarkLocation{"path", 3, 4};
77 R.Hotness = 5;
78 R.Args.emplace_back();
79 R.Args.back().Key = "key";
80 R.Args.back().Val = "value";
81 R.Args.emplace_back();
82 R.Args.back().Key = "keydebug";
83 R.Args.back().Val = "valuedebug";
84 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
85 check(remarks::Format::YAML, R,
86 "--- !Missed\n"
87 "Pass: pass\n"
88 "Name: name\n"
89 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"
90 "Function: func\n"
91 "Hotness: 5\n"
92 "Args:\n"
93 " - key: value\n"
94 " - keydebug: valuedebug\n"
95 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"
96 "...\n",
97 StringRef("REMARKS\0"
98 "\0\0\0\0\0\0\0\0"
99 "\0\0\0\0\0\0\0\0" EXTERNALFILETESTPATH "\0",
100 38));
101 }
102
TEST(YAMLRemarks,SerializerRemarkStandalone)103 TEST(YAMLRemarks, SerializerRemarkStandalone) {
104 remarks::Remark R;
105 R.RemarkType = remarks::Type::Missed;
106 R.PassName = "pass";
107 R.RemarkName = "name";
108 R.FunctionName = "func";
109 R.Loc = remarks::RemarkLocation{"path", 3, 4};
110 R.Hotness = 5;
111 R.Args.emplace_back();
112 R.Args.back().Key = "key";
113 R.Args.back().Val = "value";
114 R.Args.emplace_back();
115 R.Args.back().Key = "keydebug";
116 R.Args.back().Val = "valuedebug";
117 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
118 checkStandalone(
119 remarks::Format::YAML, R,
120 StringRef("--- !Missed\n"
121 "Pass: pass\n"
122 "Name: name\n"
123 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"
124 "Function: func\n"
125 "Hotness: 5\n"
126 "Args:\n"
127 " - key: value\n"
128 " - keydebug: valuedebug\n"
129 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"
130 "...\n"));
131 }
132
TEST(YAMLRemarks,SerializerRemarkStrTab)133 TEST(YAMLRemarks, SerializerRemarkStrTab) {
134 remarks::Remark R;
135 R.RemarkType = remarks::Type::Missed;
136 R.PassName = "pass";
137 R.RemarkName = "name";
138 R.FunctionName = "func";
139 R.Loc = remarks::RemarkLocation{"path", 3, 4};
140 R.Hotness = 5;
141 R.Args.emplace_back();
142 R.Args.back().Key = "key";
143 R.Args.back().Val = "value";
144 R.Args.emplace_back();
145 R.Args.back().Key = "keydebug";
146 R.Args.back().Val = "valuedebug";
147 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
148 check(remarks::Format::YAMLStrTab, R,
149 "--- !Missed\n"
150 "Pass: 0\n"
151 "Name: 1\n"
152 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
153 "Function: 2\n"
154 "Hotness: 5\n"
155 "Args:\n"
156 " - key: 4\n"
157 " - keydebug: 5\n"
158 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
159 "...\n",
160 StringRef("REMARKS\0"
161 "\0\0\0\0\0\0\0\0"
162 "\x2d\0\0\0\0\0\0\0"
163 "pass\0name\0func\0path\0value\0valuedebug\0argpath"
164 "\0" EXTERNALFILETESTPATH "\0",
165 83));
166 }
167
TEST(YAMLRemarks,SerializerRemarkParsedStrTab)168 TEST(YAMLRemarks, SerializerRemarkParsedStrTab) {
169 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
170 remarks::Remark R;
171 R.RemarkType = remarks::Type::Missed;
172 R.PassName = "pass";
173 R.RemarkName = "name";
174 R.FunctionName = "func";
175 R.Loc = remarks::RemarkLocation{"path", 3, 4};
176 R.Hotness = 5;
177 R.Args.emplace_back();
178 R.Args.back().Key = "key";
179 R.Args.back().Val = "value";
180 R.Args.emplace_back();
181 R.Args.back().Key = "keydebug";
182 R.Args.back().Val = "valuedebug";
183 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
184 check(remarks::Format::YAMLStrTab, R,
185 "--- !Missed\n"
186 "Pass: 0\n"
187 "Name: 1\n"
188 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
189 "Function: 2\n"
190 "Hotness: 5\n"
191 "Args:\n"
192 " - key: 4\n"
193 " - keydebug: 5\n"
194 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
195 "...\n",
196 StringRef("REMARKS\0"
197 "\0\0\0\0\0\0\0\0"
198 "\x2d\0\0\0\0\0\0\0"
199 "pass\0name\0func\0path\0value\0valuedebug\0argpath"
200 "\0" EXTERNALFILETESTPATH "\0",
201 83),
202 remarks::StringTable(remarks::ParsedStringTable(StrTab)));
203 }
204
TEST(YAMLRemarks,SerializerRemarkParsedStrTabStandaloneNoStrTab)205 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneNoStrTab) {
206 // Check that we don't use the string table even if it was provided.
207 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
208 remarks::ParsedStringTable ParsedStrTab(StrTab);
209 remarks::StringTable PreFilledStrTab(ParsedStrTab);
210 remarks::Remark R;
211 R.RemarkType = remarks::Type::Missed;
212 R.PassName = "pass";
213 R.RemarkName = "name";
214 R.FunctionName = "func";
215 R.Loc = remarks::RemarkLocation{"path", 3, 4};
216 R.Hotness = 5;
217 R.Args.emplace_back();
218 R.Args.back().Key = "key";
219 R.Args.back().Val = "value";
220 R.Args.emplace_back();
221 R.Args.back().Key = "keydebug";
222 R.Args.back().Val = "valuedebug";
223 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
224 checkStandalone(
225 remarks::Format::YAML, R,
226 StringRef("--- !Missed\n"
227 "Pass: pass\n"
228 "Name: name\n"
229 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"
230 "Function: func\n"
231 "Hotness: 5\n"
232 "Args:\n"
233 " - key: value\n"
234 " - keydebug: valuedebug\n"
235 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"
236 "...\n"),
237 std::move(PreFilledStrTab));
238 }
239
TEST(YAMLRemarks,SerializerRemarkParsedStrTabStandalone)240 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandalone) {
241 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
242 remarks::ParsedStringTable ParsedStrTab(StrTab);
243 remarks::StringTable PreFilledStrTab(ParsedStrTab);
244 remarks::Remark R;
245 R.RemarkType = remarks::Type::Missed;
246 R.PassName = "pass";
247 R.RemarkName = "name";
248 R.FunctionName = "func";
249 R.Loc = remarks::RemarkLocation{"path", 3, 4};
250 R.Hotness = 5;
251 R.Args.emplace_back();
252 R.Args.back().Key = "key";
253 R.Args.back().Val = "value";
254 R.Args.emplace_back();
255 R.Args.back().Key = "keydebug";
256 R.Args.back().Val = "valuedebug";
257 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
258 checkStandalone(
259 remarks::Format::YAMLStrTab, R,
260 StringRef("REMARKS\0"
261 "\0\0\0\0\0\0\0\0"
262 "\x2d\0\0\0\0\0\0\0"
263 "pass\0name\0func\0path\0value\0valuedebug\0argpath\0"
264 "--- !Missed\n"
265 "Pass: 0\n"
266 "Name: 1\n"
267 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
268 "Function: 2\n"
269 "Hotness: 5\n"
270 "Args:\n"
271 " - key: 4\n"
272 " - keydebug: 5\n"
273 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
274 "...\n",
275 315),
276 std::move(PreFilledStrTab));
277 }
278
TEST(YAMLRemarks,SerializerRemarkParsedStrTabStandaloneMultipleRemarks)279 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneMultipleRemarks) {
280 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
281 remarks::ParsedStringTable ParsedStrTab(StrTab);
282 remarks::StringTable PreFilledStrTab(ParsedStrTab);
283 SmallVector<remarks::Remark, 2> Rs;
284 remarks::Remark R;
285 R.RemarkType = remarks::Type::Missed;
286 R.PassName = "pass";
287 R.RemarkName = "name";
288 R.FunctionName = "func";
289 R.Loc = remarks::RemarkLocation{"path", 3, 4};
290 R.Hotness = 5;
291 R.Args.emplace_back();
292 R.Args.back().Key = "key";
293 R.Args.back().Val = "value";
294 R.Args.emplace_back();
295 R.Args.back().Key = "keydebug";
296 R.Args.back().Val = "valuedebug";
297 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
298 Rs.emplace_back(R.clone());
299 Rs.emplace_back(std::move(R));
300 check(remarks::Format::YAMLStrTab, remarks::SerializerMode::Standalone, Rs,
301 StringRef("REMARKS\0"
302 "\0\0\0\0\0\0\0\0"
303 "\x2d\0\0\0\0\0\0\0"
304 "pass\0name\0func\0path\0value\0valuedebug\0argpath\0"
305 "--- !Missed\n"
306 "Pass: 0\n"
307 "Name: 1\n"
308 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
309 "Function: 2\n"
310 "Hotness: 5\n"
311 "Args:\n"
312 " - key: 4\n"
313 " - keydebug: 5\n"
314 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
315 "...\n"
316 "--- !Missed\n"
317 "Pass: 0\n"
318 "Name: 1\n"
319 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
320 "Function: 2\n"
321 "Hotness: 5\n"
322 "Args:\n"
323 " - key: 4\n"
324 " - keydebug: 5\n"
325 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
326 "...\n",
327 561),
328 /*ExpectedMeta=*/None, std::move(PreFilledStrTab));
329 }
330