1 //===--- Utility.h ----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
9 // This file contains several utility classes used by the demangle library.
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_DEMANGLE_UTILITY_H
13 #define LLVM_DEMANGLE_UTILITY_H
15 #include "StringView.h"
23 // Stream that AST nodes write their string representation into after the AST
27 size_t CurrentPosition;
28 size_t BufferCapacity;
30 // Ensure there is at least n more positions in buffer.
32 if (N + CurrentPosition >= BufferCapacity) {
34 if (BufferCapacity < N + CurrentPosition)
35 BufferCapacity = N + CurrentPosition;
36 Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
37 if (Buffer == nullptr)
42 void writeUnsigned(uint64_t N, bool isNeg = false) {
43 // Handle special case...
50 char *TempPtr = std::end(Temp);
53 *--TempPtr = '0' + char(N % 10);
57 // Add negative sign...
60 this->operator<<(StringView(TempPtr, std::end(Temp)));
64 OutputStream(char *StartBuf, size_t Size)
65 : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
66 OutputStream() = default;
67 void reset(char *Buffer_, size_t BufferCapacity_) {
70 BufferCapacity = BufferCapacity_;
73 /// Create an OutputStream from a buffer and a size. If either of these are
74 /// null a buffer is allocated.
75 static OutputStream create(char *StartBuf, size_t *Size, size_t AllocSize) {
78 if (!StartBuf || !Size) {
79 StartBuf = static_cast<char *>(std::malloc(AllocSize));
80 if (StartBuf == nullptr)
85 Result.reset(StartBuf, *Size);
89 /// If a ParameterPackExpansion (or similar type) is encountered, the offset
90 /// into the pack that we're currently printing.
91 unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
92 unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
94 OutputStream &operator+=(StringView R) {
95 size_t Size = R.size();
99 std::memmove(Buffer + CurrentPosition, R.begin(), Size);
100 CurrentPosition += Size;
104 OutputStream &operator+=(char C) {
106 Buffer[CurrentPosition++] = C;
110 OutputStream &operator<<(StringView R) { return (*this += R); }
112 OutputStream &operator<<(char C) { return (*this += C); }
114 OutputStream &operator<<(long long N) {
116 writeUnsigned(static_cast<unsigned long long>(-N), true);
118 writeUnsigned(static_cast<unsigned long long>(N));
122 OutputStream &operator<<(unsigned long long N) {
123 writeUnsigned(N, false);
127 OutputStream &operator<<(long N) {
128 return this->operator<<(static_cast<long long>(N));
131 OutputStream &operator<<(unsigned long N) {
132 return this->operator<<(static_cast<unsigned long long>(N));
135 OutputStream &operator<<(int N) {
136 return this->operator<<(static_cast<long long>(N));
139 OutputStream &operator<<(unsigned int N) {
140 return this->operator<<(static_cast<unsigned long long>(N));
143 size_t getCurrentPosition() const { return CurrentPosition; }
144 void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
147 return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
150 bool empty() const { return CurrentPosition == 0; }
152 char *getBuffer() { return Buffer; }
153 char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
154 size_t getBufferCapacity() { return BufferCapacity; }
157 template <class T> class SwapAndRestore {
160 bool ShouldRestore = true;
163 SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
165 SwapAndRestore(T &Restore_, T NewVal)
166 : Restore(Restore_), OriginalValue(Restore) {
167 Restore = std::move(NewVal);
171 Restore = std::move(OriginalValue);
174 void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
176 void restoreNow(bool Force) {
177 if (!Force && !ShouldRestore)
180 Restore = std::move(OriginalValue);
181 ShouldRestore = false;
184 SwapAndRestore(const SwapAndRestore &) = delete;
185 SwapAndRestore &operator=(const SwapAndRestore &) = delete;