196 lines · cpp
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-exception6//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 same16// length, use a different path according to the platform.17#ifdef _WIN3218#define EXTERNALFILETESTPATH "C:/externalfi"19#else20#define EXTERNALFILETESTPATH "/externalfile"21#endif22 23using namespace llvm;24 25static void check(remarks::Format SerializerFormat,26 ArrayRef<remarks::Remark> Rs, StringRef ExpectedR,27 std::optional<StringRef> ExpectedMeta,28 std::optional<remarks::StringTable> StrTab = std::nullopt) {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, OS, std::move(*StrTab));34 else35 return createRemarkSerializer(SerializerFormat, OS);36 }();37 EXPECT_FALSE(errorToBool(MaybeS.takeError()));38 std::unique_ptr<remarks::RemarkSerializer> S = std::move(*MaybeS);39 40 for (const remarks::Remark &R : Rs)41 S->emit(R);42 S->finalize();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 54static void check(remarks::Format SerializerFormat, const remarks::Remark &R,55 StringRef ExpectedR, StringRef ExpectedMeta,56 std::optional<remarks::StringTable> StrTab = std::nullopt) {57 return check(SerializerFormat, ArrayRef(&R, &R + 1), ExpectedR, ExpectedMeta,58 std::move(StrTab));59}60 61static void62checkStandalone(remarks::Format SerializerFormat, const remarks::Remark &R,63 StringRef ExpectedR,64 std::optional<remarks::StringTable> StrTab = std::nullopt) {65 return check(SerializerFormat, ArrayRef(&R, &R + 1), ExpectedR,66 /*ExpectedMeta=*/std::nullopt, std::move(StrTab));67}68 69TEST(YAMLRemarks, SerializerRemark) {70 remarks::Remark R;71 R.RemarkType = remarks::Type::Missed;72 R.PassName = "pass";73 R.RemarkName = "name";74 R.FunctionName = "func";75 R.Loc = remarks::RemarkLocation{"path", 3, 4};76 R.Hotness = 5;77 R.Args.emplace_back();78 R.Args.back().Key = "key";79 R.Args.back().Val = "value";80 R.Args.emplace_back();81 R.Args.back().Key = "keydebug";82 R.Args.back().Val = "valuedebug";83 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};84 check(remarks::Format::YAML, R,85 "--- !Missed\n"86 "Pass: pass\n"87 "Name: name\n"88 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"89 "Function: func\n"90 "Hotness: 5\n"91 "Args:\n"92 " - key: value\n"93 " - keydebug: valuedebug\n"94 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"95 "...\n",96 StringRef("REMARKS\0"97 "\0\0\0\0\0\0\0\0"98 "\0\0\0\0\0\0\0\0" EXTERNALFILETESTPATH "\0",99 38));100}101 102TEST(YAMLRemarks, SerializerRemarkStandalone) {103 remarks::Remark R;104 R.RemarkType = remarks::Type::Missed;105 R.PassName = "pass";106 R.RemarkName = "name";107 R.FunctionName = "func";108 R.Loc = remarks::RemarkLocation{"path", 3, 4};109 R.Hotness = 5;110 R.Args.emplace_back();111 R.Args.back().Key = "key";112 R.Args.back().Val = "value";113 R.Args.emplace_back();114 R.Args.back().Key = "keydebug";115 R.Args.back().Val = "valuedebug";116 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};117 checkStandalone(118 remarks::Format::YAML, R,119 StringRef("--- !Missed\n"120 "Pass: pass\n"121 "Name: name\n"122 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"123 "Function: func\n"124 "Hotness: 5\n"125 "Args:\n"126 " - key: value\n"127 " - keydebug: valuedebug\n"128 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"129 "...\n"));130}131 132TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneNoStrTab) {133 // Check that we don't use the string table even if it was provided.134 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);135 remarks::ParsedStringTable ParsedStrTab(StrTab);136 remarks::StringTable PreFilledStrTab(ParsedStrTab);137 remarks::Remark R;138 R.RemarkType = remarks::Type::Missed;139 R.PassName = "pass";140 R.RemarkName = "name";141 R.FunctionName = "func";142 R.Loc = remarks::RemarkLocation{"path", 3, 4};143 R.Hotness = 5;144 R.Args.emplace_back();145 R.Args.back().Key = "key";146 R.Args.back().Val = "value";147 R.Args.emplace_back();148 R.Args.back().Key = "keydebug";149 R.Args.back().Val = "valuedebug";150 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};151 checkStandalone(152 remarks::Format::YAML, R,153 StringRef("--- !Missed\n"154 "Pass: pass\n"155 "Name: name\n"156 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"157 "Function: func\n"158 "Hotness: 5\n"159 "Args:\n"160 " - key: value\n"161 " - keydebug: valuedebug\n"162 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"163 "...\n"),164 std::move(PreFilledStrTab));165}166 167TEST(YAMLRemarks, SerializerRemarkStringRefOOBRead) {168 remarks::Remark R;169 R.RemarkType = remarks::Type::Missed;170 R.PassName = StringRef("passAAAA", 4);171 R.RemarkName = StringRef("nameAAAA", 4);172 R.FunctionName = StringRef("funcAAAA", 4);173 R.Loc = remarks::RemarkLocation{StringRef("pathAAAA", 4), 3, 4};174 R.Hotness = 5;175 R.Args.emplace_back();176 R.Args.back().Key = StringRef("keyAAAA", 3);177 R.Args.back().Val = StringRef("valueAAAA", 5);178 R.Args.emplace_back();179 R.Args.back().Key = StringRef("keydebugAAAA", 8);180 R.Args.back().Val = StringRef("valuedebugAAAA", 10);181 R.Args.back().Loc =182 remarks::RemarkLocation{StringRef("argpathAAAA", 7), 6, 7};183 checkStandalone(remarks::Format::YAML, R,184 "--- !Missed\n"185 "Pass: pass\n"186 "Name: name\n"187 "DebugLoc: { File: path, Line: 3, Column: 4 }\n"188 "Function: func\n"189 "Hotness: 5\n"190 "Args:\n"191 " - key: value\n"192 " - keydebug: valuedebug\n"193 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n"194 "...\n");195}196