diff options
author | Zachary Turner <zturner@google.com> | 2018-07-16 21:24:03 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2018-07-16 21:24:03 +0000 |
commit | fac2da1ba76f9ac0bef4a8963a059d1a928ba787 (patch) | |
tree | 96b0749a0843eb29baa68971d26e0855d09e2a92 /llvm/lib/Demangle/Utility.h | |
parent | ed8c05cc99c3b21ca0667908881df6b10eebc5b5 (diff) | |
download | bcm5719-llvm-fac2da1ba76f9ac0bef4a8963a059d1a928ba787.tar.gz bcm5719-llvm-fac2da1ba76f9ac0bef4a8963a059d1a928ba787.zip |
[LLVMDemangle] Move some utility classes to header files.
In a followup I'm looking to add a Microsoft demangler. Doing
so needs a lot of the same utility classes and feature test
macros which are already implemented in ItaniumDemangle.cpp.
So move all of these things into header files so that they
can be re-used by a new demangler.
Differential Revision: https://reviews.llvm.org/D49399
llvm-svn: 337217
Diffstat (limited to 'llvm/lib/Demangle/Utility.h')
-rw-r--r-- | llvm/lib/Demangle/Utility.h | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/llvm/lib/Demangle/Utility.h b/llvm/lib/Demangle/Utility.h new file mode 100644 index 00000000000..14cf02bf3e8 --- /dev/null +++ b/llvm/lib/Demangle/Utility.h @@ -0,0 +1,94 @@ +//===--- Utility.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// +// This file contains several utility classes used by the demangle library. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEMANGLE_UTILITY_H +#define LLVM_DEMANGLE_UTILITY_H + +#include <cstring> + +// Stream that AST nodes write their string representation into after the AST +// has been parsed. +class OutputStream { + char *Buffer; + size_t CurrentPosition; + size_t BufferCapacity; + + // Ensure there is at least n more positions in buffer. + void grow(size_t N) { + if (N + CurrentPosition >= BufferCapacity) { + BufferCapacity *= 2; + if (BufferCapacity < N + CurrentPosition) + BufferCapacity = N + CurrentPosition; + Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity)); + } + } + +public: + OutputStream(char *StartBuf, size_t Size) + : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {} + OutputStream() = default; + void reset(char *Buffer_, size_t BufferCapacity_) { + CurrentPosition = 0; + Buffer = Buffer_; + BufferCapacity = BufferCapacity_; + } + + /// 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(); + + OutputStream &operator+=(StringView R) { + size_t Size = R.size(); + if (Size == 0) + return *this; + grow(Size); + std::memmove(Buffer + CurrentPosition, R.begin(), Size); + CurrentPosition += Size; + return *this; + } + + OutputStream &operator+=(char C) { + grow(1); + Buffer[CurrentPosition++] = C; + return *this; + } + + size_t getCurrentPosition() const { return CurrentPosition; } + void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; } + + char back() const { + return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0'; + } + + bool empty() const { return CurrentPosition == 0; } + + char *getBuffer() { return Buffer; } + char *getBufferEnd() { return Buffer + CurrentPosition - 1; } + size_t getBufferCapacity() { return BufferCapacity; } +}; + +template <class T> class SwapAndRestore { + T &Restore; + T OriginalValue; + +public: + SwapAndRestore(T &Restore_, T NewVal) + : Restore(Restore_), OriginalValue(Restore) { + Restore = std::move(NewVal); + } + ~SwapAndRestore() { Restore = std::move(OriginalValue); } + + SwapAndRestore(const SwapAndRestore &) = delete; + SwapAndRestore &operator=(const SwapAndRestore &) = delete; +}; + +#endif |