brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 1528884 Raw
184 lines · cpp
1//===- llvm/unittest/TableGen/CodeExpanderTest.cpp - 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 "Common/GlobalISel/CodeExpander.h"10#include "Common/GlobalISel/CodeExpansions.h"11 12#include "llvm/Support/raw_ostream.h"13#include "llvm/TableGen/Error.h"14#include "gtest/gtest.h"15 16using namespace llvm;17 18static StringRef bufferize(StringRef Str) {19  std::unique_ptr<MemoryBuffer> Buffer =20      MemoryBuffer::getMemBufferCopy(Str, "TestBuffer");21  StringRef StrBufferRef = Buffer->getBuffer();22  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());23  return StrBufferRef;24}25 26class RAIIDiagnosticChecker {27  std::string EmittedDiags;28  raw_string_ostream OS;29  std::vector<SMDiagnostic> Expected;30  std::vector<SMDiagnostic> Received;31 32public:33  RAIIDiagnosticChecker() : OS(EmittedDiags) {34    SrcMgr.setDiagHandler(handler, this);35  }36  ~RAIIDiagnosticChecker() {37    SrcMgr.setDiagHandler(nullptr);38    EXPECT_EQ(Received.size(), Expected.size());39    for (unsigned i = 0; i < Received.size() && i < Expected.size(); ++i) {40      EXPECT_EQ(Received[i].getLoc(), Expected[i].getLoc());41      EXPECT_EQ(Received[i].getFilename(), Expected[i].getFilename());42      EXPECT_EQ(Received[i].getKind(), Expected[i].getKind());43      EXPECT_EQ(Received[i].getLineNo(), Expected[i].getLineNo());44      EXPECT_EQ(Received[i].getColumnNo(), Expected[i].getColumnNo());45      EXPECT_EQ(Received[i].getMessage(), Expected[i].getMessage());46      EXPECT_EQ(Received[i].getLineContents(), Expected[i].getLineContents());47      EXPECT_EQ(Received[i].getRanges(), Expected[i].getRanges());48    }49 50    if (testing::Test::HasFailure())51      errs() << "Emitted diagnostic:\n" << OS.str();52  }53 54  void expect(SMDiagnostic D) { Expected.push_back(D); }55 56  void diag(const SMDiagnostic &D) {57    Received.push_back(D);58  }59 60  static void handler(const SMDiagnostic &D, void *Context) {61    RAIIDiagnosticChecker *Self = static_cast<RAIIDiagnosticChecker *>(Context);62    Self->diag(D);63    SrcMgr.setDiagHandler(nullptr);64    SrcMgr.PrintMessage(Self->OS, D);65    SrcMgr.setDiagHandler(handler, Context);66  };67};68 69TEST(CodeExpander, NoExpansions) {70  std::string Result;71  raw_string_ostream OS(Result);72  CodeExpansions Expansions;73 74  RAIIDiagnosticChecker DiagChecker;75  CodeExpander("No expansions", Expansions, SMLoc(), false).emit(OS);76  EXPECT_EQ(OS.str(), "No expansions");77}78 79// Indentation is applied to all lines except the first80TEST(CodeExpander, Indentation) {81  std::string Result;82  raw_string_ostream OS(Result);83  CodeExpansions Expansions;84 85  RAIIDiagnosticChecker DiagChecker;86  CodeExpander("No expansions\nsecond line\nthird line", Expansions, SMLoc(),87               false, "  ")88      .emit(OS);89  EXPECT_EQ(OS.str(), "No expansions\n  second line\n  third line");90}91 92// \ is an escape character that removes special meanings from the next93// character.94TEST(CodeExpander, Escape) {95  std::string Result;96  raw_string_ostream OS(Result);97  CodeExpansions Expansions;98 99  RAIIDiagnosticChecker DiagChecker;100  CodeExpander("\\\\\\a\\$", Expansions, SMLoc(), false).emit(OS);101  EXPECT_EQ(OS.str(), "\\a$");102}103 104// $foo is not an expansion. It should warn though.105TEST(CodeExpander, NotAnExpansion) {106  std::string Result;107  raw_string_ostream OS(Result);108  CodeExpansions Expansions;109 110  RAIIDiagnosticChecker DiagChecker;111  StringRef In = bufferize(" $foo");112  CodeExpander(" $foo", Expansions, SMLoc::getFromPointer(In.data()), false)113      .emit(OS);114  EXPECT_EQ(OS.str(), " $foo");115  DiagChecker.expect(SMDiagnostic(116      SrcMgr, SMLoc::getFromPointer(In.data()), "TestBuffer", 1, 0,117      SourceMgr::DK_Warning, "Assuming missing escape character: \\$", " $foo", {}));118}119 120// \$foo is not an expansion but shouldn't warn as it's using the escape.121TEST(CodeExpander, EscapedNotAnExpansion) {122  std::string Result;123  raw_string_ostream OS(Result);124  CodeExpansions Expansions;125 126  RAIIDiagnosticChecker DiagChecker;127  CodeExpander("\\$foo", Expansions, SMLoc(), false).emit(OS);128  EXPECT_EQ(OS.str(), "$foo");129}130 131// \${foo is not an expansion but shouldn't warn as it's using the escape.132TEST(CodeExpander, EscapedUnterminatedExpansion) {133  std::string Result;134  raw_string_ostream OS(Result);135  CodeExpansions Expansions;136 137  RAIIDiagnosticChecker DiagChecker;138  CodeExpander("\\${foo", Expansions, SMLoc(), false).emit(OS);139  EXPECT_EQ(OS.str(), "${foo");140}141 142// \${foo is not an expansion but shouldn't warn as it's using the escape.143TEST(CodeExpander, EscapedExpansion) {144  std::string Result;145  raw_string_ostream OS(Result);146  CodeExpansions Expansions;147 148  RAIIDiagnosticChecker DiagChecker;149  CodeExpander("\\${foo}", Expansions, SMLoc(), false).emit(OS);150  EXPECT_EQ(OS.str(), "${foo}");151}152 153// ${foo} is an undefined expansion and should error.154TEST(CodeExpander, UndefinedExpansion) {155  std::string Result;156  raw_string_ostream OS(Result);157  CodeExpansions Expansions;158  Expansions.declare("bar", "expansion");159 160  RAIIDiagnosticChecker DiagChecker;161  CodeExpander("${foo}${bar}", Expansions, SMLoc(), false).emit(OS);162  EXPECT_EQ(OS.str(), "expansion");163  DiagChecker.expect(164      SMDiagnostic(SrcMgr, SMLoc(), "<unknown>", 0, -1, SourceMgr::DK_Error,165                   "Attempt to expand an undeclared variable 'foo'", "", {}));166}167 168// ${bar is an unterminated expansion. Warn and implicitly terminate it.169TEST(CodeExpander, UnterminatedExpansion) {170  std::string Result;171  raw_string_ostream OS(Result);172  CodeExpansions Expansions;173  Expansions.declare("bar", "expansion");174 175  RAIIDiagnosticChecker DiagChecker;176  StringRef In = bufferize(" ${bar");177  CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false)178      .emit(OS);179  EXPECT_EQ(OS.str(), " expansion");180  DiagChecker.expect(SMDiagnostic(SrcMgr, SMLoc::getFromPointer(In.data()),181                                  "TestBuffer", 1, 0, SourceMgr::DK_Warning,182                                  "Unterminated expansion '${bar'", " ${bar", {}));183}184