LLVM: lib/CodeGen/MIRParser/MILexer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

17#include

18#include

19#include

20

21using namespace llvm;

22

23namespace {

24

27

28

29

30class Cursor {

31 const char *Ptr = nullptr;

32 const char *End = nullptr;

33

34public:

35 Cursor(std::nullopt_t) {}

36

37 explicit Cursor(StringRef Str) {

38 Ptr = Str.data();

39 End = Ptr + Str.size();

40 }

41

42 bool isEOF() const { return Ptr == End; }

43

44 char peek(int I = 0) const { return End - Ptr <= I ? 0 : Ptr[I]; }

45

46 void advance(unsigned I = 1) { Ptr += I; }

47

48 StringRef remaining() const { return StringRef(Ptr, End - Ptr); }

49

50 StringRef upto(Cursor C) const {

51 assert(C.Ptr >= Ptr && C.Ptr <= End);

52 return StringRef(Ptr, C.Ptr - Ptr);

53 }

54

56

57 operator bool() const { return Ptr != nullptr; }

58};

59

60}

61

63 this->Kind = Kind;

64 this->Range = Range;

65 return *this;

66}

67

69 StringValue = StrVal;

70 return *this;

71}

72

74 StringValueStorage = std::move(StrVal);

75 StringValue = StringValueStorage;

76 return *this;

77}

78

80 this->IntVal = std::move(IntVal);

81 return *this;

82}

83

84

86 while (isblank(C.peek()))

87 C.advance();

88 return C;

89}

90

92

93

95 if (C.peek() != ';')

96 return C;

98 C.advance();

99 return C;

100}

101

102

103

105 if (C.peek() != '/' || C.peek(1) != '*')

106 return C;

107

108 while (C.peek() != '*' || C.peek(1) != '/')

109 C.advance();

110

111 C.advance();

112 C.advance();

113 return C;

114}

115

116

117

119 return isalpha(C) || isdigit(C) || C == '_' || C == '-' || C == '.' ||

120 C == '$';

121}

122

123

124

125

128 Cursor C = Cursor(Value.substr(1, Value.size() - 2));

129

130 std::string Str;

131 Str.reserve(C.remaining().size());

132 while (C.isEOF()) {

133 char Char = C.peek();

134 if (Char == '\\') {

135 if (C.peek(1) == '\\') {

136

137 Str += '\\';

138 C.advance(2);

139 continue;

140 }

141 if (isxdigit(C.peek(1)) && isxdigit(C.peek(2))) {

143 C.advance(3);

144 continue;

145 }

146 }

147 Str += Char;

148 C.advance();

149 }

150 return Str;

151}

152

153

156 for (C.advance(); C.peek() != '"'; C.advance()) {

158 ErrorCallback(

159 C.location(),

160 "end of machine instruction reached before the closing '\"'");

161 return std::nullopt;

162 }

163 }

164 C.advance();

165 return C;

166}

167

171 C.advance(PrefixLength);

172 if (C.peek() == '"') {

178 return R;

179 }

182 }

184 C.advance();

187 return C;

188}

189

241 .Case("negate_ra_sign_state",

243 .Case("negate_ra_sign_state_with_pc",

272 .Case("inlineasm-br-indirect-target",

292 .Case("machine-block-address-taken",

297}

298

300 if (!isalpha(C.peek()) && C.peek() != '_')

301 return std::nullopt;

304 C.advance();

305 auto Identifier = Range.upto(C);

308 return C;

309}

310

313 bool IsReference = C.remaining().starts_with("%bb.");

314 if (!IsReference && C.remaining().starts_with("bb."))

315 return std::nullopt;

317 unsigned PrefixLength = IsReference ? 4 : 3;

318 C.advance(PrefixLength);

319 if (!isdigit(C.peek())) {

321 ErrorCallback(C.location(), "expected a number after '%bb.'");

322 return C;

323 }

324 auto NumberRange = C;

325 while (isdigit(C.peek()))

326 C.advance();

328 unsigned StringOffset = PrefixLength + Number.size();

329

330

331

332 if (C.peek() == '.') {

333 C.advance();

334 ++StringOffset;

336 C.advance();

337 }

343 return C;

344}

345

348 if (C.remaining().starts_with(Rule) || !isdigit(C.peek(Rule.size())))

349 return std::nullopt;

351 C.advance(Rule.size());

352 auto NumberRange = C;

353 while (isdigit(C.peek()))

354 C.advance();

356 return C;

357}

