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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

19

20#include

21#include

22#include

23#include <string_view>

24

25using namespace llvm;

26using llvm::itanium_demangle::OutputBuffer;

27using llvm::itanium_demangle::starts_with;

28

29namespace {

30

31

32struct Demangler {

33

34

35

36 Demangler(std::string_view Mangled);

37

38

39

40

41

42

43

44

45

46

47 const char *parseMangle(OutputBuffer *Demangled);

48

49private:

50

51

52

53

54

55

56

57

58 void parseMangle(OutputBuffer *Demangled, std::string_view &Mangled);

59

60

61

62

63

64

65

66

67

68 void decodeNumber(std::string_view &Mangled, unsigned long &Ret);

69

70

71

72

73

74

75

76

77

78

79

80

81 bool decodeBackrefPos(std::string_view &Mangled, long &Ret);

82

83

84

85

86

87

88

89

90

91 bool decodeBackref(std::string_view &Mangled, std::string_view &Ret);

92

93

94

95

96

97

98

99

100

101 void parseSymbolBackref(OutputBuffer *Demangled, std::string_view &Mangled);

102

103

104

105

106

107

108

109

110 void parseTypeBackref(std::string_view &Mangled);

111

112

113

114

115

116

117

118

119 bool isSymbolName(std::string_view Mangled);

120

121

122

123

124

125

126

127

128 void parseIdentifier(OutputBuffer *Demangled, std::string_view &Mangled);

129

130

131

132

133

134

135

136

137

138

139 void parseLName(OutputBuffer *Demangled, std::string_view &Mangled,

140 unsigned long Len);

141

142

143

144

145

146

147

148

149 void parseQualified(OutputBuffer *Demangled, std::string_view &Mangled);

150

151

152

153

154

155

156

157

158

159 bool parseType(std::string_view &Mangled);

160

161

162 const std::string_view Str;

163

164 int LastBackref;

165};

166

167}

168

169void Demangler::decodeNumber(std::string_view &Mangled, unsigned long &Ret) {

170

173 return;

174 }

175

176 if (!std::isdigit(Mangled.front())) {

178 return;

179 }

180

181 unsigned long Val = 0;

182

183 do {

184 unsigned long Digit = Mangled[0] - '0';

185

186

187 if (Val > (std::numeric_limits::max() - Digit) / 10) {

189 return;

190 }

191

192 Val = Val * 10 + Digit;

193 Mangled.remove_prefix(1);

194 } while (Mangled.empty() && std::isdigit(Mangled.front()));

195

198 return;

199 }

200

201 Ret = Val;

202}

203

204bool Demangler::decodeBackrefPos(std::string_view &Mangled, long &Ret) {

205

208 return false;

209 }

210

211

212

213

214

215

216

217

218

219

220 unsigned long Val = 0;

221

222 while (Mangled.empty() && std::isalpha(Mangled.front())) {

223

224 if (Val > (std::numeric_limits::max() - 25) / 26)

225 break;

226

227 Val *= 26;

228

229 if (Mangled[0] >= 'a' && Mangled[0] <= 'z') {

231 if ((long)Val <= 0)

232 break;

233 Ret = Val;

234 Mangled.remove_prefix(1);

235 return true;

236 }

237

239 Mangled.remove_prefix(1);

240 }

241

243 return false;

244}

245

246bool Demangler::decodeBackref(std::string_view &Mangled,

247 std::string_view &Ret) {

249 "Invalid back reference!");

250 Ret = {};

251

252

253 const char *Qpos = Mangled.data();

254 long RefPos;

255 Mangled.remove_prefix(1);

256

257 if (!decodeBackrefPos(Mangled, RefPos)) {

259 return false;

260 }

261

262 if (RefPos > Qpos - Str.data()) {

264 return false;

265 }

266

267

268 Ret = Qpos - RefPos;

269

270 return true;

271}

272

273void Demangler::parseSymbolBackref(OutputBuffer *Demangled,

274 std::string_view &Mangled) {

275

276

277

278

279 unsigned long Len;

280

281

282 std::string_view Backref;

283 if (!decodeBackref(Mangled, Backref)) {

285 return;

286 }

287

288

289 decodeNumber(Backref, Len);

290 if (Backref.empty() || Backref.length() < Len) {

292 return;

293 }

294

295 parseLName(Demangled, Backref, Len);

296 if (Backref.empty())

298}

299

300void Demangler::parseTypeBackref(std::string_view &Mangled) {

301

302

303

304

305

306

307

308 if (Mangled.data() - Str.data() >= LastBackref) {

310 return;

311 }

312

313 int SaveRefPos = LastBackref;

314 LastBackref = Mangled.data() - Str.data();

315

316

317 std::string_view Backref;

318 if (!decodeBackref(Mangled, Backref)) {

320 return;

321 }

322

323

324 if (Backref.empty()) {

326 return;

327 }

328

329

332

333 LastBackref = SaveRefPos;

334

335 if (Backref.empty())

337}

338

