diff options
Diffstat (limited to 'llvm/unittests/Remarks')
-rw-r--r-- | llvm/unittests/Remarks/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/unittests/Remarks/RemarksParsingTest.cpp | 436 | ||||
-rw-r--r-- | llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp | 494 |
3 files changed, 437 insertions, 495 deletions
diff --git a/llvm/unittests/Remarks/CMakeLists.txt b/llvm/unittests/Remarks/CMakeLists.txt index b7d22b694ef..7d80cf2348d 100644 --- a/llvm/unittests/Remarks/CMakeLists.txt +++ b/llvm/unittests/Remarks/CMakeLists.txt @@ -4,5 +4,5 @@ set(LLVM_LINK_COMPONENTS ) add_llvm_unittest(RemarksTests - YAMLRemarksParsingTest.cpp + RemarksParsingTest.cpp ) diff --git a/llvm/unittests/Remarks/RemarksParsingTest.cpp b/llvm/unittests/Remarks/RemarksParsingTest.cpp new file mode 100644 index 00000000000..a167b8318a4 --- /dev/null +++ b/llvm/unittests/Remarks/RemarksParsingTest.cpp @@ -0,0 +1,436 @@ +//===- unittest/Support/RemarksParsingTest.cpp - OptTable tests --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/Remarks.h" +#include "gtest/gtest.h" + +using namespace llvm; + +template <size_t N> bool tryParse(const char (&Buf)[N]) { + LLVMRemarkParserRef Parser = LLVMRemarkParserCreate(Buf, N - 1); + LLVMRemarkEntry *Remark = nullptr; + while (LLVMRemarkEntry *NewRemark = LLVMRemarkParserGetNext(Parser)) { + EXPECT_TRUE(Remark == nullptr); // Only one remark per test. + Remark = NewRemark; + } + EXPECT_TRUE(Remark != nullptr); // We need *exactly* one remark per test. + bool HasError = LLVMRemarkParserHasError(Parser); + LLVMRemarkParserDispose(Parser); + return !HasError; +} + +template <size_t N> +bool parseExpectError(const char (&Buf)[N], const char *Error) { + LLVMRemarkParserRef Parser = LLVMRemarkParserCreate(Buf, N - 1); + LLVMRemarkEntry *Remark = nullptr; + while (LLVMRemarkEntry *NewRemark = LLVMRemarkParserGetNext(Parser)) { + EXPECT_FALSE(NewRemark); + } + EXPECT_TRUE(Remark == nullptr); // We are parsing only one malformed remark. + EXPECT_TRUE(LLVMRemarkParserHasError(Parser)); + bool MatchesError = + StringRef(LLVMRemarkParserGetErrorMessage(Parser)).contains(Error); + LLVMRemarkParserDispose(Parser); + + return MatchesError; +} + +TEST(Remarks, RemarksParsingEmpty) { + StringRef Buf = "\n" + "\n"; + LLVMRemarkParserRef Parser = LLVMRemarkParserCreate(Buf.data(), Buf.size()); + LLVMRemarkEntry *NewRemark = LLVMRemarkParserGetNext(Parser); + EXPECT_TRUE(NewRemark == nullptr); // No remark expected. + EXPECT_TRUE(LLVMRemarkParserHasError(Parser)); + EXPECT_TRUE(StringRef(LLVMRemarkParserGetErrorMessage(Parser)) + .contains("document root is not of mapping type.")); + LLVMRemarkParserDispose(Parser); +} + +TEST(Remarks, RemarksParsingGood) { + EXPECT_TRUE(tryParse("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" + "Function: foo\n" + "Args:\n" + " - Callee: bar\n" + " - String: ' will not be inlined into '\n" + " - Caller: foo\n" + " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" + " - String: ' because its definition is unavailable'\n" + "")); + + // No debug loc should also pass. + EXPECT_TRUE(tryParse("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "Args:\n" + " - Callee: bar\n" + " - String: ' will not be inlined into '\n" + " - Caller: foo\n" + " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" + " - String: ' because its definition is unavailable'\n" + "")); + + // No args is also ok. + EXPECT_TRUE(tryParse("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" + "Function: foo\n" + "")); + + // Different order. + EXPECT_TRUE(tryParse("\n" + "--- !Missed\n" + "DebugLoc: { Line: 3, Column: 12, File: file.c }\n" + "Function: foo\n" + "Name: NoDefinition\n" + "Args:\n" + " - Callee: bar\n" + " - String: ' will not be inlined into '\n" + " - Caller: foo\n" + " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" + " - String: ' because its definition is unavailable'\n" + "Pass: inline\n" + "")); +} + +// Mandatory common part of a remark. +#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n" +// Test all the types. +TEST(Remarks, RemarksParsingTypes) { + // Type: Passed + EXPECT_TRUE(tryParse("--- !Passed" COMMON_REMARK)); + // Type: Missed + EXPECT_TRUE(tryParse("--- !Missed" COMMON_REMARK)); + // Type: Analysis + EXPECT_TRUE(tryParse("--- !Analysis" COMMON_REMARK)); + // Type: AnalysisFPCompute + EXPECT_TRUE(tryParse("--- !AnalysisFPCompute" COMMON_REMARK)); + // Type: AnalysisAliasing + EXPECT_TRUE(tryParse("--- !AnalysisAliasing" COMMON_REMARK)); + // Type: Failure + EXPECT_TRUE(tryParse("--- !Failure" COMMON_REMARK)); +} +#undef COMMON_REMARK + +TEST(Remarks, RemarksParsingMissingFields) { + // No type. + EXPECT_TRUE(parseExpectError("\n" + "---\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "", + "error: Type, Pass, Name or Function missing.")); + // No pass. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Name: NoDefinition\n" + "Function: foo\n" + "", + "error: Type, Pass, Name or Function missing.")); + // No name. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Function: foo\n" + "", + "error: Type, Pass, Name or Function missing.")); + // No function. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "", + "error: Type, Pass, Name or Function missing.")); + // Debug loc but no file. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { Line: 3, Column: 12 }\n" + "", + "DebugLoc node incomplete.")); + // Debug loc but no line. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Column: 12 }\n" + "", + "DebugLoc node incomplete.")); + // Debug loc but no column. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Line: 3 }\n" + "", + "DebugLoc node incomplete.")); +} + +TEST(Remarks, RemarksParsingWrongTypes) { + // Wrong debug loc type. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: foo\n" + "", + "expected a value of mapping type.")); + // Wrong line type. + EXPECT_TRUE( + parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Line: b, Column: 12 }\n" + "", + "expected a value of integer type.")); + // Wrong column type. + EXPECT_TRUE( + parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Line: 3, Column: c }\n" + "", + "expected a value of integer type.")); + // Wrong args type. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "Args: foo\n" + "", + "wrong value type for key.")); + // Wrong key type. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "{ A: a }: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "", + "key is not a string.")); + // Debug loc with unknown entry. + EXPECT_TRUE( + parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n" + "", + "unknown entry in DebugLoc map.")); + // Unknown entry. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Unknown: inline\n" + "", + "unknown key.")); + // Not a scalar. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: { File: a, Line: 1, Column: 2 }\n" + "Name: NoDefinition\n" + "Function: foo\n" + "", + "expected a value of scalar type.")); + // Not a string file in debug loc. + EXPECT_TRUE( + parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n" + "", + "expected a value of scalar type.")); + // Not a integer column in debug loc. + EXPECT_TRUE(parseExpectError( + "\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n" + "", + "expected a value of scalar type.")); + // Not a integer line in debug loc. + EXPECT_TRUE(parseExpectError( + "\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n" + "", + "expected a value of scalar type.")); + // Not a mapping type value for args. + EXPECT_TRUE(parseExpectError( + "\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n" + "", + "expected a value of scalar type.")); +} + +TEST(Remarks, RemarksParsingWrongArgs) { + // Multiple debug locs per arg. + EXPECT_TRUE( + parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "Args:\n" + " - Str: string\n" + " DebugLoc: { File: a, Line: 1, Column: 2 }\n" + " DebugLoc: { File: a, Line: 1, Column: 2 }\n" + "", + "only one DebugLoc entry is allowed per argument.")); + // Multiple strings per arg. + EXPECT_TRUE( + parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "Args:\n" + " - Str: string\n" + " Str2: string\n" + " DebugLoc: { File: a, Line: 1, Column: 2 }\n" + "", + "only one string entry is allowed per argument.")); + // No arg value. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "Args:\n" + " - Callee: ''\n" + " - DebugLoc: { File: a, Line: 1, Column: 2 }\n" + "", + "argument value is missing.")); + // No arg value. + EXPECT_TRUE(parseExpectError("\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "Function: foo\n" + "Args:\n" + " - DebugLoc: { File: a, Line: 1, Column: 2 }\n" + "", + "argument key is missing.")); +} + +TEST(Remarks, RemarksGoodStruct) { + StringRef Buf = "\n" + "--- !Missed\n" + "Pass: inline\n" + "Name: NoDefinition\n" + "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" + "Function: foo\n" + "Args:\n" + " - Callee: bar\n" + " - String: ' will not be inlined into '\n" + " - Caller: foo\n" + " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" + " - String: ' because its definition is unavailable'\n" + "\n"; + + LLVMRemarkParserRef Parser = LLVMRemarkParserCreate(Buf.data(), Buf.size()); + LLVMRemarkEntry *Remark = LLVMRemarkParserGetNext(Parser); + EXPECT_FALSE(Remark == nullptr); + EXPECT_EQ(StringRef(Remark->RemarkType.Str, 7), "!Missed"); + EXPECT_EQ(Remark->RemarkType.Len, 7U); + EXPECT_EQ(StringRef(Remark->PassName.Str, 6), "inline"); + EXPECT_EQ(Remark->PassName.Len, 6U); + EXPECT_EQ(StringRef(Remark->RemarkName.Str, 12), "NoDefinition"); + EXPECT_EQ(Remark->RemarkName.Len, 12U); + EXPECT_EQ(StringRef(Remark->FunctionName.Str, 3), "foo"); + EXPECT_EQ(Remark->FunctionName.Len, 3U); + EXPECT_EQ(StringRef(Remark->DebugLoc.SourceFile.Str, 6), "file.c"); + EXPECT_EQ(Remark->DebugLoc.SourceFile.Len, 6U); + EXPECT_EQ(Remark->DebugLoc.SourceLineNumber, 3U); + EXPECT_EQ(Remark->DebugLoc.SourceColumnNumber, 12U); + EXPECT_EQ(Remark->Hotness, 0U); + EXPECT_EQ(Remark->NumArgs, 4U); + // Arg 0 + { + LLVMRemarkArg &Arg = Remark->Args[0]; + EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Callee"); + EXPECT_EQ(Arg.Key.Len, 6U); + EXPECT_EQ(StringRef(Arg.Value.Str, 3), "bar"); + EXPECT_EQ(Arg.Value.Len, 3U); + EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), ""); + EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U); + EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U); + EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U); + } + // Arg 1 + { + LLVMRemarkArg &Arg = Remark->Args[1]; + EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String"); + EXPECT_EQ(Arg.Key.Len, 6U); + EXPECT_EQ(StringRef(Arg.Value.Str, 26), " will not be inlined into "); + EXPECT_EQ(Arg.Value.Len, 26U); + EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), ""); + EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U); + EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U); + EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U); + } + // Arg 2 + { + LLVMRemarkArg &Arg = Remark->Args[2]; + EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Caller"); + EXPECT_EQ(Arg.Key.Len, 6U); + EXPECT_EQ(StringRef(Arg.Value.Str, 3), "foo"); + EXPECT_EQ(Arg.Value.Len, 3U); + EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 6), "file.c"); + EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 6U); + EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 2U); + EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U); + } + // Arg 3 + { + LLVMRemarkArg &Arg = Remark->Args[3]; + EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String"); + EXPECT_EQ(Arg.Key.Len, 6U); + EXPECT_EQ(StringRef(Arg.Value.Str, 38), + " because its definition is unavailable"); + EXPECT_EQ(Arg.Value.Len, 38U); + EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), ""); + EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U); + EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U); + EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U); + } + + EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr); + + EXPECT_FALSE(LLVMRemarkParserHasError(Parser)); + LLVMRemarkParserDispose(Parser); +} diff --git a/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp b/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp deleted file mode 100644 index 36dbb0c9518..00000000000 --- a/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp +++ /dev/null @@ -1,494 +0,0 @@ -//===- unittest/Support/YAMLRemarksParsingTest.cpp - OptTable tests -------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm-c/Remarks.h" -#include "llvm/Remarks/Remark.h" -#include "llvm/Remarks/RemarkParser.h" -#include "gtest/gtest.h" - -using namespace llvm; - -template <size_t N> void parseGood(const char (&Buf)[N]) { - remarks::Parser Parser({Buf, N - 1}); - Expected<const remarks::Remark *> Remark = Parser.getNext(); - EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors. - EXPECT_TRUE(*Remark != nullptr); // At least one remark. - Remark = Parser.getNext(); - EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors. - EXPECT_TRUE(*Remark == nullptr); // Check that there are no more remarks. -} - -template <size_t N> -bool parseExpectError(const char (&Buf)[N], const char *Error) { - remarks::Parser Parser({Buf, N - 1}); - Expected<const remarks::Remark *> Remark = Parser.getNext(); - EXPECT_FALSE(Remark); // Expect an error here. - - std::string ErrorStr; - raw_string_ostream Stream(ErrorStr); - handleAllErrors(Remark.takeError(), - [&](const ErrorInfoBase &EIB) { EIB.log(Stream); }); - return StringRef(Stream.str()).contains(Error); -} - -TEST(YAMLRemarks, ParsingEmpty) { - EXPECT_TRUE(parseExpectError("\n\n", "document root is not of mapping type.")); -} - -TEST(YAMLRemarks, ParsingNotYAML) { - EXPECT_TRUE( - parseExpectError("\x01\x02\x03\x04\x05\x06", "not a valid YAML file.")); -} - -TEST(YAMLRemarks, ParsingGood) { - parseGood("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" - "Function: foo\n" - "Args:\n" - " - Callee: bar\n" - " - String: ' will not be inlined into '\n" - " - Caller: foo\n" - " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" - " - String: ' because its definition is unavailable'\n" - ""); - - // No debug loc should also pass. - parseGood("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "Args:\n" - " - Callee: bar\n" - " - String: ' will not be inlined into '\n" - " - Caller: foo\n" - " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" - " - String: ' because its definition is unavailable'\n" - ""); - - // No args is also ok. - parseGood("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" - "Function: foo\n" - ""); - - // Different order. - parseGood("\n" - "--- !Missed\n" - "DebugLoc: { Line: 3, Column: 12, File: file.c }\n" - "Function: foo\n" - "Name: NoDefinition\n" - "Args:\n" - " - Callee: bar\n" - " - String: ' will not be inlined into '\n" - " - Caller: foo\n" - " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" - " - String: ' because its definition is unavailable'\n" - "Pass: inline\n" - ""); -} - -// Mandatory common part of a remark. -#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n" -// Test all the types. -TEST(YAMLRemarks, ParsingTypes) { - // Type: Passed - parseGood("--- !Passed" COMMON_REMARK); - // Type: Missed - parseGood("--- !Missed" COMMON_REMARK); - // Type: Analysis - parseGood("--- !Analysis" COMMON_REMARK); - // Type: AnalysisFPCommute - parseGood("--- !AnalysisFPCommute" COMMON_REMARK); - // Type: AnalysisAliasing - parseGood("--- !AnalysisAliasing" COMMON_REMARK); - // Type: Failure - parseGood("--- !Failure" COMMON_REMARK); -} -#undef COMMON_REMARK - -TEST(YAMLRemarks, ParsingMissingFields) { - // No type. - EXPECT_TRUE(parseExpectError("\n" - "---\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "", - "expected a remark tag.")); - // No pass. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Name: NoDefinition\n" - "Function: foo\n" - "", - "Type, Pass, Name or Function missing.")); - // No name. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Function: foo\n" - "", - "Type, Pass, Name or Function missing.")); - // No function. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "", - "Type, Pass, Name or Function missing.")); - // Debug loc but no file. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { Line: 3, Column: 12 }\n" - "", - "DebugLoc node incomplete.")); - // Debug loc but no line. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Column: 12 }\n" - "", - "DebugLoc node incomplete.")); - // Debug loc but no column. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Line: 3 }\n" - "", - "DebugLoc node incomplete.")); -} - -TEST(YAMLRemarks, ParsingWrongTypes) { - // Wrong debug loc type. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: foo\n" - "", - "expected a value of mapping type.")); - // Wrong line type. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Line: b, Column: 12 }\n" - "", - "expected a value of integer type.")); - // Wrong column type. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Line: 3, Column: c }\n" - "", - "expected a value of integer type.")); - // Wrong args type. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "Args: foo\n" - "", - "wrong value type for key.")); - // Wrong key type. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "{ A: a }: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "", - "key is not a string.")); - // Debug loc with unknown entry. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n" - "", - "unknown entry in DebugLoc map.")); - // Unknown entry. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Unknown: inline\n" - "", - "unknown key.")); - // Not a scalar. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: { File: a, Line: 1, Column: 2 }\n" - "Name: NoDefinition\n" - "Function: foo\n" - "", - "expected a value of scalar type.")); - // Not a string file in debug loc. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n" - "", - "expected a value of scalar type.")); - // Not a integer column in debug loc. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n" - "", - "expected a value of scalar type.")); - // Not a integer line in debug loc. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n" - "", - "expected a value of scalar type.")); - // Not a mapping type value for args. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n" - "", - "expected a value of scalar type.")); -} - -TEST(YAMLRemarks, ParsingWrongArgs) { - // Multiple debug locs per arg. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "Args:\n" - " - Str: string\n" - " DebugLoc: { File: a, Line: 1, Column: 2 }\n" - " DebugLoc: { File: a, Line: 1, Column: 2 }\n" - "", - "only one DebugLoc entry is allowed per argument.")); - // Multiple strings per arg. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "Args:\n" - " - Str: string\n" - " Str2: string\n" - " DebugLoc: { File: a, Line: 1, Column: 2 }\n" - "", - "only one string entry is allowed per argument.")); - // No arg value. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "Args:\n" - " - Callee: ''\n" - " - DebugLoc: { File: a, Line: 1, Column: 2 }\n" - "", - "argument value is missing.")); - // No arg value. - EXPECT_TRUE(parseExpectError("\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "Function: foo\n" - "Args:\n" - " - DebugLoc: { File: a, Line: 1, Column: 2 }\n" - "", - "argument key is missing.")); -} - -static inline StringRef checkStr(StringRef Str, unsigned ExpectedLen) { - const char *StrData = Str.data(); - unsigned StrLen = Str.size(); - EXPECT_EQ(StrLen, ExpectedLen); - return StringRef(StrData, StrLen); -} - -TEST(YAMLRemarks, Contents) { - StringRef Buf = "\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" - "Function: foo\n" - "Hotness: 4\n" - "Args:\n" - " - Callee: bar\n" - " - String: ' will not be inlined into '\n" - " - Caller: foo\n" - " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" - " - String: ' because its definition is unavailable'\n" - "\n"; - - remarks::Parser Parser(Buf); - Expected<const remarks::Remark *> RemarkOrErr = Parser.getNext(); - EXPECT_FALSE(errorToBool(RemarkOrErr.takeError())); - EXPECT_TRUE(*RemarkOrErr != nullptr); - - const remarks::Remark &Remark = **RemarkOrErr; - EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed); - EXPECT_EQ(checkStr(Remark.PassName, 6), "inline"); - EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition"); - EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo"); - EXPECT_TRUE(Remark.Loc); - const remarks::RemarkLocation &RL = *Remark.Loc; - EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c"); - EXPECT_EQ(RL.SourceLine, 3U); - EXPECT_EQ(RL.SourceColumn, 12U); - EXPECT_TRUE(Remark.Hotness); - EXPECT_EQ(*Remark.Hotness, 4U); - EXPECT_EQ(Remark.Args.size(), 4U); - - unsigned ArgID = 0; - for (const remarks::Argument &Arg : Remark.Args) { - switch (ArgID) { - case 0: - EXPECT_EQ(checkStr(Arg.Key, 6), "Callee"); - EXPECT_EQ(checkStr(Arg.Val, 3), "bar"); - EXPECT_FALSE(Arg.Loc); - break; - case 1: - EXPECT_EQ(checkStr(Arg.Key, 6), "String"); - EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into "); - EXPECT_FALSE(Arg.Loc); - break; - case 2: { - EXPECT_EQ(checkStr(Arg.Key, 6), "Caller"); - EXPECT_EQ(checkStr(Arg.Val, 3), "foo"); - EXPECT_TRUE(Arg.Loc); - const remarks::RemarkLocation &RL = *Arg.Loc; - EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c"); - EXPECT_EQ(RL.SourceLine, 2U); - EXPECT_EQ(RL.SourceColumn, 0U); - break; - } - case 3: - EXPECT_EQ(checkStr(Arg.Key, 6), "String"); - EXPECT_EQ(checkStr(Arg.Val, 38), - " because its definition is unavailable"); - EXPECT_FALSE(Arg.Loc); - break; - default: - break; - } - ++ArgID; - } - - RemarkOrErr = Parser.getNext(); - EXPECT_FALSE(errorToBool(RemarkOrErr.takeError())); - EXPECT_EQ(*RemarkOrErr, nullptr); -} - -static inline StringRef checkStr(LLVMRemarkStringRef Str, - unsigned ExpectedLen) { - const char *StrData = LLVMRemarkStringGetData(Str); - unsigned StrLen = LLVMRemarkStringGetLen(Str); - EXPECT_EQ(StrLen, ExpectedLen); - return StringRef(StrData, StrLen); -} - -TEST(YAMLRemarks, ContentsCAPI) { - StringRef Buf = "\n" - "--- !Missed\n" - "Pass: inline\n" - "Name: NoDefinition\n" - "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n" - "Function: foo\n" - "Args:\n" - " - Callee: bar\n" - " - String: ' will not be inlined into '\n" - " - Caller: foo\n" - " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n" - " - String: ' because its definition is unavailable'\n" - "\n"; - - LLVMRemarkParserRef Parser = - LLVMRemarkParserCreateYAML(Buf.data(), Buf.size()); - LLVMRemarkEntryRef Remark = LLVMRemarkParserGetNext(Parser); - EXPECT_FALSE(Remark == nullptr); - EXPECT_EQ(LLVMRemarkEntryGetType(Remark), LLVMRemarkTypeMissed); - EXPECT_EQ(checkStr(LLVMRemarkEntryGetPassName(Remark), 6), "inline"); - EXPECT_EQ(checkStr(LLVMRemarkEntryGetRemarkName(Remark), 12), "NoDefinition"); - EXPECT_EQ(checkStr(LLVMRemarkEntryGetFunctionName(Remark), 3), "foo"); - LLVMRemarkDebugLocRef DL = LLVMRemarkEntryGetDebugLoc(Remark); - EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c"); - EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 3U); - EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 12U); - EXPECT_EQ(LLVMRemarkEntryGetHotness(Remark), 0U); - EXPECT_EQ(LLVMRemarkEntryGetNumArgs(Remark), 4U); - - unsigned ArgID = 0; - LLVMRemarkArgRef Arg = LLVMRemarkEntryGetFirstArg(Remark); - do { - switch (ArgID) { - case 0: - EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Callee"); - EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "bar"); - EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr); - break; - case 1: - EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String"); - EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 26), - " will not be inlined into "); - EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr); - break; - case 2: { - EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Caller"); - EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "foo"); - LLVMRemarkDebugLocRef DL = LLVMRemarkArgGetDebugLoc(Arg); - EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c"); - EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 2U); - EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 0U); - break; - } - case 3: - EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String"); - EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 38), - " because its definition is unavailable"); - EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr); - break; - default: - break; - } - ++ArgID; - } while ((Arg = LLVMRemarkEntryGetNextArg(Arg, Remark))); - - EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr); - - EXPECT_FALSE(LLVMRemarkParserHasError(Parser)); - LLVMRemarkParserDispose(Parser); -} |