LLVM: lib/Demangle/RustDemangle.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

17

18#include

19#include

20#include

21#include

22#include

23#include <string_view>

24

25using namespace llvm;

26

27using llvm::itanium_demangle::OutputBuffer;

28using llvm::itanium_demangle::ScopedOverride;

29using llvm::itanium_demangle::starts_with;

30

31namespace {

32

33struct Identifier {

34 std::string_view Name;

35 bool Punycode;

36

37 bool empty() const { return Name.empty(); }

38};

39

40enum class BasicType {

41 Bool,

42 Char,

43 I8,

44 I16,

45 I32,

46 I64,

47 I128,

48 ISize,

49 U8,

50 U16,

51 U32,

52 U64,

53 U128,

54 USize,

57 Str,

58 Placeholder,

59 Unit,

60 Variadic,

62};

63

64enum class IsInType {

67};

68

69enum class LeaveGenericsOpen {

72};

73

74class Demangler {

75

76 size_t MaxRecursionLevel;

77

78 size_t RecursionLevel;

79 size_t BoundLifetimes;

80

81 std::string_view Input;

82

83 size_t Position;

84

85

87

89

90public:

91

92 OutputBuffer Output;

93

94 Demangler(size_t MaxRecursionLevel = 500);

95

96 bool demangle(std::string_view MangledName);

97

98private:

99 bool demanglePath(IsInType Type,

100 LeaveGenericsOpen LeaveOpen = LeaveGenericsOpen::No);

101 void demangleImplPath(IsInType InType);

102 void demangleGenericArg();

103 void demangleType();

104 void demangleFnSig();

105 void demangleDynBounds();

106 void demangleDynTrait();

107 void demangleOptionalBinder();

108 void demangleConst();

109 void demangleConstInt();

110 void demangleConstBool();

111 void demangleConstChar();

112

113 template void demangleBackref(Callable Demangler) {

114 uint64_t Backref = parseBase62Number();

115 if (Error || Backref >= Position) {

117 return;

118 }

119

120 if (!Print)

121 return;

122

123 ScopedOverride<size_t> SavePosition(Position, Position);

124 Position = Backref;

126 }

127

129 uint64_t parseOptionalBase62Number(char Tag);

130 uint64_t parseBase62Number();

131 uint64_t parseDecimalNumber();

132 uint64_t parseHexNumber(std::string_view &HexDigits);

133

135 void print(std::string_view S);

136 void printDecimalNumber(uint64_t N);

137 void printBasicType(BasicType);

138 void printLifetime(uint64_t Index);

139 void printIdentifier(Identifier Ident);

140

141 char look() const;

143 bool consumeIf(char Prefix);

144

145 bool addAssign(uint64_t &A, uint64_t B);

146 bool mulAssign(uint64_t &A, uint64_t B);

147};

148

149}

150

152

153 if (MangledName.empty() || starts\_with(MangledName, "_R"))

154 return nullptr;

155

156 Demangler D;

157 if (D.demangle(MangledName)) {

158 std::free(D.Output.getBuffer());

159 return nullptr;

160 }

161

162 D.Output += '\0';

163

164 return D.Output.getBuffer();

165}

166

167Demangler::Demangler(size_t MaxRecursionLevel)

168 : MaxRecursionLevel(MaxRecursionLevel) {}

169

170static inline bool isDigit(const char C) { return '0' <= C && C <= '9'; }

171

173 return ('0' <= C && C <= '9') || ('a' <= C && C <= 'f');

174}

175

176static inline bool isLower(const char C) { return 'a' <= C && C <= 'z'; }

177

178static inline bool isUpper(const char C) { return 'A' <= C && C <= 'Z'; }

179

180

184

185

186

187

188

189

190bool Demangler::demangle(std::string_view Mangled) {

191 Position = 0;

194 RecursionLevel = 0;

195 BoundLifetimes = 0;

196

199 return false;

200 }

201 Mangled.remove_prefix(2);

202 size_t Dot = Mangled.find('.');

203 Input = Dot == std::string_view::npos ? Mangled : Mangled.substr(0, Dot);

204

205 demanglePath(IsInType::No);

206

207 if (Position != Input.size()) {

208 ScopedOverride SavePrint(Print, false);

209 demanglePath(IsInType::No);

210 }

211

212 if (Position != Input.size())

214

215 if (Dot != std::string_view::npos) {

219 }

220

