summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2010-12-01 20:37:30 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2010-12-01 20:37:30 +0000
commit7dc7ac3cb20b7ef8e6febe0ac3bc430230f29893 (patch)
tree8f8f6241c8d337970dc397842482c4279e1ea9c0
parentf00140c8e16936aac3f51cc5607168f6982a987a (diff)
downloadllvm-7dc7ac3cb20b7ef8e6febe0ac3bc430230f29893.tar.gz
llvm-7dc7ac3cb20b7ef8e6febe0ac3bc430230f29893.tar.bz2
llvm-7dc7ac3cb20b7ef8e6febe0ac3bc430230f29893.tar.xz
Support/ADT/Twine: Add toNullTerminatedStringRef.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120600 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/Twine.h8
-rw-r--r--lib/Support/Twine.cpp12
-rw-r--r--unittests/ADT/TwineTest.cpp8
3 files changed, 28 insertions, 0 deletions
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index 82f46c9379..ab8d3653e3 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -382,6 +382,14 @@ namespace llvm {
/// SmallVector and a StringRef to the SmallVector's data is returned.
StringRef toStringRef(SmallVectorImpl<char> &Out) const;
+ /// toNullTerminatedStringRef - This returns the twine as a single null
+ /// terminated StringRef if it can be represented as such. Otherwise the
+ /// twine is written into the given SmallVector and a StringRef to the
+ /// SmallVector's data is returned.
+ ///
+ /// The returned StringRef's size does not include the null terminator.
+ StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+
/// print - Write the concatenated string represented by this twine to the
/// stream \arg OS.
void print(raw_ostream &OS) const;
diff --git a/lib/Support/Twine.cpp b/lib/Support/Twine.cpp
index 093e29de96..4f6f479a7e 100644
--- a/lib/Support/Twine.cpp
+++ b/lib/Support/Twine.cpp
@@ -30,6 +30,18 @@ StringRef Twine::toStringRef(SmallVectorImpl<char> &Out) const {
return StringRef(Out.data(), Out.size());
}
+StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {
+ if (isSingleStringRef()) {
+ StringRef sr = getSingleStringRef();
+ if (*(sr.begin() + sr.size()) == 0)
+ return sr;
+ }
+ toVector(Out);
+ Out.push_back(0);
+ Out.pop_back();
+ return StringRef(Out.data(), Out.size());
+}
+
void Twine::printOneChild(raw_ostream &OS, const void *Ptr,
NodeKind Kind) const {
switch (Kind) {
diff --git a/unittests/ADT/TwineTest.cpp b/unittests/ADT/TwineTest.cpp
index 61e8a0ac37..57f54cb006 100644
--- a/unittests/ADT/TwineTest.cpp
+++ b/unittests/ADT/TwineTest.cpp
@@ -9,6 +9,7 @@
#include "gtest/gtest.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -69,6 +70,13 @@ TEST(TwineTest, Concat) {
repr(Twine("a").concat(Twine("b").concat(Twine("c")))));
}
+TEST(TwineTest, toNullTerminatedStringRef) {
+ SmallString<8> storage;
+ EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end());
+ EXPECT_EQ(0,
+ *Twine(StringRef("hello")).toNullTerminatedStringRef(storage).end());
+}
+
// I suppose linking in the entire code generator to add a unit test to check
// the code size of the concat operation is overkill... :)