mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
Add support for formatv to llvm::Twine.
Differential Revision: https://reviews.llvm.org/D27835 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290020 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a908bbaf8d
commit
d69dfb10b7
@ -19,6 +19,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class formatv_object_base;
|
||||
class raw_ostream;
|
||||
|
||||
/// Twine - A lightweight data structure for efficiently representing the
|
||||
@ -102,6 +103,9 @@ namespace llvm {
|
||||
/// A pointer to a SmallString instance.
|
||||
SmallStringKind,
|
||||
|
||||
/// A pointer to a formatv_object_base instance.
|
||||
FormatvObjectKind,
|
||||
|
||||
/// A char value, to render as a character.
|
||||
CharKind,
|
||||
|
||||
@ -137,6 +141,7 @@ namespace llvm {
|
||||
const std::string *stdString;
|
||||
const StringRef *stringRef;
|
||||
const SmallVectorImpl<char> *smallString;
|
||||
const formatv_object_base *formatvObject;
|
||||
char character;
|
||||
unsigned int decUI;
|
||||
int decI;
|
||||
@ -290,6 +295,13 @@ namespace llvm {
|
||||
assert(isValid() && "Invalid twine!");
|
||||
}
|
||||
|
||||
/// Construct from a formatv_object_base.
|
||||
/*implicit*/ Twine(const formatv_object_base &Fmt)
|
||||
: LHSKind(FormatvObjectKind), RHSKind(EmptyKind) {
|
||||
LHS.formatvObject = &Fmt;
|
||||
assert(isValid() && "Invalid twine!");
|
||||
}
|
||||
|
||||
/// Construct from a char.
|
||||
explicit Twine(char Val)
|
||||
: LHSKind(CharKind), RHSKind(EmptyKind) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -18,6 +19,11 @@ std::string Twine::str() const {
|
||||
if (LHSKind == StdStringKind && RHSKind == EmptyKind)
|
||||
return *LHS.stdString;
|
||||
|
||||
// If we're storing a formatv_object, we can avoid an extra copy by formatting
|
||||
// it immediately and returning the result.
|
||||
if (LHSKind == FormatvObjectKind && RHSKind == EmptyKind)
|
||||
return LHS.formatvObject->str();
|
||||
|
||||
// Otherwise, flatten and copy the contents first.
|
||||
SmallString<256> Vec;
|
||||
return toStringRef(Vec).str();
|
||||
@ -68,6 +74,9 @@ void Twine::printOneChild(raw_ostream &OS, Child Ptr,
|
||||
case Twine::SmallStringKind:
|
||||
OS << *Ptr.smallString;
|
||||
break;
|
||||
case Twine::FormatvObjectKind:
|
||||
OS << *Ptr.formatvObject;
|
||||
break;
|
||||
case Twine::CharKind:
|
||||
OS << Ptr.character;
|
||||
break;
|
||||
@ -121,6 +130,9 @@ void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
|
||||
case Twine::SmallStringKind:
|
||||
OS << "smallstring:\"" << *Ptr.smallString << "\"";
|
||||
break;
|
||||
case Twine::FormatvObjectKind:
|
||||
OS << "formatv:\"" << *Ptr.formatvObject << "\"";
|
||||
break;
|
||||
case Twine::CharKind:
|
||||
OS << "char:\"" << Ptr.character << "\"";
|
||||
break;
|
||||
|
@ -7,8 +7,10 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/FormatAdapters.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "gtest/gtest.h"
|
||||
using namespace llvm;
|
||||
@ -30,6 +32,7 @@ TEST(TwineTest, Construction) {
|
||||
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) {
|
||||
@ -65,6 +68,10 @@ TEST(TwineTest, Concat) {
|
||||
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"))));
|
||||
|
||||
@ -89,6 +96,25 @@ TEST(TwineTest, toNullTerminatedStringRef) {
|
||||
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) : Count(Count), FormatAdapter(0) {}
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user