222}

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241bool Demangler::demanglePath(IsInType InType, LeaveGenericsOpen LeaveOpen) {

242 if (Error || RecursionLevel >= MaxRecursionLevel) {

244 return false;

245 }

246 ScopedOverride<size_t> SaveRecursionLevel(RecursionLevel, RecursionLevel + 1);

247

249 case 'C': {

250 parseOptionalBase62Number('s');

251 printIdentifier(parseIdentifier());

252 break;

253 }

254 case 'M': {

255 demangleImplPath(InType);

257 demangleType();

259 break;

260 }

261 case 'X': {

262 demangleImplPath(InType);

264 demangleType();

266 demanglePath(IsInType::Yes);

268 break;

269 }

270 case 'Y': {

272 demangleType();

274 demanglePath(IsInType::Yes);

276 break;

277 }

278 case 'N': {

282 break;

283 }

284 demanglePath(InType);

285

286 uint64_t Disambiguator = parseOptionalBase62Number('s');

287 Identifier Ident = parseIdentifier();

288

290

292 if (NS == 'C')

293 print("closure");

294 else if (NS == 'S')

296 else

298 if (!Ident.empty()) {

300 printIdentifier(Ident);

301 }

303 printDecimalNumber(Disambiguator);

305 } else {

306

307 if (!Ident.empty()) {

309 printIdentifier(Ident);

310 }

311 }

312 break;

313 }

314 case 'I': {

315 demanglePath(InType);

316

317 if (InType == IsInType::No)

320 for (size_t I = 0; Error && !consumeIf('E'); ++I) {

321 if (I > 0)

323 demangleGenericArg();

324 }

325 if (LeaveOpen == LeaveGenericsOpen::Yes)

326 return true;

327 else

329 break;

330 }

331 case 'B': {

332 bool IsOpen = false;

333 demangleBackref([&] { IsOpen = demanglePath(InType, LeaveOpen); });

334 return IsOpen;

335 }

336 default:

338 break;

339 }

340

341 return false;

342}

343

344

345

346void Demangler::demangleImplPath(IsInType InType) {

347 ScopedOverride SavePrint(Print, false);

348 parseOptionalBase62Number('s');

349 demanglePath(InType);

350}

351

352

353

354

355

356void Demangler::demangleGenericArg() {

357 if (consumeIf('L'))

358 printLifetime(parseBase62Number());

359 else if (consumeIf('K'))

360 demangleConst();

361 else

362 demangleType();

363}

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

387 switch (C) {

388 case 'a':

389 Type = BasicType::I8;

390 return true;

391 case 'b':

392 Type = BasicType::Bool;

393 return true;

394 case 'c':

395 Type = BasicType::Char;

396 return true;

397 case 'd':

398 Type = BasicType::F64;

399 return true;

400 case 'e':

401 Type = BasicType::Str;

402 return true;

403 case 'f':

404 Type = BasicType::F32;

405 return true;

406 case 'h':

407 Type = BasicType::U8;

408 return true;

409 case 'i':

410 Type = BasicType::ISize;

411 return true;

412 case 'j':

413 Type = BasicType::USize;

414 return true;

415 case 'l':

416 Type = BasicType::I32;

417 return true;

418 case 'm':

419 Type = BasicType::U32;

420 return true;

421 case 'n':

422 Type = BasicType::I128;

423 return true;

424 case 'o':

425 Type = BasicType::U128;

426 return true;

427 case 'p':

428 Type = BasicType::Placeholder;

429 return true;

430 case 's':

431 Type = BasicType::I16;

432 return true;

433 case 't':

434 Type = BasicType::U16;

435 return true;

436 case 'u':

437 Type = BasicType::Unit;

438 return true;

439 case 'v':

440 Type = BasicType::Variadic;

441 return true;

442 case 'x':

443 Type = BasicType::I64;

444 return true;

445 case 'y':

446 Type = BasicType::U64;

447 return true;

448 case 'z':

449 Type = BasicType::Never;

450 return true;

451 default:

452 return false;

453 }

454}

455