358

361 if (C.remaining().starts_with(Rule) || !isdigit(C.peek(Rule.size())))

362 return std::nullopt;

364 C.advance(Rule.size());

365 auto NumberRange = C;

366 while (isdigit(C.peek()))

367 C.advance();

369 unsigned StringOffset = Rule.size() + Number.size();

370 if (C.peek() == '.') {

371 C.advance();

372 ++StringOffset;

374 C.advance();

375 }

379 return C;

380}

381

385

389

393

397

400 const StringRef Rule = "%subreg.";

401 if (C.remaining().starts_with(Rule))

402 return std::nullopt;

404 ErrorCallback);

405}

406

409 const StringRef Rule = "%ir-block.";

410 if (C.remaining().starts_with(Rule))

411 return std::nullopt;

412 if (isdigit(C.peek(Rule.size())))

415}

416

420 if (C.remaining().starts_with(Rule))

421 return std::nullopt;

422 if (isdigit(C.peek(Rule.size())))

425}

426

429 if (C.peek() != '"')

430 return std::nullopt;

432 ErrorCallback);

433}

434

437 C.advance();

438 auto NumberRange = C;

439 while (isdigit(C.peek()))

440 C.advance();

443 return C;

444}

445

446

450

453 C.advance();

455 C.advance();

458 return C;

459}

460

463 if (C.peek() != '%' && C.peek() != '$')

464 return std::nullopt;

465

466 if (C.peek() == '%') {

467 if (isdigit(C.peek(1)))

469

472

473 return std::nullopt;

474 }

475

478 C.advance();

480 C.advance();

483 return C;

484}

485

488 if (C.peek() != '@')

489 return std::nullopt;

490 if (!isdigit(C.peek(1)))

492 ErrorCallback);

494 C.advance(1);

495 auto NumberRange = C;

496 while (isdigit(C.peek()))

497 C.advance();

500 return C;

501}

502

505 if (C.peek() != '&')

506 return std::nullopt;

508 ErrorCallback);

509}

510

513 const StringRef Rule = "<mcsymbol ";

514 if (C.remaining().starts_with(Rule))

515 return std::nullopt;

516 auto Start = C;

517 C.advance(Rule.size());

518

519

520 if (C.peek() != '"') {

522 C.advance();

524 if (C.peek() != '>') {

525 ErrorCallback(C.location(),

526 "expected the '<mcsymbol ...' to be closed by a '>'");

528 return Start;

529 }

530 C.advance();

531

533 return C;

534 }

535

536

538 if (!R) {

539 ErrorCallback(C.location(),

540 "unable to parse quoted string from opening quote");

542 return Start;

543 }

545 if (R.peek() != '>') {

546 ErrorCallback(R.location(),

547 "expected the '<mcsymbol ...' to be closed by a '>'");

549 return Start;

550 }

551 R.advance();

552

555 return R;

556}

557

559 return C == 'H' || C == 'K' || C == 'L' || C == 'M' || C == 'R';

560}

561

563 C.advance();

564

565 while (isdigit(C.peek()))

566 C.advance();

567 if ((C.peek() == 'e' || C.peek() == 'E') &&

568 (isdigit(C.peek(1)) ||

569 ((C.peek(1) == '-' || C.peek(1) == '+') && isdigit(C.peek(2))))) {

570 C.advance(2);

571 while (isdigit(C.peek()))

572 C.advance();

573 }

