brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.6 KiB · 54942ff Raw
263 lines · cpp
1//===- unittest/Support/RemarksLinkingTest.cpp - Linking 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Bitcode/BitcodeAnalyzer.h"10#include "llvm/Remarks/RemarkLinker.h"11#include "llvm/Remarks/RemarkSerializer.h"12#include "llvm/Support/raw_ostream.h"13#include "gtest/gtest.h"14#include <string>15 16using namespace llvm;17 18static void serializeAndCheck(remarks::RemarkLinker &RL,19                              remarks::Format OutputFormat,20                              StringRef ExpectedOutput) {21  // 1. Create a serializer.22  // 2. Serialize all the remarks from the linker.23  // 3. Check that it matches the output.24  std::string Buf;25  raw_string_ostream OS(Buf);26  Error E = RL.serialize(OS, OutputFormat);27  EXPECT_FALSE(static_cast<bool>(E));28 29  // For bitstream, run it through the analyzer.30  if (OutputFormat == remarks::Format::Bitstream) {31    std::string AnalyzeBuf;32    raw_string_ostream AnalyzeOS(AnalyzeBuf);33    BCDumpOptions O(AnalyzeOS);34    O.ShowBinaryBlobs = true;35    BitcodeAnalyzer BA(OS.str());36    EXPECT_FALSE(BA.analyze(O)); // Expect no errors.37    EXPECT_EQ(AnalyzeOS.str(), ExpectedOutput);38  } else {39    EXPECT_EQ(OS.str(), ExpectedOutput);40  }41}42 43static void check(remarks::Format InputFormat, StringRef Input,44                  remarks::Format OutputFormat, StringRef ExpectedOutput,45                  std::optional<bool> KeepAllRemarks = {}) {46  remarks::RemarkLinker RL;47  if (KeepAllRemarks)48    RL.setKeepAllRemarks(*KeepAllRemarks);49  EXPECT_FALSE(RL.link(Input, InputFormat));50  serializeAndCheck(RL, OutputFormat, ExpectedOutput);51}52 53static void check(remarks::Format InputFormat, StringRef Input,54                  remarks::Format InputFormat2, StringRef Input2,55                  remarks::Format OutputFormat, StringRef ExpectedOutput) {56  remarks::RemarkLinker RL;57  EXPECT_FALSE(RL.link(Input, InputFormat));58  EXPECT_FALSE(RL.link(Input2, InputFormat2));59  serializeAndCheck(RL, OutputFormat, ExpectedOutput);60}61 62TEST(Remarks, LinkingGoodYAML) {63  // One YAML remark.64  check(remarks::Format::YAML,65        "--- !Missed\n"66        "Pass:            inline\n"67        "Name:            NoDefinition\n"68        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"69        "Function:        foo\n"70        "...\n",71        remarks::Format::YAML,72        "--- !Missed\n"73        "Pass:            inline\n"74        "Name:            NoDefinition\n"75        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"76        "Function:        foo\n"77        "...\n");78 79  // Check that we don't keep remarks without debug locations, unless80  // KeepAllRemarks is set.81  check(remarks::Format::YAML,82        "--- !Missed\n"83        "Pass:            inline\n"84        "Name:            NoDefinition\n"85        "Function:        foo\n"86        "...\n",87        remarks::Format::YAML, "",88        /*KeepAllRemarks=*/false);89  check(remarks::Format::YAML,90        "--- !Missed\n"91        "Pass:            inline\n"92        "Name:            NoDefinition\n"93        "Function:        foo\n"94        "...\n",95        remarks::Format::YAML,96        "--- !Missed\n"97        "Pass:            inline\n"98        "Name:            NoDefinition\n"99        "Function:        foo\n"100        "...\n");101 102  // Check that we deduplicate remarks.103  check(remarks::Format::YAML,104        "--- !Missed\n"105        "Pass:            inline\n"106        "Name:            NoDefinition\n"107        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"108        "Function:        foo\n"109        "...\n"110        "--- !Missed\n"111        "Pass:            inline\n"112        "Name:            NoDefinition\n"113        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"114        "Function:        foo\n"115        "...\n",116        remarks::Format::YAML,117        "--- !Missed\n"118        "Pass:            inline\n"119        "Name:            NoDefinition\n"120        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"121        "Function:        foo\n"122        "...\n");123}124 125TEST(Remarks, LinkingGoodBitstream) {126  // One YAML remark.127  check(remarks::Format::YAML,128        "--- !Missed\n"129        "Pass:            inline\n"130        "Name:            NoDefinition\n"131        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"132        "Function:        foo\n"133        "...\n",134        remarks::Format::Bitstream,135        "<BLOCKINFO_BLOCK/>\n"136        "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"137        "  <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"138        "  <Remark version codeid=2 abbrevid=5 op0=0/>\n"139        "</Meta>\n"140        "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"141        "  <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"142        "  <Remark debug location codeid=6 abbrevid=5 op0=3 op1=3 op2=12/>\n"143        "</Remark>\n"144        "<Meta BlockID=8 NumWords=10 BlockCodeSize=3>\n"145        "  <String table codeid=3 abbrevid=6/> blob data = "146        "'inline\\x00NoDefinition\\x00foo\\x00file.c\\x00'\n"147        "</Meta>\n");148 149  // Check that we keep remarks without debug info.150  check(remarks::Format::YAML,151        "--- !Missed\n"152        "Pass:            inline\n"153        "Name:            NoDefinition\n"154        "Function:        foo\n"155        "...\n",156        remarks::Format::Bitstream,157        "<BLOCKINFO_BLOCK/>\n"158        "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"159        "  <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"160        "  <Remark version codeid=2 abbrevid=5 op0=0/>\n"161        "</Meta>\n"162        "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"163        "  <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"164        "</Remark>\n"165        "<Meta BlockID=8 NumWords=8 BlockCodeSize=3>\n"166        "  <String table codeid=3 abbrevid=6/> blob data = "167        "'inline\\x00NoDefinition\\x00foo\\x00'\n"168        "</Meta>\n");169 170  // Check that we deduplicate remarks.171  check(remarks::Format::YAML,172        "--- !Missed\n"173        "Pass:            inline\n"174        "Name:            NoDefinition\n"175        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"176        "Function:        foo\n"177        "...\n"178        "--- !Missed\n"179        "Pass:            inline\n"180        "Name:            NoDefinition\n"181        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"182        "Function:        foo\n"183        "...\n",184        remarks::Format::Bitstream,185        "<BLOCKINFO_BLOCK/>\n"186        "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"187        "  <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"188        "  <Remark version codeid=2 abbrevid=5 op0=0/>\n"189        "</Meta>\n"190        "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"191        "  <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"192        "  <Remark debug location codeid=6 abbrevid=5 op0=3 op1=3 op2=12/>\n"193        "</Remark>\n"194        "<Meta BlockID=8 NumWords=10 BlockCodeSize=3>\n"195        "  <String table codeid=3 abbrevid=6/> blob data = "196        "'inline\\x00NoDefinition\\x00foo\\x00file.c\\x00'\n"197        "</Meta>\n");198}199 200TEST(Remarks, LinkingGoodStrTab) {201  // Check that remarks from different entries use the same strtab.202  check(remarks::Format::YAML,203        "--- !Missed\n"204        "Pass:            inline\n"205        "Name:            NoDefinition\n"206        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"207        "Function:        foo\n"208        "...\n",209        remarks::Format::YAML,210        "--- !Passed\n"211        "Pass:            inline\n"212        "Name:            Ok\n"213        "DebugLoc:        { File: file.c, Line: 3, Column: 12 }\n"214        "Function:        foo\n"215        "...\n",216        remarks::Format::Bitstream,217        "<BLOCKINFO_BLOCK/>\n"218        "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"219        "  <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"220        "  <Remark version codeid=2 abbrevid=5 op0=0/>\n"221        "</Meta>\n"222        "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"223        "  <Remark header codeid=5 abbrevid=4 op0=1 op1=4 op2=0 op3=2/>\n"224        "  <Remark debug location codeid=6 abbrevid=5 op0=3 op1=3 op2=12/>\n"225        "</Remark>\n"226        "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"227        "  <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"228        "  <Remark debug location codeid=6 abbrevid=5 op0=3 op1=3 op2=12/>\n"229        "</Remark>\n"230        "<Meta BlockID=8 NumWords=11 BlockCodeSize=3>\n"231        "  <String table codeid=3 abbrevid=6/> blob data = "232        "'inline\\x00NoDefinition\\x00foo\\x00file.c\\x00Ok\\x00'\n"233        "</Meta>\n");234}235 236// Check that we propagate parsing errors.237TEST(Remarks, LinkingError) {238  remarks::RemarkLinker RL;239  {240    Error E = RL.link("badyaml", remarks::Format::YAML);241    EXPECT_TRUE(static_cast<bool>(E));242    EXPECT_EQ(toString(std::move(E)),243              "YAML:1:1: error: document root is not of mapping type.\n"244              "\n"245              "badyaml\n"246              "^~~~~~~\n"247              "\n");248  }249 250  {251    // Check that the prepend path is propagated and fails with the full path.252    // Also ensures that the remark format is correctly auto-detected.253    RL.setExternalFilePrependPath("/baddir/");254    Error E = RL.link(StringRef(255        "REMARKS\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0badfile.opt.yaml", 40));256    EXPECT_TRUE(static_cast<bool>(E));257    std::string ErrorMessage = toString(std::move(E));258    EXPECT_EQ(StringRef(ErrorMessage).lower(),259              StringRef("'/baddir/badfile.opt.yaml': No such file or directory")260                  .lower());261  }262}263