456void Demangler::printBasicType(BasicType Type) {

457 switch (Type) {

458 case BasicType::Bool:

460 break;

461 case BasicType::Char:

463 break;

464 case BasicType::I8:

466 break;

467 case BasicType::I16:

469 break;

470 case BasicType::I32:

472 break;

473 case BasicType::I64:

475 break;

476 case BasicType::I128:

478 break;

479 case BasicType::ISize:

481 break;

482 case BasicType::U8:

484 break;

485 case BasicType::U16:

487 break;

488 case BasicType::U32:

490 break;

491 case BasicType::U64:

493 break;

494 case BasicType::U128:

496 break;

497 case BasicType::USize:

499 break;

500 case BasicType::F32:

502 break;

503 case BasicType::F64:

505 break;

506 case BasicType::Str:

508 break;

509 case BasicType::Placeholder:

511 break;

512 case BasicType::Unit:

514 break;

515 case BasicType::Variadic:

517 break;

518 case BasicType::Never:

520 break;

521 }

522}

523

524

525

526

527

528

529

530

531

532

533

534

535

536void Demangler::demangleType() {

537 if (Error || RecursionLevel >= MaxRecursionLevel) {

539 return;

540 }

541 ScopedOverride<size_t> SaveRecursionLevel(RecursionLevel, RecursionLevel + 1);

542

543 size_t Start = Position;

545 BasicType Type;

547 return printBasicType(Type);

548

549 switch (C) {

550 case 'A':

552 demangleType();

554 demangleConst();

556 break;

557 case 'S':

559 demangleType();

561 break;

562 case 'T': {

564 size_t I = 0;

565 for (; Error && !consumeIf('E'); ++I) {

566 if (I > 0)

568 demangleType();

569 }

570 if (I == 1)

573 break;

574 }

575 case 'R':

576 case 'Q':

578 if (consumeIf('L')) {

579 if (auto Lifetime = parseBase62Number()) {

580 printLifetime(Lifetime);

582 }

583 }

584 if (C == 'Q')

586 demangleType();

587 break;

588 case 'P':

589 print("*const ");

590 demangleType();

591 break;

592 case 'O':

594 demangleType();

595 break;

596 case 'F':

597 demangleFnSig();

598 break;

599 case 'D':

600 demangleDynBounds();

601 if (consumeIf('L')) {

602 if (auto Lifetime = parseBase62Number()) {

604 printLifetime(Lifetime);

605 }

606 } else {

608 }

609 break;

610 case 'B':

611 demangleBackref([&] { demangleType(); });

612 break;

613 default:

614 Position = Start;

615 demanglePath(IsInType::Yes);

616 break;

617 }

618}

619

620

621

622

623void Demangler::demangleFnSig() {

624 ScopedOverride<size_t> SaveBoundLifetimes(BoundLifetimes, BoundLifetimes);

625 demangleOptionalBinder();

626

627 if (consumeIf('U'))

628 print("unsafe ");

629

630 if (consumeIf('K')) {

631 print("extern \"");

632 if (consumeIf('C')) {

634 } else {

635 Identifier Ident = parseIdentifier();

636 if (Ident.Punycode)

638 for (char C : Ident.Name) {

639

640 if (C == '_')

641 C = '-';

643 }

644 }

646 }

647

649 for (size_t I = 0; Error && !consumeIf('E'); ++I) {

650 if (I > 0)

652 demangleType();

653 }

655

656 if (consumeIf('u')) {

657

658 } else {

660 demangleType();

661 }

662}

663

664

665void Demangler::demangleDynBounds() {

666 ScopedOverride<size_t> SaveBoundLifetimes(BoundLifetimes, BoundLifetimes);

668 demangleOptionalBinder();

669 for (size_t I = 0; Error && !consumeIf('E'); ++I) {

670 if (I > 0)

672 demangleDynTrait();

673 }

674}

675

676

677

678void Demangler::demangleDynTrait() {

679 bool IsOpen = demanglePath(IsInType::Yes, LeaveGenericsOpen::Yes);

680 while (Error && consumeIf('p')) {

681 if (!IsOpen) {

682 IsOpen = true;

684 } else {

686 }

687 print(parseIdentifier().Name);

689 demangleType();

690 }

691 if (IsOpen)

693}

694

695

696

697

698void Demangler::demangleOptionalBinder() {

699 uint64_t Binder = parseOptionalBase62Number('G');

700 if (Error || Binder == 0)

701 return;

702

703

704

705

706

707 if (Binder >= Input.size() - BoundLifetimes) {

709 return;

710 }

711

713 for (size_t I = 0; I != Binder; ++I) {

714 BoundLifetimes += 1;

715 if (I > 0)

717 printLifetime(1);

718 }

720}

721

722

723

724

