Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/c++abi/src/demangle/Utility.h
12346 views
1
//===--- Utility.h ----------------------------------------------*- C++ -*-===//
2
//
3
// The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//
9
// This file is copied from llvm/lib/Demangle/Utility.h.
10
//===----------------------------------------------------------------------===//
11
12
#ifndef LIBCXX_DEMANGLE_UTILITY_H
13
#define LIBCXX_DEMANGLE_UTILITY_H
14
15
#include "StringView.h"
16
17
#include <cstdint>
18
#include <cstdlib>
19
#include <cstring>
20
#include <iterator>
21
#include <limits>
22
23
namespace {
24
// Stream that AST nodes write their string representation into after the AST
25
// has been parsed.
26
class OutputStream {
27
char *Buffer;
28
size_t CurrentPosition;
29
size_t BufferCapacity;
30
31
// Ensure there is at least n more positions in buffer.
32
void grow(size_t N) {
33
if (N + CurrentPosition >= BufferCapacity) {
34
BufferCapacity *= 2;
35
if (BufferCapacity < N + CurrentPosition)
36
BufferCapacity = N + CurrentPosition;
37
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
38
if (Buffer == nullptr)
39
std::terminate();
40
}
41
}
42
43
void writeUnsigned(uint64_t N, bool isNeg = false) {
44
// Handle special case...
45
if (N == 0) {
46
*this << '0';
47
return;
48
}
49
50
char Temp[21];
51
char *TempPtr = std::end(Temp);
52
53
while (N) {
54
*--TempPtr = '0' + char(N % 10);
55
N /= 10;
56
}
57
58
// Add negative sign...
59
if (isNeg)
60
*--TempPtr = '-';
61
this->operator<<(StringView(TempPtr, std::end(Temp)));
62
}
63
64
public:
65
OutputStream(char *StartBuf, size_t Size)
66
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
67
OutputStream() = default;
68
void reset(char *Buffer_, size_t BufferCapacity_) {
69
CurrentPosition = 0;
70
Buffer = Buffer_;
71
BufferCapacity = BufferCapacity_;
72
}
73
74
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
75
/// into the pack that we're currently printing.
76
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
77
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
78
79
OutputStream &operator+=(StringView R) {
80
size_t Size = R.size();
81
if (Size == 0)
82
return *this;
83
grow(Size);
84
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
85
CurrentPosition += Size;
86
return *this;
87
}
88
89
OutputStream &operator+=(char C) {
90
grow(1);
91
Buffer[CurrentPosition++] = C;
92
return *this;
93
}
94
95
OutputStream &operator<<(StringView R) { return (*this += R); }
96
97
OutputStream &operator<<(char C) { return (*this += C); }
98
99
OutputStream &operator<<(long long N) {
100
if (N < 0)
101
writeUnsigned(static_cast<unsigned long long>(-N), true);
102
else
103
writeUnsigned(static_cast<unsigned long long>(N));
104
return *this;
105
}
106
107
OutputStream &operator<<(unsigned long long N) {
108
writeUnsigned(N, false);
109
return *this;
110
}
111
112
OutputStream &operator<<(long N) {
113
return this->operator<<(static_cast<long long>(N));
114
}
115
116
OutputStream &operator<<(unsigned long N) {
117
return this->operator<<(static_cast<unsigned long long>(N));
118
}
119
120
OutputStream &operator<<(int N) {
121
return this->operator<<(static_cast<long long>(N));
122
}
123
124
OutputStream &operator<<(unsigned int N) {
125
return this->operator<<(static_cast<unsigned long long>(N));
126
}
127
128
size_t getCurrentPosition() const { return CurrentPosition; }
129
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
130
131
char back() const {
132
return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
133
}
134
135
bool empty() const { return CurrentPosition == 0; }
136
137
char *getBuffer() { return Buffer; }
138
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
139
size_t getBufferCapacity() { return BufferCapacity; }
140
};
141
142
template <class T> class SwapAndRestore {
143
T &Restore;
144
T OriginalValue;
145
bool ShouldRestore = true;
146
147
public:
148
SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
149
150
SwapAndRestore(T &Restore_, T NewVal)
151
: Restore(Restore_), OriginalValue(Restore) {
152
Restore = std::move(NewVal);
153
}
154
~SwapAndRestore() {
155
if (ShouldRestore)
156
Restore = std::move(OriginalValue);
157
}
158
159
void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
160
161
void restoreNow(bool Force) {
162
if (!Force && !ShouldRestore)
163
return;
164
165
Restore = std::move(OriginalValue);
166
ShouldRestore = false;
167
}
168
169
SwapAndRestore(const SwapAndRestore &) = delete;
170
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
171
};
172
173
inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
174
size_t InitSize) {
175
size_t BufferSize;
176
if (Buf == nullptr) {
177
Buf = static_cast<char *>(std::malloc(InitSize));
178
if (Buf == nullptr)
179
return false;
180
BufferSize = InitSize;
181
} else
182
BufferSize = *N;
183
184
S.reset(Buf, BufferSize);
185
return true;
186
}
187
188
} // namespace
189
190
#endif
191
192