Sure.<br><div class="gmail_quote"><div dir="ltr">On Thu, Jul 19, 2018 at 11:05 AM Erik Pilkington <<a href="mailto:erik.pilkington@gmail.com">erik.pilkington@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Zachary,<br>
Would you mind also committing any changes to these data structures to <br>
the copy of the itanium demangler in libcxxabi/src/cxa_demangle.cpp? I <br>
really want to avoid having to maintain 2 demanglers with a bunch of <br>
little differences (This is already a little true, but it would still be <br>
nice to minimize the differences).<br>
<br>
Thanks!<br>
<br>
On 7/17/18 12:42 PM, Zachary Turner via llvm-commits wrote:<br>
> Author: zturner<br>
> Date: Tue Jul 17 12:42:29 2018<br>
> New Revision: 337316<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=337316&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=337316&view=rev</a><br>
> Log:<br>
> Add some helper functions to the demangle utility classes.<br>
><br>
> These are all methods that, while not currently used in the<br>
> Itanium demangler, are generally useful enough that it's<br>
> likely the itanium demangler could find a use for them.  More<br>
> importantly, they are all necessary for the Microsoft demangler<br>
> which is up and coming in a subsequent patch.  Rather than<br>
> combine these into a single monolithic patch, I think it makes<br>
> sense to commit this utility code first since it is very simple,<br>
> this way it won't detract from the substance of the MS demangler<br>
> patch.<br>
><br>
> Modified:<br>
>      llvm/trunk/include/llvm/Demangle/Demangle.h<br>
>      llvm/trunk/lib/Demangle/ItaniumDemangle.cpp<br>
>      llvm/trunk/lib/Demangle/StringView.h<br>
>      llvm/trunk/lib/Demangle/Utility.h<br>
><br>
> Modified: llvm/trunk/include/llvm/Demangle/Demangle.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Demangle/Demangle.h?rev=337316&r1=337315&r2=337316&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Demangle/Demangle.h?rev=337316&r1=337315&r2=337316&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Demangle/Demangle.h (original)<br>
> +++ llvm/trunk/include/llvm/Demangle/Demangle.h Tue Jul 17 12:42:29 2018<br>
> @@ -16,12 +16,14 @@ namespace llvm {<br>
>   /// The mangled_name is demangled into buf and returned. If the buffer is not<br>
>   /// large enough, realloc is used to expand it.<br>
>   ///<br>
> -/// The *status will be set to<br>
> -///   unknown_error: -4<br>
> -///   invalid_args:  -3<br>
> -///   invalid_mangled_name: -2<br>
> -///   memory_alloc_failure: -1<br>
> -///   success: 0<br>
> +/// The *status will be set to a value from the enumeration<br>
> +enum : int {<br>
> +  demangle_unknown_error = -4,<br>
> +  demangle_invalid_args = -3,<br>
> +  demangle_invalid_mangled_name = -2,<br>
> +  demangle_memory_alloc_failure = -1,<br>
> +  demangle_success = 0,<br>
> +};<br>
>   <br>
>   char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,<br>
>                         int *status);<br>
><br>
> Modified: llvm/trunk/lib/Demangle/ItaniumDemangle.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/ItaniumDemangle.cpp?rev=337316&r1=337315&r2=337316&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/ItaniumDemangle.cpp?rev=337316&r1=337315&r2=337316&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Demangle/ItaniumDemangle.cpp (original)<br>
> +++ llvm/trunk/lib/Demangle/ItaniumDemangle.cpp Tue Jul 17 12:42:29 2018<br>
> @@ -4925,32 +4925,24 @@ bool initializeOutputStream(char *Buf, s<br>
>   <br>
>   }  // unnamed namespace<br>
>   <br>
> -enum {<br>
> -  unknown_error = -4,<br>
> -  invalid_args = -3,<br>
> -  invalid_mangled_name = -2,<br>
> -  memory_alloc_failure = -1,<br>
> -  success = 0,<br>
> -};<br>
> -<br>
>   char *llvm::itaniumDemangle(const char *MangledName, char *Buf,<br>
>                               size_t *N, int *Status) {<br>
>     if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {<br>
>       if (Status)<br>
> -      *Status = invalid_args;<br>
> +      *Status = demangle_invalid_args;<br>
>       return nullptr;<br>
>     }<br>
>   <br>
> -  int InternalStatus = success;<br>
> +  int InternalStatus = demangle_success;<br>
>     Db Parser(MangledName, MangledName + std::strlen(MangledName));<br>
>     OutputStream S;<br>
>   <br>
>     Node *AST = Parser.parse();<br>
>   <br>
>     if (AST == nullptr)<br>
> -    InternalStatus = invalid_mangled_name;<br>
> +    InternalStatus = demangle_invalid_mangled_name;<br>
>     else if (initializeOutputStream(Buf, N, S, 1024))<br>
> -    InternalStatus = memory_alloc_failure;<br>
> +    InternalStatus = demangle_memory_alloc_failure;<br>
>     else {<br>
>       assert(Parser.ForwardTemplateRefs.empty());<br>
>       AST->print(S);<br>
> @@ -4962,7 +4954,7 @@ char *llvm::itaniumDemangle(const char *<br>
>   <br>
>     if (Status)<br>
>       *Status = InternalStatus;<br>
> -  return InternalStatus == success ? Buf : nullptr;<br>
> +  return InternalStatus == demangle_success ? Buf : nullptr;<br>
>   }<br>
>   <br>
>   namespace llvm {<br>
><br>
> Modified: llvm/trunk/lib/Demangle/StringView.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/StringView.h?rev=337316&r1=337315&r2=337316&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/StringView.h?rev=337316&r1=337315&r2=337316&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Demangle/StringView.h (original)<br>
> +++ llvm/trunk/lib/Demangle/StringView.h Tue Jul 17 12:42:29 2018<br>
> @@ -14,6 +14,7 @@<br>
>   #define LLVM_DEMANGLE_STRINGVIEW_H<br>
>   <br>
>   #include <algorithm><br>
> +#include <cassert><br>
>   <br>
>   class StringView {<br>
>     const char *First;<br>
> @@ -24,9 +25,16 @@ public:<br>
>     StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}<br>
>     StringView(const char *First_, const char *Last_)<br>
>         : First(First_), Last(Last_) {}<br>
> +  StringView(const char *First_, size_t Len)<br>
> +      : First(First_), Last(First_ + Len) {}<br>
> +  StringView(const char *Str) : First(Str), Last(Str + strlen(Str)) {}<br>
>     StringView() : First(nullptr), Last(nullptr) {}<br>
>   <br>
> -  StringView substr(size_t From, size_t To) {<br>
> +  StringView substr(size_t From) const {<br>
> +    return StringView(begin() + From, size() - From);<br>
> +  }<br>
> +<br>
> +  StringView substr(size_t From, size_t To) const {<br>
>       if (To >= size())<br>
>         To = size() - 1;<br>
>       if (From >= size())<br>
> @@ -34,12 +42,38 @@ public:<br>
>       return StringView(First + From, First + To);<br>
>     }<br>
>   <br>
> -  StringView dropFront(size_t N) const {<br>
> +  StringView dropFront(size_t N = 1) const {<br>
>       if (N >= size())<br>
>         N = size() - 1;<br>
>       return StringView(First + N, Last);<br>
>     }<br>
>   <br>
> +  char front() const {<br>
> +    assert(!empty());<br>
> +    return *begin();<br>
> +  }<br>
> +<br>
> +  char popFront() {<br>
> +    assert(!empty());<br>
> +    return *First++;<br>
> +  }<br>
> +<br>
> +  bool consumeFront(char C) {<br>
> +    if (!startsWith(C))<br>
> +      return false;<br>
> +    *this = dropFront(1);<br>
> +    return true;<br>
> +  }<br>
> +<br>
> +  bool consumeFront(StringView S) {<br>
> +    if (!startsWith(S))<br>
> +      return false;<br>
> +    *this = dropFront(S.size());<br>
> +    return true;<br>
> +  }<br>
> +<br>
> +  bool startsWith(char C) const { return !empty() && *begin() == C; }<br>
> +<br>
>     bool startsWith(StringView Str) const {<br>
>       if (Str.size() > size())<br>
>         return false;<br>
><br>
> Modified: llvm/trunk/lib/Demangle/Utility.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/Utility.h?rev=337316&r1=337315&r2=337316&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/Utility.h?rev=337316&r1=337315&r2=337316&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Demangle/Utility.h (original)<br>
> +++ llvm/trunk/lib/Demangle/Utility.h Tue Jul 17 12:42:29 2018<br>
> @@ -12,6 +12,8 @@<br>
>   #ifndef LLVM_DEMANGLE_UTILITY_H<br>
>   #define LLVM_DEMANGLE_UTILITY_H<br>
>   <br>
> +#include "StringView.h"<br>
> +<br>
>   #include <cstdlib><br>
>   #include <cstring><br>
>   #include <limits><br>
> @@ -33,6 +35,27 @@ class OutputStream {<br>
>       }<br>
>     }<br>
>   <br>
> +  void writeUnsigned(uint64_t N, bool isNeg = false) {<br>
> +    // Handle special case...<br>
> +    if (N == 0) {<br>
> +      *this << '0';<br>
> +      return;<br>
> +    }<br>
> +<br>
> +    char Temp[21];<br>
> +    char *TempPtr = std::end(Temp);<br>
> +<br>
> +    while (N) {<br>
> +      *--TempPtr = '0' + char(N % 10);<br>
> +      N /= 10;<br>
> +    }<br>
> +<br>
> +    // Add negative sign...<br>
> +    if (isNeg)<br>
> +      *--TempPtr = '-';<br>
> +    this->operator<<(StringView(TempPtr, std::end(Temp)));<br>
> +  }<br>
> +<br>
>   public:<br>
>     OutputStream(char *StartBuf, size_t Size)<br>
>         : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}<br>
> @@ -43,6 +66,20 @@ public:<br>
>       BufferCapacity = BufferCapacity_;<br>
>     }<br>
>   <br>
> +  /// Create an OutputStream from a buffer and a size.  If either of these are<br>
> +  /// null a buffer is allocated.<br>
> +  static OutputStream create(char *StartBuf, size_t *Size, size_t AllocSize) {<br>
> +    OutputStream Result;<br>
> +<br>
> +    if (!StartBuf || !Size) {<br>
> +      StartBuf = static_cast<char *>(std::malloc(AllocSize));<br>
> +      Size = &AllocSize;<br>
> +    }<br>
> +<br>
> +    Result.reset(StartBuf, *Size);<br>
> +    return Result;<br>
> +  }<br>
> +<br>
>     /// If a ParameterPackExpansion (or similar type) is encountered, the offset<br>
>     /// into the pack that we're currently printing.<br>
>     unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();<br>
> @@ -64,6 +101,39 @@ public:<br>
>       return *this;<br>
>     }<br>
>   <br>
> +  OutputStream &operator<<(StringView R) { return (*this += R); }<br>
> +<br>
> +  OutputStream &operator<<(char C) { return (*this += C); }<br>
> +<br>
> +  OutputStream &operator<<(long long N) {<br>
> +    if (N < 0)<br>
> +      writeUnsigned(static_cast<unsigned long long>(-N), true);<br>
> +    else<br>
> +      writeUnsigned(static_cast<unsigned long long>(N));<br>
> +    return *this;<br>
> +  }<br>
> +<br>
> +  OutputStream &operator<<(unsigned long long N) {<br>
> +    writeUnsigned(N, false);<br>
> +    return *this;<br>
> +  }<br>
> +<br>
> +  OutputStream &operator<<(long N) {<br>
> +    return this->operator<<(static_cast<long long>(N));<br>
> +  }<br>
> +<br>
> +  OutputStream &operator<<(unsigned long N) {<br>
> +    return this->operator<<(static_cast<unsigned long long>(N));<br>
> +  }<br>
> +<br>
> +  OutputStream &operator<<(int N) {<br>
> +    return this->operator<<(static_cast<long long>(N));<br>
> +  }<br>
> +<br>
> +  OutputStream &operator<<(unsigned int N) {<br>
> +    return this->operator<<(static_cast<unsigned long long>(N));<br>
> +  }<br>
> +<br>
>     size_t getCurrentPosition() const { return CurrentPosition; }<br>
>     void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }<br>
>   <br>
> @@ -81,13 +151,29 @@ public:<br>
>   template <class T> class SwapAndRestore {<br>
>     T &Restore;<br>
>     T OriginalValue;<br>
> +  bool ShouldRestore = true;<br>
>   <br>
>   public:<br>
> +  SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}<br>
> +<br>
>     SwapAndRestore(T &Restore_, T NewVal)<br>
>         : Restore(Restore_), OriginalValue(Restore) {<br>
>       Restore = std::move(NewVal);<br>
>     }<br>
> -  ~SwapAndRestore() { Restore = std::move(OriginalValue); }<br>
> +  ~SwapAndRestore() {<br>
> +    if (ShouldRestore)<br>
> +      Restore = std::move(OriginalValue);<br>
> +  }<br>
> +<br>
> +  void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }<br>
> +<br>
> +  void restoreNow(bool Force) {<br>
> +    if (!Force && !ShouldRestore)<br>
> +      return;<br>
> +<br>
> +    Restore = std::move(OriginalValue);<br>
> +    ShouldRestore = false;<br>
> +  }<br>
>   <br>
>     SwapAndRestore(const SwapAndRestore &) = delete;<br>
>     SwapAndRestore &operator=(const SwapAndRestore &) = delete;<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br>
</blockquote></div>