725void Demangler::demangleConst() {

726 if (Error || RecursionLevel >= MaxRecursionLevel) {

728 return;

729 }

730 ScopedOverride<size_t> SaveRecursionLevel(RecursionLevel, RecursionLevel + 1);

731

733 BasicType Type;

735 switch (Type) {

736 case BasicType::I8:

737 case BasicType::I16:

738 case BasicType::I32:

739 case BasicType::I64:

740 case BasicType::I128:

741 case BasicType::ISize:

742 case BasicType::U8:

743 case BasicType::U16:

744 case BasicType::U32:

745 case BasicType::U64:

746 case BasicType::U128:

747 case BasicType::USize:

748 demangleConstInt();

749 break;

750 case BasicType::Bool:

751 demangleConstBool();

752 break;

753 case BasicType::Char:

754 demangleConstChar();

755 break;

756 case BasicType::Placeholder:

758 break;

759 default:

761 break;

762 }

763 } else if (C == 'B') {

764 demangleBackref([&] { demangleConst(); });

765 } else {

767 }

768}

769

770

771void Demangler::demangleConstInt() {

772 if (consumeIf('n'))

774

775 std::string_view HexDigits;

776 uint64_t Value = parseHexNumber(HexDigits);

777 if (HexDigits.size() <= 16) {

778 printDecimalNumber(Value);

779 } else {

781 print(HexDigits);

782 }

783}

784

785

786

787void Demangler::demangleConstBool() {

788 std::string_view HexDigits;

789 parseHexNumber(HexDigits);

790 if (HexDigits == "0")

792 else if (HexDigits == "1")

794 else

796}

797

798

800 return 0x20 <= CodePoint && CodePoint <= 0x7e;

801}

802

803

804void Demangler::demangleConstChar() {

805 std::string_view HexDigits;

806 uint64_t CodePoint = parseHexNumber(HexDigits);

807 if (Error || HexDigits.size() > 6) {

809 return;

810 }

811

813 switch (CodePoint) {

814 case '\t':

816 break;

817 case '\r':

819 break;

820 case '\n':

822 break;

823 case '\\':

825 break;

826 case '"':

828 break;

829 case '\'':

831 break;

832 default:

834 char C = CodePoint;

836 } else {

838 print(HexDigits);

840 }

841 break;

842 }

844}

845

846

847Identifier Demangler::parseIdentifier() {

848 bool Punycode = consumeIf('u');

849 uint64_t Bytes = parseDecimalNumber();

850

851

852

853 consumeIf('_');

854

855 if (Error || Bytes > Input.size() - Position) {

857 return {};

858 }

859 std::string_view S = Input.substr(Position, Bytes);

860 Position += Bytes;

861

862 if (!std::all_of(S.begin(), S.end(), isValid)) {

864 return {};

865 }

866

867 return {S, Punycode};

868}

869

870

871

872

873

874

875

876

877uint64_t Demangler::parseOptionalBase62Number(char Tag) {

878 if (!consumeIf(Tag))

879 return 0;

880

881 uint64_t N = parseBase62Number();

882 if (Error || !addAssign(N, 1))

883 return 0;

884

885 return N;

886}

887

888

889

890

891

892

893uint64_t Demangler::parseBase62Number() {

894 if (consumeIf('_'))

895 return 0;

896

897 uint64_t Value = 0;

898

899 while (true) {

900 uint64_t Digit;

902

903 if (C == '_') {

904 break;

906 Digit = C - '0';

908 Digit = 10 + (C - 'a');

910 Digit = 10 + 26 + (C - 'A');

911 } else {

913 return 0;

914 }

915

916 if (!mulAssign(Value, 62))

917 return 0;

918

919 if (!addAssign(Value, Digit))

920 return 0;

921 }

922

923 if (!addAssign(Value, 1))

924 return 0;

925

927}

928

929

930

931

932

933uint64_t Demangler::parseDecimalNumber() {

934 char C = look();

937 return 0;

938 }

939

940 if (C == '0') {

942 return 0;

943 }

944

945 uint64_t Value = 0;

946

947 while (isDigit(look())) {

948 if (!mulAssign(Value, 10)) {

950 return 0;

951 }

952

953 uint64_t D = consume() - '0';

954 if (!addAssign(Value, D))

955 return 0;

956 }

957

959}

960

961

962

963

964

965

966

