mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
0cb0f08935
Summary: This patch is part of a patch series to add support for FileCheck numeric expressions. This specific patch introduces the @LINE numeric expressions. This commit introduces a new syntax to express a relation a numeric value in the input text must have with the line number of a given CHECK pattern: [[#<@LINE numeric expression>]]. Further commits build on that to express relations between several numeric values in the input text. To help with naming, regular variables are renamed into pattern variables and old @LINE expression syntax is referred to as legacy numeric expression. Compared to existing @LINE expressions, this new syntax allow arbitrary spacing between the component of the expression. It offers otherwise the same functionality but the commit serves to introduce some of the data structure needed to support more general numeric expressions. Copyright: - Linaro (changes up to diff 183612 of revision D55940) - GraphCore (changes in later versions of revision D55940 and in new revision created off D55940) Reviewers: jhenderson, chandlerc, jdenny, probinson, grimar, arichardson, rnk Subscribers: hiraditya, llvm-commits, probinson, dblaikie, grimar, arichardson, tra, rnk, kristina, hfinkel, rogfer01, JonChesterfield Tags: #llvm Differential Revision: https://reviews.llvm.org/D60384 llvm-svn: 359741
256 lines
8.3 KiB
C++
256 lines
8.3 KiB
C++
//===- llvm/unittest/Support/FileCheckTest.cpp - FileCheck 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/Support/FileCheck.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
namespace {
|
|
|
|
class FileCheckTest : public ::testing::Test {};
|
|
|
|
TEST_F(FileCheckTest, ValidVarNameStart) {
|
|
EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a'));
|
|
EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G'));
|
|
EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_'));
|
|
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2'));
|
|
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$'));
|
|
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@'));
|
|
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+'));
|
|
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-'));
|
|
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':'));
|
|
}
|
|
|
|
TEST_F(FileCheckTest, ParseVar) {
|
|
StringRef VarName = "GoodVar42";
|
|
bool IsPseudo = true;
|
|
unsigned TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, VarName.size());
|
|
|
|
VarName = "$GoodGlobalVar";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, VarName.size());
|
|
|
|
VarName = "@GoodPseudoVar";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_TRUE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, VarName.size());
|
|
|
|
VarName = "42BadVar";
|
|
EXPECT_TRUE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
|
|
VarName = "$@";
|
|
EXPECT_TRUE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
|
|
VarName = "B@dVar";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, 1U);
|
|
|
|
VarName = "B$dVar";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, 1U);
|
|
|
|
VarName = "BadVar+";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, VarName.size() - 1);
|
|
|
|
VarName = "BadVar-";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, VarName.size() - 1);
|
|
|
|
VarName = "BadVar:";
|
|
IsPseudo = true;
|
|
TrailIdx = 0;
|
|
EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx));
|
|
EXPECT_FALSE(IsPseudo);
|
|
EXPECT_EQ(TrailIdx, VarName.size() - 1);
|
|
}
|
|
|
|
class ExprTester {
|
|
private:
|
|
SourceMgr SM;
|
|
FileCheckPatternContext Context;
|
|
FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context);
|
|
|
|
public:
|
|
bool parseExpect(std::string &VarName, std::string &Trailer) {
|
|
std::string NameTrailer = VarName + Trailer;
|
|
std::unique_ptr<MemoryBuffer> Buffer =
|
|
MemoryBuffer::getMemBufferCopy(NameTrailer, "TestBuffer");
|
|
StringRef NameTrailerRef = Buffer->getBuffer();
|
|
SM.AddNewSourceBuffer(std::move(Buffer), SMLoc());
|
|
StringRef VarNameRef = NameTrailerRef.substr(0, VarName.size());
|
|
StringRef TrailerRef = NameTrailerRef.substr(VarName.size());
|
|
return P.parseNumericExpression(VarNameRef, TrailerRef, SM) == nullptr;
|
|
}
|
|
};
|
|
|
|
TEST_F(FileCheckTest, ParseExpr) {
|
|
ExprTester Tester;
|
|
|
|
// @LINE with offset.
|
|
std::string VarName = "@LINE";
|
|
std::string Trailer = "+3";
|
|
EXPECT_FALSE(Tester.parseExpect(VarName, Trailer));
|
|
|
|
// @LINE only.
|
|
Trailer = "";
|
|
EXPECT_FALSE(Tester.parseExpect(VarName, Trailer));
|
|
|
|
// Wrong Pseudovar.
|
|
VarName = "@FOO";
|
|
EXPECT_TRUE(Tester.parseExpect(VarName, Trailer));
|
|
|
|
// Unsupported operator.
|
|
VarName = "@LINE";
|
|
Trailer = "/2";
|
|
EXPECT_TRUE(Tester.parseExpect(VarName, Trailer));
|
|
|
|
// Missing offset operand.
|
|
VarName = "@LINE";
|
|
Trailer = "+";
|
|
EXPECT_TRUE(Tester.parseExpect(VarName, Trailer));
|
|
|
|
// Cannot parse offset operand.
|
|
VarName = "@LINE";
|
|
Trailer = "+x";
|
|
EXPECT_TRUE(Tester.parseExpect(VarName, Trailer));
|
|
|
|
// Unexpected string at end of numeric expression.
|
|
VarName = "@LINE";
|
|
Trailer = "+5x";
|
|
EXPECT_TRUE(Tester.parseExpect(VarName, Trailer));
|
|
}
|
|
|
|
TEST_F(FileCheckTest, Substitution) {
|
|
SourceMgr SM;
|
|
FileCheckPatternContext Context;
|
|
std::vector<std::string> GlobalDefines;
|
|
GlobalDefines.emplace_back(std::string("FOO=BAR"));
|
|
Context.defineCmdlineVariables(GlobalDefines, SM);
|
|
|
|
FileCheckPatternSubstitution Substitution =
|
|
FileCheckPatternSubstitution(&Context, "VAR404", 42);
|
|
EXPECT_FALSE(Substitution.getResult());
|
|
|
|
FileCheckNumExpr NumExpr = FileCheckNumExpr(42);
|
|
Substitution = FileCheckPatternSubstitution(&Context, "@LINE", &NumExpr, 12);
|
|
llvm::Optional<std::string> Value = Substitution.getResult();
|
|
EXPECT_TRUE(Value);
|
|
EXPECT_EQ("42", *Value);
|
|
|
|
FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context);
|
|
Substitution = FileCheckPatternSubstitution(&Context, "FOO", 42);
|
|
Value = Substitution.getResult();
|
|
EXPECT_TRUE(Value);
|
|
EXPECT_EQ("BAR", *Value);
|
|
}
|
|
|
|
TEST_F(FileCheckTest, UndefVars) {
|
|
SourceMgr SM;
|
|
FileCheckPatternContext Context;
|
|
std::vector<std::string> GlobalDefines;
|
|
GlobalDefines.emplace_back(std::string("FOO=BAR"));
|
|
Context.defineCmdlineVariables(GlobalDefines, SM);
|
|
|
|
FileCheckPatternSubstitution Substitution =
|
|
FileCheckPatternSubstitution(&Context, "VAR404", 42);
|
|
StringRef UndefVar = Substitution.getUndefVarName();
|
|
EXPECT_EQ("VAR404", UndefVar);
|
|
|
|
FileCheckNumExpr NumExpr = FileCheckNumExpr(42);
|
|
Substitution = FileCheckPatternSubstitution(&Context, "@LINE", &NumExpr, 12);
|
|
UndefVar = Substitution.getUndefVarName();
|
|
EXPECT_EQ("", UndefVar);
|
|
|
|
Substitution = FileCheckPatternSubstitution(&Context, "FOO", 42);
|
|
UndefVar = Substitution.getUndefVarName();
|
|
EXPECT_EQ("", UndefVar);
|
|
}
|
|
|
|
TEST_F(FileCheckTest, FileCheckContext) {
|
|
FileCheckPatternContext Cxt = FileCheckPatternContext();
|
|
std::vector<std::string> GlobalDefines;
|
|
SourceMgr SM;
|
|
|
|
// Missing equal sign
|
|
GlobalDefines.emplace_back(std::string("LocalVar"));
|
|
EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM));
|
|
|
|
// Empty variable
|
|
GlobalDefines.clear();
|
|
GlobalDefines.emplace_back(std::string("=18"));
|
|
EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM));
|
|
|
|
// Invalid variable
|
|
GlobalDefines.clear();
|
|
GlobalDefines.emplace_back(std::string("18LocalVar=18"));
|
|
EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM));
|
|
|
|
// Define local variables from command-line.
|
|
GlobalDefines.clear();
|
|
GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
|
|
GlobalDefines.emplace_back(std::string("EmptyVar="));
|
|
bool GotError = Cxt.defineCmdlineVariables(GlobalDefines, SM);
|
|
EXPECT_FALSE(GotError);
|
|
|
|
// Check defined variables are present and undefined is absent.
|
|
StringRef LocalVarStr = "LocalVar";
|
|
StringRef EmptyVarStr = "EmptyVar";
|
|
StringRef UnknownVarStr = "UnknownVar";
|
|
llvm::Optional<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
|
|
llvm::Optional<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
|
llvm::Optional<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
|
|
EXPECT_TRUE(LocalVar);
|
|
EXPECT_EQ(*LocalVar, "FOO");
|
|
EXPECT_TRUE(EmptyVar);
|
|
EXPECT_EQ(*EmptyVar, "");
|
|
EXPECT_FALSE(UnknownVar);
|
|
|
|
// Clear local variables and check they become absent.
|
|
Cxt.clearLocalVars();
|
|
LocalVar = Cxt.getPatternVarValue(LocalVarStr);
|
|
EXPECT_FALSE(LocalVar);
|
|
EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
|
EXPECT_FALSE(EmptyVar);
|
|
|
|
// Redefine global variables and check variables are defined again.
|
|
GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
|
|
GotError = Cxt.defineCmdlineVariables(GlobalDefines, SM);
|
|
EXPECT_FALSE(GotError);
|
|
StringRef GlobalVarStr = "$GlobalVar";
|
|
llvm::Optional<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
|
|
EXPECT_TRUE(GlobalVar);
|
|
EXPECT_EQ(*GlobalVar, "BAR");
|
|
|
|
// Clear local variables and check global variables remain defined.
|
|
Cxt.clearLocalVars();
|
|
GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
|
|
EXPECT_TRUE(GlobalVar);
|
|
}
|
|
} // namespace
|