RustDemangle.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //===--- RustDemangle.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-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_DEMANGLE_RUSTDEMANGLE_H
  9. #define LLVM_DEMANGLE_RUSTDEMANGLE_H
  10. #include "llvm/Demangle/DemangleConfig.h"
  11. #include "llvm/Demangle/StringView.h"
  12. #include "llvm/Demangle/Utility.h"
  13. #include <cstdint>
  14. namespace llvm {
  15. namespace rust_demangle {
  16. using llvm::itanium_demangle::OutputStream;
  17. using llvm::itanium_demangle::StringView;
  18. using llvm::itanium_demangle::SwapAndRestore;
  19. struct Identifier {
  20. StringView Name;
  21. bool Punycode;
  22. bool empty() const { return Name.empty(); }
  23. };
  24. enum class BasicType {
  25. Bool,
  26. Char,
  27. I8,
  28. I16,
  29. I32,
  30. I64,
  31. I128,
  32. ISize,
  33. U8,
  34. U16,
  35. U32,
  36. U64,
  37. U128,
  38. USize,
  39. F32,
  40. F64,
  41. Str,
  42. Placeholder,
  43. Unit,
  44. Variadic,
  45. Never,
  46. };
  47. enum class InType {
  48. No,
  49. Yes,
  50. };
  51. class Demangler {
  52. // Maximum recursion level. Used to avoid stack overflow.
  53. size_t MaxRecursionLevel;
  54. // Current recursion level.
  55. size_t RecursionLevel;
  56. // Input string that is being demangled with "_R" prefix removed.
  57. StringView Input;
  58. // Position in the input string.
  59. size_t Position;
  60. // When true, print methods append the output to the stream.
  61. // When false, the output is suppressed.
  62. bool Print;
  63. // True if an error occurred.
  64. bool Error;
  65. public:
  66. // Demangled output.
  67. OutputStream Output;
  68. Demangler(size_t MaxRecursionLevel = 500);
  69. bool demangle(StringView MangledName);
  70. private:
  71. void demanglePath(InType InType);
  72. void demangleImplPath(InType InType);
  73. void demangleGenericArg();
  74. void demangleType();
  75. void demangleFnSig();
  76. void demangleConst();
  77. void demangleConstInt();
  78. void demangleConstBool();
  79. void demangleConstChar();
  80. Identifier parseIdentifier();
  81. uint64_t parseOptionalBase62Number(char Tag);
  82. uint64_t parseBase62Number();
  83. uint64_t parseDecimalNumber();
  84. uint64_t parseHexNumber(StringView &HexDigits);
  85. void print(char C) {
  86. if (Error || !Print)
  87. return;
  88. Output += C;
  89. }
  90. void print(StringView S) {
  91. if (Error || !Print)
  92. return;
  93. Output += S;
  94. }
  95. void printDecimalNumber(uint64_t N) {
  96. if (Error || !Print)
  97. return;
  98. Output << N;
  99. }
  100. void printBasicType(BasicType);
  101. char look() const {
  102. if (Error || Position >= Input.size())
  103. return 0;
  104. return Input[Position];
  105. }
  106. char consume() {
  107. if (Error || Position >= Input.size()) {
  108. Error = true;
  109. return 0;
  110. }
  111. return Input[Position++];
  112. }
  113. bool consumeIf(char Prefix) {
  114. if (Error || Position >= Input.size() || Input[Position] != Prefix)
  115. return false;
  116. Position += 1;
  117. return true;
  118. }
  119. /// Computes A + B. When computation wraps around sets the error and returns
  120. /// false. Otherwise assigns the result to A and returns true.
  121. bool addAssign(uint64_t &A, const uint64_t B) {
  122. if (A > std::numeric_limits<uint64_t>::max() - B) {
  123. Error = true;
  124. return false;
  125. }
  126. A += B;
  127. return true;
  128. }
  129. /// Computes A * B. When computation wraps around sets the error and returns
  130. /// false. Otherwise assigns the result to A and returns true.
  131. bool mulAssign(uint64_t &A, const uint64_t B) {
  132. if (B != 0 && A > std::numeric_limits<uint64_t>::max() / B) {
  133. Error = true;
  134. return false;
  135. }
  136. A *= B;
  137. return true;
  138. }
  139. };
  140. } // namespace rust_demangle
  141. } // namespace llvm
  142. #endif