123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- Utility.h -------------------*- mode:c++;eval:(read-only-mode) -*-===//
- // Do not edit! See README.txt.
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Provide some utility classes for use in the demangler.
- // There are two copies of this file in the source tree. The one in libcxxabi
- // is the original and the one in llvm is the copy. Use cp-to-llvm.sh to update
- // the copy. See README.txt for more details.
- //
- //===----------------------------------------------------------------------===//
- #ifndef DEMANGLE_UTILITY_H
- #define DEMANGLE_UTILITY_H
- #include "StringView.h"
- #include <array>
- #include <cstdint>
- #include <cstdlib>
- #include <cstring>
- #include <exception>
- #include <limits>
- DEMANGLE_NAMESPACE_BEGIN
- // Stream that AST nodes write their string representation into after the AST
- // has been parsed.
- class OutputBuffer {
- char *Buffer = nullptr;
- size_t CurrentPosition = 0;
- size_t BufferCapacity = 0;
- // Ensure there are at least N more positions in the buffer.
- void grow(size_t N) {
- size_t Need = N + CurrentPosition;
- if (Need > BufferCapacity) {
- // Reduce the number of reallocations, with a bit of hysteresis. The
- // number here is chosen so the first allocation will more-than-likely not
- // allocate more than 1K.
- Need += 1024 - 32;
- BufferCapacity *= 2;
- if (BufferCapacity < Need)
- BufferCapacity = Need;
- Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
- if (Buffer == nullptr)
- std::terminate();
- }
- }
- OutputBuffer &writeUnsigned(uint64_t N, bool isNeg = false) {
- std::array<char, 21> Temp;
- char *TempPtr = Temp.data() + Temp.size();
- // Output at least one character.
- do {
- *--TempPtr = char('0' + N % 10);
- N /= 10;
- } while (N);
- // Add negative sign.
- if (isNeg)
- *--TempPtr = '-';
- return operator+=(StringView(TempPtr, Temp.data() + Temp.size()));
- }
- public:
- OutputBuffer(char *StartBuf, size_t Size)
- : Buffer(StartBuf), BufferCapacity(Size) {}
- OutputBuffer(char *StartBuf, size_t *SizePtr)
- : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
- OutputBuffer() = default;
- // Non-copyable
- OutputBuffer(const OutputBuffer &) = delete;
- OutputBuffer &operator=(const OutputBuffer &) = delete;
- operator StringView() const { return StringView(Buffer, CurrentPosition); }
- /// 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();
- unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
- /// When zero, we're printing template args and '>' needs to be parenthesized.
- /// Use a counter so we can simply increment inside parentheses.
- unsigned GtIsGt = 1;
- bool isGtInsideTemplateArgs() const { return GtIsGt == 0; }
- void printOpen(char Open = '(') {
- GtIsGt++;
- *this += Open;
- }
- void printClose(char Close = ')') {
- GtIsGt--;
- *this += Close;
- }
- OutputBuffer &operator+=(StringView R) {
- if (size_t Size = R.size()) {
- grow(Size);
- std::memcpy(Buffer + CurrentPosition, R.begin(), Size);
- CurrentPosition += Size;
- }
- return *this;
- }
- OutputBuffer &operator+=(char C) {
- grow(1);
- Buffer[CurrentPosition++] = C;
- return *this;
- }
- 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<<(StringView R) { return (*this += R); }
- OutputBuffer &operator<<(char C) { return (*this += C); }
- OutputBuffer &operator<<(long long N) {
- return writeUnsigned(static_cast<unsigned long long>(std::abs(N)), N < 0);
- }
- OutputBuffer &operator<<(unsigned long long N) {
- return writeUnsigned(N, false);
- }
- OutputBuffer &operator<<(long N) {
- return this->operator<<(static_cast<long long>(N));
- }
- OutputBuffer &operator<<(unsigned long N) {
- return this->operator<<(static_cast<unsigned long long>(N));
- }
- OutputBuffer &operator<<(int N) {
- return this->operator<<(static_cast<long long>(N));
- }
- OutputBuffer &operator<<(unsigned int N) {
- return this->operator<<(static_cast<unsigned long long>(N));
- }
- void insert(size_t Pos, const char *S, size_t N) {
- assert(Pos <= CurrentPosition);
- if (N == 0)
- return;
- grow(N);
- std::memmove(Buffer + Pos + N, Buffer + Pos, CurrentPosition - Pos);
- std::memcpy(Buffer + Pos, S, N);
- CurrentPosition += N;
- }
- size_t getCurrentPosition() const { return CurrentPosition; }
- void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
- char back() const {
- assert(CurrentPosition);
- return Buffer[CurrentPosition - 1];
- }
- bool empty() const { return CurrentPosition == 0; }
- char *getBuffer() { return Buffer; }
- char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
- size_t getBufferCapacity() const { return BufferCapacity; }
- };
- template <class T> class ScopedOverride {
- T &Loc;
- T Original;
- public:
- ScopedOverride(T &Loc_) : ScopedOverride(Loc_, Loc_) {}
- ScopedOverride(T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) {
- Loc_ = std::move(NewVal);
- }
- ~ScopedOverride() { Loc = std::move(Original); }
- ScopedOverride(const ScopedOverride &) = delete;
- ScopedOverride &operator=(const ScopedOverride &) = delete;
- };
- DEMANGLE_NAMESPACE_END
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|