summaryrefslogtreecommitdiff
path: root/externals/demangle/llvm/Demangle/Utility.h
diff options
context:
space:
mode:
authorGravatar Alexandre Bouvier2023-01-23 01:51:12 +0100
committerGravatar Alexandre Bouvier2023-01-23 06:23:00 +0100
commit34b1ea9c1925d0da9377973d25e10e9b5ec40e94 (patch)
tree0ada6de7ae81a250258a4243d5bd4d2cc1283aef /externals/demangle/llvm/Demangle/Utility.h
parentMerge pull request #9555 from abouvier/catch2-update (diff)
downloadyuzu-34b1ea9c1925d0da9377973d25e10e9b5ec40e94.tar.gz
yuzu-34b1ea9c1925d0da9377973d25e10e9b5ec40e94.tar.xz
yuzu-34b1ea9c1925d0da9377973d25e10e9b5ec40e94.zip
cmake: prefer system llvm library
Diffstat (limited to 'externals/demangle/llvm/Demangle/Utility.h')
-rw-r--r--externals/demangle/llvm/Demangle/Utility.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/externals/demangle/llvm/Demangle/Utility.h b/externals/demangle/llvm/Demangle/Utility.h
new file mode 100644
index 000000000..50d05c6b1
--- /dev/null
+++ b/externals/demangle/llvm/Demangle/Utility.h
@@ -0,0 +1,192 @@
1//===--- Utility.h ----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-FileCopyrightText: Part of the LLVM Project
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9//
10// Provide some utility classes for use in the demangler(s).
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef DEMANGLE_UTILITY_H
15#define DEMANGLE_UTILITY_H
16
17#include "StringView.h"
18#include <cstdint>
19#include <cstdlib>
20#include <cstring>
21#include <iterator>
22#include <limits>
23
24DEMANGLE_NAMESPACE_BEGIN
25
26// Stream that AST nodes write their string representation into after the AST
27// has been parsed.
28class OutputStream {
29 char *Buffer;
30 size_t CurrentPosition;
31 size_t BufferCapacity;
32
33 // Ensure there is at least n more positions in buffer.
34 void grow(size_t N) {
35 if (N + CurrentPosition >= BufferCapacity) {
36 BufferCapacity *= 2;
37 if (BufferCapacity < N + CurrentPosition)
38 BufferCapacity = N + CurrentPosition;
39 Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
40 if (Buffer == nullptr)
41 std::terminate();
42 }
43 }
44
45 void writeUnsigned(uint64_t N, bool isNeg = false) {
46 // Handle special case...
47 if (N == 0) {
48 *this << '0';
49 return;
50 }
51
52 char Temp[21];
53 char *TempPtr = std::end(Temp);
54
55 while (N) {
56 *--TempPtr = '0' + char(N % 10);
57 N /= 10;
58 }
59
60 // Add negative sign...
61 if (isNeg)
62 *--TempPtr = '-';
63 this->operator<<(StringView(TempPtr, std::end(Temp)));
64 }
65
66public:
67 OutputStream(char *StartBuf, size_t Size)
68 : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
69 OutputStream() = default;
70 void reset(char *Buffer_, size_t BufferCapacity_) {
71 CurrentPosition = 0;
72 Buffer = Buffer_;
73 BufferCapacity = BufferCapacity_;
74 }
75
76 /// If a ParameterPackExpansion (or similar type) is encountered, the offset
77 /// into the pack that we're currently printing.
78 unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
79 unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
80
81 OutputStream &operator+=(StringView R) {
82 size_t Size = R.size();
83 if (Size == 0)
84 return *this;
85 grow(Size);
86 std::memmove(Buffer + CurrentPosition, R.begin(), Size);
87 CurrentPosition += Size;
88 return *this;
89 }
90
91 OutputStream &operator+=(char C) {
92 grow(1);
93 Buffer[CurrentPosition++] = C;
94 return *this;
95 }
96
97 OutputStream &operator<<(StringView R) { return (*this += R); }
98
99 OutputStream &operator<<(char C) { return (*this += C); }
100
101 OutputStream &operator<<(long long N) {
102 if (N < 0)
103 writeUnsigned(static_cast<unsigned long long>(-N), true);
104 else
105 writeUnsigned(static_cast<unsigned long long>(N));
106 return *this;
107 }
108
109 OutputStream &operator<<(unsigned long long N) {
110 writeUnsigned(N, false);
111 return *this;
112 }
113
114 OutputStream &operator<<(long N) {
115 return this->operator<<(static_cast<long long>(N));
116 }
117
118 OutputStream &operator<<(unsigned long N) {
119 return this->operator<<(static_cast<unsigned long long>(N));
120 }
121
122 OutputStream &operator<<(int N) {
123 return this->operator<<(static_cast<long long>(N));
124 }
125
126 OutputStream &operator<<(unsigned int N) {
127 return this->operator<<(static_cast<unsigned long long>(N));
128 }
129
130 size_t getCurrentPosition() const { return CurrentPosition; }
131 void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
132
133 char back() const {
134 return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
135 }
136
137 bool empty() const { return CurrentPosition == 0; }
138
139 char *getBuffer() { return Buffer; }
140 char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
141 size_t getBufferCapacity() { return BufferCapacity; }
142};
143
144template <class T> class SwapAndRestore {
145 T &Restore;
146 T OriginalValue;
147 bool ShouldRestore = true;
148
149public:
150 SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
151
152 SwapAndRestore(T &Restore_, T NewVal)
153 : Restore(Restore_), OriginalValue(Restore) {
154 Restore = std::move(NewVal);
155 }
156 ~SwapAndRestore() {
157 if (ShouldRestore)
158 Restore = std::move(OriginalValue);
159 }
160
161 void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
162
163 void restoreNow(bool Force) {
164 if (!Force && !ShouldRestore)
165 return;
166
167 Restore = std::move(OriginalValue);
168 ShouldRestore = false;
169 }
170
171 SwapAndRestore(const SwapAndRestore &) = delete;
172 SwapAndRestore &operator=(const SwapAndRestore &) = delete;
173};
174
175inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
176 size_t InitSize) {
177 size_t BufferSize;
178 if (Buf == nullptr) {
179 Buf = static_cast<char *>(std::malloc(InitSize));
180 if (Buf == nullptr)
181 return false;
182 BufferSize = InitSize;
183 } else
184 BufferSize = *N;
185
186 S.reset(Buf, BufferSize);
187 return true;
188}
189
190DEMANGLE_NAMESPACE_END
191
192#endif