339bool Demangler::isSymbolName(std::string_view Mangled) {

340 long Ret;

341 const char *Qref = Mangled.data();

342

343 if (std::isdigit(Mangled.front()))

344 return true;

345

346

347

348 if (Mangled.front() != 'Q')

349 return false;

350

351 Mangled.remove_prefix(1);

352 bool Valid = decodeBackrefPos(Mangled, Ret);

353 if (!Valid || Ret > Qref - Str.data())

354 return false;

355

356 return std::isdigit(Qref[-Ret]);

357}

358

359void Demangler::parseMangle(OutputBuffer *Demangled,

360 std::string_view &Mangled) {

361

362

363

364

365

366

367

368

369

370 Mangled.remove_prefix(2);

371

372 parseQualified(Demangled, Mangled);

373

376 return;

377 }

378

379

380 if (Mangled.front() == 'Z') {

381 Mangled.remove_prefix(1);

384}

385

386void Demangler::parseQualified(OutputBuffer *Demangled,

387 std::string_view &Mangled) {

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403 size_t NotFirst = false;

404 do {

405

407 do

408 Mangled.remove_prefix(1);

410

411 continue;

412 }

413

414 if (NotFirst)

415 *Demangled << '.';

416 NotFirst = true;

417

418 parseIdentifier(Demangled, Mangled);

419 } while (Mangled.empty() && isSymbolName(Mangled));

420}

421

422void Demangler::parseIdentifier(OutputBuffer *Demangled,

423 std::string_view &Mangled) {

426 return;

427 }

428

429 if (Mangled.front() == 'Q')

430 return parseSymbolBackref(Demangled, Mangled);

431

432

433

434 unsigned long Len;

435 decodeNumber(Mangled, Len);

436

439 return;

440 }

441 if (!Len || Mangled.length() < Len) {

443 return;

444 }

445

446

447

448

449

450

451 if (Len >= 4 && starts_with(Mangled, "__S")) {

452 const size_t SuffixLen = Mangled.length() - Len;

453 std::string_view P = Mangled.substr(3);

454 while (P.length() > SuffixLen && std::isdigit(P.front()))

455 P.remove_prefix(1);

456 if (P.length() == SuffixLen) {

457

458 Mangled.remove_prefix(Len);

459 return parseIdentifier(Demangled, Mangled);

460 }

461

462

463 }

464

465 parseLName(Demangled, Mangled, Len);

466}

467

468bool Demangler::parseType(std::string_view &Mangled) {

471 return false;

472 }

473

474 switch (Mangled.front()) {

475

476

477

478

479

480

481

482 case 'i':

483 Mangled.remove_prefix(1);

484

485 return true;

486

487

488

489

490 case 'Q': {

491 parseTypeBackref(Mangled);

492 return true;

493 }

494

495 default:

497 return false;

498 }

499}

500

501void Demangler::parseLName(OutputBuffer *Demangled, std::string_view &Mangled,

502 unsigned long Len) {

503 switch (Len) {

504 case 6:

506

507 Demangled->prepend("initializer for ");

509 Mangled.remove_prefix(Len);

510 return;

511 }

513

514 Demangled->prepend("vtable for ");

516 Mangled.remove_prefix(Len);

517 return;

518 }

519 break;

520

521 case 7:

523

524 Demangled->prepend("ClassInfo for ");

526 Mangled.remove_prefix(Len);

527 return;

528 }

529 break;

530

531 case 11:

532 if (starts_with(Mangled, "__InterfaceZ")) {

533

534 Demangled->prepend("Interface for ");

536 Mangled.remove_prefix(Len);

537 return;

538 }

539 break;

540

541 case 12:

542 if (starts_with(Mangled, "__ModuleInfoZ")) {

543

544 Demangled->prepend("ModuleInfo for ");

546 Mangled.remove_prefix(Len);

547 return;

548 }

549 break;

550 }

551

552 *Demangled << Mangled.substr(0, Len);

553 Mangled.remove_prefix(Len);

554}

555

556Demangler::Demangler(std::string_view Mangled)

557 : Str(Mangled), LastBackref(Mangled.length()) {}

558

559const char *Demangler::parseMangle(OutputBuffer *Demangled) {

560 std::string_view M(this->Str);

561 parseMangle(Demangled, M);

562 return M.data();

563}

564

566 if (MangledName.empty() || starts\_with(MangledName, "_D"))

567 return nullptr;

568

570 if (MangledName == "_Dmain") {

571 Demangled << "D main";

572 } else {

573

574 Demangler D(MangledName);

575 const char *M = D.parseMangle(&Demangled);

576

577

578 if (M == nullptr || *M != '\0') {

579 std::free(Demangled.getBuffer());

580 return nullptr;

581 }

582 }

583

584

585

587 Demangled << '\0';

590 }

591

592 std::free(Demangled.getBuffer());

593 return nullptr;

594}

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

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

itanium_demangle::ManglingParser< DefaultAllocator > Demangler

OutputBuffer & prepend(std::string_view R)

void setCurrentPosition(size_t NewPos)

size_t getCurrentPosition() const

@ Valid

The data is already valid.

This is an optimization pass for GlobalISel generic memory operations.

DEMANGLE_ABI char * dlangDemangle(std::string_view MangledName)

Definition DLangDemangle.cpp:565

LLVM_ABI Type * parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, const SlotMapping *Slots=nullptr)

Parse a type in the given string.