blob: baa481409f9e3122cb78a91a2f3d11a63a1c550d [file] [log] [blame]
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +00001//===- unittest/Support/YAMLRemarksParsingTest.cpp - OptTable tests -------===//
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-c/Remarks.h"
10#include "llvm/Remarks/Remark.h"
11#include "llvm/Remarks/RemarkParser.h"
12#include "gtest/gtest.h"
13
14using namespace llvm;
15
16template <size_t N> void parseGood(const char (&Buf)[N]) {
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +000017 Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
18 remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
19 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
20 EXPECT_TRUE(*MaybeParser != nullptr);
21
22 remarks::Parser &Parser = **MaybeParser;
23 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +000024 EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors.
25 EXPECT_TRUE(*Remark != nullptr); // At least one remark.
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +000026 Remark = Parser.next();
27 Error E = Remark.takeError();
28 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
29 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +000030}
31
32template <size_t N>
33bool parseExpectError(const char (&Buf)[N], const char *Error) {
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +000034 Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
35 remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
36 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
37 EXPECT_TRUE(*MaybeParser != nullptr);
38
39 remarks::Parser &Parser = **MaybeParser;
40 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
41 EXPECT_FALSE(Remark); // Check for parsing errors.
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +000042
43 std::string ErrorStr;
44 raw_string_ostream Stream(ErrorStr);
45 handleAllErrors(Remark.takeError(),
46 [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
47 return StringRef(Stream.str()).contains(Error);
48}
49
50TEST(YAMLRemarks, ParsingEmpty) {
51 EXPECT_TRUE(parseExpectError("\n\n", "document root is not of mapping type."));
52}
53
54TEST(YAMLRemarks, ParsingNotYAML) {
55 EXPECT_TRUE(
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +000056 parseExpectError("\x01\x02\x03\x04\x05\x06", "Got empty plain scalar"));
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +000057}
58
59TEST(YAMLRemarks, ParsingGood) {
60 parseGood("\n"
61 "--- !Missed\n"
62 "Pass: inline\n"
63 "Name: NoDefinition\n"
64 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
65 "Function: foo\n"
66 "Args:\n"
67 " - Callee: bar\n"
68 " - String: ' will not be inlined into '\n"
69 " - Caller: foo\n"
70 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
71 " - String: ' because its definition is unavailable'\n"
72 "");
73
74 // No debug loc should also pass.
75 parseGood("\n"
76 "--- !Missed\n"
77 "Pass: inline\n"
78 "Name: NoDefinition\n"
79 "Function: foo\n"
80 "Args:\n"
81 " - Callee: bar\n"
82 " - String: ' will not be inlined into '\n"
83 " - Caller: foo\n"
84 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
85 " - String: ' because its definition is unavailable'\n"
86 "");
87
88 // No args is also ok.
89 parseGood("\n"
90 "--- !Missed\n"
91 "Pass: inline\n"
92 "Name: NoDefinition\n"
93 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
94 "Function: foo\n"
95 "");
96
97 // Different order.
98 parseGood("\n"
99 "--- !Missed\n"
100 "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
101 "Function: foo\n"
102 "Name: NoDefinition\n"
103 "Args:\n"
104 " - Callee: bar\n"
105 " - String: ' will not be inlined into '\n"
106 " - Caller: foo\n"
107 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
108 " - String: ' because its definition is unavailable'\n"
109 "Pass: inline\n"
110 "");
111}
112
113// Mandatory common part of a remark.
114#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
115// Test all the types.
116TEST(YAMLRemarks, ParsingTypes) {
117 // Type: Passed
118 parseGood("--- !Passed" COMMON_REMARK);
119 // Type: Missed
120 parseGood("--- !Missed" COMMON_REMARK);
121 // Type: Analysis
122 parseGood("--- !Analysis" COMMON_REMARK);
123 // Type: AnalysisFPCommute
124 parseGood("--- !AnalysisFPCommute" COMMON_REMARK);
125 // Type: AnalysisAliasing
126 parseGood("--- !AnalysisAliasing" COMMON_REMARK);
127 // Type: Failure
128 parseGood("--- !Failure" COMMON_REMARK);
129}
130#undef COMMON_REMARK
131
132TEST(YAMLRemarks, ParsingMissingFields) {
133 // No type.
134 EXPECT_TRUE(parseExpectError("\n"
135 "---\n"
136 "Pass: inline\n"
137 "Name: NoDefinition\n"
138 "Function: foo\n"
139 "",
140 "expected a remark tag."));
141 // No pass.
142 EXPECT_TRUE(parseExpectError("\n"
143 "--- !Missed\n"
144 "Name: NoDefinition\n"
145 "Function: foo\n"
146 "",
147 "Type, Pass, Name or Function missing."));
148 // No name.
149 EXPECT_TRUE(parseExpectError("\n"
150 "--- !Missed\n"
151 "Pass: inline\n"
152 "Function: foo\n"
153 "",
154 "Type, Pass, Name or Function missing."));
155 // No function.
156 EXPECT_TRUE(parseExpectError("\n"
157 "--- !Missed\n"
158 "Pass: inline\n"
159 "Name: NoDefinition\n"
160 "",
161 "Type, Pass, Name or Function missing."));
162 // Debug loc but no file.
163 EXPECT_TRUE(parseExpectError("\n"
164 "--- !Missed\n"
165 "Pass: inline\n"
166 "Name: NoDefinition\n"
167 "Function: foo\n"
168 "DebugLoc: { Line: 3, Column: 12 }\n"
169 "",
170 "DebugLoc node incomplete."));
171 // Debug loc but no line.
172 EXPECT_TRUE(parseExpectError("\n"
173 "--- !Missed\n"
174 "Pass: inline\n"
175 "Name: NoDefinition\n"
176 "Function: foo\n"
177 "DebugLoc: { File: file.c, Column: 12 }\n"
178 "",
179 "DebugLoc node incomplete."));
180 // Debug loc but no column.
181 EXPECT_TRUE(parseExpectError("\n"
182 "--- !Missed\n"
183 "Pass: inline\n"
184 "Name: NoDefinition\n"
185 "Function: foo\n"
186 "DebugLoc: { File: file.c, Line: 3 }\n"
187 "",
188 "DebugLoc node incomplete."));
189}
190
191TEST(YAMLRemarks, ParsingWrongTypes) {
192 // Wrong debug loc type.
193 EXPECT_TRUE(parseExpectError("\n"
194 "--- !Missed\n"
195 "Pass: inline\n"
196 "Name: NoDefinition\n"
197 "Function: foo\n"
198 "DebugLoc: foo\n"
199 "",
200 "expected a value of mapping type."));
201 // Wrong line type.
202 EXPECT_TRUE(parseExpectError("\n"
203 "--- !Missed\n"
204 "Pass: inline\n"
205 "Name: NoDefinition\n"
206 "Function: foo\n"
207 "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
208 "",
209 "expected a value of integer type."));
210 // Wrong column type.
211 EXPECT_TRUE(parseExpectError("\n"
212 "--- !Missed\n"
213 "Pass: inline\n"
214 "Name: NoDefinition\n"
215 "Function: foo\n"
216 "DebugLoc: { File: file.c, Line: 3, Column: c }\n"
217 "",
218 "expected a value of integer type."));
219 // Wrong args type.
220 EXPECT_TRUE(parseExpectError("\n"
221 "--- !Missed\n"
222 "Pass: inline\n"
223 "Name: NoDefinition\n"
224 "Function: foo\n"
225 "Args: foo\n"
226 "",
227 "wrong value type for key."));
228 // Wrong key type.
229 EXPECT_TRUE(parseExpectError("\n"
230 "--- !Missed\n"
231 "{ A: a }: inline\n"
232 "Name: NoDefinition\n"
233 "Function: foo\n"
234 "",
235 "key is not a string."));
236 // Debug loc with unknown entry.
237 EXPECT_TRUE(parseExpectError("\n"
238 "--- !Missed\n"
239 "Pass: inline\n"
240 "Name: NoDefinition\n"
241 "Function: foo\n"
242 "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
243 "",
244 "unknown entry in DebugLoc map."));
245 // Unknown entry.
246 EXPECT_TRUE(parseExpectError("\n"
247 "--- !Missed\n"
248 "Unknown: inline\n"
249 "",
250 "unknown key."));
251 // Not a scalar.
252 EXPECT_TRUE(parseExpectError("\n"
253 "--- !Missed\n"
254 "Pass: { File: a, Line: 1, Column: 2 }\n"
255 "Name: NoDefinition\n"
256 "Function: foo\n"
257 "",
258 "expected a value of scalar type."));
259 // Not a string file in debug loc.
260 EXPECT_TRUE(parseExpectError("\n"
261 "--- !Missed\n"
262 "Pass: inline\n"
263 "Name: NoDefinition\n"
264 "Function: foo\n"
265 "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
266 "",
267 "expected a value of scalar type."));
268 // Not a integer column in debug loc.
269 EXPECT_TRUE(parseExpectError("\n"
270 "--- !Missed\n"
271 "Pass: inline\n"
272 "Name: NoDefinition\n"
273 "Function: foo\n"
274 "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
275 "",
276 "expected a value of scalar type."));
277 // Not a integer line in debug loc.
278 EXPECT_TRUE(parseExpectError("\n"
279 "--- !Missed\n"
280 "Pass: inline\n"
281 "Name: NoDefinition\n"
282 "Function: foo\n"
283 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
284 "",
285 "expected a value of scalar type."));
286 // Not a mapping type value for args.
287 EXPECT_TRUE(parseExpectError("\n"
288 "--- !Missed\n"
289 "Pass: inline\n"
290 "Name: NoDefinition\n"
291 "Function: foo\n"
292 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
293 "",
294 "expected a value of scalar type."));
295}
296
297TEST(YAMLRemarks, ParsingWrongArgs) {
298 // Multiple debug locs per arg.
299 EXPECT_TRUE(parseExpectError("\n"
300 "--- !Missed\n"
301 "Pass: inline\n"
302 "Name: NoDefinition\n"
303 "Function: foo\n"
304 "Args:\n"
305 " - Str: string\n"
306 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
307 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
308 "",
309 "only one DebugLoc entry is allowed per argument."));
310 // Multiple strings per arg.
311 EXPECT_TRUE(parseExpectError("\n"
312 "--- !Missed\n"
313 "Pass: inline\n"
314 "Name: NoDefinition\n"
315 "Function: foo\n"
316 "Args:\n"
317 " - Str: string\n"
318 " Str2: string\n"
319 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
320 "",
321 "only one string entry is allowed per argument."));
322 // No arg value.
323 EXPECT_TRUE(parseExpectError("\n"
324 "--- !Missed\n"
325 "Pass: inline\n"
326 "Name: NoDefinition\n"
327 "Function: foo\n"
328 "Args:\n"
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +0000329 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
330 "",
331 "argument key is missing."));
332}
333
334static inline StringRef checkStr(StringRef Str, unsigned ExpectedLen) {
335 const char *StrData = Str.data();
336 unsigned StrLen = Str.size();
337 EXPECT_EQ(StrLen, ExpectedLen);
338 return StringRef(StrData, StrLen);
339}
340
341TEST(YAMLRemarks, Contents) {
342 StringRef Buf = "\n"
343 "--- !Missed\n"
344 "Pass: inline\n"
345 "Name: NoDefinition\n"
346 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
347 "Function: foo\n"
348 "Hotness: 4\n"
349 "Args:\n"
350 " - Callee: bar\n"
351 " - String: ' will not be inlined into '\n"
352 " - Caller: foo\n"
353 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
354 " - String: ' because its definition is unavailable'\n"
355 "\n";
356
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000357 Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
358 remarks::createRemarkParser(remarks::Format::YAML, Buf);
359 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
360 EXPECT_TRUE(*MaybeParser != nullptr);
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +0000361
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000362 remarks::Parser &Parser = **MaybeParser;
363 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
364 EXPECT_FALSE(
365 errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
366 EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.
367
368 const remarks::Remark &Remark = **MaybeRemark;
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +0000369 EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
370 EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
371 EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
372 EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
373 EXPECT_TRUE(Remark.Loc);
374 const remarks::RemarkLocation &RL = *Remark.Loc;
375 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
376 EXPECT_EQ(RL.SourceLine, 3U);
377 EXPECT_EQ(RL.SourceColumn, 12U);
378 EXPECT_TRUE(Remark.Hotness);
379 EXPECT_EQ(*Remark.Hotness, 4U);
380 EXPECT_EQ(Remark.Args.size(), 4U);
381
382 unsigned ArgID = 0;
383 for (const remarks::Argument &Arg : Remark.Args) {
384 switch (ArgID) {
385 case 0:
386 EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
387 EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
388 EXPECT_FALSE(Arg.Loc);
389 break;
390 case 1:
391 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
392 EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
393 EXPECT_FALSE(Arg.Loc);
394 break;
395 case 2: {
396 EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
397 EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
398 EXPECT_TRUE(Arg.Loc);
399 const remarks::RemarkLocation &RL = *Arg.Loc;
400 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
401 EXPECT_EQ(RL.SourceLine, 2U);
402 EXPECT_EQ(RL.SourceColumn, 0U);
403 break;
404 }
405 case 3:
406 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
407 EXPECT_EQ(checkStr(Arg.Val, 38),
408 " because its definition is unavailable");
409 EXPECT_FALSE(Arg.Loc);
410 break;
411 default:
412 break;
413 }
414 ++ArgID;
415 }
416
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000417 MaybeRemark = Parser.next();
418 Error E = MaybeRemark.takeError();
419 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
420 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +0000421}
422
423static inline StringRef checkStr(LLVMRemarkStringRef Str,
424 unsigned ExpectedLen) {
425 const char *StrData = LLVMRemarkStringGetData(Str);
426 unsigned StrLen = LLVMRemarkStringGetLen(Str);
427 EXPECT_EQ(StrLen, ExpectedLen);
428 return StringRef(StrData, StrLen);
429}
430
431TEST(YAMLRemarks, ContentsCAPI) {
432 StringRef Buf = "\n"
433 "--- !Missed\n"
434 "Pass: inline\n"
435 "Name: NoDefinition\n"
436 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
437 "Function: foo\n"
438 "Args:\n"
439 " - Callee: bar\n"
440 " - String: ' will not be inlined into '\n"
441 " - Caller: foo\n"
442 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
443 " - String: ' because its definition is unavailable'\n"
444 "\n";
445
446 LLVMRemarkParserRef Parser =
447 LLVMRemarkParserCreateYAML(Buf.data(), Buf.size());
448 LLVMRemarkEntryRef Remark = LLVMRemarkParserGetNext(Parser);
449 EXPECT_FALSE(Remark == nullptr);
450 EXPECT_EQ(LLVMRemarkEntryGetType(Remark), LLVMRemarkTypeMissed);
451 EXPECT_EQ(checkStr(LLVMRemarkEntryGetPassName(Remark), 6), "inline");
452 EXPECT_EQ(checkStr(LLVMRemarkEntryGetRemarkName(Remark), 12), "NoDefinition");
453 EXPECT_EQ(checkStr(LLVMRemarkEntryGetFunctionName(Remark), 3), "foo");
454 LLVMRemarkDebugLocRef DL = LLVMRemarkEntryGetDebugLoc(Remark);
455 EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
456 EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 3U);
457 EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 12U);
458 EXPECT_EQ(LLVMRemarkEntryGetHotness(Remark), 0U);
459 EXPECT_EQ(LLVMRemarkEntryGetNumArgs(Remark), 4U);
460
461 unsigned ArgID = 0;
462 LLVMRemarkArgRef Arg = LLVMRemarkEntryGetFirstArg(Remark);
463 do {
464 switch (ArgID) {
465 case 0:
466 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Callee");
467 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "bar");
468 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
469 break;
470 case 1:
471 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
472 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 26),
473 " will not be inlined into ");
474 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
475 break;
476 case 2: {
477 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Caller");
478 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "foo");
479 LLVMRemarkDebugLocRef DL = LLVMRemarkArgGetDebugLoc(Arg);
480 EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
481 EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 2U);
482 EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 0U);
483 break;
484 }
485 case 3:
486 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
487 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 38),
488 " because its definition is unavailable");
489 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
490 break;
491 default:
492 break;
493 }
494 ++ArgID;
495 } while ((Arg = LLVMRemarkEntryGetNextArg(Arg, Remark)));
496
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000497 LLVMRemarkEntryDispose(Remark);
498
Francis Visoiu Mistrih5a05cc02019-03-19 21:11:07 +0000499 EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr);
500
501 EXPECT_FALSE(LLVMRemarkParserHasError(Parser));
502 LLVMRemarkParserDispose(Parser);
503}
Francis Visoiu Mistrih7fee2b82019-04-24 00:06:24 +0000504
505TEST(YAMLRemarks, ContentsStrTab) {
506 StringRef Buf = "\n"
507 "--- !Missed\n"
508 "Pass: 0\n"
509 "Name: 1\n"
510 "DebugLoc: { File: 2, Line: 3, Column: 12 }\n"
511 "Function: 3\n"
512 "Hotness: 4\n"
513 "Args:\n"
514 " - Callee: 5\n"
515 " - String: 7\n"
516 " - Caller: 3\n"
517 " DebugLoc: { File: 2, Line: 2, Column: 0 }\n"
518 " - String: 8\n"
519 "\n";
520
521 StringRef StrTabBuf =
522 StringRef("inline\0NoDefinition\0file.c\0foo\0Callee\0bar\0String\0 "
523 "will not be inlined into \0 because its definition is "
524 "unavailable",
525 115);
526
Francis Visoiu Mistrihe6ba3132019-07-04 00:30:58 +0000527 remarks::ParsedStringTable StrTab(StrTabBuf);
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000528 Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
Francis Visoiu Mistrih4287c952019-07-23 22:50:08 +0000529 remarks::createRemarkParser(remarks::Format::YAMLStrTab, Buf,
530 std::move(StrTab));
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000531 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
532 EXPECT_TRUE(*MaybeParser != nullptr);
Francis Visoiu Mistrih7fee2b82019-04-24 00:06:24 +0000533
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000534 remarks::Parser &Parser = **MaybeParser;
535 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
536 EXPECT_FALSE(
537 errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
538 EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.
539
540 const remarks::Remark &Remark = **MaybeRemark;
Francis Visoiu Mistrih7fee2b82019-04-24 00:06:24 +0000541 EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
542 EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
543 EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
544 EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
545 EXPECT_TRUE(Remark.Loc);
546 const remarks::RemarkLocation &RL = *Remark.Loc;
547 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
548 EXPECT_EQ(RL.SourceLine, 3U);
549 EXPECT_EQ(RL.SourceColumn, 12U);
550 EXPECT_TRUE(Remark.Hotness);
551 EXPECT_EQ(*Remark.Hotness, 4U);
552 EXPECT_EQ(Remark.Args.size(), 4U);
553
554 unsigned ArgID = 0;
555 for (const remarks::Argument &Arg : Remark.Args) {
556 switch (ArgID) {
557 case 0:
558 EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
559 EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
560 EXPECT_FALSE(Arg.Loc);
561 break;
562 case 1:
563 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
564 EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
565 EXPECT_FALSE(Arg.Loc);
566 break;
567 case 2: {
568 EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
569 EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
570 EXPECT_TRUE(Arg.Loc);
571 const remarks::RemarkLocation &RL = *Arg.Loc;
572 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
573 EXPECT_EQ(RL.SourceLine, 2U);
574 EXPECT_EQ(RL.SourceColumn, 0U);
575 break;
576 }
577 case 3:
578 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
579 EXPECT_EQ(checkStr(Arg.Val, 38),
580 " because its definition is unavailable");
581 EXPECT_FALSE(Arg.Loc);
582 break;
583 default:
584 break;
585 }
586 ++ArgID;
587 }
588
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000589 MaybeRemark = Parser.next();
590 Error E = MaybeRemark.takeError();
591 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
592 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
Francis Visoiu Mistrih7fee2b82019-04-24 00:06:24 +0000593}
594
595TEST(YAMLRemarks, ParsingBadStringTableIndex) {
596 StringRef Buf = "\n"
597 "--- !Missed\n"
598 "Pass: 50\n"
599 "\n";
600
601 StringRef StrTabBuf = StringRef("inline");
602
Francis Visoiu Mistrihe6ba3132019-07-04 00:30:58 +0000603 remarks::ParsedStringTable StrTab(StrTabBuf);
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000604 Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
Francis Visoiu Mistrih4287c952019-07-23 22:50:08 +0000605 remarks::createRemarkParser(remarks::Format::YAMLStrTab, Buf,
606 std::move(StrTab));
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000607 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
608 EXPECT_TRUE(*MaybeParser != nullptr);
609
610 remarks::Parser &Parser = **MaybeParser;
611 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
612 EXPECT_FALSE(MaybeRemark); // Expect an error here.
Francis Visoiu Mistrih7fee2b82019-04-24 00:06:24 +0000613
614 std::string ErrorStr;
615 raw_string_ostream Stream(ErrorStr);
Francis Visoiu Mistrih94bad222019-07-16 15:25:05 +0000616 handleAllErrors(MaybeRemark.takeError(),
Francis Visoiu Mistrih7fee2b82019-04-24 00:06:24 +0000617 [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
618 EXPECT_TRUE(
619 StringRef(Stream.str())
620 .contains("String with index 50 is out of bounds (size = 1)."));
621}