967uint64_t Demangler::parseHexNumber(std::string_view &HexDigits) {

968 size_t Start = Position;

969 uint64_t Value = 0;

970

973

974 if (consumeIf('0')) {

975 if (!consumeIf('_'))

977 } else {

978 while (Error && !consumeIf('_')) {

983 else if ('a' <= C && C <= 'f')

984 Value += 10 + (C - 'a');

985 else

987 }

988 }

989

991 HexDigits = std::string_view();

992 return 0;

993 }

994

995 size_t End = Position - 1;

997 HexDigits = Input.substr(Start, End - Start);

999}

1000

1001void Demangler::print(char C) {

1002 if (Error || !Print)

1003 return;

1004

1005 Output += C;

1006}

1007

1008void Demangler::print(std::string_view S) {

1009 if (Error || !Print)

1010 return;

1011

1012 Output += S;

1013}

1014

1015void Demangler::printDecimalNumber(uint64_t N) {

1016 if (Error || !Print)

1017 return;

1018

1019 Output << N;

1020}

1021

1022

1023

1024

1025void Demangler::printLifetime(uint64_t Index) {

1026 if (Index == 0) {

1028 return;

1029 }

1030

1031 if (Index - 1 >= BoundLifetimes) {

1033 return;

1034 }

1035

1036 uint64_t Depth = BoundLifetimes - Index;

1038 if (Depth < 26) {

1039 char C = 'a' + Depth;

1041 } else {

1043 printDecimalNumber(Depth - 26 + 1);

1044 }

1045}

1046

1050 return true;

1051 }

1052

1054 Value = 26 + (C - '0');

1055 return true;

1056 }

1057

1058 return false;

1059}

1060

1062 char *Buffer = Output.getBuffer();

1063 char *Start = Buffer + StartIdx;

1066}

1067

1068

1069

1070static inline bool encodeUTF8(size_t CodePoint, char *Output) {

1071 if (0xD800 <= CodePoint && CodePoint <= 0xDFFF)

1072 return false;

1073

1074 if (CodePoint <= 0x7F) {

1075 Output[0] = CodePoint;

1076 return true;

1077 }

1078

1079 if (CodePoint <= 0x7FF) {

1080 Output[0] = 0xC0 | ((CodePoint >> 6) & 0x3F);

1081 Output[1] = 0x80 | (CodePoint & 0x3F);

1082 return true;

1083 }

1084

1085 if (CodePoint <= 0xFFFF) {

1086 Output[0] = 0xE0 | (CodePoint >> 12);

1087 Output[1] = 0x80 | ((CodePoint >> 6) & 0x3F);

1088 Output[2] = 0x80 | (CodePoint & 0x3F);

1089 return true;

1090 }

1091

1092 if (CodePoint <= 0x10FFFF) {

1093 Output[0] = 0xF0 | (CodePoint >> 18);

1094 Output[1] = 0x80 | ((CodePoint >> 12) & 0x3F);

1095 Output[2] = 0x80 | ((CodePoint >> 6) & 0x3F);

1096 Output[3] = 0x80 | (CodePoint & 0x3F);

1097 return true;

1098 }

1099

1100 return false;

1101}

1102

1103

1104

1107 size_t InputIdx = 0;

1108

1109

1110 size_t DelimiterPos = std::string_view::npos;

1111 for (size_t I = 0; I != Input.size(); ++I)

1112 if (Input[I] == '_')

1113 DelimiterPos = I;

1114

1115 if (DelimiterPos != std::string_view::npos) {

1116

1117 for (; InputIdx != DelimiterPos; ++InputIdx) {

1118 char C = Input[InputIdx];

1120 return false;

1121

1122 char UTF8[4] = {C};

1123 Output += std::string_view(UTF8, 4);

1124 }

1125

1126 ++InputIdx;

1127 }

1128

1129 size_t Base = 36;

1130 size_t Skew = 38;

1131 size_t Bias = 72;

1132 size_t N = 0x80;

1133 size_t TMin = 1;

1134 size_t TMax = 26;

1135 size_t Damp = 700;

1136

1137 auto Adapt = [&](size_t Delta, size_t NumPoints) {

1138 Delta /= Damp;

1139 Delta += Delta / NumPoints;

1140 Damp = 2;

1141

1142 size_t K = 0;

1143 while (Delta > (Base - TMin) * TMax / 2) {

1144 Delta /= Base - TMin;

1146 }

1147 return K + (((Base - TMin + 1) * Delta) / (Delta + Skew));

1148 };

1149

1150

