summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Demangle/Utility.h
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2018-07-17 19:42:29 +0000
committerZachary Turner <zturner@google.com>2018-07-17 19:42:29 +0000
commit8a0efd09190e75c283dc929a8c739c76b5d0917e (patch)
tree9b24026fede8e8207d0651fb280367a3feda4a5f /llvm/lib/Demangle/Utility.h
parentf989a92dea46f96548bdc83a394ff0a12c5ffa6b (diff)
downloadbcm5719-llvm-8a0efd09190e75c283dc929a8c739c76b5d0917e.tar.gz
bcm5719-llvm-8a0efd09190e75c283dc929a8c739c76b5d0917e.zip
Add some helper functions to the demangle utility classes.
These are all methods that, while not currently used in the Itanium demangler, are generally useful enough that it's likely the itanium demangler could find a use for them. More importantly, they are all necessary for the Microsoft demangler which is up and coming in a subsequent patch. Rather than combine these into a single monolithic patch, I think it makes sense to commit this utility code first since it is very simple, this way it won't detract from the substance of the MS demangler patch. llvm-svn: 337316
Diffstat (limited to 'llvm/lib/Demangle/Utility.h')
-rw-r--r--llvm/lib/Demangle/Utility.h88
1 files changed, 87 insertions, 1 deletions
diff --git a/llvm/lib/Demangle/Utility.h b/llvm/lib/Demangle/Utility.h
index 62c0e7430a5..f764663436d 100644
--- a/llvm/lib/Demangle/Utility.h
+++ b/llvm/lib/Demangle/Utility.h
@@ -12,6 +12,8 @@
#ifndef LLVM_DEMANGLE_UTILITY_H
#define LLVM_DEMANGLE_UTILITY_H
+#include "StringView.h"
+
#include <cstdlib>
#include <cstring>
#include <limits>
@@ -33,6 +35,27 @@ class OutputStream {
}
}
+ void writeUnsigned(uint64_t N, bool isNeg = false) {
+ // Handle special case...
+ if (N == 0) {
+ *this << '0';
+ return;
+ }
+
+ char Temp[21];
+ char *TempPtr = std::end(Temp);
+
+ while (N) {
+ *--TempPtr = '0' + char(N % 10);
+ N /= 10;
+ }
+
+ // Add negative sign...
+ if (isNeg)
+ *--TempPtr = '-';
+ this->operator<<(StringView(TempPtr, std::end(Temp)));
+ }
+
public:
OutputStream(char *StartBuf, size_t Size)
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
@@ -43,6 +66,20 @@ public:
BufferCapacity = BufferCapacity_;
}
+ /// Create an OutputStream from a buffer and a size. If either of these are
+ /// null a buffer is allocated.
+ static OutputStream create(char *StartBuf, size_t *Size, size_t AllocSize) {
+ OutputStream Result;
+
+ if (!StartBuf || !Size) {
+ StartBuf = static_cast<char *>(std::malloc(AllocSize));
+ Size = &AllocSize;
+ }
+
+ Result.reset(StartBuf, *Size);
+ return Result;
+ }
+
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
@@ -64,6 +101,39 @@ public:
return *this;
}
+ OutputStream &operator<<(StringView R) { return (*this += R); }
+
+ OutputStream &operator<<(char C) { return (*this += C); }
+
+ OutputStream &operator<<(long long N) {
+ if (N < 0)
+ writeUnsigned(static_cast<unsigned long long>(-N), true);
+ else
+ writeUnsigned(static_cast<unsigned long long>(N));
+ return *this;
+ }
+
+ OutputStream &operator<<(unsigned long long N) {
+ writeUnsigned(N, false);
+ return *this;
+ }
+
+ OutputStream &operator<<(long N) {
+ return this->operator<<(static_cast<long long>(N));
+ }
+
+ OutputStream &operator<<(unsigned long N) {
+ return this->operator<<(static_cast<unsigned long long>(N));
+ }
+
+ OutputStream &operator<<(int N) {
+ return this->operator<<(static_cast<long long>(N));
+ }
+
+ OutputStream &operator<<(unsigned int N) {
+ return this->operator<<(static_cast<unsigned long long>(N));
+ }
+
size_t getCurrentPosition() const { return CurrentPosition; }
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
@@ -81,13 +151,29 @@ public:
template <class T> class SwapAndRestore {
T &Restore;
T OriginalValue;
+ bool ShouldRestore = true;
public:
+ SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
+
SwapAndRestore(T &Restore_, T NewVal)
: Restore(Restore_), OriginalValue(Restore) {
Restore = std::move(NewVal);
}
- ~SwapAndRestore() { Restore = std::move(OriginalValue); }
+ ~SwapAndRestore() {
+ if (ShouldRestore)
+ Restore = std::move(OriginalValue);
+ }
+
+ void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
+
+ void restoreNow(bool Force) {
+ if (!Force && !ShouldRestore)
+ return;
+
+ Restore = std::move(OriginalValue);
+ ShouldRestore = false;
+ }
SwapAndRestore(const SwapAndRestore &) = delete;
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
OpenPOWER on IntegriCloud