575 return C;

576}

577

579 if (C.peek() != '0' || (C.peek(1) != 'x' && C.peek(1) != 'X'))

580 return std::nullopt;

582 C.advance(2);

583 unsigned PrefLen = 2;

585 C.advance();

586 PrefLen++;

587 }

588 while (isxdigit(C.peek()))

589 C.advance();

591 if (StrVal.size() <= PrefLen)

592 return std::nullopt;

593 if (PrefLen == 2)

595 else

597 return C;

598}

599

601 if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1))))

602 return std::nullopt;

604 C.advance();

605 while (isdigit(C.peek()))

606 C.advance();

607 if (C.peek() == '.')

611 return C;

612}

613

625

628 if (C.peek() != '!')

629 return std::nullopt;

631 C.advance(1);

634 return C;

635 }

637 C.advance();

641 ErrorCallback(Token.location(),

642 "use of unknown metadata keyword '" + StrVal + "'");

643 return C;

644}

645

647 switch (C) {

648 case ',':

650 case '.':

652 case '=':

654 case ':':

656 case '(':

658 case ')':

660 case '{':

662 case '}':

664 case '+':

666 case '-':

668 case '<':

670 case '>':

672 default:

674 }

675}

676

680 if (C.peek() == ':' && C.peek(1) == ':') {

683 } else

686 return std::nullopt;

690 return C;

691}

692

695 return std::nullopt;

697 C.advance();

699 return C;

700}

701

704 if (C.peek() != '`')

705 return std::nullopt;

707 C.advance();

708 auto StrRange = C;

709 while (C.peek() != '`') {

711 ErrorCallback(

712 C.location(),

713 "end of machine instruction reached before the closing '`'");

715 return C;

716 }

717 C.advance();

718 }

720 C.advance();

722 return C;

723}

724

728 if (C.isEOF()) {

730 return C.remaining();

731 }

732

734

736 return R.remaining();

738 return R.remaining();

740 return R.remaining();

742 return R.remaining();

744 return R.remaining();

746 return R.remaining();

748 return R.remaining();

750 return R.remaining();

752 return R.remaining();

754 return R.remaining();

756 return R.remaining();

758 return R.remaining();

760 return R.remaining();

762 return R.remaining();

764 return R.remaining();

766 return R.remaining();

768 return R.remaining();

770 return R.remaining();

772 return R.remaining();

774 return R.remaining();

775

777 ErrorCallback(C.location(),

778 Twine("unexpected character '") + Twine(C.peek()) + "'");

779 return C.remaining();

780}

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

static Cursor maybeLexEscapedIRValue(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:702

static Cursor skipComment(Cursor C)

Skip a line comment and return the updated cursor.

Definition MILexer.cpp:94

static bool isRegisterChar(char C)

Returns true for a character allowed in a register name.

Definition MILexer.cpp:447

static Cursor lexStringConstant(Cursor C, ErrorCallbackType ErrorCallback)

Lex a string constant using the following regular expression: "[^"]*".

Definition MILexer.cpp:154

static bool isNewlineChar(char C)

Definition MILexer.cpp:91

static MIToken::TokenKind symbolToken(char C)

Definition MILexer.cpp:646

static bool isValidHexFloatingPointPrefix(char C)

Definition MILexer.cpp:558

static MIToken::TokenKind getIdentifierKind(StringRef Identifier)

Definition MILexer.cpp:190

static Cursor maybeLexIRBlock(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:407

static Cursor maybeLexSymbol(Cursor C, MIToken &Token)

Definition MILexer.cpp:677

static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token)

Definition MILexer.cpp:382