1151 for (size_t I = 0; InputIdx != Input.size(); I += 1) {

1152 size_t OldI = I;

1153 size_t W = 1;

1154 size_t Max = std::numeric_limits<size_t>::max();

1155 for (size_t K = Base; true; K += Base) {

1156 if (InputIdx == Input.size())

1157 return false;

1158 char C = Input[InputIdx++];

1159 size_t Digit = 0;

1161 return false;

1162

1163 if (Digit > (Max - I) / W)

1164 return false;

1165 I += Digit * W;

1166

1167 size_t T;

1168 if (K <= Bias)

1169 T = TMin;

1170 else if (K >= Bias + TMax)

1171 T = TMax;

1172 else

1173 T = K - Bias;

1174

1175 if (Digit < T)

1176 break;

1177

1178 if (W > Max / (Base - T))

1179 return false;

1180 W *= (Base - T);

1181 }

1182 size_t NumPoints = (Output.getCurrentPosition() - OutputSize) / 4 + 1;

1183 Bias = Adapt(I - OldI, NumPoints);

1184

1185 if (I / NumPoints > Max - N)

1186 return false;

1187 N += I / NumPoints;

1188 I = I % NumPoints;

1189

1190

1191 char UTF8[4] = {};

1193 return false;

1194 Output.insert(OutputSize + I * 4, UTF8, 4);

1195 }

1196

1198 return true;

1199}

1200

1201void Demangler::printIdentifier(Identifier Ident) {

1202 if (Error || !Print)

1203 return;

1204

1205 if (Ident.Punycode) {

1208 } else {

1209 print(Ident.Name);

1210 }

1211}

1212

1213char Demangler::look() const {

1214 if (Error || Position >= Input.size())

1215 return 0;

1216

1217 return Input[Position];

1218}

1219

1220char Demangler::consume() {

1221 if (Error || Position >= Input.size()) {

1223 return 0;

1224 }

1225

1226 return Input[Position++];

1227}

1228

1229bool Demangler::consumeIf(char Prefix) {

1230 if (Error || Position >= Input.size() || Input[Position] != Prefix)

1231 return false;

1232

1233 Position += 1;

1234 return true;

1235}

1236

1237

1238

1239bool Demangler::addAssign(uint64_t &A, uint64_t B) {

1240 if (A > std::numeric_limits<uint64_t>::max() - B) {

1242 return false;

1243 }

1244

1245 A += B;

1246 return true;

1247}

1248

1249

1250

1251bool Demangler::mulAssign(uint64_t &A, uint64_t B) {

1252 if (B != 0 && A > std::numeric_limits<uint64_t>::max() / B) {

1254 return false;

1255 }

1256

1257 A *= B;

1258 return true;

1259}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

itanium_demangle::ManglingParser< DefaultAllocator > Demangler

static bool isValid(const char C)

Returns true if C is a valid mangled character: <0-9a-zA-Z_>.

Definition RustDemangle.cpp:181

static bool decodePunycodeDigit(char C, size_t &Value)

Definition RustDemangle.cpp:1047

static bool isAsciiPrintable(uint64_t CodePoint)

Returns true if CodePoint represents a printable ASCII character.

Definition RustDemangle.cpp:799

static void removeNullBytes(OutputBuffer &Output, size_t StartIdx)

Definition RustDemangle.cpp:1061

static bool encodeUTF8(size_t CodePoint, char *Output)

Definition RustDemangle.cpp:1070

static bool decodePunycode(std::string_view Input, OutputBuffer &Output)

Definition RustDemangle.cpp:1105

static bool parseBasicType(char C, BasicType &Type)

Definition RustDemangle.cpp:386

The Input class is used to parse a yaml document into in-memory structs and vectors.

void setCurrentPosition(size_t NewPos)

size_t getCurrentPosition() const

void insert(size_t Pos, const char *S, size_t N)

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

@ C

The default llvm calling convention, compatible with C.

Print(const T &, const DataFlowGraph &) -> Print< T >

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)

bool isLower(char C)

Checks if character C is a lowercase letter as classified by "C" locale.

bool isUpper(char C)

Checks if character C is a uppercase letter as classified by "C" locale.

@ Never

Never set the bit.

bool isDigit(char C)

Checks if character C is one of the 10 decimal digits.

DEMANGLE_ABI char * rustDemangle(std::string_view MangledName)

Definition RustDemangle.cpp:151

bool isHexDigit(char C)

Checks if character C is a hexadecimal numeric character.

DEMANGLE_ABI std::string demangle(std::string_view MangledName)

Attempt to demangle a string using different demangling schemes.