330 lines
12 KiB
C++
330 lines
12 KiB
C++
|
//===- unittest/Support/YAMLRemarksSerializerTest.cpp --------------------===//
|
||
|
//
|
||
|
// 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/Remarks/Remark.h"
|
||
|
#include "llvm/Remarks/RemarkParser.h"
|
||
|
#include "llvm/Remarks/YAMLRemarkSerializer.h"
|
||
|
#include "llvm/Support/Error.h"
|
||
|
#include "gtest/gtest.h"
|
||
|
|
||
|
// We need to supprt Windows paths as well. In order to have paths with the same
|
||
|
// length, use a different path according to the platform.
|
||
|
#ifdef _WIN32
|
||
|
#define EXTERNALFILETESTPATH "C:/externalfi"
|
||
|
#else
|
||
|
#define EXTERNALFILETESTPATH "/externalfile"
|
||
|
#endif
|
||
|
|
||
|
using namespace llvm;
|
||
|
|
||
|
static void check(remarks::Format SerializerFormat,
|
||
|
remarks::SerializerMode Mode, ArrayRef<remarks::Remark> Rs,
|
||
|
StringRef ExpectedR, Optional<StringRef> ExpectedMeta,
|
||
|
Optional<remarks::StringTable> StrTab = None) {
|
||
|
std::string Buf;
|
||
|
raw_string_ostream OS(Buf);
|
||
|
Expected<std::unique_ptr<remarks::RemarkSerializer>> MaybeS = [&] {
|
||
|
if (StrTab)
|
||
|
return createRemarkSerializer(SerializerFormat, Mode, OS,
|
||
|
std::move(*StrTab));
|
||
|
else
|
||
|
return createRemarkSerializer(SerializerFormat, Mode, OS);
|
||
|
}();
|
||
|
EXPECT_FALSE(errorToBool(MaybeS.takeError()));
|
||
|
std::unique_ptr<remarks::RemarkSerializer> S = std::move(*MaybeS);
|
||
|
|
||
|
for (const remarks::Remark &R : Rs)
|
||
|
S->emit(R);
|
||
|
EXPECT_EQ(OS.str(), ExpectedR);
|
||
|
|
||
|
if (ExpectedMeta) {
|
||
|
Buf.clear();
|
||
|
std::unique_ptr<remarks::MetaSerializer> MS =
|
||
|
S->metaSerializer(OS, StringRef(EXTERNALFILETESTPATH));
|
||
|
MS->emit();
|
||
|
EXPECT_EQ(OS.str(), *ExpectedMeta);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void check(remarks::Format SerializerFormat, const remarks::Remark &R,
|
||
|
StringRef ExpectedR, StringRef ExpectedMeta,
|
||
|
Optional<remarks::StringTable> StrTab = None) {
|
||
|
return check(SerializerFormat, remarks::SerializerMode::Separate,
|
||
|
makeArrayRef(&R, &R + 1), ExpectedR, ExpectedMeta,
|
||
|
std::move(StrTab));
|
||
|
}
|
||
|
|
||
|
static void checkStandalone(remarks::Format SerializerFormat,
|
||
|
const remarks::Remark &R, StringRef ExpectedR,
|
||
|
Optional<remarks::StringTable> StrTab = None) {
|
||
|
return check(SerializerFormat, remarks::SerializerMode::Standalone,
|
||
|
makeArrayRef(&R, &R + 1), ExpectedR,
|
||
|
/*ExpectedMeta=*/None, std::move(StrTab));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemark) {
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
check(remarks::Format::YAML, R,
|
||
|
"--- !Missed\n"
|
||
|
"Pass: pass\n"
|
||
|
"Name: name\n"
|
||
|
"DebugLoc: { File: path, Line: 3, Column: 4 }\n"
|
||
|
"Function: func\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: value\n"
|
||
|
" - keydebug: valuedebug\n"
|
||
|
" DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"
|
||
|
"...\n",
|
||
|
StringRef("REMARKS\0"
|
||
|
"\0\0\0\0\0\0\0\0"
|
||
|
"\0\0\0\0\0\0\0\0" EXTERNALFILETESTPATH "\0",
|
||
|
38));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemarkStandalone) {
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
checkStandalone(
|
||
|
remarks::Format::YAML, R,
|
||
|
StringRef("--- !Missed\n"
|
||
|
"Pass: pass\n"
|
||
|
"Name: name\n"
|
||
|
"DebugLoc: { File: path, Line: 3, Column: 4 }\n"
|
||
|
"Function: func\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: value\n"
|
||
|
" - keydebug: valuedebug\n"
|
||
|
" DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"
|
||
|
"...\n"));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemarkStrTab) {
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
check(remarks::Format::YAMLStrTab, R,
|
||
|
"--- !Missed\n"
|
||
|
"Pass: 0\n"
|
||
|
"Name: 1\n"
|
||
|
"DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
|
||
|
"Function: 2\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: 4\n"
|
||
|
" - keydebug: 5\n"
|
||
|
" DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
|
||
|
"...\n",
|
||
|
StringRef("REMARKS\0"
|
||
|
"\0\0\0\0\0\0\0\0"
|
||
|
"\x2d\0\0\0\0\0\0\0"
|
||
|
"pass\0name\0func\0path\0value\0valuedebug\0argpath"
|
||
|
"\0" EXTERNALFILETESTPATH "\0",
|
||
|
83));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemarkParsedStrTab) {
|
||
|
StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
check(remarks::Format::YAMLStrTab, R,
|
||
|
"--- !Missed\n"
|
||
|
"Pass: 0\n"
|
||
|
"Name: 1\n"
|
||
|
"DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
|
||
|
"Function: 2\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: 4\n"
|
||
|
" - keydebug: 5\n"
|
||
|
" DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
|
||
|
"...\n",
|
||
|
StringRef("REMARKS\0"
|
||
|
"\0\0\0\0\0\0\0\0"
|
||
|
"\x2d\0\0\0\0\0\0\0"
|
||
|
"pass\0name\0func\0path\0value\0valuedebug\0argpath"
|
||
|
"\0" EXTERNALFILETESTPATH "\0",
|
||
|
83),
|
||
|
remarks::StringTable(remarks::ParsedStringTable(StrTab)));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneNoStrTab) {
|
||
|
// Check that we don't use the string table even if it was provided.
|
||
|
StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
|
||
|
remarks::ParsedStringTable ParsedStrTab(StrTab);
|
||
|
remarks::StringTable PreFilledStrTab(ParsedStrTab);
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
checkStandalone(
|
||
|
remarks::Format::YAML, R,
|
||
|
StringRef("--- !Missed\n"
|
||
|
"Pass: pass\n"
|
||
|
"Name: name\n"
|
||
|
"DebugLoc: { File: path, Line: 3, Column: 4 }\n"
|
||
|
"Function: func\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: value\n"
|
||
|
" - keydebug: valuedebug\n"
|
||
|
" DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"
|
||
|
"...\n"),
|
||
|
std::move(PreFilledStrTab));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandalone) {
|
||
|
StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
|
||
|
remarks::ParsedStringTable ParsedStrTab(StrTab);
|
||
|
remarks::StringTable PreFilledStrTab(ParsedStrTab);
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
checkStandalone(
|
||
|
remarks::Format::YAMLStrTab, R,
|
||
|
StringRef("REMARKS\0"
|
||
|
"\0\0\0\0\0\0\0\0"
|
||
|
"\x2d\0\0\0\0\0\0\0"
|
||
|
"pass\0name\0func\0path\0value\0valuedebug\0argpath\0"
|
||
|
"--- !Missed\n"
|
||
|
"Pass: 0\n"
|
||
|
"Name: 1\n"
|
||
|
"DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
|
||
|
"Function: 2\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: 4\n"
|
||
|
" - keydebug: 5\n"
|
||
|
" DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
|
||
|
"...\n",
|
||
|
315),
|
||
|
std::move(PreFilledStrTab));
|
||
|
}
|
||
|
|
||
|
TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneMultipleRemarks) {
|
||
|
StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
|
||
|
remarks::ParsedStringTable ParsedStrTab(StrTab);
|
||
|
remarks::StringTable PreFilledStrTab(ParsedStrTab);
|
||
|
SmallVector<remarks::Remark, 2> Rs;
|
||
|
remarks::Remark R;
|
||
|
R.RemarkType = remarks::Type::Missed;
|
||
|
R.PassName = "pass";
|
||
|
R.RemarkName = "name";
|
||
|
R.FunctionName = "func";
|
||
|
R.Loc = remarks::RemarkLocation{"path", 3, 4};
|
||
|
R.Hotness = 5;
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "key";
|
||
|
R.Args.back().Val = "value";
|
||
|
R.Args.emplace_back();
|
||
|
R.Args.back().Key = "keydebug";
|
||
|
R.Args.back().Val = "valuedebug";
|
||
|
R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
|
||
|
Rs.emplace_back(R.clone());
|
||
|
Rs.emplace_back(std::move(R));
|
||
|
check(remarks::Format::YAMLStrTab, remarks::SerializerMode::Standalone, Rs,
|
||
|
StringRef("REMARKS\0"
|
||
|
"\0\0\0\0\0\0\0\0"
|
||
|
"\x2d\0\0\0\0\0\0\0"
|
||
|
"pass\0name\0func\0path\0value\0valuedebug\0argpath\0"
|
||
|
"--- !Missed\n"
|
||
|
"Pass: 0\n"
|
||
|
"Name: 1\n"
|
||
|
"DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
|
||
|
"Function: 2\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: 4\n"
|
||
|
" - keydebug: 5\n"
|
||
|
" DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
|
||
|
"...\n"
|
||
|
"--- !Missed\n"
|
||
|
"Pass: 0\n"
|
||
|
"Name: 1\n"
|
||
|
"DebugLoc: { File: 3, Line: 3, Column: 4 }\n"
|
||
|
"Function: 2\n"
|
||
|
"Hotness: 5\n"
|
||
|
"Args:\n"
|
||
|
" - key: 4\n"
|
||
|
" - keydebug: 5\n"
|
||
|
" DebugLoc: { File: 6, Line: 6, Column: 7 }\n"
|
||
|
"...\n",
|
||
|
561),
|
||
|
/*ExpectedMeta=*/None, std::move(PreFilledStrTab));
|
||
|
}
|