1 //===- unittest/Support/OptRemarksParsingTest.cpp - OptTable tests --------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm-c/OptRemarks.h"
10 #include "gtest/gtest.h"
14 template <size_t N
> bool tryParse(const char (&Buf
)[N
]) {
15 LLVMOptRemarkParserRef Parser
= LLVMOptRemarkParserCreate(Buf
, N
- 1);
16 LLVMOptRemarkEntry
*Remark
= nullptr;
17 while (LLVMOptRemarkEntry
*NewRemark
= LLVMOptRemarkParserGetNext(Parser
)) {
18 EXPECT_TRUE(Remark
== nullptr); // Only one remark per test.
21 EXPECT_TRUE(Remark
!= nullptr); // We need *exactly* one remark per test.
22 bool HasError
= LLVMOptRemarkParserHasError(Parser
);
23 LLVMOptRemarkParserDispose(Parser
);
28 bool parseExpectError(const char (&Buf
)[N
], const char *Error
) {
29 LLVMOptRemarkParserRef Parser
= LLVMOptRemarkParserCreate(Buf
, N
- 1);
30 LLVMOptRemarkEntry
*Remark
= nullptr;
31 while (LLVMOptRemarkEntry
*NewRemark
= LLVMOptRemarkParserGetNext(Parser
)) {
32 EXPECT_FALSE(NewRemark
);
34 EXPECT_TRUE(Remark
== nullptr); // We are parsing only one malformed remark.
35 EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser
));
37 StringRef(LLVMOptRemarkParserGetErrorMessage(Parser
)).contains(Error
);
38 LLVMOptRemarkParserDispose(Parser
);
43 TEST(OptRemarks
, OptRemarksParsingEmpty
) {
46 LLVMOptRemarkParserRef Parser
=
47 LLVMOptRemarkParserCreate(Buf
.data(), Buf
.size());
48 LLVMOptRemarkEntry
*NewRemark
= LLVMOptRemarkParserGetNext(Parser
);
49 EXPECT_TRUE(NewRemark
== nullptr); // No remark expected.
50 EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser
));
51 EXPECT_TRUE(StringRef(LLVMOptRemarkParserGetErrorMessage(Parser
))
52 .contains("document root is not of mapping type."));
53 LLVMOptRemarkParserDispose(Parser
);
56 TEST(OptRemarks
, OptRemarksParsingGood
) {
57 EXPECT_TRUE(tryParse("\n"
60 "Name: NoDefinition\n"
61 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
65 " - String: ' will not be inlined into '\n"
67 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
68 " - String: ' because its definition is unavailable'\n"
71 // No debug loc should also pass.
72 EXPECT_TRUE(tryParse("\n"
75 "Name: NoDefinition\n"
79 " - String: ' will not be inlined into '\n"
81 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
82 " - String: ' because its definition is unavailable'\n"
85 // No args is also ok.
86 EXPECT_TRUE(tryParse("\n"
89 "Name: NoDefinition\n"
90 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
95 EXPECT_TRUE(tryParse("\n"
97 "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
99 "Name: NoDefinition\n"
102 " - String: ' will not be inlined into '\n"
104 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
105 " - String: ' because its definition is unavailable'\n"
110 // Mandatory common part of a remark.
111 #define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
112 // Test all the types.
113 TEST(OptRemarks
, OptRemarksParsingTypes
) {
115 EXPECT_TRUE(tryParse("--- !Passed" COMMON_REMARK
));
117 EXPECT_TRUE(tryParse("--- !Missed" COMMON_REMARK
));
119 EXPECT_TRUE(tryParse("--- !Analysis" COMMON_REMARK
));
120 // Type: AnalysisFPCompute
121 EXPECT_TRUE(tryParse("--- !AnalysisFPCompute" COMMON_REMARK
));
122 // Type: AnalysisAliasing
123 EXPECT_TRUE(tryParse("--- !AnalysisAliasing" COMMON_REMARK
));
125 EXPECT_TRUE(tryParse("--- !Failure" COMMON_REMARK
));
129 TEST(OptRemarks
, OptRemarksParsingMissingFields
) {
131 EXPECT_TRUE(parseExpectError("\n"
134 "Name: NoDefinition\n"
137 "error: Type, Pass, Name or Function missing."));
139 EXPECT_TRUE(parseExpectError("\n"
141 "Name: NoDefinition\n"
144 "error: Type, Pass, Name or Function missing."));
146 EXPECT_TRUE(parseExpectError("\n"
151 "error: Type, Pass, Name or Function missing."));
153 EXPECT_TRUE(parseExpectError("\n"
156 "Name: NoDefinition\n"
158 "error: Type, Pass, Name or Function missing."));
159 // Debug loc but no file.
160 EXPECT_TRUE(parseExpectError("\n"
163 "Name: NoDefinition\n"
165 "DebugLoc: { Line: 3, Column: 12 }\n"
167 "DebugLoc node incomplete."));
168 // Debug loc but no line.
169 EXPECT_TRUE(parseExpectError("\n"
172 "Name: NoDefinition\n"
174 "DebugLoc: { File: file.c, Column: 12 }\n"
176 "DebugLoc node incomplete."));
177 // Debug loc but no column.
178 EXPECT_TRUE(parseExpectError("\n"
181 "Name: NoDefinition\n"
183 "DebugLoc: { File: file.c, Line: 3 }\n"
185 "DebugLoc node incomplete."));
188 TEST(OptRemarks
, OptRemarksParsingWrongTypes
) {
189 // Wrong debug loc type.
190 EXPECT_TRUE(parseExpectError("\n"
193 "Name: NoDefinition\n"
197 "expected a value of mapping type."));
199 EXPECT_TRUE(parseExpectError("\n"
202 "Name: NoDefinition\n"
204 "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
206 "expected a value of integer type."));
207 // Wrong column type.
208 EXPECT_TRUE(parseExpectError("\n"
211 "Name: NoDefinition\n"
213 "DebugLoc: { File: file.c, Line: 3, Column: c }\n"
215 "expected a value of integer type."));
217 EXPECT_TRUE(parseExpectError("\n"
220 "Name: NoDefinition\n"
224 "wrong value type for key."));
226 EXPECT_TRUE(parseExpectError("\n"
229 "Name: NoDefinition\n"
232 "key is not a string."));
233 // Debug loc with unknown entry.
234 EXPECT_TRUE(parseExpectError("\n"
237 "Name: NoDefinition\n"
239 "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
241 "unknown entry in DebugLoc map."));
243 EXPECT_TRUE(parseExpectError("\n"
249 EXPECT_TRUE(parseExpectError("\n"
251 "Pass: { File: a, Line: 1, Column: 2 }\n"
252 "Name: NoDefinition\n"
255 "expected a value of scalar type."));
256 // Not a string file in debug loc.
257 EXPECT_TRUE(parseExpectError("\n"
260 "Name: NoDefinition\n"
262 "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
264 "expected a value of scalar type."));
265 // Not a integer column in debug loc.
266 EXPECT_TRUE(parseExpectError("\n"
269 "Name: NoDefinition\n"
271 "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
273 "expected a value of scalar type."));
274 // Not a integer line in debug loc.
275 EXPECT_TRUE(parseExpectError("\n"
278 "Name: NoDefinition\n"
280 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
282 "expected a value of scalar type."));
283 // Not a mapping type value for args.
284 EXPECT_TRUE(parseExpectError("\n"
287 "Name: NoDefinition\n"
289 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
291 "expected a value of scalar type."));
294 TEST(OptRemarks
, OptRemarksParsingWrongArgs
) {
295 // Multiple debug locs per arg.
297 parseExpectError("\n"
300 "Name: NoDefinition\n"
304 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
305 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
307 "only one DebugLoc entry is allowed per argument."));
308 // Multiple strings per arg.
310 parseExpectError("\n"
313 "Name: NoDefinition\n"
318 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
320 "only one string entry is allowed per argument."));
322 EXPECT_TRUE(parseExpectError("\n"
325 "Name: NoDefinition\n"
329 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
331 "argument value is missing."));
333 EXPECT_TRUE(parseExpectError("\n"
336 "Name: NoDefinition\n"
339 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
341 "argument key is missing."));
345 TEST(OptRemarks
, OptRemarksGoodStruct
) {
349 "Name: NoDefinition\n"
350 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
354 " - String: ' will not be inlined into '\n"
356 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
357 " - String: ' because its definition is unavailable'\n"
360 LLVMOptRemarkParserRef Parser
=
361 LLVMOptRemarkParserCreate(Buf
.data(), Buf
.size());
362 LLVMOptRemarkEntry
*Remark
= LLVMOptRemarkParserGetNext(Parser
);
363 EXPECT_FALSE(Remark
== nullptr);
364 EXPECT_EQ(StringRef(Remark
->RemarkType
.Str
, 7), "!Missed");
365 EXPECT_EQ(Remark
->RemarkType
.Len
, 7U);
366 EXPECT_EQ(StringRef(Remark
->PassName
.Str
, 6), "inline");
367 EXPECT_EQ(Remark
->PassName
.Len
, 6U);
368 EXPECT_EQ(StringRef(Remark
->RemarkName
.Str
, 12), "NoDefinition");
369 EXPECT_EQ(Remark
->RemarkName
.Len
, 12U);
370 EXPECT_EQ(StringRef(Remark
->FunctionName
.Str
, 3), "foo");
371 EXPECT_EQ(Remark
->FunctionName
.Len
, 3U);
372 EXPECT_EQ(StringRef(Remark
->DebugLoc
.SourceFile
.Str
, 6), "file.c");
373 EXPECT_EQ(Remark
->DebugLoc
.SourceFile
.Len
, 6U);
374 EXPECT_EQ(Remark
->DebugLoc
.SourceLineNumber
, 3U);
375 EXPECT_EQ(Remark
->DebugLoc
.SourceColumnNumber
, 12U);
376 EXPECT_EQ(Remark
->Hotness
, 0U);
377 EXPECT_EQ(Remark
->NumArgs
, 4U);
380 LLVMOptRemarkArg
&Arg
= Remark
->Args
[0];
381 EXPECT_EQ(StringRef(Arg
.Key
.Str
, 6), "Callee");
382 EXPECT_EQ(Arg
.Key
.Len
, 6U);
383 EXPECT_EQ(StringRef(Arg
.Value
.Str
, 3), "bar");
384 EXPECT_EQ(Arg
.Value
.Len
, 3U);
385 EXPECT_EQ(StringRef(Arg
.DebugLoc
.SourceFile
.Str
, 0), "");
386 EXPECT_EQ(Arg
.DebugLoc
.SourceFile
.Len
, 0U);
387 EXPECT_EQ(Arg
.DebugLoc
.SourceLineNumber
, 0U);
388 EXPECT_EQ(Arg
.DebugLoc
.SourceColumnNumber
, 0U);
392 LLVMOptRemarkArg
&Arg
= Remark
->Args
[1];
393 EXPECT_EQ(StringRef(Arg
.Key
.Str
, 6), "String");
394 EXPECT_EQ(Arg
.Key
.Len
, 6U);
395 EXPECT_EQ(StringRef(Arg
.Value
.Str
, 26), " will not be inlined into ");
396 EXPECT_EQ(Arg
.Value
.Len
, 26U);
397 EXPECT_EQ(StringRef(Arg
.DebugLoc
.SourceFile
.Str
, 0), "");
398 EXPECT_EQ(Arg
.DebugLoc
.SourceFile
.Len
, 0U);
399 EXPECT_EQ(Arg
.DebugLoc
.SourceLineNumber
, 0U);
400 EXPECT_EQ(Arg
.DebugLoc
.SourceColumnNumber
, 0U);
404 LLVMOptRemarkArg
&Arg
= Remark
->Args
[2];
405 EXPECT_EQ(StringRef(Arg
.Key
.Str
, 6), "Caller");
406 EXPECT_EQ(Arg
.Key
.Len
, 6U);
407 EXPECT_EQ(StringRef(Arg
.Value
.Str
, 3), "foo");
408 EXPECT_EQ(Arg
.Value
.Len
, 3U);
409 EXPECT_EQ(StringRef(Arg
.DebugLoc
.SourceFile
.Str
, 6), "file.c");
410 EXPECT_EQ(Arg
.DebugLoc
.SourceFile
.Len
, 6U);
411 EXPECT_EQ(Arg
.DebugLoc
.SourceLineNumber
, 2U);
412 EXPECT_EQ(Arg
.DebugLoc
.SourceColumnNumber
, 0U);
416 LLVMOptRemarkArg
&Arg
= Remark
->Args
[3];
417 EXPECT_EQ(StringRef(Arg
.Key
.Str
, 6), "String");
418 EXPECT_EQ(Arg
.Key
.Len
, 6U);
419 EXPECT_EQ(StringRef(Arg
.Value
.Str
, 38),
420 " because its definition is unavailable");
421 EXPECT_EQ(Arg
.Value
.Len
, 38U);
422 EXPECT_EQ(StringRef(Arg
.DebugLoc
.SourceFile
.Str
, 0), "");
423 EXPECT_EQ(Arg
.DebugLoc
.SourceFile
.Len
, 0U);
424 EXPECT_EQ(Arg
.DebugLoc
.SourceLineNumber
, 0U);
425 EXPECT_EQ(Arg
.DebugLoc
.SourceColumnNumber
, 0U);
428 EXPECT_EQ(LLVMOptRemarkParserGetNext(Parser
), nullptr);
430 EXPECT_FALSE(LLVMOptRemarkParserHasError(Parser
));
431 LLVMOptRemarkParserDispose(Parser
);