diff --git a/libcxxabi/src/demangle/Utility.h b/libcxxabi/src/demangle/Utility.h --- a/libcxxabi/src/demangle/Utility.h +++ b/libcxxabi/src/demangle/Utility.h @@ -95,6 +95,17 @@ OutputBuffer &operator<<(StringView R) { return (*this += R); } + OutputBuffer prepend(StringView R) { + size_t Size = R.size(); + + grow(Size); + std::memmove(Buffer + Size, Buffer, CurrentPosition); + std::memcpy(Buffer, R.begin(), Size); + CurrentPosition += Size; + + return *this; + } + OutputBuffer &operator<<(char C) { return (*this += C); } OutputBuffer &operator<<(long long N) { diff --git a/llvm/include/llvm/Demangle/Utility.h b/llvm/include/llvm/Demangle/Utility.h --- a/llvm/include/llvm/Demangle/Utility.h +++ b/llvm/include/llvm/Demangle/Utility.h @@ -95,6 +95,17 @@ OutputBuffer &operator<<(StringView R) { return (*this += R); } + OutputBuffer prepend(StringView R) { + size_t Size = R.size(); + + grow(Size); + std::memmove(Buffer + Size, Buffer, CurrentPosition); + std::memcpy(Buffer, R.begin(), Size); + CurrentPosition += Size; + + return *this; + } + OutputBuffer &operator<<(char C) { return (*this += C); } OutputBuffer &operator<<(long long N) { diff --git a/llvm/unittests/Demangle/OutputBufferTest.cpp b/llvm/unittests/Demangle/OutputBufferTest.cpp --- a/llvm/unittests/Demangle/OutputBufferTest.cpp +++ b/llvm/unittests/Demangle/OutputBufferTest.cpp @@ -60,3 +60,21 @@ std::free(OB.getBuffer()); } + +TEST(OutputBufferTest, Prepend) { + OutputBuffer OB; + + OB.prepend("n"); + EXPECT_EQ("n", toString(OB)); + + OB << "abc"; + OB.prepend("def"); + EXPECT_EQ("defnabc", toString(OB)); + + OB.setCurrentPosition(3); + + OB.prepend("abc"); + EXPECT_EQ("abcdef", toString(OB)); + + std::free(OB.getBuffer()); +}