static Cursor maybeLexRegister(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:461

static Cursor maybeLexHexadecimalLiteral(Cursor C, MIToken &Token)

Definition MILexer.cpp:578

static Cursor lexVirtualRegister(Cursor C, MIToken &Token)

Definition MILexer.cpp:435

static Cursor maybeLexNumericalLiteral(Cursor C, MIToken &Token)

Definition MILexer.cpp:600

static Cursor maybeLexExclaim(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:626

static Cursor lexNamedVirtualRegister(Cursor C, MIToken &Token)

Definition MILexer.cpp:451

static std::string unescapeQuotedString(StringRef Value)

Unescapes the given string value.

Definition MILexer.cpp:126

static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule, MIToken::TokenKind Kind)

Definition MILexer.cpp:359

static Cursor maybeLexNewline(Cursor C, MIToken &Token)

Definition MILexer.cpp:693

static Cursor maybeLexMCSymbol(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:511

static Cursor skipMachineOperandComment(Cursor C)

Machine operands can have comments, enclosed between /* and ‍/.

Definition MILexer.cpp:104

static MIToken::TokenKind getMetadataKeywordKind(StringRef Identifier)

Definition MILexer.cpp:614

static Cursor maybeLexIdentifier(Cursor C, MIToken &Token)

Definition MILexer.cpp:299

static Cursor maybeLexStackObject(Cursor C, MIToken &Token)

Definition MILexer.cpp:386

static Cursor skipWhitespace(Cursor C)

Skip the leading whitespace characters and return the updated cursor.

Definition MILexer.cpp:85

static Cursor maybeLexExternalSymbol(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:503

static bool isIdentifierChar(char C)

Return true if the given character satisfies the following regular expression: [-a-zA-Z$....

Definition MILexer.cpp:118

static Cursor lexName(Cursor C, MIToken &Token, MIToken::TokenKind Type, unsigned PrefixLength, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:168

static Cursor maybeLexGlobalValue(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:486

static Cursor maybeLexIRValue(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:417

static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token)

Definition MILexer.cpp:390

static Cursor maybeLexMachineBasicBlock(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:311

static Cursor maybeLexStringConstant(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:427

static Cursor maybeLexSubRegisterIndex(Cursor C, MIToken &Token, ErrorCallbackType ErrorCallback)

Definition MILexer.cpp:398

static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token)

Definition MILexer.cpp:562

static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token)

Definition MILexer.cpp:394

static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule, MIToken::TokenKind Kind)

Definition MILexer.cpp:346

function_ref< bool(StringRef::iterator Loc, const Twine &)> ErrorCallbackType

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static bool peek(struct InternalInstruction *insn, uint8_t &byte)

An arbitrary precision integer that knows its signedness.

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

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

LLVM Value Representation.

An efficient, type-erasing, non-owning reference to a callable.

@ C

The default llvm calling convention, compatible with C.

LocationClass< Ty > location(Ty &L)

This is an optimization pass for GlobalISel generic memory operations.

unsigned hexDigitValue(char C)

Interpret the given character C as a hexadecimal digit and return its value.

StringRef lexMIToken(StringRef Source, MIToken &Token, function_ref< void(StringRef::iterator, const Twine &)> ErrorCallback)

Consume a single machine instruction token in the given source and return the remaining source string...

A token produced by the machine instruction lexer.

MIToken & setStringValue(StringRef StrVal)

Definition MILexer.cpp:68

@ kw_cfi_aarch64_negate_ra_sign_state

@ kw_cfi_llvm_def_aspace_cfa

@ kw_inlineasm_br_indirect_target

@ kw_cfi_aarch64_negate_ra_sign_state_with_pc

@ kw_cfi_def_cfa_register

@ kw_cfi_adjust_cfa_offset

@ kw_machine_block_address_taken

@ kw_ir_block_address_taken

MIToken & setIntegerValue(APSInt IntVal)

Definition MILexer.cpp:79

MIToken & reset(TokenKind Kind, StringRef Range)

Definition MILexer.cpp:62

MIToken & setOwnedStringValue(std::string StrVal)

Definition MILexer.cpp:73

StringRef::iterator location() const