1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00
llvm-mirror/unittests/ADT/TwineTest.cpp
Zachary Turner ab809dc2fa [ADT] Make Twine's copy constructor private.
There's a lot of misuse of Twine scattered around LLVM.  This
ranges in severity from benign (returning a Twine from a function
by value that is just a string literal) to pretty sketchy (storing
a Twine by value in a class).  While there are some uses for
copying Twines, most of the very compelling ones are confined
to the Twine class implementation itself, and other uses are
either dubious or easily worked around.

This patch makes Twine's copy constructor private, and fixes up
all callsites.

Differential Revision: https://reviews.llvm.org/D38767

llvm-svn: 315530
2017-10-11 23:33:06 +00:00

132 lines
4.6 KiB
C++

//===- TwineTest.cpp - Twine unit tests -----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
std::string repr(const Twine &Value) {
std::string res;
llvm::raw_string_ostream OS(res);
Value.printRepr(OS);
return OS.str();
}
TEST(TwineTest, Construction) {
EXPECT_EQ("", Twine().str());
EXPECT_EQ("hi", Twine("hi").str());
EXPECT_EQ("hi", Twine(std::string("hi")).str());
EXPECT_EQ("hi", Twine(StringRef("hi")).str());
EXPECT_EQ("hi", Twine(StringRef(std::string("hi"))).str());
EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str());
EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str());
EXPECT_EQ("hi", Twine(formatv("{0}", "hi")).str());
}
TEST(TwineTest, Numbers) {
EXPECT_EQ("123", Twine(123U).str());
EXPECT_EQ("123", Twine(123).str());
EXPECT_EQ("-123", Twine(-123).str());
EXPECT_EQ("123", Twine(123).str());
EXPECT_EQ("-123", Twine(-123).str());
EXPECT_EQ("7b", Twine::utohexstr(123).str());
}
TEST(TwineTest, Characters) {
EXPECT_EQ("x", Twine('x').str());
EXPECT_EQ("x", Twine(static_cast<unsigned char>('x')).str());
EXPECT_EQ("x", Twine(static_cast<signed char>('x')).str());
}
TEST(TwineTest, Concat) {
// Check verse repr, since we care about the actual representation not just
// the result.
// Concat with null.
EXPECT_EQ("(Twine null empty)",
repr(Twine("hi").concat(Twine::createNull())));
EXPECT_EQ("(Twine null empty)",
repr(Twine::createNull().concat(Twine("hi"))));
// Concat with empty.
EXPECT_EQ("(Twine cstring:\"hi\" empty)",
repr(Twine("hi").concat(Twine())));
EXPECT_EQ("(Twine cstring:\"hi\" empty)",
repr(Twine().concat(Twine("hi"))));
EXPECT_EQ("(Twine smallstring:\"hi\" empty)",
repr(Twine().concat(Twine(SmallString<5>("hi")))));
EXPECT_EQ("(Twine formatv:\"howdy\" empty)",
repr(Twine(formatv("howdy")).concat(Twine())));
EXPECT_EQ("(Twine formatv:\"howdy\" empty)",
repr(Twine().concat(Twine(formatv("howdy")))));
EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")",
repr(Twine(SmallString<7>("hey")).concat(Twine("there"))));
// Concatenation of unary ropes.
EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")",
repr(Twine("a").concat(Twine("b"))));
// Concatenation of other ropes.
EXPECT_EQ("(Twine rope:(Twine cstring:\"a\" cstring:\"b\") cstring:\"c\")",
repr(Twine("a").concat(Twine("b")).concat(Twine("c"))));
EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine cstring:\"b\" cstring:\"c\"))",
repr(Twine("a").concat(Twine("b").concat(Twine("c")))));
EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine smallstring:\"b\" cstring:\"c\"))",
repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c")))));
}
TEST(TwineTest, Operators) {
EXPECT_EQ(R"((Twine cstring:"a" stringref:"b"))", repr("a" + StringRef("b")));
EXPECT_EQ(R"((Twine stringref:"a" cstring:"b"))", repr(StringRef("a") + "b"));
EXPECT_EQ(R"((Twine stringref:"a" stringref:"b"))",
repr(StringRef("a") + StringRef("b")));
}
TEST(TwineTest, toNullTerminatedStringRef) {
SmallString<8> storage;
EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end());
EXPECT_EQ(0,
*Twine(StringRef("hello")).toNullTerminatedStringRef(storage).end());
EXPECT_EQ(0, *Twine(SmallString<11>("hello"))
.toNullTerminatedStringRef(storage)
.end());
EXPECT_EQ(0, *Twine(formatv("{0}{1}", "how", "dy"))
.toNullTerminatedStringRef(storage)
.end());
}
TEST(TwineTest, LazyEvaluation) {
struct formatter : FormatAdapter<int> {
explicit formatter(int &Count) : FormatAdapter(0), Count(Count) {}
int &Count;
void format(raw_ostream &OS, StringRef Style) { ++Count; }
};
int Count = 0;
formatter Formatter(Count);
(void)Twine(formatv("{0}", Formatter));
EXPECT_EQ(0, Count);
(void)Twine(formatv("{0}", Formatter)).str();
EXPECT_EQ(1, Count);
}
// I suppose linking in the entire code generator to add a unit test to check
// the code size of the concat operation is overkill... :)
} // end anonymous namespace