LLVM: lib/MC/MCParser/MasmParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

55#include

56#include

57#include

58#include

59#include

60#include

61#include

62#include

63#include

64#include

65#include

66#include

67#include

68#include

69

70using namespace llvm;

71

72namespace {

73

74

75typedef std::vector MCAsmMacroArgument;

76typedef std::vector MCAsmMacroArguments;

77

78

79struct MacroInstantiation {

80

81 SMLoc InstantiationLoc;

82

83

84 unsigned ExitBuffer;

85

86

87 SMLoc ExitLoc;

88

89

90 size_t CondStackDepth;

91};

92

93struct ParseStatementInfo {

94

96

97

98 unsigned Opcode = ~0U;

99

100

101 bool ParseError = false;

102

103

104 std::optionalstd::string ExitValue;

105

106 SmallVectorImpl *AsmRewrites = nullptr;

107

108 ParseStatementInfo() = delete;

109 ParseStatementInfo(SmallVectorImpl *rewrites)

110 : AsmRewrites(rewrites) {}

111};

112

113enum FieldType {

114 FT_INTEGRAL,

115 FT_REAL,

116 FT_STRUCT

117};

118

119struct FieldInfo;

120struct StructInfo {

121 StringRef Name;

122 bool IsUnion = false;

123 bool Initializable = true;

124 unsigned Alignment = 0;

125 unsigned AlignmentSize = 0;

126 unsigned NextOffset = 0;

127 unsigned Size = 0;

128 std::vector Fields;

129 StringMap<size_t> FieldsByName;

130

131 FieldInfo &addField(StringRef FieldName, FieldType FT,

132 unsigned FieldAlignmentSize);

133

134 StructInfo() = default;

135 StructInfo(StringRef StructName, bool Union, unsigned AlignmentValue);

136};

137

138

139

140

141

142

143struct StructInitializer;

144struct IntFieldInfo {

146

147 IntFieldInfo() = default;

150};

151struct RealFieldInfo {

153

154 RealFieldInfo() = default;

157};

158struct StructFieldInfo {

159 std::vector Initializers;

160 StructInfo Structure;

161

162 StructFieldInfo() = default;

163 StructFieldInfo(std::vector V, StructInfo S);

164};

165

166class FieldInitializer {

167public:

168 FieldType FT;

169 union {

170 IntFieldInfo IntInfo;

171 RealFieldInfo RealInfo;

172 StructFieldInfo StructInfo;

173 };

174

175 ~FieldInitializer();

176 FieldInitializer(FieldType FT);

177

180 FieldInitializer(std::vector &&Initializers,

181 struct StructInfo Structure);

182

183 FieldInitializer(const FieldInitializer &Initializer);

184 FieldInitializer(FieldInitializer &&Initializer);

185

186 FieldInitializer &operator=(const FieldInitializer &Initializer);

187 FieldInitializer &operator=(FieldInitializer &&Initializer);

188};

189

190struct StructInitializer {

191 std::vector FieldInitializers;

192};

193

194struct FieldInfo {

195

196 unsigned Offset = 0;

197

198

199 unsigned SizeOf = 0;

200

201

202 unsigned LengthOf = 0;

203

204

205 unsigned Type = 0;

206

207 FieldInitializer Contents;

208

209 FieldInfo(FieldType FT) : Contents(FT) {}

210};

211

212StructFieldInfo::StructFieldInfo(std::vector V,

213 StructInfo S) {

214 Initializers = std::move(V);

215 Structure = S;

216}

217

218StructInfo::StructInfo(StringRef StructName, bool Union,

219 unsigned AlignmentValue)

221

222FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT,

223 unsigned FieldAlignmentSize) {

224 if (!FieldName.empty())

225 FieldsByName[FieldName.lower()] = Fields.size();

226 Fields.emplace_back(FT);

227 FieldInfo &Field = Fields.back();

229 llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize));

230 if (!IsUnion) {

231 NextOffset = std::max(NextOffset, Field.Offset);

232 }

233 AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);

235}

236

237FieldInitializer::~FieldInitializer() {

238 switch (FT) {

239 case FT_INTEGRAL:

240 IntInfo.~IntFieldInfo();

241 break;

242 case FT_REAL:

243 RealInfo.~RealFieldInfo();

244 break;

245 case FT_STRUCT:

246 StructInfo.~StructFieldInfo();

247 break;

248 }

249}

250

251FieldInitializer::FieldInitializer(FieldType FT) : FT(FT) {

252 switch (FT) {

253 case FT_INTEGRAL:

254 new (&IntInfo) IntFieldInfo();

255 break;

256 case FT_REAL:

257 new (&RealInfo) RealFieldInfo();

258 break;

259 case FT_STRUCT:

260 new (&StructInfo) StructFieldInfo();

261 break;

262 }

263}

264

266 : FT(FT_INTEGRAL) {

267 new (&IntInfo) IntFieldInfo(std::move(Values));

268}

269

271 : FT(FT_REAL) {

272 new (&RealInfo) RealFieldInfo(std::move(AsIntValues));

273}

274

275FieldInitializer::FieldInitializer(

276 std::vector &&Initializers, struct StructInfo Structure)

277 : FT(FT_STRUCT) {

278 new (&StructInfo) StructFieldInfo(std::move(Initializers), Structure);

279}

280

281FieldInitializer::FieldInitializer(const FieldInitializer &Initializer)

282 : FT(Initializer.FT) {

283 switch (FT) {

284 case FT_INTEGRAL:

285 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);

286 break;

287 case FT_REAL:

288 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);

289 break;

290 case FT_STRUCT:

291 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);

292 break;

293 }

294}

295

296FieldInitializer::FieldInitializer(FieldInitializer &&Initializer)

297 : FT(Initializer.FT) {

298 switch (FT) {

299 case FT_INTEGRAL:

300 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);

301 break;

302 case FT_REAL:

303 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);

304 break;

305 case FT_STRUCT:

306 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);

307 break;

308 }

309}

310

311FieldInitializer &

312FieldInitializer::operator=(const FieldInitializer &Initializer) {

313 if (FT != Initializer.FT) {

314 switch (FT) {

315 case FT_INTEGRAL:

316 IntInfo.~IntFieldInfo();

317 break;

318 case FT_REAL:

319 RealInfo.~RealFieldInfo();

320 break;

321 case FT_STRUCT:

322 StructInfo.~StructFieldInfo();

323 break;

324 }

325 }

326 FT = Initializer.FT;

327 switch (FT) {

328 case FT_INTEGRAL:

329 IntInfo = Initializer.IntInfo;

330 break;

331 case FT_REAL:

332 RealInfo = Initializer.RealInfo;

333 break;

334 case FT_STRUCT:

335 StructInfo = Initializer.StructInfo;

336 break;

337 }

338 return *this;

339}

340

341FieldInitializer &FieldInitializer::operator=(FieldInitializer &&Initializer) {

342 if (FT != Initializer.FT) {

343 switch (FT) {

344 case FT_INTEGRAL:

345 IntInfo.~IntFieldInfo();

346 break;

347 case FT_REAL:

348 RealInfo.~RealFieldInfo();

349 break;

350 case FT_STRUCT:

351 StructInfo.~StructFieldInfo();

352 break;

353 }

354 }

355 FT = Initializer.FT;

356 switch (FT) {

357 case FT_INTEGRAL:

358 IntInfo = Initializer.IntInfo;

359 break;

360 case FT_REAL:

361 RealInfo = Initializer.RealInfo;

362 break;

363 case FT_STRUCT:

364 StructInfo = Initializer.StructInfo;

365 break;

366 }

367 return *this;

368}

369

370

371

372

373class MasmParser : public MCAsmParser {

374private:

376 void *SavedDiagContext;

377 std::unique_ptr PlatformParser;

378

379

380

381 unsigned CurBuffer;

382

383

384 struct tm TM;

385

386 BitVector EndStatementAtEOFStack;

387

388 AsmCond TheCondState;

389 std::vector TheCondStack;

390

391

392

393

394 StringMap ExtensionDirectiveMap;

395

396

398 enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE };

399

400 StringRef Name;

401 RedefinableKind Redefinable = REDEFINABLE;

402 bool IsText = false;

403 std::string TextValue;

404 };

405 StringMap Variables;

406

407

409

410

411 StringMap Structs;

412

413

414 StringMap KnownType;

415

416

417 std::vector<MacroInstantiation*> ActiveMacros;

418

419

420 std::deque MacroLikeBodies;

421

422

423 unsigned NumOfMacroInstantiations;

424

425

426 struct CppHashInfoTy {

427 StringRef Filename;

428 int64_t LineNumber;

429 SMLoc Loc;

430 unsigned Buf;

431 CppHashInfoTy() : LineNumber(0), Buf(0) {}

432 };

433 CppHashInfoTy CppHashInfo;

434

435

436 StringRef FirstCppHashFilename;

437

438

440

441

442

443 unsigned AssemblerDialect = 1U;

444

445

446 bool ParsingMSInlineAsm = false;

447

448

449 unsigned AngleBracketDepth = 0U;

450

451

452 uint16_t LocalCounter = 0;

453

454public:

455 MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,

456 const MCAsmInfo &MAI, struct tm TM, unsigned CB = 0);

457 MasmParser(const MasmParser &) = delete;

458 MasmParser &operator=(const MasmParser &) = delete;

459 ~MasmParser() override;

460

461 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;

462

463 void addDirectiveHandler(StringRef Directive,

464 ExtensionDirectiveHandler Handler) override {

465 ExtensionDirectiveMap[Directive] = Handler;

466 DirectiveKindMap.try_emplace(Directive, DK_HANDLER_DIRECTIVE);

467 }

468

469 void addAliasForDirective(StringRef Directive, StringRef Alias) override {

470 DirectiveKindMap[Directive] = DirectiveKindMap[Alias];

471 }

472

473

474

475

476 unsigned getAssemblerDialect() override {

477 if (AssemblerDialect == ~0U)

478 return MAI.getAssemblerDialect();

479 else

480 return AssemblerDialect;

481 }

482 void setAssemblerDialect(unsigned i) override {

483 AssemblerDialect = i;

484 }

485

486 void Note(SMLoc L, const Twine &Msg, SMRange Range = {}) override;

487 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = {}) override;

488 bool printError(SMLoc L, const Twine &Msg, SMRange Range = {}) override;

489

490 enum ExpandKind { ExpandMacros, DoNotExpandMacros };

491 const AsmToken &Lex(ExpandKind ExpandNextToken);

492 const AsmToken &Lex() override { return Lex(ExpandMacros); }

493

494 void setParsingMSInlineAsm(bool V) override {

495 ParsingMSInlineAsm = V;

496

497

498 Lexer.setLexMasmIntegers(V);

499 }

500 bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }

501

502 bool isParsingMasm() const override { return true; }

503

504 bool defineMacro(StringRef Name, StringRef Value) override;

505

506 bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override;

507 bool lookUpField(StringRef Base, StringRef Member,

508 AsmFieldInfo &Info) const override;

509

510 bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override;

511

512 bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs,

513 unsigned &NumInputs,

514 SmallVectorImpl<std::pair<void *, bool>> &OpDecls,

515 SmallVectorImplstd::string &Constraints,

516 SmallVectorImplstd::string &Clobbers,

517 const MCInstrInfo *MII, MCInstPrinter *IP,

518 MCAsmParserSemaCallback &SI) override;

519

520 bool parseExpression(const MCExpr *&Res);

521 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;

522 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,

523 AsmTypeInfo *TypeInfo) override;

524 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;

525 bool parseAbsoluteExpression(int64_t &Res) override;

526

527

528

529 bool parseRealValue(const fltSemantics &Semantics, APInt &Res);

530

531

532

533 enum IdentifierPositionKind { StandardPosition, StartOfStatement };

534 bool parseIdentifier(StringRef &Res, IdentifierPositionKind Position);

535 bool parseIdentifier(StringRef &Res) override {

536 return parseIdentifier(Res, StandardPosition);

537 }

538 void eatToEndOfStatement() override;

539

540 bool checkForValidSection() override;

541

542

543

544private:

545 bool expandMacros();

546 const AsmToken peekTok(bool ShouldSkipSpace = true);

547

548 bool parseStatement(ParseStatementInfo &Info,

549 MCAsmParserSemaCallback *SI);

550 bool parseCurlyBlockScope(SmallVectorImpl& AsmStrRewrites);

551 bool parseCppHashLineFilenameComment(SMLoc L);

552

553 bool expandMacro(raw_svector_ostream &OS, StringRef Body,

556 const std::vectorstd::string &Locals, SMLoc L);

557

558

559 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}

560

561

562

563

564

565 bool handleMacroEntry(

566 const MCAsmMacro *M, SMLoc NameLoc,

568

569

570

571

572

573 bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc);

574

575

576 void handleMacroExit();

577

578

579 bool

580 parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA,

582

583

584 bool

585 parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A,

587

588 void printMacroInstantiations();

589

590 bool expandStatement(SMLoc Loc);

591

593 SMRange Range = {}) const {

596 }

598

599 bool lookUpField(const StructInfo &Structure, StringRef Member,

600 AsmFieldInfo &Info) const;

601

602

603 bool enterIncludeFile(const std::string &Filename);

604

605

606

607

608

609

610

611 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0,

612 bool EndStatementAtEOF = true);

613

614

615

616

617

620

621

622

623

624 StringRef parseStringToEndOfStatement() override;

625

626 bool parseTextItem(std::string &Data);

627

630

631 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);

632 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);

633 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);

634

635

636 enum DirectiveKind {

637 DK_NO_DIRECTIVE,

638 DK_HANDLER_DIRECTIVE,

639 DK_ASSIGN,

640 DK_EQU,

641 DK_TEXTEQU,

642 DK_ASCII,

643 DK_ASCIZ,

644 DK_STRING,

645 DK_BYTE,

646 DK_SBYTE,

647 DK_WORD,

648 DK_SWORD,

649 DK_DWORD,

650 DK_SDWORD,

651 DK_FWORD,

652 DK_QWORD,

653 DK_SQWORD,

654 DK_DB,

655 DK_DD,

656 DK_DF,

657 DK_DQ,

658 DK_DW,

659 DK_REAL4,

660 DK_REAL8,

661 DK_REAL10,

662 DK_ALIGN,

663 DK_EVEN,

664 DK_ORG,

665 DK_ENDR,

666 DK_EXTERN,

667 DK_PUBLIC,

668 DK_COMM,

669 DK_COMMENT,

670 DK_INCLUDE,

671 DK_REPEAT,

672 DK_WHILE,

673 DK_FOR,

674 DK_FORC,

675 DK_IF,

676 DK_IFE,

677 DK_IFB,

678 DK_IFNB,

679 DK_IFDEF,

680 DK_IFNDEF,

681 DK_IFDIF,

682 DK_IFDIFI,

683 DK_IFIDN,

684 DK_IFIDNI,

685 DK_ELSEIF,

686 DK_ELSEIFE,

687 DK_ELSEIFB,

688 DK_ELSEIFNB,

689 DK_ELSEIFDEF,

690 DK_ELSEIFNDEF,

691 DK_ELSEIFDIF,

692 DK_ELSEIFDIFI,

693 DK_ELSEIFIDN,

694 DK_ELSEIFIDNI,

695 DK_ELSE,

696 DK_ENDIF,

697

698 DK_MACRO,

699 DK_EXITM,

700 DK_ENDM,

701 DK_PURGE,

702 DK_ERR,

703 DK_ERRB,

704 DK_ERRNB,

705 DK_ERRDEF,

706 DK_ERRNDEF,

707 DK_ERRDIF,

708 DK_ERRDIFI,

709 DK_ERRIDN,

710 DK_ERRIDNI,

711 DK_ERRE,

712 DK_ERRNZ,

713 DK_ECHO,

714 DK_STRUCT,

715 DK_UNION,

716 DK_ENDS,

717 DK_END,

718 DK_PUSHFRAME,

719 DK_PUSHREG,

720 DK_SAVEREG,

721 DK_SAVEXMM128,

722 DK_SETFRAME,

723 DK_RADIX,

724 };

725

726

727

728 StringMap DirectiveKindMap;

729

730 bool isMacroLikeDirective();

731

732

733 enum BuiltinSymbol {

734 BI_NO_SYMBOL,

735 BI_DATE,

736 BI_TIME,

737 BI_VERSION,

738 BI_FILECUR,

739 BI_FILENAME,

740 BI_LINE,

741 BI_CURSEG,

742 BI_CPU,

743 BI_INTERFACE,

744 BI_CODE,

745 BI_DATA,

746 BI_FARDATA,

747 BI_WORDSIZE,

748 BI_CODESIZE,

749 BI_DATASIZE,

750 BI_MODEL,

751 BI_STACK,

752 };

753

754

755

756 StringMap BuiltinSymbolMap;

757

758 const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol, SMLoc StartLoc);

759

760 std::optionalstd::string evaluateBuiltinTextMacro(BuiltinSymbol Symbol,

761 SMLoc StartLoc);

762

763

764 enum BuiltinFunction {

765 BI_NO_FUNCTION,

766 BI_CATSTR,

767 };

768

769

770

771 StringMap BuiltinFunctionMap;

772

773 bool evaluateBuiltinMacroFunction(BuiltinFunction Function, StringRef Name,

774 std::string &Res);

775

776

777 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);

778

779

780 bool emitIntValue(const MCExpr *Value, unsigned Size);

781 bool parseScalarInitializer(unsigned Size,

782 SmallVectorImpl<const MCExpr *> &Values,

783 unsigned StringPadLength = 0);

784 bool parseScalarInstList(

785 unsigned Size, SmallVectorImpl<const MCExpr *> &Values,

787 bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr);

788 bool addIntegralField(StringRef Name, unsigned Size);

789 bool parseDirectiveValue(StringRef IDVal, unsigned Size);

790 bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,

791 StringRef Name, SMLoc NameLoc);

792

793

794 bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);

795 bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);

796 bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,

797 size_t Size);

798 bool parseRealInstList(

799 const fltSemantics &Semantics, SmallVectorImpl &Values,

801 bool parseDirectiveNamedRealValue(StringRef TypeName,

802 const fltSemantics &Semantics,

803 unsigned Size, StringRef Name,

804 SMLoc NameLoc);

805

806 bool parseOptionalAngleBracketOpen();

807 bool parseAngleBracketClose(const Twine &Msg = "expected '>'");

808

809 bool parseFieldInitializer(const FieldInfo &Field,

810 FieldInitializer &Initializer);

811 bool parseFieldInitializer(const FieldInfo &Field,

812 const IntFieldInfo &Contents,

813 FieldInitializer &Initializer);

814 bool parseFieldInitializer(const FieldInfo &Field,

815 const RealFieldInfo &Contents,

816 FieldInitializer &Initializer);

817 bool parseFieldInitializer(const FieldInfo &Field,

818 const StructFieldInfo &Contents,

819 FieldInitializer &Initializer);

820

821 bool parseStructInitializer(const StructInfo &Structure,

822 StructInitializer &Initializer);

823 bool parseStructInstList(

824 const StructInfo &Structure, std::vector &Initializers,

826

827 bool emitFieldValue(const FieldInfo &Field);

828 bool emitFieldValue(const FieldInfo &Field, const IntFieldInfo &Contents);

829 bool emitFieldValue(const FieldInfo &Field, const RealFieldInfo &Contents);

830 bool emitFieldValue(const FieldInfo &Field, const StructFieldInfo &Contents);

831

832 bool emitFieldInitializer(const FieldInfo &Field,

833 const FieldInitializer &Initializer);

834 bool emitFieldInitializer(const FieldInfo &Field,

835 const IntFieldInfo &Contents,

836 const IntFieldInfo &Initializer);

837 bool emitFieldInitializer(const FieldInfo &Field,

838 const RealFieldInfo &Contents,

839 const RealFieldInfo &Initializer);

840 bool emitFieldInitializer(const FieldInfo &Field,

841 const StructFieldInfo &Contents,

842 const StructFieldInfo &Initializer);

843

844 bool emitStructInitializer(const StructInfo &Structure,

845 const StructInitializer &Initializer);

846

847

848 bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr);

849 bool addStructField(StringRef Name, const StructInfo &Structure);

850 bool parseDirectiveStructValue(const StructInfo &Structure,

851 StringRef Directive, SMLoc DirLoc);

852 bool parseDirectiveNamedStructValue(const StructInfo &Structure,

853 StringRef Directive, SMLoc DirLoc,

854 StringRef Name);

855

856

857 bool parseDirectiveEquate(StringRef IDVal, StringRef Name,

858 DirectiveKind DirKind, SMLoc NameLoc);

859

860 bool parseDirectiveOrg();

861

862 bool emitAlignTo(int64_t Alignment);

863 bool parseDirectiveAlign();

864 bool parseDirectiveEven();

865

866

867 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);

868 bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,

869 std::string &Value);

870 bool parseDirectiveEndMacro(StringRef Directive);

871 bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);

872

873 bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind,

874 StringRef Name, SMLoc NameLoc);

875 bool parseDirectiveNestedStruct(StringRef Directive, DirectiveKind DirKind);

876 bool parseDirectiveEnds(StringRef Name, SMLoc NameLoc);

877 bool parseDirectiveNestedEnds();

878

879 bool parseDirectiveExtern();

880

881

882

883 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);

884

885 bool parseDirectiveComm(bool IsLocal);

886

887 bool parseDirectiveComment(SMLoc DirectiveLoc);

888

889 bool parseDirectiveInclude();

890

891

892 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);

893

894 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);

895

896

897 bool parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,

898 bool CaseInsensitive);

899

900 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);

901

902 bool parseDirectiveElseIf(SMLoc DirectiveLoc, DirectiveKind DirKind);

903

904 bool parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank);

905

906 bool parseDirectiveElseIfdef(SMLoc DirectiveLoc, bool expect_defined);

907

908

909 bool parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,

910 bool CaseInsensitive);

911 bool parseDirectiveElse(SMLoc DirectiveLoc);

912 bool parseDirectiveEndIf(SMLoc DirectiveLoc);

913 bool parseEscapedString(std::string &Data) override;

914 bool parseAngleBracketString(std::string &Data) override;

915

916

917 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);

918 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,

919 raw_svector_ostream &OS);

920 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,

921 SMLoc ExitLoc, raw_svector_ostream &OS);

922 bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive);

923 bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive);

924 bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive);

925 bool parseDirectiveWhile(SMLoc DirectiveLoc);

926

927

928 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,

929 size_t Len);

930

931

932 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);

933

934

935 bool parseDirectiveEnd(SMLoc DirectiveLoc);

936

937

938 bool parseDirectiveError(SMLoc DirectiveLoc);

939

940 bool parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank);

941

942 bool parseDirectiveErrorIfdef(SMLoc DirectiveLoc, bool ExpectDefined);

943

944

945 bool parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,

946 bool CaseInsensitive);

947

948 bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero);

949

950

951 bool parseDirectiveRadix(SMLoc DirectiveLoc);

952

953

954 bool parseDirectiveEcho(SMLoc DirectiveLoc);

955

956 void initializeDirectiveKindMap();

957 void initializeBuiltinSymbolMaps();

958};

959

960}

961

962namespace llvm {

963

965

966}

967

969

970MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,

971 const MCAsmInfo &MAI, struct tm TM, unsigned CB)

972 : MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),

973 TM(TM) {

974 HadError = false;

975

976 SavedDiagHandler = SrcMgr.getDiagHandler();

977 SavedDiagContext = SrcMgr.getDiagContext();

978

980 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());

981 EndStatementAtEOFStack.push_back(true);

982

983

984 switch (Ctx.getObjectFileType()) {

985 case MCContext::IsCOFF:

986 PlatformParser.reset(createCOFFMasmParser());

987 break;

988 default:

989 report_fatal_error("llvm-ml currently supports only COFF output.");

990 break;

991 }

992

993 initializeDirectiveKindMap();

994 PlatformParser->Initialize(*this);

995 initializeBuiltinSymbolMaps();

996

997 NumOfMacroInstantiations = 0;

998}

999

1000MasmParser::~MasmParser() {

1001 assert((HadError || ActiveMacros.empty()) &&

1002 "Unexpected active macro instantiation!");

1003

1004

1005

1007}

1008

1009void MasmParser::printMacroInstantiations() {

1010

1011 for (std::vector<MacroInstantiation *>::const_reverse_iterator

1012 it = ActiveMacros.rbegin(),

1013 ie = ActiveMacros.rend();

1014 it != ie; ++it)

1016 "while in macro instantiation");

1017}

1018

1019void MasmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {

1020 printPendingErrors();

1022 printMacroInstantiations();

1023}

1024

1025bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {

1026 if (getTargetParser().getTargetOptions().MCNoWarn)

1027 return false;

1028 if (getTargetParser().getTargetOptions().MCFatalWarnings)

1031 printMacroInstantiations();

1032 return false;

1033}

1034

1035bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {

1036 HadError = true;

1038 printMacroInstantiations();

1039 return true;

1040}

1041

1042bool MasmParser::enterIncludeFile(const std::string &Filename) {

1043 std::string IncludedFile;

1044 unsigned NewBuf =

1046 if (!NewBuf)

1047 return true;

1048

1049 CurBuffer = NewBuf;

1051 EndStatementAtEOFStack.push_back(true);

1052 return false;

1053}

1054

1055void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer,

1056 bool EndStatementAtEOF) {

1059 Loc.getPointer(), EndStatementAtEOF);

1060}

1061

1062bool MasmParser::expandMacros() {

1063 const AsmToken &Tok = getTok();

1065

1066 const llvm::MCAsmMacro *M = getContext().lookupMacro(IDLower);

1068

1069 const SMLoc MacroLoc = Tok.getLoc();

1071 Lexer.Lex();

1072 if (handleMacroInvocation(M, MacroLoc)) {

1074 Lexer.Lex();

1075 }

1076 return false;

1077 }

1078

1079 std::optionalstd::string ExpandedValue;

1080

1081 if (auto BuiltinIt = BuiltinSymbolMap.find(IDLower);

1082 BuiltinIt != BuiltinSymbolMap.end()) {

1083 ExpandedValue =

1084 evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.getLoc());

1085 } else if (auto BuiltinFuncIt = BuiltinFunctionMap.find(IDLower);

1086 BuiltinFuncIt != BuiltinFunctionMap.end()) {

1087 StringRef Name;

1088 if (parseIdentifier(Name)) {

1089 return true;

1090 }

1091 std::string Res;

1092 if (evaluateBuiltinMacroFunction(BuiltinFuncIt->getValue(), Name, Res)) {

1093 return true;

1094 }

1095 ExpandedValue = Res;

1096 } else if (auto VarIt = Variables.find(IDLower);

1097 VarIt != Variables.end() && VarIt->getValue().IsText) {

1098 ExpandedValue = VarIt->getValue().TextValue;

1099 }

1100

1101 if (!ExpandedValue)

1102 return true;

1103 std::unique_ptr Instantiation =

1105

1106

1107 CurBuffer =

1110 false);

1111 EndStatementAtEOFStack.push_back(false);

1112 Lexer.Lex();

1113 return false;

1114}

1115

1116const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {

1118 Error(Lexer.getErrLoc(), Lexer.getErr());

1119 bool StartOfStatement = false;

1120

1121

1123

1124 if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&

1127 StartOfStatement = true;

1128 }

1129

1130 const AsmToken *tok = &Lexer.Lex();

1131

1133 if (StartOfStatement) {

1134 AsmToken NextTok;

1136 size_t ReadCount = Lexer.peekTokens(Buf);

1140

1141

1142 break;

1143 }

1144 }

1145 if (expandMacros())

1146 break;

1147 }

1148

1149

1153 tok = &Lexer.Lex();

1154 }

1155

1156

1159

1160 Lexer.Lex();

1161 tok = &Lexer.Lex();

1162 }

1163

1165

1166

1168 if (ParentIncludeLoc != SMLoc()) {

1169 EndStatementAtEOFStack.pop_back();

1170 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());

1171 return Lex();

1172 }

1173 EndStatementAtEOFStack.pop_back();

1174 assert(EndStatementAtEOFStack.empty());

1175 }

1176

1177 return *tok;

1178}

1179

1180const AsmToken MasmParser::peekTok(bool ShouldSkipSpace) {

1181 AsmToken Tok;

1182

1184 size_t ReadCount = Lexer.peekTokens(Buf, ShouldSkipSpace);

1185

1186 if (ReadCount == 0) {

1187

1188

1190 if (ParentIncludeLoc != SMLoc()) {

1191 EndStatementAtEOFStack.pop_back();

1192 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());

1193 return peekTok(ShouldSkipSpace);

1194 }

1195 EndStatementAtEOFStack.pop_back();

1196 assert(EndStatementAtEOFStack.empty());

1197 }

1198

1199 assert(ReadCount == 1);

1200 return Tok;

1201}

1202

1203bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {

1204

1205 if (!NoInitialTextSection)

1206 Out.initSections(false, getTargetParser().getSTI());

1207

1208

1209 Lex();

1210

1211 HadError = false;

1212 AsmCond StartingCondState = TheCondState;

1214

1215

1218

1220 Lex();

1221

1222 ParseStatementInfo Info(&AsmStrRewrites);

1223 bool HasError = parseStatement(Info, nullptr);

1224

1225

1226

1227

1228 if (HasError && !hasPendingError() && Lexer.getTok().is(AsmToken::Error))

1229 Lex();

1230

1231

1232 printPendingErrors();

1233

1234

1235 if (HasError && !getLexer().justConsumedEOL())

1236 eatToEndOfStatement();

1237 }

1238

1239 printPendingErrors();

1240

1241

1242 assert(!hasPendingError() && "unexpected error from parseStatement");

1243

1244 if (TheCondState.TheCond != StartingCondState.TheCond ||

1245 TheCondState.Ignore != StartingCondState.Ignore)

1246 printError(getTok().getLoc(), "unmatched .ifs or .elses");

1247

1248

1249

1250

1251

1252 if (!NoFinalize) {

1253

1254

1255 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {

1256 if (std::get<2>(LocSym)->isUndefined()) {

1257

1258

1259 CppHashInfo = std::get<1>(LocSym);

1260 printError(std::get<0>(LocSym), "directional label undefined");

1261 }

1262 }

1263 }

1264

1265

1266

1267 if (!HadError && !NoFinalize)

1268 Out.finish(Lexer.getLoc());

1269

1270 return HadError || getContext().hadError();

1271}

1272

1273bool MasmParser::checkForValidSection() {

1274 if (!ParsingMSInlineAsm && !(getStreamer().getCurrentFragment() &&

1275 getStreamer().getCurrentSectionOnly())) {

1276 Out.initSections(false, getTargetParser().getSTI());

1277 return Error(getTok().getLoc(),

1278 "expected section directive before assembly directive");

1279 }

1280 return false;

1281}

1282

1283

1284void MasmParser::eatToEndOfStatement() {

1288 if (ParentIncludeLoc == SMLoc()) {

1289 break;

1290 }

1291

1292 EndStatementAtEOFStack.pop_back();

1293 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());

1294 }

1295

1296 Lexer.Lex();

1297 }

1298

1299

1301 Lexer.Lex();

1302}

1303

1304SmallVector<StringRef, 1>

1306 SmallVector<StringRef, 1> Refs;

1307 const char *Start = getTok().getLoc().getPointer();

1308 while (Lexer.isNot(EndTok)) {

1311 if (ParentIncludeLoc == SMLoc()) {

1312 break;

1313 }

1315

1316 EndStatementAtEOFStack.pop_back();

1317 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());

1318 Lexer.Lex();

1319 Start = getTok().getLoc().getPointer();

1320 } else {

1321 Lexer.Lex();

1322 }

1323 }

1325 return Refs;

1326}

1327

1329 SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok);

1330 std::string Str;

1331 for (StringRef S : Refs) {

1332 Str.append(S.str());

1333 }

1334 return Str;

1335}

1336

1337StringRef MasmParser::parseStringToEndOfStatement() {

1338 const char *Start = getTok().getLoc().getPointer();

1339

1341 Lexer.Lex();

1342

1343 const char *End = getTok().getLoc().getPointer();

1344 return StringRef(Start, End - Start);

1345}

1346

1347

1348

1349

1350

1351

1352bool MasmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {

1353 if (parseExpression(Res))

1354 return true;

1355 EndLoc = Lexer.getTok().getEndLoc();

1356 return parseRParen();

1357}

1358

1359

1360

1361

1362

1363

1364bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {

1365 if (parseExpression(Res))

1366 return true;

1367 EndLoc = getTok().getEndLoc();

1368 if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))

1369 return true;

1370 return false;

1371}

1372

1373

1374

1375

1376

1377

1378

1379

1380

1381bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,

1382 AsmTypeInfo *TypeInfo) {

1383 SMLoc FirstTokenLoc = getLexer().getLoc();

1385 switch (FirstTokenKind) {

1386 default:

1387 return TokError("unknown token in expression");

1388

1390 return true;

1392 Lex();

1393 if (parsePrimaryExpr(Res, EndLoc, nullptr))

1394 return true;

1396 return false;

1401 if (parseIdentifier(Identifier)) {

1402

1404 if (Lexer.getMAI().getDollarIsPC()) {

1405 Lex();

1406

1407

1411 EndLoc = FirstTokenLoc;

1412 return false;

1413 }

1414 return Error(FirstTokenLoc, "invalid token in expression");

1415 }

1416 }

1417

1418 if (Identifier.equals_insensitive("not")) {

1419 if (parsePrimaryExpr(Res, EndLoc, nullptr))

1420 return true;

1422 return false;

1423 }

1424

1425 if (Identifier.equals_insensitive("@b") ||

1426 Identifier.equals_insensitive("@f")) {

1427 bool Before = Identifier.equals_insensitive("@b");

1430 return Error(FirstTokenLoc, "Expected @@ label before @B reference");

1432 return false;

1433 }

1434

1436

1437

1440 return Error(getLexer().getLoc(), "expected a symbol reference");

1441

1442

1443 AsmFieldInfo Info;

1445 if (Split.second.empty()) {

1446 } else {

1448 if (lookUpField(SymbolName, Split.second, Info)) {

1449 std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');

1450 StringRef Base = BaseMember.first, Member = BaseMember.second;

1451 lookUpField(Base, Member, Info);

1453

1455 return false;

1456 }

1457 }

1458

1460 if (!Sym) {

1461

1462 auto BuiltinIt = BuiltinSymbolMap.find(SymbolName.lower());

1463 const BuiltinSymbol Symbol = (BuiltinIt == BuiltinSymbolMap.end())

1464 ? BI_NO_SYMBOL

1465 : BuiltinIt->getValue();

1466 if (Symbol != BI_NO_SYMBOL) {

1467 const MCExpr *Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);

1470 return false;

1471 }

1472 }

1473

1474

1475

1477 if (VarIt != Variables.end())

1479 Sym = getContext().parseSymbol(SymbolName);

1480 }

1481

1482

1483

1488 DoInline = TV->inlineAssignedExpr();

1489 if (DoInline) {

1491 return false;

1492 }

1493 }

1494

1495

1496 const MCExpr *SymRef =

1498 if (Info.Offset) {

1502 } else {

1503 Res = SymRef;

1504 }

1505 if (TypeInfo) {

1506 if (Info.Type.Name.empty()) {

1508 if (TypeIt != KnownType.end()) {

1509 Info.Type = TypeIt->second;

1510 }

1511 }

1512

1513 *TypeInfo = Info.Type;

1514 }

1515 return false;

1516 }

1518 return TokError("literal value out of range for directive");

1520 int64_t IntVal = getTok().getIntVal();

1522 EndLoc = Lexer.getTok().getEndLoc();

1523 Lex();

1524 return false;

1525 }

1527

1528 SMLoc ValueLoc = getTok().getLoc();

1529 std::string Value;

1530 if (parseEscapedString(Value))

1531 return true;

1532 if (Value.size() > 8)

1533 return Error(ValueLoc, "literal value out of range");

1534 uint64_t IntValue = 0;

1535 for (const unsigned char CharVal : Value)

1536 IntValue = (IntValue << 8) | CharVal;

1538 return false;

1539 }

1541 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());

1542 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();

1544 EndLoc = Lexer.getTok().getEndLoc();

1545 Lex();

1546 return false;

1547 }

1549

1550

1554 EndLoc = Lexer.getTok().getEndLoc();

1555 Lex();

1556 return false;

1557 }

1559 Lex();

1560 return parseParenExpr(Res, EndLoc);

1562 if (!PlatformParser->HasBracketExpressions())

1563 return TokError("brackets expression not supported on this target");

1564 Lex();

1565 return parseBracketExpr(Res, EndLoc);

1567 Lex();

1568 if (parsePrimaryExpr(Res, EndLoc, nullptr))

1569 return true;

1571 return false;

1573 Lex();

1574 if (parsePrimaryExpr(Res, EndLoc, nullptr))

1575 return true;

1577 return false;

1579 Lex();

1580 if (parsePrimaryExpr(Res, EndLoc, nullptr))

1581 return true;

1583 return false;

1584 }

1585}

1586

1587bool MasmParser::parseExpression(const MCExpr *&Res) {

1588 SMLoc EndLoc;

1589 return parseExpression(Res, EndLoc);

1590}

1591

1592

1593

1594

1595

1596

1597

1600 "Argument to the function cannot be a NULL value");

1601 const char *CharPtr = StrLoc.getPointer();

1602 while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&

1603 (*CharPtr != '\0')) {

1604 if (*CharPtr == '!')

1605 CharPtr++;

1606 CharPtr++;

1607 }

1608 if (*CharPtr == '>') {

1610 return true;

1611 }

1612 return false;

1613}

1614

1615

1617 std::string Res;

1618 for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) {

1619 if (BracketContents[Pos] == '!')

1620 Pos++;

1621 Res += BracketContents[Pos];

1622 }

1623 return Res;

1624}

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636bool MasmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {

1637

1638 Res = nullptr;

1639 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||

1640 parseBinOpRHS(1, Res, EndLoc))

1641 return true;

1642

1643

1644

1646 if (Res->evaluateAsAbsolute(Value))

1648

1649 return false;

1650}

1651

1652bool MasmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {

1653 Res = nullptr;

1654 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);

1655}

1656

1657bool MasmParser::parseAbsoluteExpression(int64_t &Res) {

1658 const MCExpr *Expr;

1659

1660 SMLoc StartLoc = Lexer.getLoc();

1661 if (parseExpression(Expr))

1662 return true;

1663

1664 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))

1665 return Error(StartLoc, "expected absolute expression");

1666

1667 return false;

1668}

1669

1672 bool ShouldUseLogicalShr,

1673 bool EndExpressionAtGreater) {

1674 switch (K) {

1675 default:

1676 return 0;

1677

1678

1681 return 2;

1684 return 1;

1685

1686

1689 return 3;

1693 return 3;

1696 return 3;

1699 return 3;

1701 if (EndExpressionAtGreater)

1702 return 0;

1704 return 3;

1707 return 3;

1708

1709

1712 return 4;

1715 return 4;

1716

1717

1720 return 5;

1723 return 5;

1726 return 5;

1727

1728

1731 return 6;

1734 return 6;

1737 return 6;

1740 return 6;

1742 if (EndExpressionAtGreater)

1743 return 0;

1745 return 6;

1746 }

1747}

1748

1753 AngleBracketDepth > 0);

1754}

1755

1756

1757

1758bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,

1759 SMLoc &EndLoc) {

1760 SMLoc StartLoc = Lexer.getLoc();

1761 while (true) {

1764 TokKind = StringSwitchAsmToken::TokenKind(Lexer.getTok().getString())

1777 .Default(TokKind);

1778 }

1780 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);

1781

1782

1783

1784 if (TokPrec < Precedence)

1785 return false;

1786

1787 Lex();

1788

1789

1790 const MCExpr *RHS;

1791 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))

1792 return true;

1793

1794

1795

1797 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);

1798 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))

1799 return true;

1800

1801

1803 }

1804}

1805

1806

1807

1808

1809

1810

1811bool MasmParser::parseStatement(ParseStatementInfo &Info,

1812 MCAsmParserSemaCallback *SI) {

1813 assert(!hasPendingError() && "parseStatement started with pending error");

1814

1816 Lex();

1818

1819 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||

1820 getTok().getString().front() == '\n')

1822 Lex();

1823 return false;

1824 }

1825

1826

1827

1829 SMLoc ExpansionLoc = getTok().getLoc();

1830 if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc))

1831 return true;

1832 }

1833

1834

1835

1836 AsmToken ID = getTok();

1837 SMLoc IDLoc = ID.getLoc();

1838 StringRef IDVal;

1840 return parseCppHashLineFilenameComment(IDLoc);

1842

1843 Lex();

1844 IDVal = ".";

1846

1847 IDVal = getTok().getString();

1848 Lex();

1850 return Error(IDLoc, "unexpected token at start of statement");

1851 } else if (parseIdentifier(IDVal, StartOfStatement)) {

1852 if (!TheCondState.Ignore) {

1853 Lex();

1854 return Error(IDLoc, "unexpected token at start of statement");

1855 }

1856 IDVal = "";

1857 }

1858

1859

1860

1861

1863 DirectiveKindMap.find(IDVal.lower());

1864 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())

1865 ? DK_NO_DIRECTIVE

1866 : DirKindIt->getValue();

1867 switch (DirKind) {

1868 default:

1869 break;

1870 case DK_IF:

1871 case DK_IFE:

1872 return parseDirectiveIf(IDLoc, DirKind);

1873 case DK_IFB:

1874 return parseDirectiveIfb(IDLoc, true);

1875 case DK_IFNB:

1876 return parseDirectiveIfb(IDLoc, false);

1877 case DK_IFDEF:

1878 return parseDirectiveIfdef(IDLoc, true);

1879 case DK_IFNDEF:

1880 return parseDirectiveIfdef(IDLoc, false);

1881 case DK_IFDIF:

1882 return parseDirectiveIfidn(IDLoc, false,

1883 false);

1884 case DK_IFDIFI:

1885 return parseDirectiveIfidn(IDLoc, false,

1886 true);

1887 case DK_IFIDN:

1888 return parseDirectiveIfidn(IDLoc, true,

1889 false);

1890 case DK_IFIDNI:

1891 return parseDirectiveIfidn(IDLoc, true,

1892 true);

1893 case DK_ELSEIF:

1894 case DK_ELSEIFE:

1895 return parseDirectiveElseIf(IDLoc, DirKind);

1896 case DK_ELSEIFB:

1897 return parseDirectiveElseIfb(IDLoc, true);

1898 case DK_ELSEIFNB:

1899 return parseDirectiveElseIfb(IDLoc, false);

1900 case DK_ELSEIFDEF:

1901 return parseDirectiveElseIfdef(IDLoc, true);

1902 case DK_ELSEIFNDEF:

1903 return parseDirectiveElseIfdef(IDLoc, false);

1904 case DK_ELSEIFDIF:

1905 return parseDirectiveElseIfidn(IDLoc, false,

1906 false);

1907 case DK_ELSEIFDIFI:

1908 return parseDirectiveElseIfidn(IDLoc, false,

1909 true);

1910 case DK_ELSEIFIDN:

1911 return parseDirectiveElseIfidn(IDLoc, true,

1912 false);

1913 case DK_ELSEIFIDNI:

1914 return parseDirectiveElseIfidn(IDLoc, true,

1915 true);

1916 case DK_ELSE:

1917 return parseDirectiveElse(IDLoc);

1918 case DK_ENDIF:

1919 return parseDirectiveEndIf(IDLoc);

1920 }

1921

1922

1923

1924 if (TheCondState.Ignore) {

1925 eatToEndOfStatement();

1926 return false;

1927 }

1928

1929

1930

1931

1932

1933

1934 if (Lexer.is(AsmToken::Colon) && getTargetParser().isLabel(ID)) {

1935 if (checkForValidSection())

1936 return true;

1937

1938

1939 Lex();

1940

1941

1942 if (IDVal == ".")

1943 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");

1944

1945

1946

1947

1948

1949

1951 if (ParsingMSInlineAsm && SI) {

1952 StringRef RewrittenLabel =

1953 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);

1955 "We should have an internal name here.");

1957 RewrittenLabel);

1958 IDVal = RewrittenLabel;

1959 }

1960

1961 if (IDVal == "@@") {

1963 } else {

1964 Sym = getContext().parseSymbol(IDVal);

1965 }

1966

1967

1968

1969

1970

1973 Lexer.Lex();

1975 }

1976

1977

1978

1980 Lex();

1981 }

1982

1983

1984 if (!getTargetParser().isParsingMSInlineAsm())

1986 return false;

1987 }

1988

1989

1990 if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) {

1994 return handleMacroEntry(M, IDLoc, ArgumentEndTok);

1995 }

1996

1997

1998

1999 if (DirKind != DK_NO_DIRECTIVE) {

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2015 return parseDirectiveNestedEnds();

2016 }

2017

2018

2019

2020 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =

2021 ExtensionDirectiveMap.lookup(IDVal.lower());

2022 if (Handler.first)

2023 return (*Handler.second)(Handler.first, IDVal, IDLoc);

2024

2025

2027 return false;

2028

2029 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);

2030 assert(TPDirectiveReturn.isFailure() == hasPendingError() &&

2031 "Should only return Failure iff there was an error");

2032 if (TPDirectiveReturn.isFailure())

2033 return true;

2034 if (TPDirectiveReturn.isSuccess())

2035 return false;

2036

2037

2038

2039 switch (DirKind) {

2040 default:

2041 break;

2042 case DK_ASCII:

2043 return parseDirectiveAscii(IDVal, false);

2044 case DK_ASCIZ:

2045 case DK_STRING:

2046 return parseDirectiveAscii(IDVal, true);

2047 case DK_BYTE:

2048 case DK_SBYTE:

2049 case DK_DB:

2050 return parseDirectiveValue(IDVal, 1);

2051 case DK_WORD:

2052 case DK_SWORD:

2053 case DK_DW:

2054 return parseDirectiveValue(IDVal, 2);

2055 case DK_DWORD:

2056 case DK_SDWORD:

2057 case DK_DD:

2058 return parseDirectiveValue(IDVal, 4);

2059 case DK_FWORD:

2060 case DK_DF:

2061 return parseDirectiveValue(IDVal, 6);

2062 case DK_QWORD:

2063 case DK_SQWORD:

2064 case DK_DQ:

2065 return parseDirectiveValue(IDVal, 8);

2066 case DK_REAL4:

2067 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);

2068 case DK_REAL8:

2069 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);

2070 case DK_REAL10:

2071 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);

2072 case DK_STRUCT:

2073 case DK_UNION:

2074 return parseDirectiveNestedStruct(IDVal, DirKind);

2075 case DK_ENDS:

2076 return parseDirectiveNestedEnds();

2077 case DK_ALIGN:

2078 return parseDirectiveAlign();

2079 case DK_EVEN:

2080 return parseDirectiveEven();

2081 case DK_ORG:

2082 return parseDirectiveOrg();

2083 case DK_EXTERN:

2084 return parseDirectiveExtern();

2085 case DK_PUBLIC:

2086 return parseDirectiveSymbolAttribute(MCSA_Global);

2087 case DK_COMM:

2088 return parseDirectiveComm(false);

2089 case DK_COMMENT:

2090 return parseDirectiveComment(IDLoc);

2091 case DK_INCLUDE:

2092 return parseDirectiveInclude();

2093 case DK_REPEAT:

2094 return parseDirectiveRepeat(IDLoc, IDVal);

2095 case DK_WHILE:

2096 return parseDirectiveWhile(IDLoc);

2097 case DK_FOR:

2098 return parseDirectiveFor(IDLoc, IDVal);

2099 case DK_FORC:

2100 return parseDirectiveForc(IDLoc, IDVal);

2101 case DK_EXITM:

2102 Info.ExitValue = "";

2103 return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);

2104 case DK_ENDM:

2105 Info.ExitValue = "";

2106 return parseDirectiveEndMacro(IDVal);

2107 case DK_PURGE:

2108 return parseDirectivePurgeMacro(IDLoc);

2109 case DK_END:

2110 return parseDirectiveEnd(IDLoc);

2111 case DK_ERR:

2112 return parseDirectiveError(IDLoc);

2113 case DK_ERRB:

2114 return parseDirectiveErrorIfb(IDLoc, true);

2115 case DK_ERRNB:

2116 return parseDirectiveErrorIfb(IDLoc, false);

2117 case DK_ERRDEF:

2118 return parseDirectiveErrorIfdef(IDLoc, true);

2119 case DK_ERRNDEF:

2120 return parseDirectiveErrorIfdef(IDLoc, false);

2121 case DK_ERRDIF:

2122 return parseDirectiveErrorIfidn(IDLoc, false,

2123 false);

2124 case DK_ERRDIFI:

2125 return parseDirectiveErrorIfidn(IDLoc, false,

2126 true);

2127 case DK_ERRIDN:

2128 return parseDirectiveErrorIfidn(IDLoc, true,

2129 false);

2130 case DK_ERRIDNI:

2131 return parseDirectiveErrorIfidn(IDLoc, true,

2132 true);

2133 case DK_ERRE:

2134 return parseDirectiveErrorIfe(IDLoc, true);

2135 case DK_ERRNZ:

2136 return parseDirectiveErrorIfe(IDLoc, false);

2137 case DK_RADIX:

2138 return parseDirectiveRadix(IDLoc);

2139 case DK_ECHO:

2140 return parseDirectiveEcho(IDLoc);

2141 }

2142

2143 return Error(IDLoc, "unknown directive");

2144 }

2145

2146

2147 auto IDIt = Structs.find(IDVal.lower());

2148 if (IDIt != Structs.end())

2149 return parseDirectiveStructValue(IDIt->getValue(), IDVal,

2150 IDLoc);

2151

2152

2153 const AsmToken nextTok = getTok();

2154 const StringRef nextVal = nextTok.getString();

2155 const SMLoc nextLoc = nextTok.getLoc();

2156

2157 const AsmToken afterNextTok = peekTok();

2158

2159

2160

2161

2162

2163

2164

2165

2166

2167

2168 getTargetParser().flushPendingInstructions(getStreamer());

2169

2170

2171

2173 Lex();

2174 return parseDirectiveEnds(IDVal, IDLoc);

2175 }

2176

2177

2178

2179 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =

2180 ExtensionDirectiveMap.lookup(nextVal.lower());

2181 if (Handler.first) {

2182 Lex();

2183 Lexer.UnLex(ID);

2184 return (*Handler.second)(Handler.first, nextVal, nextLoc);

2185 }

2186

2187

2188

2189 DirKindIt = DirectiveKindMap.find(nextVal.lower());

2190 DirKind = (DirKindIt == DirectiveKindMap.end())

2191 ? DK_NO_DIRECTIVE

2192 : DirKindIt->getValue();

2193 switch (DirKind) {

2194 default:

2195 break;

2196 case DK_ASSIGN:

2197 case DK_EQU:

2198 case DK_TEXTEQU:

2199 Lex();

2200 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);

2201 case DK_BYTE:

2204

2205 break;

2206 }

2207 [[fallthrough]];

2208 case DK_SBYTE:

2209 case DK_DB:

2210 Lex();

2211 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);

2212 case DK_WORD:

2215

2216 break;

2217 }

2218 [[fallthrough]];

2219 case DK_SWORD:

2220 case DK_DW:

2221 Lex();

2222 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);

2223 case DK_DWORD:

2226

2227 break;

2228 }

2229 [[fallthrough]];

2230 case DK_SDWORD:

2231 case DK_DD:

2232 Lex();

2233 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);

2234 case DK_FWORD:

2237

2238 break;

2239 }

2240 [[fallthrough]];

2241 case DK_DF:

2242 Lex();

2243 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);

2244 case DK_QWORD:

2247

2248 break;

2249 }

2250 [[fallthrough]];

2251 case DK_SQWORD:

2252 case DK_DQ:

2253 Lex();

2254 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);

2255 case DK_REAL4:

2256 Lex();

2257 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,

2258 IDVal, IDLoc);

2259 case DK_REAL8:

2260 Lex();

2261 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,

2262 IDVal, IDLoc);

2263 case DK_REAL10:

2264 Lex();

2265 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),

2266 10, IDVal, IDLoc);

2267 case DK_STRUCT:

2268 case DK_UNION:

2269 Lex();

2270 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);

2271 case DK_ENDS:

2272 Lex();

2273 return parseDirectiveEnds(IDVal, IDLoc);

2274 case DK_MACRO:

2275 Lex();

2276 return parseDirectiveMacro(IDVal, IDLoc);

2277 }

2278

2279

2280 auto NextIt = Structs.find(nextVal.lower());

2281 if (NextIt != Structs.end()) {

2282 Lex();

2283 return parseDirectiveNamedStructValue(NextIt->getValue(),

2284 nextVal, nextLoc, IDVal);

2285 }

2286

2287

2288 if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||

2289 IDVal == "_EMIT" || IDVal == "__EMIT"))

2290 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());

2291

2292

2293 if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))

2294 return parseDirectiveMSAlign(IDLoc, Info);

2295

2296 if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))

2297 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);

2298 if (checkForValidSection())

2299 return true;

2300

2301

2302 std::string OpcodeStr = IDVal.lower();

2303 ParseInstructionInfo IInfo(Info.AsmRewrites);

2304 bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr, ID,

2305 Info.ParsedOperands);

2306 Info.ParseError = ParseHadError;

2307

2308

2309 if (getShowParsedOperands()) {

2310 SmallString<256> Str;

2311 raw_svector_ostream OS(Str);

2312 OS << "parsed instruction: [";

2313 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {

2314 if (i != 0)

2315 OS << ", ";

2316 Info.ParsedOperands[i]->print(OS, MAI);

2317 }

2318 OS << "]";

2319

2321 }

2322

2323

2324 if (hasPendingError() || ParseHadError)

2325 return true;

2326

2327

2328 if (!ParseHadError) {

2329 uint64_t ErrorInfo;

2330 if (getTargetParser().matchAndEmitInstruction(

2331 IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,

2332 getTargetParser().isParsingMSInlineAsm()))

2333 return true;

2334 }

2335 return false;

2336}

2337

2338

2339bool MasmParser::parseCurlyBlockScope(

2340 SmallVectorImpl &AsmStrRewrites) {

2341

2343 return false;

2344

2345 SMLoc StartLoc = Lexer.getLoc();

2346 Lex();

2348 Lex();

2349

2350

2351 AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -

2353 return true;

2354}

2355

2356

2357

2358bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) {

2359 Lex();

2360

2361

2363 "Lexing Cpp line comment: Expected Integer");

2364 int64_t LineNumber = getTok().getIntVal();

2365 Lex();

2367 "Lexing Cpp line comment: Expected String");

2368 StringRef Filename = getTok().getString();

2369 Lex();

2370

2371

2373

2374

2375

2376 CppHashInfo.Loc = L;

2377 CppHashInfo.Filename = Filename;

2378 CppHashInfo.LineNumber = LineNumber;

2379 CppHashInfo.Buf = CurBuffer;

2380 if (FirstCppHashFilename.empty())

2381 FirstCppHashFilename = Filename;

2382 return false;

2383}

2384

2385

2386

2387void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {

2388 const MasmParser *Parser = static_cast<const MasmParser *>(Context);

2389 raw_ostream &OS = errs();

2390

2391 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();

2392 SMLoc DiagLoc = Diag.getLoc();

2394 unsigned CppHashBuf =

2395 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);

2396

2397

2398

2400 if (!Parser->SavedDiagHandler && DiagCurBuffer &&

2404 }

2405

2406

2407

2408

2409 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||

2410 DiagBuf != CppHashBuf) {

2411 if (Parser->SavedDiagHandler)

2412 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);

2413 else

2414 Diag.print(nullptr, OS);

2415 return;

2416 }

2417

2418

2419

2420

2421 const std::string &Filename = std::string(Parser->CppHashInfo.Filename);

2422

2423 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);

2424 int CppHashLocLineNo =

2425 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);

2426 int LineNo =

2427 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);

2428

2429 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,

2432

2433 if (Parser->SavedDiagHandler)

2434 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);

2435 else

2436 NewDiag.print(nullptr, OS);

2437}

2438

2439

2440

2442 return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?';

2443}

2444

2445bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,

2448 const std::vectorstd::string &Locals, SMLoc L) {

2449 unsigned NParameters = Parameters.size();

2450 if (NParameters != A.size())

2451 return Error(L, "Wrong number of arguments");

2452 StringMapstd::string LocalSymbols;

2453 std::string Name;

2454 Name.reserve(6);

2455 for (StringRef Local : Locals) {

2456 raw_string_ostream LocalName(Name);

2457 LocalName << "??"

2460 Name.clear();

2461 }

2462

2463 std::optional CurrentQuote;

2464 while (!Body.empty()) {

2465

2466 std::size_t End = Body.size(), Pos = 0;

2467 std::size_t IdentifierPos = End;

2468 for (; Pos != End; ++Pos) {

2469

2470

2471 if (Body[Pos] == '&')

2472 break;

2474 if (!CurrentQuote)

2475 break;

2476 if (IdentifierPos == End)

2477 IdentifierPos = Pos;

2478 } else {

2479 IdentifierPos = End;

2480 }

2481

2482

2483 if (!CurrentQuote) {

2484 if (Body[Pos] == '\'' || Body[Pos] == '"')

2485 CurrentQuote = Body[Pos];

2486 } else if (Body[Pos] == CurrentQuote) {

2487 if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {

2488

2489 ++Pos;

2490 continue;

2491 } else {

2492 CurrentQuote.reset();

2493 }

2494 }

2495 }

2496 if (IdentifierPos != End) {

2497

2498

2499 Pos = IdentifierPos;

2500 IdentifierPos = End;

2501 }

2502

2503

2504 OS << Body.slice(0, Pos);

2505

2506

2507 if (Pos == End)

2508 break;

2509

2510 unsigned I = Pos;

2511 bool InitialAmpersand = (Body[I] == '&');

2512 if (InitialAmpersand) {

2513 ++I;

2514 ++Pos;

2515 }

2517 ++I;

2518

2519 const char *Begin = Body.data() + Pos;

2520 StringRef Argument(Begin, I - Pos);

2521 const std::string ArgumentLower = Argument.lower();

2522 unsigned Index = 0;

2523

2524 for (; Index < NParameters; ++Index)

2525 if (Parameters[Index].Name.equals_insensitive(ArgumentLower))

2526 break;

2527

2528 if (Index == NParameters) {

2529 if (InitialAmpersand)

2530 OS << '&';

2531 auto it = LocalSymbols.find(ArgumentLower);

2532 if (it != LocalSymbols.end())

2533 OS << it->second;

2534 else

2536 Pos = I;

2537 } else {

2538 for (const AsmToken &Token : A[Index]) {

2539

2540

2541

2542

2543

2544

2545

2546 if (Token.getString().front() == '%' && Token.is(AsmToken::Integer))

2547

2548 OS << Token.getIntVal();

2549 else

2550 OS << Token.getString();

2551 }

2552

2554 if (Pos < End && Body[Pos] == '&') {

2555 ++Pos;

2556 }

2557 }

2558

2559 Body = Body.substr(Pos);

2560 }

2561

2562 return false;

2563}

2564

2565bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,

2566 MCAsmMacroArgument &MA,

2568 if (MP && MP->Vararg) {

2569 if (Lexer.isNot(EndTok)) {

2570 SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok);

2571 for (StringRef S : Str) {

2573 }

2574 }

2575 return false;

2576 }

2577

2578 SMLoc StrLoc = Lexer.getLoc(), EndLoc;

2580 const char *StrChar = StrLoc.getPointer() + 1;

2581 const char *EndChar = EndLoc.getPointer() - 1;

2582 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());

2583

2584 Lex();

2585 MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar));

2586 return false;

2587 }

2588

2589 unsigned ParenLevel = 0;

2590

2591 while (true) {

2593 return TokError("unexpected token");

2594

2596 break;

2597

2598

2599

2600 if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0))

2601 break;

2602

2603

2605 ++ParenLevel;

2607 --ParenLevel;

2608

2609

2610 MA.push_back(getTok());

2611 Lex();

2612 }

2613

2614 if (ParenLevel != 0)

2615 return TokError("unbalanced parentheses in argument");

2616

2617 if (MA.empty() && MP) {

2619 return TokError("missing value for required parameter '" + MP->Name +

2620 "'");

2621 } else {

2623 }

2624 }

2625 return false;

2626}

2627

2628

2629bool MasmParser::parseMacroArguments(const MCAsmMacro *M,

2630 MCAsmMacroArguments &A,

2632 const unsigned NParameters = M ? M->Parameters.size() : 0;

2633 bool NamedParametersFound = false;

2634 SmallVector<SMLoc, 4> FALocs;

2635

2636 A.resize(NParameters);

2637 FALocs.resize(NParameters);

2638

2639

2640

2641

2642 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;

2644 SMLoc IDLoc = Lexer.getLoc();

2645 MCAsmMacroParameter FA;

2646

2648 if (parseIdentifier(FA.Name))

2649 return Error(IDLoc, "invalid argument identifier for formal argument");

2650

2652 return TokError("expected '=' after formal parameter identifier");

2653

2654 Lex();

2655

2656 NamedParametersFound = true;

2657 }

2658

2659 if (NamedParametersFound && FA.Name.empty())

2660 return Error(IDLoc, "cannot mix positional and keyword arguments");

2661

2664 assert(M && "expected macro to be defined");

2665 unsigned FAI = 0;

2666 for (FAI = 0; FAI < NParameters; ++FAI)

2667 if (M->Parameters[FAI].Name == FA.Name)

2668 break;

2669

2670 if (FAI >= NParameters) {

2671 return Error(IDLoc, "parameter named '" + FA.Name +

2672 "' does not exist for macro '" + M->Name + "'");

2673 }

2674 PI = FAI;

2675 }

2676 const MCAsmMacroParameter *MP = nullptr;

2677 if (M && PI < NParameters)

2678 MP = &M->Parameters[PI];

2679

2680 SMLoc StrLoc = Lexer.getLoc();

2681 SMLoc EndLoc;

2683 const MCExpr *AbsoluteExp;

2685

2686 Lex();

2687 if (parseExpression(AbsoluteExp, EndLoc))

2688 return false;

2689 if (!AbsoluteExp->evaluateAsAbsolute(Value,

2690 getStreamer().getAssemblerPtr()))

2691 return Error(StrLoc, "expected absolute expression");

2692 const char *StrChar = StrLoc.getPointer();

2693 const char *EndChar = EndLoc.getPointer();

2695 StringRef(StrChar, EndChar - StrChar), Value);

2696 FA.Value.push_back(newToken);

2697 } else if (parseMacroArgument(MP, FA.Value, EndTok)) {

2698 if (M)

2699 return addErrorSuffix(" in '" + M->Name + "' macro");

2700 else

2701 return true;

2702 }

2703

2704 if (!FA.Value.empty()) {

2705 if (A.size() <= PI)

2706 A.resize(PI + 1);

2708

2709 if (FALocs.size() <= PI)

2710 FALocs.resize(PI + 1);

2711

2712 FALocs[PI] = Lexer.getLoc();

2713 }

2714

2715

2716

2717

2718 if (Lexer.is(EndTok)) {

2720 for (unsigned FAI = 0; FAI < NParameters; ++FAI) {

2721 if (A[FAI].empty()) {

2722 if (M->Parameters[FAI].Required) {

2723 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),

2724 "missing value for required parameter "

2725 "'" +

2726 M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");

2728 }

2729

2730 if (M->Parameters[FAI].Value.empty())

2731 A[FAI] = M->Parameters[FAI].Value;

2732 }

2733 }

2735 }

2736

2738 Lex();

2739 }

2740

2741 return TokError("too many positional arguments");

2742}

2743

2744bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,

2746

2747

2749 if (ActiveMacros.size() == MaxNestingDepth) {

2750 std::ostringstream MaxNestingDepthError;

2751 MaxNestingDepthError << "macros cannot be nested more than "

2752 << MaxNestingDepth << " levels deep."

2753 << " Use -asm-macro-max-nesting-depth to increase "

2754 "this limit.";

2755 return TokError(MaxNestingDepthError.str());

2756 }

2757

2758 MCAsmMacroArguments A;

2759 if (parseMacroArguments(M, A, ArgumentEndTok) || parseToken(ArgumentEndTok))

2760 return true;

2761

2762

2763

2764 SmallString<256> Buf;

2765 StringRef Body = M->Body;

2766 raw_svector_ostream OS(Buf);

2767

2768 if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc()))

2769 return true;

2770

2771

2772

2773 OS << "endm\n";

2774

2775 std::unique_ptr Instantiation =

2777

2778

2779

2780 MacroInstantiation *MI = new MacroInstantiation{

2781 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};

2782 ActiveMacros.push_back(MI);

2783

2784 ++NumOfMacroInstantiations;

2785

2786

2789 EndStatementAtEOFStack.push_back(true);

2790 Lex();

2791

2792 return false;

2793}

2794

2795void MasmParser::handleMacroExit() {

2796

2797 EndStatementAtEOFStack.pop_back();

2798 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,

2799 EndStatementAtEOFStack.back());

2800 Lex();

2801

2802

2803 delete ActiveMacros.back();

2804 ActiveMacros.pop_back();

2805}

2806

2807bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) {

2808 if (M->IsFunction)

2809 return Error(NameLoc, "cannot invoke macro procedure as function");

2810

2811 if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name +

2812 "' requires arguments in parentheses") ||

2814 return true;

2815

2816

2817 std::string ExitValue;

2820 ParseStatementInfo Info(&AsmStrRewrites);

2821 bool HasError = parseStatement(Info, nullptr);

2822

2823 if (!HasError && Info.ExitValue) {

2824 ExitValue = std::move(*Info.ExitValue);

2825 break;

2826 }

2827

2828

2829

2830

2831 if (HasError && !hasPendingError() && Lexer.getTok().is(AsmToken::Error))

2832 Lex();

2833

2834

2835 printPendingErrors();

2836

2837

2838 if (HasError && !getLexer().justConsumedEOL())

2839 eatToEndOfStatement();

2840 }

2841

2842

2843

2844 std::unique_ptr MacroValue =

2846

2847

2848

2851 false);

2852 EndStatementAtEOFStack.push_back(false);

2853 Lex();

2854

2855 return false;

2856}

2857

2858

2859

2860

2861bool MasmParser::parseIdentifier(StringRef &Res,

2862 IdentifierPositionKind Position) {

2863

2864

2865

2866

2867

2869 SMLoc PrefixLoc = getLexer().getLoc();

2870

2871

2872

2873 AsmToken nextTok = peekTok(false);

2874

2876 return true;

2877

2878

2880 return true;

2881

2882

2883 Lexer.Lex();

2884

2885 Res =

2886 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);

2887 Lex();

2888 return false;

2889 }

2890

2892 return true;

2893

2894 Res = getTok().getIdentifier();

2895

2896

2897

2898 ExpandKind ExpandNextToken = ExpandMacros;

2899 if (Position == StartOfStatement &&

2900 StringSwitch(Res)

2901 .CaseLower("echo", true)

2902 .CasesLower({"ifdef", "ifndef", "elseifdef", "elseifndef"}, true)

2903 .Default(false)) {

2904 ExpandNextToken = DoNotExpandMacros;

2905 }

2906 Lex(ExpandNextToken);

2907

2908 return false;

2909}

2910

2911

2912

2913

2914

2915

2916bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,

2917 DirectiveKind DirKind, SMLoc NameLoc) {

2918 auto BuiltinIt = BuiltinSymbolMap.find(Name.lower());

2919 if (BuiltinIt != BuiltinSymbolMap.end())

2920 return Error(NameLoc, "cannot redefine a built-in symbol");

2921

2923 if (Var.Name.empty()) {

2924 Var.Name = Name;

2925 }

2926

2927 SMLoc StartLoc = Lexer.getLoc();

2928 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {

2929

2930 std::string Value;

2931 std::string TextItem;

2932 if (!parseTextItem(TextItem)) {

2933 Value += TextItem;

2934

2935

2936 auto parseItem = [&]() -> bool {

2937 if (parseTextItem(TextItem))

2938 return TokError("expected text item");

2939 Value += TextItem;

2940 return false;

2941 };

2942 if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem))

2943 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

2944

2945 if (!Var.IsText || Var.TextValue != Value) {

2946 switch (Var.Redefinable) {

2947 case Variable::NOT_REDEFINABLE:

2948 return Error(getTok().getLoc(), "invalid variable redefinition");

2949 case Variable::WARN_ON_REDEFINITION:

2950 if (Warning(NameLoc, "redefining '" + Name +

2951 "', already defined on the command line")) {

2952 return true;

2953 }

2954 break;

2955 default:

2956 break;

2957 }

2958 }

2959 Var.IsText = true;

2960 Var.TextValue = Value;

2961 Var.Redefinable = Variable::REDEFINABLE;

2962

2963 return false;

2964 }

2965 }

2966 if (DirKind == DK_TEXTEQU)

2967 return TokError("expected in '" + Twine(IDVal) + "' directive");

2968

2969

2970 const MCExpr *Expr;

2971 SMLoc EndLoc;

2972 if (parseExpression(Expr, EndLoc))

2973 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

2974 StringRef ExprAsString = StringRef(

2976

2978 if (!Expr->evaluateAsAbsolute(Value, getStreamer().getAssemblerPtr())) {

2979 if (DirKind == DK_ASSIGN)

2981 StartLoc,

2982 "expected absolute expression; not all symbols have known values",

2983 {StartLoc, EndLoc});

2984

2985

2986 if (!Var.IsText || Var.TextValue != ExprAsString) {

2987 switch (Var.Redefinable) {

2988 case Variable::NOT_REDEFINABLE:

2989 return Error(getTok().getLoc(), "invalid variable redefinition");

2990 case Variable::WARN_ON_REDEFINITION:

2991 if (Warning(NameLoc, "redefining '" + Name +

2992 "', already defined on the command line")) {

2993 return true;

2994 }

2995 break;

2996 default:

2997 break;

2998 }

2999 }

3000

3001 Var.IsText = true;

3002 Var.TextValue = ExprAsString.str();

3003 Var.Redefinable = Variable::REDEFINABLE;

3004

3005 return false;

3006 }

3007

3008 auto *Sym = static_cast<MCSymbolCOFF *>(getContext().parseSymbol(Var.Name));

3009 const MCConstantExpr *PrevValue =

3012 : nullptr;

3013 if (Var.IsText || !PrevValue || PrevValue->getValue() != Value) {

3014 switch (Var.Redefinable) {

3015 case Variable::NOT_REDEFINABLE:

3016 return Error(getTok().getLoc(), "invalid variable redefinition");

3017 case Variable::WARN_ON_REDEFINITION:

3018 if (Warning(NameLoc, "redefining '" + Name +

3019 "', already defined on the command line")) {

3020 return true;

3021 }

3022 break;

3023 default:

3024 break;

3025 }

3026 }

3027

3028 Var.IsText = false;

3029 Var.TextValue.clear();

3030 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE

3031 : Variable::NOT_REDEFINABLE;

3032

3033 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);

3035 Sym->setExternal(false);

3036

3037 return false;

3038}

3039

3040bool MasmParser::parseEscapedString(std::string &Data) {

3042 return true;

3043

3045 char Quote = getTok().getString().front();

3046 StringRef Str = getTok().getStringContents();

3047 Data.reserve(Str.size());

3048 for (size_t i = 0, e = Str.size(); i != e; ++i) {

3049 Data.push_back(Str[i]);

3050 if (Str[i] == Quote) {

3051

3052

3053

3054 if (i + 1 == Str.size())

3055 return Error(getTok().getLoc(), "missing quotation mark in string");

3056 if (Str[i + 1] == Quote)

3057 ++i;

3058 }

3059 }

3060

3061 Lex();

3062 return false;

3063}

3064

3065bool MasmParser::parseAngleBracketString(std::string &Data) {

3066 SMLoc EndLoc, StartLoc = getTok().getLoc();

3068 const char *StartChar = StartLoc.getPointer() + 1;

3069 const char *EndChar = EndLoc.getPointer() - 1;

3070 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());

3071

3072 Lex();

3073

3075 return false;

3076 }

3077 return true;

3078}

3079

3080

3081bool MasmParser::parseTextItem(std::string &Data) {

3082 switch (getTok().getKind()) {

3083 default:

3084 return true;

3086 int64_t Res;

3087 if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))

3088 return true;

3089 Data = std::to_string(Res);

3090 return false;

3091 }

3096 return parseAngleBracketString(Data);

3098

3099 StringRef ID;

3100 SMLoc StartLoc = getTok().getLoc();

3101 if (parseIdentifier(ID))

3102 return true;

3104

3105 bool Expanded = false;

3106 while (true) {

3107

3108 auto BuiltinIt = BuiltinSymbolMap.find(ID.lower());

3109 if (BuiltinIt != BuiltinSymbolMap.end()) {

3110 std::optionalstd::string BuiltinText =

3111 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);

3112 if (!BuiltinText) {

3113

3114 break;

3115 }

3116 Data = std::move(*BuiltinText);

3117 ID = StringRef(Data);

3118 Expanded = true;

3119 continue;

3120 }

3121

3122

3123 auto BuiltinFuncIt = BuiltinFunctionMap.find(ID.lower());

3124 if (BuiltinFuncIt != BuiltinFunctionMap.end()) {

3125 Data.clear();

3126 if (evaluateBuiltinMacroFunction(BuiltinFuncIt->getValue(), ID, Data)) {

3127 return true;

3128 }

3129 ID = StringRef(Data);

3130 Expanded = true;

3131 continue;

3132 }

3133

3134

3135 auto VarIt = Variables.find(ID.lower());

3136 if (VarIt != Variables.end()) {

3137 const Variable &Var = VarIt->getValue();

3138 if (!Var.IsText) {

3139

3140 break;

3141 }

3142 Data = Var.TextValue;

3143 ID = StringRef(Data);

3144 Expanded = true;

3145 continue;

3146 }

3147

3148 break;

3149 }

3150

3151 if (!Expanded) {

3152

3153

3155 return true;

3156 }

3157 return false;

3158 }

3159 }

3161}

3162

3163

3164

3165bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {

3166 auto parseOp = [&]() -> bool {

3167 std::string Data;

3168 if (checkForValidSection() || parseEscapedString(Data))

3169 return true;

3170 getStreamer().emitBytes(Data);

3171 if (ZeroTerminated)

3172 getStreamer().emitBytes(StringRef("\0", 1));

3173 return false;

3174 };

3175

3176 if (parseMany(parseOp))

3177 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

3178 return false;

3179}

3180

3181bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) {

3182

3184 assert(Size <= 8 && "Invalid size");

3185 int64_t IntValue = MCE->getValue();

3187 return Error(MCE->getLoc(), "out of range literal value");

3188 getStreamer().emitIntValue(IntValue, Size);

3189 } else {

3192

3193 getStreamer().emitIntValue(0, Size);

3194 } else {

3195 getStreamer().emitValue(Value, Size, Value->getLoc());

3196 }

3197 }

3198 return false;

3199}

3200

3201bool MasmParser::parseScalarInitializer(unsigned Size,

3202 SmallVectorImpl<const MCExpr *> &Values,

3203 unsigned StringPadLength) {

3205 std::string Value;

3206 if (parseEscapedString(Value))

3207 return true;

3208

3209 for (const unsigned char CharVal : Value)

3211

3212

3213 for (size_t i = Value.size(); i < StringPadLength; ++i)

3215 } else {

3216 const MCExpr *Value;

3217 if (parseExpression(Value))

3218 return true;

3220 getTok().getString().equals_insensitive("dup")) {

3221 Lex();

3223 if (!MCE)

3225 "cannot repeat value a non-constant number of times");

3226 const int64_t Repetitions = MCE->getValue();

3227 if (Repetitions < 0)

3229 "cannot repeat value a negative number of times");

3230

3233 "parentheses required for 'dup' contents") ||

3234 parseScalarInstList(Size, DuplicatedValues) || parseRParen())

3235 return true;

3236

3237 for (int i = 0; i < Repetitions; ++i)

3238 Values.append(DuplicatedValues.begin(), DuplicatedValues.end());

3239 } else {

3241 }

3242 }

3243 return false;

3244}

3245

3246bool MasmParser::parseScalarInstList(unsigned Size,

3247 SmallVectorImpl<const MCExpr *> &Values,

3249 while (getTok().isNot(EndToken) &&

3252 parseScalarInitializer(Size, Values);

3253

3254

3256 break;

3258 }

3259 return false;

3260}

3261

3262bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {

3264 if (checkForValidSection() || parseScalarInstList(Size, Values))

3265 return true;

3266

3267 for (const auto *Value : Values) {

3269 }

3271 *Count = Values.size();

3272 return false;

3273}

3274

3275

3276bool MasmParser::addIntegralField(StringRef Name, unsigned Size) {

3277 StructInfo &Struct = StructInProgress.back();

3278 FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size);

3279 IntFieldInfo &IntInfo = Field.Contents.IntInfo;

3280

3282

3283 if (parseScalarInstList(Size, IntInfo.Values))

3284 return true;

3285

3286 Field.SizeOf = Field.Type * IntInfo.Values.size();

3287 Field.LengthOf = IntInfo.Values.size();

3289 if (Struct.IsUnion) {

3290 Struct.NextOffset = FieldEnd;

3291 }

3292 Struct.Size = std::max(Struct.Size, FieldEnd);

3293 return false;

3294}

3295

3296

3297

3298bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {

3299 if (StructInProgress.empty()) {

3300

3301 if (emitIntegralValues(Size))

3302 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

3303 } else if (addIntegralField("", Size)) {

3304 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

3305 }

3306

3307 return false;

3308}

3309

3310

3311

3312bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size,

3313 StringRef Name, SMLoc NameLoc) {

3314 if (StructInProgress.empty()) {

3315

3317 getStreamer().emitLabel(Sym);

3319 if (emitIntegralValues(Size, &Count))

3320 return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");

3321

3322 AsmTypeInfo Type;

3327 KnownType[Name.lower()] = Type;

3328 } else if (addIntegralField(Name, Size)) {

3329 return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");

3330 }

3331

3332 return false;

3333}

3334

3335bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {

3336

3337

3338 bool IsNeg = false;

3339 SMLoc SignLoc;

3341 SignLoc = getLexer().getLoc();

3342 Lexer.Lex();

3343 IsNeg = true;

3345 SignLoc = getLexer().getLoc();

3346 Lexer.Lex();

3347 }

3348

3350 return TokError(Lexer.getErr());

3353 return TokError("unexpected token in directive");

3354

3355

3357 StringRef IDVal = getTok().getString();

3365 else

3366 return TokError("invalid floating point literal");

3368

3369

3370 unsigned SizeInBits = Value.getSizeInBits(Semantics);

3371 if (SizeInBits != (IDVal.size() << 2))

3372 return TokError("invalid floating point literal");

3373

3374

3375 Lex();

3376

3377 Res = APInt(SizeInBits, IDVal, 16);

3379 return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");

3380 return false;

3382 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)

3383 .takeError())) {

3384 return TokError("invalid floating point literal");

3385 }

3386 if (IsNeg)

3387 Value.changeSign();

3388

3389

3390 Lex();

3391

3392 Res = Value.bitcastToAPInt();

3393

3394 return false;

3395}

3396

3397bool MasmParser::parseRealInstList(const fltSemantics &Semantics,

3398 SmallVectorImpl &ValuesAsInt,

3400 while (getTok().isNot(EndToken) ||

3403 const AsmToken NextTok = peekTok();

3406 const MCExpr *Value;

3408 return true;

3410 if (!MCE)

3412 "cannot repeat value a non-constant number of times");

3413 const int64_t Repetitions = MCE->getValue();

3414 if (Repetitions < 0)

3416 "cannot repeat value a negative number of times");

3417

3420 "parentheses required for 'dup' contents") ||

3421 parseRealInstList(Semantics, DuplicatedValues) || parseRParen())

3422 return true;

3423

3424 for (int i = 0; i < Repetitions; ++i)

3425 ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end());

3426 } else {

3427 APInt AsInt;

3428 if (parseRealValue(Semantics, AsInt))

3429 return true;

3431 }

3432

3433

3435 break;

3437 }

3438

3439 return false;

3440}

3441

3442

3443bool MasmParser::emitRealValues(const fltSemantics &Semantics,

3444 unsigned *Count) {

3445 if (checkForValidSection())

3446 return true;

3447

3449 if (parseRealInstList(Semantics, ValuesAsInt))

3450 return true;

3451

3452 for (const APInt &AsInt : ValuesAsInt) {

3453 getStreamer().emitIntValue(AsInt);

3454 }

3456 *Count = ValuesAsInt.size();

3457 return false;

3458}

3459

3460

3461bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,

3462 size_t Size) {

3463 StructInfo &Struct = StructInProgress.back();

3464 FieldInfo &Field = Struct.addField(Name, FT_REAL, Size);

3465 RealFieldInfo &RealInfo = Field.Contents.RealInfo;

3466

3467 Field.SizeOf = 0;

3468

3469 if (parseRealInstList(Semantics, RealInfo.AsIntValues))

3470 return true;

3471

3472 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;

3473 Field.LengthOf = RealInfo.AsIntValues.size();

3475

3477 if (Struct.IsUnion) {

3478 Struct.NextOffset = FieldEnd;

3479 }

3480 Struct.Size = std::max(Struct.Size, FieldEnd);

3481 return false;

3482}

3483

3484

3485

3486bool MasmParser::parseDirectiveRealValue(StringRef IDVal,

3487 const fltSemantics &Semantics,

3488 size_t Size) {

3489 if (StructInProgress.empty()) {

3490

3491 if (emitRealValues(Semantics))

3492 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

3493 } else if (addRealField("", Semantics, Size)) {

3494 return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");

3495 }

3496 return false;

3497}

3498

3499

3500

3501bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,

3502 const fltSemantics &Semantics,

3503 unsigned Size, StringRef Name,

3504 SMLoc NameLoc) {

3505 if (StructInProgress.empty()) {

3506

3508 getStreamer().emitLabel(Sym);

3510 if (emitRealValues(Semantics, &Count))

3511 return addErrorSuffix(" in '" + TypeName + "' directive");

3512

3513 AsmTypeInfo Type;

3518 KnownType[Name.lower()] = Type;

3519 } else if (addRealField(Name, Semantics, Size)) {

3520 return addErrorSuffix(" in '" + TypeName + "' directive");

3521 }

3522 return false;

3523}

3524

3525bool MasmParser::parseOptionalAngleBracketOpen() {

3526 const AsmToken Tok = getTok();

3528 AngleBracketDepth++;

3530 return true;

3532 AngleBracketDepth++;

3534 return true;

3536 AngleBracketDepth++;

3537 return true;

3538 }

3539

3540 return false;

3541}

3542

3543bool MasmParser::parseAngleBracketClose(const Twine &Msg) {

3544 const AsmToken Tok = getTok();

3548 return true;

3549 }

3550 AngleBracketDepth--;

3551 return false;

3552}

3553

3554bool MasmParser::parseFieldInitializer(const FieldInfo &Field,

3555 const IntFieldInfo &Contents,

3556 FieldInitializer &Initializer) {

3557 SMLoc Loc = getTok().getLoc();

3558

3561 if (Field.LengthOf == 1 && Field.Type > 1)

3562 return Error(Loc, "Cannot initialize scalar field with array value");

3565 return true;

3566 } else if (parseOptionalAngleBracketOpen()) {

3567 if (Field.LengthOf == 1 && Field.Type > 1)

3568 return Error(Loc, "Cannot initialize scalar field with array value");

3570 parseAngleBracketClose())

3571 return true;

3572 } else if (Field.LengthOf > 1 && Field.Type > 1) {

3573 return Error(Loc, "Cannot initialize array field with scalar value");

3574 } else if (parseScalarInitializer(Field.Type, Values,

3575 Field.LengthOf)) {

3576 return true;

3577 }

3578

3579 if (Values.size() > Field.LengthOf) {

3580 return Error(Loc, "Initializer too long for field; expected at most " +

3581 std::to_string(Field.LengthOf) + " elements, got " +

3582 std::to_string(Values.size()));

3583 }

3584

3585 Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end());

3586

3587 Initializer = FieldInitializer(std::move(Values));

3588 return false;

3589}

3590

3591bool MasmParser::parseFieldInitializer(const FieldInfo &Field,

3592 const RealFieldInfo &Contents,

3593 FieldInitializer &Initializer) {

3594 const fltSemantics *Semantics;

3595 switch (Field.Type) {

3596 case 4:

3597 Semantics = &APFloat::IEEEsingle();

3598 break;

3599 case 8:

3600 Semantics = &APFloat::IEEEdouble();

3601 break;

3602 case 10:

3603 Semantics = &APFloat::x87DoubleExtended();

3604 break;

3605 default:

3607 }

3608

3609 SMLoc Loc = getTok().getLoc();

3610

3613 if (Field.LengthOf == 1)

3614 return Error(Loc, "Cannot initialize scalar field with array value");

3615 if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||

3617 return true;

3618 } else if (parseOptionalAngleBracketOpen()) {

3619 if (Field.LengthOf == 1)

3620 return Error(Loc, "Cannot initialize scalar field with array value");

3621 if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||

3622 parseAngleBracketClose())

3623 return true;

3624 } else if (Field.LengthOf > 1) {

3625 return Error(Loc, "Cannot initialize array field with scalar value");

3626 } else {

3628 if (parseRealValue(*Semantics, AsIntValues.back()))

3629 return true;

3630 }

3631

3632 if (AsIntValues.size() > Field.LengthOf) {

3633 return Error(Loc, "Initializer too long for field; expected at most " +

3634 std::to_string(Field.LengthOf) + " elements, got " +

3635 std::to_string(AsIntValues.size()));

3636 }

3637

3638 AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(),

3639 Contents.AsIntValues.end());

3640

3641 Initializer = FieldInitializer(std::move(AsIntValues));

3642 return false;

3643}

3644

3645bool MasmParser::parseFieldInitializer(const FieldInfo &Field,

3646 const StructFieldInfo &Contents,

3647 FieldInitializer &Initializer) {

3648 SMLoc Loc = getTok().getLoc();

3649

3650 std::vector Initializers;

3651 if (Field.LengthOf > 1) {

3653 if (parseStructInstList(Contents.Structure, Initializers,

3656 return true;

3657 } else if (parseOptionalAngleBracketOpen()) {

3658 if (parseStructInstList(Contents.Structure, Initializers,

3660 parseAngleBracketClose())

3661 return true;

3662 } else {

3663 return Error(Loc, "Cannot initialize array field with scalar value");

3664 }

3665 } else {

3666 Initializers.emplace_back();

3667 if (parseStructInitializer(Contents.Structure, Initializers.back()))

3668 return true;

3669 }

3670

3671 if (Initializers.size() > Field.LengthOf) {

3672 return Error(Loc, "Initializer too long for field; expected at most " +

3673 std::to_string(Field.LengthOf) + " elements, got " +

3674 std::to_string(Initializers.size()));

3675 }

3676

3678 Initializers.size()));

3679

3680 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);

3681 return false;

3682}

3683

3684bool MasmParser::parseFieldInitializer(const FieldInfo &Field,

3685 FieldInitializer &Initializer) {

3686 switch (Field.Contents.FT) {

3687 case FT_INTEGRAL:

3688 return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer);

3689 case FT_REAL:

3690 return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer);

3691 case FT_STRUCT:

3692 return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer);

3693 }

3695}

3696

3697bool MasmParser::parseStructInitializer(const StructInfo &Structure,

3698 StructInitializer &Initializer) {

3699 const AsmToken FirstToken = getTok();

3700

3701 std::optionalAsmToken::TokenKind EndToken;

3704 } else if (parseOptionalAngleBracketOpen()) {

3706 AngleBracketDepth++;

3708 FirstToken.getString() == "?") {

3709

3711 return true;

3712 } else {

3713 return Error(FirstToken.getLoc(), "Expected struct initializer");

3714 }

3715

3716 auto &FieldInitializers = Initializer.FieldInitializers;

3717 size_t FieldIndex = 0;

3718 if (EndToken) {

3719

3720 while (getTok().isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {

3721 const FieldInfo &Field = Structure.Fields[FieldIndex++];

3723

3724

3725 FieldInitializers.push_back(Field.Contents);

3727 continue;

3728 }

3729 FieldInitializers.emplace_back(Field.Contents.FT);

3730 if (parseFieldInitializer(Field, FieldInitializers.back()))

3731 return true;

3732

3733

3734 SMLoc CommaLoc = getTok().getLoc();

3736 break;

3737 if (FieldIndex == Structure.Fields.size())

3738 return Error(CommaLoc, "'" + Structure.Name +

3739 "' initializer initializes too many fields");

3741 }

3742 }

3743

3745 FieldInitializers.push_back(Field.Contents);

3746

3747 if (EndToken) {

3749 return parseAngleBracketClose();

3750

3751 return parseToken(*EndToken);

3752 }

3753

3754 return false;

3755}

3756

3757bool MasmParser::parseStructInstList(

3758 const StructInfo &Structure, std::vector &Initializers,

3760 while (getTok().isNot(EndToken) ||

3763 const AsmToken NextTok = peekTok();

3766 const MCExpr *Value;

3768 return true;

3770 if (!MCE)

3772 "cannot repeat value a non-constant number of times");

3773 const int64_t Repetitions = MCE->getValue();

3774 if (Repetitions < 0)

3776 "cannot repeat value a negative number of times");

3777

3778 std::vector DuplicatedValues;

3780 "parentheses required for 'dup' contents") ||

3781 parseStructInstList(Structure, DuplicatedValues) || parseRParen())

3782 return true;

3783

3784 for (int i = 0; i < Repetitions; ++i)

3786 } else {

3787 Initializers.emplace_back();

3788 if (parseStructInitializer(Structure, Initializers.back()))

3789 return true;

3790 }

3791

3792

3794 break;

3796 }

3797

3798 return false;

3799}

3800

3801bool MasmParser::emitFieldValue(const FieldInfo &Field,

3802 const IntFieldInfo &Contents) {

3803

3804 for (const MCExpr *Value : Contents.Values) {

3805 if (emitIntValue(Value, Field.Type))

3806 return true;

3807 }

3808 return false;

3809}

3810

3811bool MasmParser::emitFieldValue(const FieldInfo &Field,

3812 const RealFieldInfo &Contents) {

3813 for (const APInt &AsInt : Contents.AsIntValues) {

3816 }

3817 return false;

3818}

3819

3820bool MasmParser::emitFieldValue(const FieldInfo &Field,

3821 const StructFieldInfo &Contents) {

3822 for (const auto &Initializer : Contents.Initializers) {

3824 for (const auto &SubField : Contents.Structure.Fields) {

3825 getStreamer().emitZeros(SubField.Offset - Offset);

3826 Offset = SubField.Offset + SubField.SizeOf;

3827 emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);

3828 }

3829 }

3830 return false;

3831}

3832

3833bool MasmParser::emitFieldValue(const FieldInfo &Field) {

3834 switch (Field.Contents.FT) {

3835 case FT_INTEGRAL:

3836 return emitFieldValue(Field, Field.Contents.IntInfo);

3837 case FT_REAL:

3838 return emitFieldValue(Field, Field.Contents.RealInfo);

3839 case FT_STRUCT:

3840 return emitFieldValue(Field, Field.Contents.StructInfo);

3841 }

3843}

3844

3845bool MasmParser::emitFieldInitializer(const FieldInfo &Field,

3846 const IntFieldInfo &Contents,

3847 const IntFieldInfo &Initializer) {

3848 for (const auto &Value : Initializer.Values) {

3849 if (emitIntValue(Value, Field.Type))

3850 return true;

3851 }

3852

3853 for (const auto &Value :

3854 llvm::drop_begin(Contents.Values, Initializer.Values.size())) {

3855 if (emitIntValue(Value, Field.Type))

3856 return true;

3857 }

3858 return false;

3859}

3860

3861bool MasmParser::emitFieldInitializer(const FieldInfo &Field,

3862 const RealFieldInfo &Contents,

3863 const RealFieldInfo &Initializer) {

3864 for (const auto &AsInt : Initializer.AsIntValues) {

3867 }

3868

3869 for (const auto &AsInt :

3870 llvm::drop_begin(Contents.AsIntValues, Initializer.AsIntValues.size())) {

3873 }

3874 return false;

3875}

3876

3877bool MasmParser::emitFieldInitializer(const FieldInfo &Field,

3878 const StructFieldInfo &Contents,

3879 const StructFieldInfo &Initializer) {

3880 for (const auto &Init : Initializer.Initializers) {

3881 if (emitStructInitializer(Contents.Structure, Init))

3882 return true;

3883 }

3884

3885 for (const auto &Init : llvm::drop_begin(Contents.Initializers,

3886 Initializer.Initializers.size())) {

3887 if (emitStructInitializer(Contents.Structure, Init))

3888 return true;

3889 }

3890 return false;

3891}

3892

3893bool MasmParser::emitFieldInitializer(const FieldInfo &Field,

3894 const FieldInitializer &Initializer) {

3895 switch (Field.Contents.FT) {

3896 case FT_INTEGRAL:

3897 return emitFieldInitializer(Field, Field.Contents.IntInfo,

3898 Initializer.IntInfo);

3899 case FT_REAL:

3900 return emitFieldInitializer(Field, Field.Contents.RealInfo,

3901 Initializer.RealInfo);

3902 case FT_STRUCT:

3903 return emitFieldInitializer(Field, Field.Contents.StructInfo,

3904 Initializer.StructInfo);

3905 }

3907}

3908

3909bool MasmParser::emitStructInitializer(const StructInfo &Structure,

3910 const StructInitializer &Initializer) {

3911 if (!Structure.Initializable)

3912 return Error(getLexer().getLoc(),

3913 "cannot initialize a value of type '" + Structure.Name +

3914 "'; 'org' was used in the type's declaration");

3916 for (const auto &Init : Initializer.FieldInitializers) {

3917 const auto &Field = Structure.Fields[Index++];

3920 if (emitFieldInitializer(Field, Init))

3921 return true;

3922 }

3923

3925 Structure.Fields, Initializer.FieldInitializers.size())) {

3928 if (emitFieldValue(Field))

3929 return true;

3930 }

3931

3932 if (Offset != Structure.Size)

3933 getStreamer().emitZeros(Structure.Size - Offset);

3934 return false;

3935}

3936

3937

3938bool MasmParser::emitStructValues(const StructInfo &Structure,

3939 unsigned *Count) {

3940 std::vector Initializers;

3941 if (parseStructInstList(Structure, Initializers))

3942 return true;

3943

3944 for (const auto &Initializer : Initializers) {

3945 if (emitStructInitializer(Structure, Initializer))

3946 return true;

3947 }

3948

3950 *Count = Initializers.size();

3951 return false;

3952}

3953

3954

3955bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) {

3956 StructInfo &OwningStruct = StructInProgress.back();

3957 FieldInfo &Field =

3958 OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize);

3959 StructFieldInfo &StructInfo = Field.Contents.StructInfo;

3960

3961 StructInfo.Structure = Structure;

3962 Field.Type = Structure.Size;

3963

3964 if (parseStructInstList(Structure, StructInfo.Initializers))

3965 return true;

3966

3967 Field.LengthOf = StructInfo.Initializers.size();

3969

3971 if (!OwningStruct.IsUnion) {

3972 OwningStruct.NextOffset = FieldEnd;

3973 }

3974 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);

3975

3976 return false;

3977}

3978

3979

3980

3981

3982bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure,

3983 StringRef Directive, SMLoc DirLoc) {

3984 if (StructInProgress.empty()) {

3985 if (emitStructValues(Structure))

3986 return true;

3987 } else if (addStructField("", Structure)) {

3988 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");

3989 }

3990

3991 return false;

3992}

3993

3994

3995

3996bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure,

3997 StringRef Directive,

3998 SMLoc DirLoc, StringRef Name) {

3999 if (StructInProgress.empty()) {

4000

4002 getStreamer().emitLabel(Sym);

4004 if (emitStructValues(Structure, &Count))

4005 return true;

4006 AsmTypeInfo Type;

4007 Type.Name = Structure.Name;

4008 Type.Size = Structure.Size * Count;

4009 Type.ElementSize = Structure.Size;

4011 KnownType[Name.lower()] = Type;

4012 } else if (addStructField(Name, Structure)) {

4013 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");

4014 }

4015

4016 return false;

4017}

4018

4019

4020

4021

4022

4023

4024

4025bool MasmParser::parseDirectiveStruct(StringRef Directive,

4026 DirectiveKind DirKind, StringRef Name,

4027 SMLoc NameLoc) {

4028

4029

4030 AsmToken NextTok = getTok();

4031 int64_t AlignmentValue = 1;

4034 parseAbsoluteExpression(AlignmentValue)) {

4035 return addErrorSuffix(" in alignment value for '" + Twine(Directive) +

4036 "' directive");

4037 }

4039 return Error(NextTok.getLoc(), "alignment must be a power of two; was " +

4040 std::to_string(AlignmentValue));

4041 }

4042

4044 SMLoc QualifierLoc;

4046 QualifierLoc = getTok().getLoc();

4047 if (parseIdentifier(Qualifier))

4048 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");

4049 if (Qualifier.equals_insensitive("nonunique"))

4050 return Error(QualifierLoc, "Unrecognized qualifier for '" +

4051 Twine(Directive) +

4052 "' directive; expected none or NONUNIQUE");

4053 }

4054

4055 if (parseEOL())

4056 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");

4057

4058 StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue);

4059 return false;

4060}

4061

4062

4063

4064

4065

4066bool MasmParser::parseDirectiveNestedStruct(StringRef Directive,

4067 DirectiveKind DirKind) {

4068 if (StructInProgress.empty())

4069 return TokError("missing name in top-level '" + Twine(Directive) +

4070 "' directive");

4071

4072 StringRef Name;

4074 Name = getTok().getIdentifier();

4076 }

4077 if (parseEOL())

4078 return addErrorSuffix(" in '" + Twine(Directive) + "' directive");

4079

4080

4081

4082 StructInProgress.reserve(StructInProgress.size() + 1);

4083 StructInProgress.emplace_back(Name, DirKind == DK_UNION,

4084 StructInProgress.back().Alignment);

4085 return false;

4086}

4087

4088bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {

4089 if (StructInProgress.empty())

4090 return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION");

4091 if (StructInProgress.size() > 1)

4092 return Error(NameLoc, "unexpected name in nested ENDS directive");

4093 if (StructInProgress.back().Name.compare_insensitive(Name))

4094 return Error(NameLoc, "mismatched name in ENDS directive; expected '" +

4095 StructInProgress.back().Name + "'");

4096 StructInfo Structure = StructInProgress.pop_back_val();

4097

4098

4100 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));

4101 Structs[Name.lower()] = Structure;

4102

4103 if (parseEOL())

4104 return addErrorSuffix(" in ENDS directive");

4105

4106 return false;

4107}

4108

4109bool MasmParser::parseDirectiveNestedEnds() {

4110 if (StructInProgress.empty())

4111 return TokError("ENDS directive without matching STRUC/STRUCT/UNION");

4112 if (StructInProgress.size() == 1)

4113 return TokError("missing name in top-level ENDS directive");

4114

4115 if (parseEOL())

4116 return addErrorSuffix(" in nested ENDS directive");

4117

4118 StructInfo Structure = StructInProgress.pop_back_val();

4119

4120 Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);

4121

4122 StructInfo &ParentStruct = StructInProgress.back();

4123 if (Structure.Name.empty()) {

4124

4125

4126 const size_t OldFields = ParentStruct.Fields.size();

4127 ParentStruct.Fields.insert(

4128 ParentStruct.Fields.end(),

4129 std::make_move_iterator(Structure.Fields.begin()),

4130 std::make_move_iterator(Structure.Fields.end()));

4131 for (const auto &FieldByName : Structure.FieldsByName) {

4132 ParentStruct.FieldsByName[FieldByName.getKey()] =

4133 FieldByName.getValue() + OldFields;

4134 }

4135

4136 unsigned FirstFieldOffset = 0;

4137 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {

4139 ParentStruct.NextOffset,

4140 std::min(ParentStruct.Alignment, Structure.AlignmentSize));

4141 }

4142

4143 if (ParentStruct.IsUnion) {

4144 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);

4145 } else {

4148

4149 const unsigned StructureEnd = FirstFieldOffset + Structure.Size;

4150 if (!ParentStruct.IsUnion) {

4151 ParentStruct.NextOffset = StructureEnd;

4152 }

4153 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);

4154 }

4155 } else {

4156 FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,

4157 Structure.AlignmentSize);

4158 StructFieldInfo &StructInfo = Field.Contents.StructInfo;

4159 Field.Type = Structure.Size;

4160 Field.LengthOf = 1;

4161 Field.SizeOf = Structure.Size;

4162

4164 if (!ParentStruct.IsUnion) {

4165 ParentStruct.NextOffset = StructureEnd;

4166 }

4167 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);

4168

4169 StructInfo.Structure = Structure;

4170 StructInfo.Initializers.emplace_back();

4171 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;

4172 for (const auto &SubField : Structure.Fields) {

4173 FieldInitializers.push_back(SubField.Contents);

4174 }

4175 }

4176

4177 return false;

4178}

4179

4180

4181

4182bool MasmParser::parseDirectiveOrg() {

4183 const MCExpr *Offset;

4184 SMLoc OffsetLoc = Lexer.getLoc();

4185 if (checkForValidSection() || parseExpression(Offset))

4186 return true;

4187 if (parseEOL())

4188 return addErrorSuffix(" in 'org' directive");

4189

4190 if (StructInProgress.empty()) {

4191

4192 if (checkForValidSection())

4193 return addErrorSuffix(" in 'org' directive");

4194

4195 getStreamer().emitValueToOffset(Offset, 0, OffsetLoc);

4196 } else {

4197

4198 StructInfo &Structure = StructInProgress.back();

4199 int64_t OffsetRes;

4200 if (Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))

4201 return Error(OffsetLoc,

4202 "expected absolute expression in 'org' directive");

4203 if (OffsetRes < 0)

4205 OffsetLoc,

4206 "expected non-negative value in struct's 'org' directive; was " +

4207 std::to_string(OffsetRes));

4208 Structure.NextOffset = static_cast<unsigned>(OffsetRes);

4209

4210

4211 Structure.Initializable = false;

4212 }

4213

4214 return false;

4215}

4216

4217bool MasmParser::emitAlignTo(int64_t Alignment) {

4218 if (StructInProgress.empty()) {

4219

4220 if (checkForValidSection())

4221 return true;

4222

4223

4224

4225 const MCSection *Section = getStreamer().getCurrentSectionOnly();

4227 getStreamer().emitCodeAlignment(Align(Alignment),

4228 &getTargetParser().getSTI(),

4229 0);

4230 } else {

4231

4232 getStreamer().emitValueToAlignment(Align(Alignment), 0,

4233 1,

4234 0);

4235 }

4236 } else {

4237

4238 StructInfo &Structure = StructInProgress.back();

4239 Structure.NextOffset = llvm::alignTo(Structure.NextOffset, Alignment);

4240 }

4241

4242 return false;

4243}

4244

4245

4246

4247bool MasmParser::parseDirectiveAlign() {

4248 SMLoc AlignmentLoc = getLexer().getLoc();

4249 int64_t Alignment;

4250

4251

4253 return Warning(AlignmentLoc,

4254 "align directive with no operand is ignored") &&

4255 parseEOL();

4256 }

4257 if (parseAbsoluteExpression(Alignment) || parseEOL())

4258 return addErrorSuffix(" in align directive");

4259

4260

4261 bool ReturnVal = false;

4262

4263

4264

4265 if (Alignment == 0)

4266 Alignment = 1;

4268 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2; was " +

4269 std::to_string(Alignment));

4270

4271 if (emitAlignTo(Alignment))

4272 ReturnVal |= addErrorSuffix(" in align directive");

4273

4274 return ReturnVal;

4275}

4276

4277

4278

4279bool MasmParser::parseDirectiveEven() {

4280 if (parseEOL() || emitAlignTo(2))

4281 return addErrorSuffix(" in even directive");

4282

4283 return false;

4284}

4285

4286

4287

4288

4289

4290

4291

4292bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {

4296 return Error(Lexer.getLoc(),

4297 "Vararg parameter '" + Parameters.back().Name +

4298 "' should be last in the list of parameters");

4299

4301 if (parseIdentifier(Parameter.Name))

4302 return TokError("expected identifier in 'macro' directive");

4303

4304

4305 for (const MCAsmMacroParameter& CurrParam : Parameters)

4306 if (CurrParam.Name.equals_insensitive(Parameter.Name))

4307 return TokError("macro '" + Name + "' has multiple parameters"

4308 " named '" + Parameter.Name + "'");

4309

4311 Lex();

4312

4314

4315 SMLoc ParamLoc;

4316

4317 ParamLoc = Lexer.getLoc();

4318 if (parseMacroArgument(nullptr, Parameter.Value))

4319 return true;

4320 } else {

4321 SMLoc QualLoc;

4323

4324 QualLoc = Lexer.getLoc();

4325 if (parseIdentifier(Qualifier))

4326 return Error(QualLoc, "missing parameter qualifier for "

4327 "'" +

4328 Parameter.Name + "' in macro '" + Name +

4329 "'");

4330

4331 if (Qualifier.equals_insensitive("req"))

4333 else if (Qualifier.equals_insensitive("vararg"))

4335 else

4336 return Error(QualLoc,

4337 Qualifier + " is not a valid parameter qualifier for '" +

4338 Parameter.Name + "' in macro '" + Name + "'");

4339 }

4340 }

4341

4342 Parameters.push_back(std::move(Parameter));

4343

4345 Lex();

4346 }

4347

4348

4349 Lexer.Lex();

4350

4351 std::vectorstd::string Locals;

4353 getTok().getIdentifier().equals_insensitive("local")) {

4354 Lex();

4355

4356 StringRef ID;

4357 while (true) {

4358 if (parseIdentifier(ID))

4359 return true;

4360 Locals.push_back(ID.lower());

4361

4362

4364 break;

4366 }

4367 }

4368

4369

4370 AsmToken EndToken, StartToken = getTok();

4371 unsigned MacroDepth = 0;

4372 bool IsMacroFunction = false;

4373

4374 while (true) {

4375

4377 Lexer.Lex();

4378 }

4379

4380

4382 return Error(NameLoc, "no matching 'endm' in definition");

4383

4384

4385

4387 if (getTok().getIdentifier().equals_insensitive("endm")) {

4388 if (MacroDepth == 0) {

4389 EndToken = getTok();

4390 Lexer.Lex();

4392 return TokError("unexpected token in '" + EndToken.getIdentifier() +

4393 "' directive");

4394 break;

4395 } else {

4396

4397 --MacroDepth;

4398 }

4399 } else if (getTok().getIdentifier().equals_insensitive("exitm")) {

4401 IsMacroFunction = true;

4402 }

4403 } else if (isMacroLikeDirective()) {

4404

4405

4406 ++MacroDepth;

4407 }

4408 }

4409

4410

4411 eatToEndOfStatement();

4412 }

4413

4415 return Error(NameLoc, "macro '" + Name + "' is already defined");

4416 }

4417

4420 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);

4421 MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals),

4422 IsMacroFunction);

4426 return false;

4427}

4428

4429

4430

4431bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,

4432 StringRef Directive,

4433 std::string &Value) {

4434 SMLoc EndLoc = getTok().getLoc();

4436 return Error(EndLoc,

4437 "unable to parse text item in '" + Directive + "' directive");

4438 eatToEndOfStatement();

4439

4440 if (!isInsideMacroInstantiation())

4441 return TokError("unexpected '" + Directive + "' in file, "

4442 "no current macro definition");

4443

4444

4445 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {

4446 TheCondState = TheCondStack.back();

4447 TheCondStack.pop_back();

4448 }

4449

4450 handleMacroExit();

4451 return false;

4452}

4453

4454

4455

4456bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {

4458 return TokError("unexpected token in '" + Directive + "' directive");

4459

4460

4461

4462 if (isInsideMacroInstantiation()) {

4463 handleMacroExit();

4464 return false;

4465 }

4466

4467

4468

4469 return TokError("unexpected '" + Directive + "' in file, "

4470 "no current macro definition");

4471}

4472

4473

4474

4475bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {

4476 StringRef Name;

4477 while (true) {

4478 SMLoc NameLoc;

4479 if (parseTokenLoc(NameLoc) ||

4480 check(parseIdentifier(Name), NameLoc,

4481 "expected identifier in 'purge' directive"))

4482 return true;

4483

4485 << "Un-defining macro: " << Name << "\n");

4487 return Error(NameLoc, "macro '" + Name + "' is not defined");

4489

4491 break;

4493 }

4494

4495 return false;

4496}

4497

4498bool MasmParser::parseDirectiveExtern() {

4499

4500 auto parseOp = [&]() -> bool {

4502 SMLoc NameLoc = getTok().getLoc();

4504 return Error(NameLoc, "expected name");

4506 return true;

4507

4509 SMLoc TypeLoc = getTok().getLoc();

4510 if (parseIdentifier(TypeName))

4511 return Error(TypeLoc, "expected type");

4512 if (TypeName.equals_insensitive("proc")) {

4513 AsmTypeInfo Type;

4514 if (lookUpType(TypeName, Type))

4515 return Error(TypeLoc, "unrecognized type");

4517 }

4518

4519 static_cast<MCSymbolCOFF *>(Sym)->setExternal(true);

4520 getStreamer().emitSymbolAttribute(Sym, MCSA_Extern);

4521

4522 return false;

4523 };

4524

4525 if (parseMany(parseOp))

4526 return addErrorSuffix(" in directive 'extern'");

4527 return false;

4528}

4529

4530

4531

4532bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {

4533 auto parseOp = [&]() -> bool {

4534 SMLoc Loc = getTok().getLoc();

4537 return Error(Loc, "expected identifier");

4538

4539

4541 return Error(Loc, "non-local symbol required");

4542

4543 if (!getStreamer().emitSymbolAttribute(Sym, Attr))

4544 return Error(Loc, "unable to emit symbol attribute");

4545 return false;

4546 };

4547

4548 if (parseMany(parseOp))

4549 return addErrorSuffix(" in directive");

4550 return false;

4551}

4552

4553

4554

4555bool MasmParser::parseDirectiveComm(bool IsLocal) {

4556 if (checkForValidSection())

4557 return true;

4558

4559 SMLoc IDLoc = getLexer().getLoc();

4562 return TokError("expected identifier in directive");

4563

4565 return TokError("unexpected token in directive");

4566 Lex();

4567

4568 int64_t Size;

4569 SMLoc SizeLoc = getLexer().getLoc();

4570 if (parseAbsoluteExpression(Size))

4571 return true;

4572

4573 int64_t Pow2Alignment = 0;

4574 SMLoc Pow2AlignmentLoc;

4576 Lex();

4577 Pow2AlignmentLoc = getLexer().getLoc();

4578 if (parseAbsoluteExpression(Pow2Alignment))

4579 return true;

4580

4581 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();

4583 return Error(Pow2AlignmentLoc, "alignment not supported on this target");

4584

4585

4586 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||

4589 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");

4590 Pow2Alignment = Log2_64(Pow2Alignment);

4591 }

4592 }

4593

4594 if (parseEOL())

4595 return true;

4596

4597

4598

4599 if (Size < 0)

4600 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "

4601 "be less than zero");

4602

4603

4604

4605

4606 if (Pow2Alignment < 0)

4607 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "

4608 "alignment, can't be less than zero");

4609

4612 return Error(IDLoc, "invalid symbol redefinition");

4613

4614

4615 if (IsLocal) {

4616 getStreamer().emitLocalCommonSymbol(Sym, Size,

4617 Align(1ULL << Pow2Alignment));

4618 return false;

4619 }

4620

4621 getStreamer().emitCommonSymbol(Sym, Size, Align(1ULL << Pow2Alignment));

4622 return false;

4623}

4624

4625

4626

4627

4628

4629bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {

4631 size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");

4632 assert(DelimiterEnd != std:🧵:npos);

4633 StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd);

4634 if (Delimiter.empty())

4635 return Error(DirectiveLoc, "no delimiter in 'comment' directive");

4636 do {

4638 return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");

4639 Lex();

4640 } while (

4642 return parseEOL();

4643}

4644

4645

4646

4647

4648bool MasmParser::parseDirectiveInclude() {

4649

4651 SMLoc IncludeLoc = getTok().getLoc();

4652

4653 if (parseAngleBracketString(Filename))

4655 if (check(Filename.empty(), "missing filename in 'include' directive") ||

4657 "unexpected token in 'include' directive") ||

4658

4659

4660 check(enterIncludeFile(Filename), IncludeLoc,

4661 "Could not find include file '" + Filename + "'"))

4662 return true;

4663

4664 return false;

4665}

4666

4667

4668

4669bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {

4670 TheCondStack.push_back(TheCondState);

4672 if (TheCondState.Ignore) {

4673 eatToEndOfStatement();

4674 } else {

4675 int64_t ExprValue;

4676 if (parseAbsoluteExpression(ExprValue) || parseEOL())

4677 return true;

4678

4679 switch (DirKind) {

4680 default:

4682 case DK_IF:

4683 break;

4684 case DK_IFE:

4685 ExprValue = ExprValue == 0;

4686 break;

4687 }

4688

4689 TheCondState.CondMet = ExprValue;

4691 }

4692

4693 return false;

4694}

4695

4696

4697

4698bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {

4699 TheCondStack.push_back(TheCondState);

4701

4702 if (TheCondState.Ignore) {

4703 eatToEndOfStatement();

4704 } else {

4705 std::string Str;

4706 if (parseTextItem(Str))

4707 return TokError("expected text item parameter for 'ifb' directive");

4708

4709 if (parseEOL())

4710 return true;

4711

4712 TheCondState.CondMet = ExpectBlank == Str.empty();

4714 }

4715

4716 return false;

4717}

4718

4719

4720

4721bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,

4722 bool CaseInsensitive) {

4723 std::string String1, String2;

4724

4725 if (parseTextItem(String1)) {

4726 if (ExpectEqual)

4727 return TokError("expected text item parameter for 'ifidn' directive");

4728 return TokError("expected text item parameter for 'ifdif' directive");

4729 }

4730

4732 if (ExpectEqual)

4733 return TokError(

4734 "expected comma after first string for 'ifidn' directive");

4735 return TokError("expected comma after first string for 'ifdif' directive");

4736 }

4737 Lex();

4738

4739 if (parseTextItem(String2)) {

4740 if (ExpectEqual)

4741 return TokError("expected text item parameter for 'ifidn' directive");

4742 return TokError("expected text item parameter for 'ifdif' directive");

4743 }

4744

4745 TheCondStack.push_back(TheCondState);

4747 if (CaseInsensitive)

4749 ExpectEqual == (StringRef(String1).equals_insensitive(String2));

4750 else

4751 TheCondState.CondMet = ExpectEqual == (String1 == String2);

4753

4754 return false;

4755}

4756

4757

4758

4759

4760bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {

4761 TheCondStack.push_back(TheCondState);

4763

4764 if (TheCondState.Ignore) {

4765 eatToEndOfStatement();

4766 } else {

4767 bool is_defined = false;

4768 MCRegister Reg;

4769 SMLoc StartLoc, EndLoc;

4770 is_defined =

4771 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();

4772 if (!is_defined) {

4773 StringRef Name;

4774 if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||

4775 parseEOL())

4776 return true;

4777

4778 if (BuiltinSymbolMap.contains(Name.lower())) {

4779 is_defined = true;

4780 } else if (Variables.contains(Name.lower())) {

4781 is_defined = true;

4782 } else {

4784 is_defined = (Sym && !Sym->isUndefined());

4785 }

4786 }

4787

4788 TheCondState.CondMet = (is_defined == expect_defined);

4790 }

4791

4792 return false;

4793}

4794

4795

4796

4797bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,

4798 DirectiveKind DirKind) {

4801 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"

4802 " .if or an .elseif");

4804

4805 bool LastIgnoreState = false;

4806 if (!TheCondStack.empty())

4807 LastIgnoreState = TheCondStack.back().Ignore;

4808 if (LastIgnoreState || TheCondState.CondMet) {

4809 TheCondState.Ignore = true;

4810 eatToEndOfStatement();

4811 } else {

4812 int64_t ExprValue;

4813 if (parseAbsoluteExpression(ExprValue))

4814 return true;

4815

4816 if (parseEOL())

4817 return true;

4818

4819 switch (DirKind) {

4820 default:

4822 case DK_ELSEIF:

4823 break;

4824 case DK_ELSEIFE:

4825 ExprValue = ExprValue == 0;

4826 break;

4827 }

4828

4829 TheCondState.CondMet = ExprValue;

4831 }

4832

4833 return false;

4834}

4835

4836

4837

4838bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {

4841 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"

4842 " if or an elseif");

4844

4845 bool LastIgnoreState = false;

4846 if (!TheCondStack.empty())

4847 LastIgnoreState = TheCondStack.back().Ignore;

4848 if (LastIgnoreState || TheCondState.CondMet) {

4849 TheCondState.Ignore = true;

4850 eatToEndOfStatement();

4851 } else {

4852 std::string Str;

4853 if (parseTextItem(Str)) {

4854 if (ExpectBlank)

4855 return TokError("expected text item parameter for 'elseifb' directive");

4856 return TokError("expected text item parameter for 'elseifnb' directive");

4857 }

4858

4859 if (parseEOL())

4860 return true;

4861

4862 TheCondState.CondMet = ExpectBlank == Str.empty();

4864 }

4865

4866 return false;

4867}

4868

4869

4870

4871

4872bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,

4873 bool expect_defined) {

4876 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"

4877 " if or an elseif");

4879

4880 bool LastIgnoreState = false;

4881 if (!TheCondStack.empty())

4882 LastIgnoreState = TheCondStack.back().Ignore;

4883 if (LastIgnoreState || TheCondState.CondMet) {

4884 TheCondState.Ignore = true;

4885 eatToEndOfStatement();

4886 } else {

4887 bool is_defined = false;

4888 MCRegister Reg;

4889 SMLoc StartLoc, EndLoc;

4890 is_defined =

4891 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();

4892 if (!is_defined) {

4893 StringRef Name;

4894 if (check(parseIdentifier(Name),

4895 "expected identifier after 'elseifdef'") ||

4896 parseEOL())

4897 return true;

4898

4899 if (BuiltinSymbolMap.contains(Name.lower())) {

4900 is_defined = true;

4901 } else if (Variables.contains(Name.lower())) {

4902 is_defined = true;

4903 } else {

4905 is_defined = (Sym && !Sym->isUndefined());

4906 }

4907 }

4908

4909 TheCondState.CondMet = (is_defined == expect_defined);

4911 }

4912

4913 return false;

4914}

4915

4916

4917

4918bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,

4919 bool CaseInsensitive) {

4922 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"

4923 " if or an elseif");

4925

4926 bool LastIgnoreState = false;

4927 if (!TheCondStack.empty())

4928 LastIgnoreState = TheCondStack.back().Ignore;

4929 if (LastIgnoreState || TheCondState.CondMet) {

4930 TheCondState.Ignore = true;

4931 eatToEndOfStatement();

4932 } else {

4933 std::string String1, String2;

4934

4935 if (parseTextItem(String1)) {

4936 if (ExpectEqual)

4937 return TokError(

4938 "expected text item parameter for 'elseifidn' directive");

4939 return TokError("expected text item parameter for 'elseifdif' directive");

4940 }

4941

4943 if (ExpectEqual)

4944 return TokError(

4945 "expected comma after first string for 'elseifidn' directive");

4946 return TokError(

4947 "expected comma after first string for 'elseifdif' directive");

4948 }

4949 Lex();

4950

4951 if (parseTextItem(String2)) {

4952 if (ExpectEqual)

4953 return TokError(

4954 "expected text item parameter for 'elseifidn' directive");

4955 return TokError("expected text item parameter for 'elseifdif' directive");

4956 }

4957

4958 if (CaseInsensitive)

4960 ExpectEqual == (StringRef(String1).equals_insensitive(String2));

4961 else

4962 TheCondState.CondMet = ExpectEqual == (String1 == String2);

4964 }

4965

4966 return false;

4967}

4968

4969

4970

4971bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {

4972 if (parseEOL())

4973 return true;

4974

4977 return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"

4978 " or an elseif");

4980 bool LastIgnoreState = false;

4981 if (!TheCondStack.empty())

4982 LastIgnoreState = TheCondStack.back().Ignore;

4983 if (LastIgnoreState || TheCondState.CondMet)

4984 TheCondState.Ignore = true;

4985 else

4986 TheCondState.Ignore = false;

4987

4988 return false;

4989}

4990

4991

4992

4993bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {

4994 if (parseEOL())

4995 return true;

4996

4998 Lexer.Lex();

4999

5000 return false;

5001}

5002

5003

5004

5005bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {

5006 if (!TheCondStack.empty()) {

5007 if (TheCondStack.back().Ignore) {

5008 eatToEndOfStatement();

5009 return false;

5010 }

5011 }

5012

5013 std::string Message = ".err directive invoked in source file";

5016 Lex();

5017

5018 return Error(DirectiveLoc, Message);

5019}

5020

5021

5022

5023bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {

5024 if (!TheCondStack.empty()) {

5025 if (TheCondStack.back().Ignore) {

5026 eatToEndOfStatement();

5027 return false;

5028 }

5029 }

5030

5031 std::string Text;

5032 if (parseTextItem(Text))

5033 return Error(getTok().getLoc(), "missing text item in '.errb' directive");

5034

5035 std::string Message = ".errb directive invoked in source file";

5038 return addErrorSuffix(" in '.errb' directive");

5040 }

5041 Lex();

5042

5043 if (Text.empty() == ExpectBlank)

5044 return Error(DirectiveLoc, Message);

5045 return false;

5046}

5047

5048

5049

5050bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,

5051 bool ExpectDefined) {

5052 if (!TheCondStack.empty()) {

5053 if (TheCondStack.back().Ignore) {

5054 eatToEndOfStatement();

5055 return false;

5056 }

5057 }

5058

5059 bool IsDefined = false;

5060 MCRegister Reg;

5061 SMLoc StartLoc, EndLoc;

5062 IsDefined =

5063 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();

5064 if (!IsDefined) {

5065 StringRef Name;

5066 if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))

5067 return true;

5068

5069 if (BuiltinSymbolMap.contains(Name.lower())) {

5070 IsDefined = true;

5071 } else if (Variables.contains(Name.lower())) {

5072 IsDefined = true;

5073 } else {

5075 IsDefined = (Sym && !Sym->isUndefined());

5076 }

5077 }

5078

5079 std::string Message = ".errdef directive invoked in source file";

5082 return addErrorSuffix(" in '.errdef' directive");

5084 }

5085 Lex();

5086

5087 if (IsDefined == ExpectDefined)

5088 return Error(DirectiveLoc, Message);

5089 return false;

5090}

5091

5092

5093

5094bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,

5095 bool CaseInsensitive) {

5096 if (!TheCondStack.empty()) {

5097 if (TheCondStack.back().Ignore) {

5098 eatToEndOfStatement();

5099 return false;

5100 }

5101 }

5102

5103 std::string String1, String2;

5104

5105 if (parseTextItem(String1)) {

5106 if (ExpectEqual)

5107 return TokError("expected string parameter for '.erridn' directive");

5108 return TokError("expected string parameter for '.errdif' directive");

5109 }

5110

5112 if (ExpectEqual)

5113 return TokError(

5114 "expected comma after first string for '.erridn' directive");

5115 return TokError(

5116 "expected comma after first string for '.errdif' directive");

5117 }

5118 Lex();

5119

5120 if (parseTextItem(String2)) {

5121 if (ExpectEqual)

5122 return TokError("expected string parameter for '.erridn' directive");

5123 return TokError("expected string parameter for '.errdif' directive");

5124 }

5125

5126 std::string Message;

5127 if (ExpectEqual)

5128 Message = ".erridn directive invoked in source file";

5129 else

5130 Message = ".errdif directive invoked in source file";

5133 return addErrorSuffix(" in '.erridn' directive");

5135 }

5136 Lex();

5137

5138 if (CaseInsensitive)

5140 ExpectEqual == (StringRef(String1).equals_insensitive(String2));

5141 else

5142 TheCondState.CondMet = ExpectEqual == (String1 == String2);

5144

5145 if ((CaseInsensitive &&

5146 ExpectEqual == StringRef(String1).equals_insensitive(String2)) ||

5147 (ExpectEqual == (String1 == String2)))

5148 return Error(DirectiveLoc, Message);

5149 return false;

5150}

5151

5152

5153

5154bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {

5155 if (!TheCondStack.empty()) {

5156 if (TheCondStack.back().Ignore) {

5157 eatToEndOfStatement();

5158 return false;

5159 }

5160 }

5161

5162 int64_t ExprValue;

5163 if (parseAbsoluteExpression(ExprValue))

5164 return addErrorSuffix(" in '.erre' directive");

5165

5166 std::string Message = ".erre directive invoked in source file";

5169 return addErrorSuffix(" in '.erre' directive");

5171 }

5172 Lex();

5173

5174 if ((ExprValue == 0) == ExpectZero)

5175 return Error(DirectiveLoc, Message);

5176 return false;

5177}

5178

5179

5180

5181bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {

5182 if (parseEOL())

5183 return true;

5184

5186 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "

5187 "an .if or .else");

5188 if (!TheCondStack.empty()) {

5189 TheCondState = TheCondStack.back();

5190 TheCondStack.pop_back();

5191 }

5192

5193 return false;

5194}

5195

5196void MasmParser::initializeDirectiveKindMap() {

5197 DirectiveKindMap["="] = DK_ASSIGN;

5198 DirectiveKindMap["equ"] = DK_EQU;

5199 DirectiveKindMap["textequ"] = DK_TEXTEQU;

5200

5201

5202

5203 DirectiveKindMap["byte"] = DK_BYTE;

5204 DirectiveKindMap["sbyte"] = DK_SBYTE;

5205 DirectiveKindMap["word"] = DK_WORD;

5206 DirectiveKindMap["sword"] = DK_SWORD;

5207 DirectiveKindMap["dword"] = DK_DWORD;

5208 DirectiveKindMap["sdword"] = DK_SDWORD;

5209 DirectiveKindMap["fword"] = DK_FWORD;

5210 DirectiveKindMap["qword"] = DK_QWORD;

5211 DirectiveKindMap["sqword"] = DK_SQWORD;

5212 DirectiveKindMap["real4"] = DK_REAL4;

5213 DirectiveKindMap["real8"] = DK_REAL8;

5214 DirectiveKindMap["real10"] = DK_REAL10;

5215 DirectiveKindMap["align"] = DK_ALIGN;

5216 DirectiveKindMap["even"] = DK_EVEN;

5217 DirectiveKindMap["org"] = DK_ORG;

5218 DirectiveKindMap["extern"] = DK_EXTERN;

5219 DirectiveKindMap["extrn"] = DK_EXTERN;

5220 DirectiveKindMap["public"] = DK_PUBLIC;

5221

5222 DirectiveKindMap["comment"] = DK_COMMENT;

5223 DirectiveKindMap["include"] = DK_INCLUDE;

5224 DirectiveKindMap["repeat"] = DK_REPEAT;

5225 DirectiveKindMap["rept"] = DK_REPEAT;

5226 DirectiveKindMap["while"] = DK_WHILE;

5227 DirectiveKindMap["for"] = DK_FOR;

5228 DirectiveKindMap["irp"] = DK_FOR;

5229 DirectiveKindMap["forc"] = DK_FORC;

5230 DirectiveKindMap["irpc"] = DK_FORC;

5231 DirectiveKindMap["if"] = DK_IF;

5232 DirectiveKindMap["ife"] = DK_IFE;

5233 DirectiveKindMap["ifb"] = DK_IFB;

5234 DirectiveKindMap["ifnb"] = DK_IFNB;

5235 DirectiveKindMap["ifdef"] = DK_IFDEF;

5236 DirectiveKindMap["ifndef"] = DK_IFNDEF;

5237 DirectiveKindMap["ifdif"] = DK_IFDIF;

5238 DirectiveKindMap["ifdifi"] = DK_IFDIFI;

5239 DirectiveKindMap["ifidn"] = DK_IFIDN;

5240 DirectiveKindMap["ifidni"] = DK_IFIDNI;

5241 DirectiveKindMap["elseif"] = DK_ELSEIF;

5242 DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;

5243 DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;

5244 DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;

5245 DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;

5246 DirectiveKindMap["else"] = DK_ELSE;

5247 DirectiveKindMap["end"] = DK_END;

5248 DirectiveKindMap["endif"] = DK_ENDIF;

5249

5250

5251

5252

5253

5254

5255

5256

5257

5258

5259

5260

5261

5262

5263

5264

5265

5266

5267

5268

5269

5270

5271

5272

5273

5274

5275

5276

5277

5278

5279

5280

5281

5282

5283

5284

5285

5286

5287

5288 DirectiveKindMap["macro"] = DK_MACRO;

5289 DirectiveKindMap["exitm"] = DK_EXITM;

5290 DirectiveKindMap["endm"] = DK_ENDM;

5291 DirectiveKindMap["purge"] = DK_PURGE;

5292 DirectiveKindMap[".err"] = DK_ERR;

5293 DirectiveKindMap[".errb"] = DK_ERRB;

5294 DirectiveKindMap[".errnb"] = DK_ERRNB;

5295 DirectiveKindMap[".errdef"] = DK_ERRDEF;

5296 DirectiveKindMap[".errndef"] = DK_ERRNDEF;

5297 DirectiveKindMap[".errdif"] = DK_ERRDIF;

5298 DirectiveKindMap[".errdifi"] = DK_ERRDIFI;

5299 DirectiveKindMap[".erridn"] = DK_ERRIDN;

5300 DirectiveKindMap[".erridni"] = DK_ERRIDNI;

5301 DirectiveKindMap[".erre"] = DK_ERRE;

5302 DirectiveKindMap[".errnz"] = DK_ERRNZ;

5303 DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;

5304 DirectiveKindMap[".pushreg"] = DK_PUSHREG;

5305 DirectiveKindMap[".savereg"] = DK_SAVEREG;

5306 DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;

5307 DirectiveKindMap[".setframe"] = DK_SETFRAME;

5308 DirectiveKindMap[".radix"] = DK_RADIX;

5309 DirectiveKindMap["db"] = DK_DB;

5310 DirectiveKindMap["dd"] = DK_DD;

5311 DirectiveKindMap["df"] = DK_DF;

5312 DirectiveKindMap["dq"] = DK_DQ;

5313 DirectiveKindMap["dw"] = DK_DW;

5314 DirectiveKindMap["echo"] = DK_ECHO;

5315 DirectiveKindMap["struc"] = DK_STRUCT;

5316 DirectiveKindMap["struct"] = DK_STRUCT;

5317 DirectiveKindMap["union"] = DK_UNION;

5318 DirectiveKindMap["ends"] = DK_ENDS;

5319}

5320

5321bool MasmParser::isMacroLikeDirective() {

5323 bool IsMacroLike = StringSwitch(getTok().getIdentifier())

5324 .CasesLower({"repeat", "rept"}, true)

5325 .CaseLower("while", true)

5326 .CasesLower({"for", "irp"}, true)

5327 .CasesLower({"forc", "irpc"}, true)

5329 if (IsMacroLike)

5330 return true;

5331 }

5333 peekTok().getIdentifier().equals_insensitive("macro"))

5334 return true;

5335

5336 return false;

5337}

5338

5339MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {

5340 AsmToken EndToken, StartToken = getTok();

5341

5342 unsigned NestLevel = 0;

5343 while (true) {

5344

5346 printError(DirectiveLoc, "no matching 'endm' in definition");

5347 return nullptr;

5348 }

5349

5350 if (isMacroLikeDirective())

5351 ++NestLevel;

5352

5353

5355 getTok().getIdentifier().equals_insensitive("endm")) {

5356 if (NestLevel == 0) {

5357 EndToken = getTok();

5358 Lex();

5360 printError(getTok().getLoc(), "unexpected token in 'endm' directive");

5361 return nullptr;

5362 }

5363 break;

5364 }

5365 --NestLevel;

5366 }

5367

5368

5369 eatToEndOfStatement();

5370 }

5371

5374 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);

5375

5376

5378 return &MacroLikeBodies.back();

5379}

5380

5381bool MasmParser::expandStatement(SMLoc Loc) {

5383 SMLoc EndLoc = getTok().getLoc();

5384

5387

5388 StringMapstd::string BuiltinValues;

5389 for (const auto &S : BuiltinSymbolMap) {

5390 const BuiltinSymbol &Sym = S.getValue();

5391 if (std::optionalstd::string Text = evaluateBuiltinTextMacro(Sym, Loc)) {

5392 BuiltinValues[S.getKey().lower()] = std::move(*Text);

5393 }

5394 }

5395 for (const auto &B : BuiltinValues) {

5396 MCAsmMacroParameter P;

5397 MCAsmMacroArgument A;

5398 P.Name = B.getKey();

5399 P.Required = true;

5401

5404 }

5405

5406 for (const auto &V : Variables) {

5407 const Variable &Var = V.getValue();

5408 if (Var.IsText) {

5409 MCAsmMacroParameter P;

5410 MCAsmMacroArgument A;

5411 P.Name = Var.Name;

5412 P.Required = true;

5414

5417 }

5418 }

5419 MacroLikeBodies.emplace_back(StringRef(), Body, Parameters);

5420 MCAsmMacro M = MacroLikeBodies.back();

5421

5422

5423 SmallString<80> Buf;

5424 raw_svector_ostream OS(Buf);

5425 if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc))

5426 return true;

5427 std::unique_ptr Expansion =

5429

5430

5433 EndStatementAtEOFStack.push_back(false);

5434 Lex();

5435 return false;

5436}

5437

5438void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,

5439 raw_svector_ostream &OS) {

5440 instantiateMacroLikeBody(M, DirectiveLoc, getTok().getLoc(), OS);

5441}

5442void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,

5443 SMLoc ExitLoc,

5444 raw_svector_ostream &OS) {

5445 OS << "endm\n";

5446

5447 std::unique_ptr Instantiation =

5449

5450

5451

5452 MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,

5453 ExitLoc, TheCondStack.size()};

5454 ActiveMacros.push_back(MI);

5455

5456

5459 EndStatementAtEOFStack.push_back(true);

5460 Lex();

5461}

5462

5463

5464

5465

5466

5467bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {

5468 const MCExpr *CountExpr;

5469 SMLoc CountLoc = getTok().getLoc();

5470 if (parseExpression(CountExpr))

5471 return true;

5472

5474 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {

5475 return Error(CountLoc, "unexpected token in '" + Dir + "' directive");

5476 }

5477

5478 if (check(Count < 0, CountLoc, "Count is negative") || parseEOL())

5479 return true;

5480

5481

5482 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);

5483 if (!M)

5484 return true;

5485

5486

5487

5488 SmallString<256> Buf;

5489 raw_svector_ostream OS(Buf);

5490 while (Count--) {

5491 if (expandMacro(OS, M->Body, {}, {}, M->Locals, getTok().getLoc()))

5492 return true;

5493 }

5494 instantiateMacroLikeBody(M, DirectiveLoc, OS);

5495

5496 return false;

5497}

5498

5499

5500

5501

5502

5503bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {

5504 const MCExpr *CondExpr;

5505 SMLoc CondLoc = getTok().getLoc();

5506 if (parseExpression(CondExpr))

5507 return true;

5508

5509

5510 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);

5511 if (!M)

5512 return true;

5513

5514

5515

5516 SmallString<256> Buf;

5517 raw_svector_ostream OS(Buf);

5518 int64_t Condition;

5519 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))

5520 return Error(CondLoc, "expected absolute expression in 'while' directive");

5521 if (Condition) {

5522

5523

5524 if (expandMacro(OS, M->Body, {}, {}, M->Locals, getTok().getLoc()))

5525 return true;

5526 instantiateMacroLikeBody(M, DirectiveLoc, DirectiveLoc, OS);

5527 }

5528

5529 return false;

5530}

5531

5532

5533

5534

5535

5536bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {

5538 MCAsmMacroArguments A;

5539 if (check(parseIdentifier(Parameter.Name),

5540 "expected identifier in '" + Dir + "' directive"))

5541 return true;

5542

5543

5546

5547 SMLoc ParamLoc;

5548

5549 ParamLoc = Lexer.getLoc();

5550 if (parseMacroArgument(nullptr, Parameter.Value))

5551 return true;

5552 } else {

5553 SMLoc QualLoc;

5555

5556 QualLoc = Lexer.getLoc();

5557 if (parseIdentifier(Qualifier))

5558 return Error(QualLoc, "missing parameter qualifier for "

5559 "'" +

5560 Parameter.Name + "' in '" + Dir +

5561 "' directive");

5562

5563 if (Qualifier.equals_insensitive("req"))

5565 else

5566 return Error(QualLoc,

5567 Qualifier + " is not a valid parameter qualifier for '" +

5568 Parameter.Name + "' in '" + Dir + "' directive");

5569 }

5570 }

5571

5573 "expected comma in '" + Dir + "' directive") ||

5575 "values in '" + Dir +

5576 "' directive must be enclosed in angle brackets"))

5577 return true;

5578

5579 while (true) {

5580 A.emplace_back();

5581 if (parseMacroArgument(&Parameter, A.back(), AsmToken::Greater))

5582 return addErrorSuffix(" in arguments for '" + Dir + "' directive");

5583

5584

5586 break;

5588 }

5589

5591 "values in '" + Dir +

5592 "' directive must be enclosed in angle brackets") ||

5593 parseEOL())

5594 return true;

5595

5596

5597 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);

5598 if (!M)

5599 return true;

5600

5601

5602

5603 SmallString<256> Buf;

5604 raw_svector_ostream OS(Buf);

5605

5606 for (const MCAsmMacroArgument &Arg : A) {

5607 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))

5608 return true;

5609 }

5610

5611 instantiateMacroLikeBody(M, DirectiveLoc, OS);

5612

5613 return false;

5614}

5615

5616

5617

5618

5619

5620bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {

5622

5624 if (check(parseIdentifier(Parameter.Name),

5625 "expected identifier in '" + Directive + "' directive") ||

5627 "expected comma in '" + Directive + "' directive"))

5628 return true;

5629 if (parseAngleBracketString(Argument)) {

5630

5631

5632

5635 Argument += getTok().getString();

5636 size_t End = 0;

5637 for (; End < Argument.size(); ++End) {

5638 if (isSpace(Argument[End]))

5639 break;

5640 }

5642 }

5643 if (parseEOL())

5644 return true;

5645

5646

5647 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);

5648 if (!M)

5649 return true;

5650

5651

5652

5653 SmallString<256> Buf;

5654 raw_svector_ostream OS(Buf);

5655

5656 StringRef Values(Argument);

5657 for (std::size_t I = 0, End = Values.size(); I != End; ++I) {

5658 MCAsmMacroArgument Arg;

5660

5661 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))

5662 return true;

5663 }

5664

5665 instantiateMacroLikeBody(M, DirectiveLoc, OS);

5666

5667 return false;

5668}

5669

5670bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,

5671 size_t Len) {

5672 const MCExpr *Value;

5673 SMLoc ExprLoc = getLexer().getLoc();

5674 if (parseExpression(Value))

5675 return true;

5677 if (!MCE)

5678 return Error(ExprLoc, "unexpected expression in _emit");

5679 uint64_t IntValue = MCE->getValue();

5681 return Error(ExprLoc, "literal value out of range for directive");

5682

5683 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);

5684 return false;

5685}

5686

5687bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {

5688 const MCExpr *Value;

5689 SMLoc ExprLoc = getLexer().getLoc();

5690 if (parseExpression(Value))

5691 return true;

5693 if (!MCE)

5694 return Error(ExprLoc, "unexpected expression in align");

5695 uint64_t IntValue = MCE->getValue();

5697 return Error(ExprLoc, "literal value not a power of two greater then zero");

5698

5700 return false;

5701}

5702

5703bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {

5704 const SMLoc Loc = getLexer().getLoc();

5706 StringRef RadixString = StringRef(RadixStringRaw).trim();

5707 unsigned Radix;

5709 return Error(Loc,

5710 "radix must be a decimal number in the range 2 to 16; was " +

5711 RadixString);

5712 }

5713 if (Radix < 2 || Radix > 16)

5714 return Error(Loc, "radix must be in the range 2 to 16; was " +

5715 std::to_string(Radix));

5716 getLexer().setMasmDefaultRadix(Radix);

5717 return false;

5718}

5719

5720

5721

5722bool MasmParser::parseDirectiveEcho(SMLoc DirectiveLoc) {

5725 if (!StringRef(Message).ends_with("\n"))

5727 return false;

5728}

5729

5730

5731

5735 return -1;

5737 return 1;

5738

5739

5740

5741

5742

5745 return -1;

5746

5749 return 1;

5751}

5752

5753bool MasmParser::defineMacro(StringRef Name, StringRef Value) {

5755 if (Var.Name.empty()) {

5756 Var.Name = Name;

5757 } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {

5758 return Error(SMLoc(), "invalid variable redefinition");

5759 } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&

5760 Warning(SMLoc(), "redefining '" + Name +

5761 "', already defined on the command line")) {

5762 return true;

5763 }

5764 Var.Redefinable = Variable::WARN_ON_REDEFINITION;

5765 Var.IsText = true;

5766 Var.TextValue = Value.str();

5767 return false;

5768}

5769

5770bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {

5771 const std::pair<StringRef, StringRef> BaseMember = Name.split('.');

5772 const StringRef Base = BaseMember.first, Member = BaseMember.second;

5773 return lookUpField(Base, Member, Info);

5774}

5775

5776bool MasmParser::lookUpField(StringRef Base, StringRef Member,

5777 AsmFieldInfo &Info) const {

5778 if (Base.empty())

5779 return true;

5780

5781 AsmFieldInfo BaseInfo;

5782 if (Base.contains('.') && !lookUpField(Base, BaseInfo))

5784

5785 auto StructIt = Structs.find(Base.lower());

5786 auto TypeIt = KnownType.find(Base.lower());

5787 if (TypeIt != KnownType.end()) {

5788 StructIt = Structs.find(TypeIt->second.Name.lower());

5789 }

5790 if (StructIt != Structs.end())

5791 return lookUpField(StructIt->second, Member, Info);

5792

5793 return true;

5794}

5795

5796bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,

5797 AsmFieldInfo &Info) const {

5798 if (Member.empty()) {

5799 Info.Type.Name = Structure.Name;

5800 Info.Type.Size = Structure.Size;

5801 Info.Type.ElementSize = Structure.Size;

5802 Info.Type.Length = 1;

5803 return false;

5804 }

5805

5806 std::pair<StringRef, StringRef> Split = Member.split('.');

5807 const StringRef FieldName = Split.first, FieldMember = Split.second;

5808

5809 auto StructIt = Structs.find(FieldName.lower());

5810 if (StructIt != Structs.end())

5811 return lookUpField(StructIt->second, FieldMember, Info);

5812

5813 auto FieldIt = Structure.FieldsByName.find(FieldName.lower());

5814 if (FieldIt == Structure.FieldsByName.end())

5815 return true;

5816

5817 const FieldInfo &Field = Structure.Fields[FieldIt->second];

5818 if (FieldMember.empty()) {

5821 Info.Type.ElementSize = Field.Type;

5822 Info.Type.Length = Field.LengthOf;

5823 if (Field.Contents.FT == FT_STRUCT)

5824 Info.Type.Name = Field.Contents.StructInfo.Structure.Name;

5825 else

5826 Info.Type.Name = "";

5827 return false;

5828 }

5829

5830 if (Field.Contents.FT != FT_STRUCT)

5831 return true;

5832 const StructFieldInfo &StructInfo = Field.Contents.StructInfo;

5833

5834 if (lookUpField(StructInfo.Structure, FieldMember, Info))

5835 return true;

5836

5838 return false;

5839}

5840

5841bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {

5842 unsigned Size = StringSwitch(Name)

5843 .CasesLower({"byte", "db", "sbyte"}, 1)

5844 .CasesLower({"word", "dw", "sword"}, 2)

5845 .CasesLower({"dword", "dd", "sdword"}, 4)

5846 .CasesLower({"fword", "df"}, 6)

5847 .CasesLower({"qword", "dq", "sqword"}, 8)

5848 .CaseLower("real4", 4)

5849 .CaseLower("real8", 8)

5850 .CaseLower("real10", 10)

5851 .Default(0);

5855 Info.Length = 1;

5857 return false;

5858 }

5859

5860 auto StructIt = Structs.find(Name.lower());

5861 if (StructIt != Structs.end()) {

5862 const StructInfo &Structure = StructIt->second;

5864 Info.ElementSize = Structure.Size;

5865 Info.Length = 1;

5866 Info.Size = Structure.Size;

5867 return false;

5868 }

5869

5870 return true;

5871}

5872

5873bool MasmParser::parseMSInlineAsm(

5874 std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs,

5875 SmallVectorImpl<std::pair<void *, bool>> &OpDecls,

5876 SmallVectorImplstd::string &Constraints,

5877 SmallVectorImplstd::string &Clobbers, const MCInstrInfo *MII,

5878 MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {

5879 SmallVector<void *, 4> InputDecls;

5880 SmallVector<void *, 4> OutputDecls;

5883 SmallVector<std::string, 4> InputConstraints;

5884 SmallVector<std::string, 4> OutputConstraints;

5886

5888

5889

5890 Lex();

5891

5892

5893 unsigned InputIdx = 0;

5894 unsigned OutputIdx = 0;

5896

5897 if (parseCurlyBlockScope(AsmStrRewrites))

5898 continue;

5899

5900 ParseStatementInfo Info(&AsmStrRewrites);

5901 bool StatementErr = parseStatement(Info, &SI);

5902

5903 if (StatementErr || Info.ParseError) {

5904

5905 printPendingErrors();

5906 return true;

5907 }

5908

5909

5910 assert(!hasPendingError() && "unexpected error from parseStatement");

5911

5912 if (Info.Opcode == ~0U)

5913 continue;

5914

5915 const MCInstrDesc &Desc = MII->get(Info.Opcode);

5916

5917

5918 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {

5919 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];

5920

5921

5923 !getTargetParser().omitRegisterFromClobberLists(Operand.getReg())) {

5924 unsigned NumDefs = Desc.getNumDefs();

5925

5928 continue;

5929 }

5930

5931

5932 StringRef SymName = Operand.getSymName();

5933 if (SymName.empty())

5934 continue;

5935

5936 void *OpDecl = Operand.getOpDecl();

5937 if (!OpDecl)

5938 continue;

5939

5941 if (Operand.isImm()) {

5942

5944 Constraint = "r";

5945 else

5946 Constraint = "i";

5947 }

5948

5949 bool isOutput = (i == 1) && Desc.mayStore();

5951 if (isOutput) {

5952 ++InputIdx;

5955 OutputConstraints.push_back(("=" + Constraint).str());

5957 } else {

5960 InputConstraints.push_back(Constraint.str());

5961 if (Desc.operands()[i - 1].isBranchTarget())

5963 else

5965 }

5966 }

5967

5968

5970 }

5971

5972

5973 NumOutputs = OutputDecls.size();

5974 NumInputs = InputDecls.size();

5975

5976

5979 Clobbers.assign(ClobberRegs.size(), std::string());

5980 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {

5981 raw_string_ostream OS(Clobbers[I]);

5983 }

5984

5985

5986 if (NumOutputs || NumInputs) {

5987 unsigned NumExprs = NumOutputs + NumInputs;

5988 OpDecls.resize(NumExprs);

5989 Constraints.resize(NumExprs);

5990 for (unsigned i = 0; i < NumOutputs; ++i) {

5991 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);

5992 Constraints[i] = OutputConstraints[i];

5993 }

5994 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {

5995 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);

5996 Constraints[j] = InputConstraints[i];

5997 }

5998 }

5999

6000

6001 std::string AsmStringIR;

6002 raw_string_ostream OS(AsmStringIR);

6003 StringRef ASMString =

6005 const char *AsmStart = ASMString.begin();

6006 const char *AsmEnd = ASMString.end();

6008 for (auto I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) {

6009 const AsmRewrite &AR = *I;

6010

6011 if (AR.Done)

6012 continue;

6014

6016 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");

6017

6018

6019 if (unsigned Len = Loc - AsmStart)

6020 OS << StringRef(AsmStart, Len);

6021

6022

6024 AsmStart = Loc + AR.Len;

6025 continue;

6026 }

6027

6028 unsigned AdditionalSkip = 0;

6029

6030 switch (Kind) {

6031 default:

6032 break;

6036 OS << "[";

6046 OS << " + ";

6047

6050 size_t OffsetLen = OffsetName.size();

6051 auto rewrite_it = std::find_if(

6052 I, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {

6053 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&

6054 (FusingAR.Kind == AOK_Input ||

6055 FusingAR.Kind == AOK_CallInput);

6056 });

6057 if (rewrite_it == AsmStrRewrites.end()) {

6058 OS << "offset " << OffsetName;

6060 OS << "${" << InputIdx++ << ":P}";

6061 rewrite_it->Done = true;

6062 } else {

6063 OS << '$' << InputIdx++;

6064 rewrite_it->Done = true;

6065 }

6066 }

6070 OS << "]";

6071 break;

6074 break;

6076 OS << '$' << InputIdx++;

6077 break;

6079 OS << "${" << InputIdx++ << ":P}";

6080 break;

6082 OS << '$' << OutputIdx++;

6083 break;

6085 switch (AR.Val) {

6086 default: break;

6087 case 8: OS << "byte ptr "; break;

6088 case 16: OS << "word ptr "; break;

6089 case 32: OS << "dword ptr "; break;

6090 case 64: OS << "qword ptr "; break;

6091 case 80: OS << "xword ptr "; break;

6092 case 128: OS << "xmmword ptr "; break;

6093 case 256: OS << "ymmword ptr "; break;

6094 }

6095 break;

6097 OS << ".byte";

6098 break;

6100

6101

6102 OS << ".align";

6103 if (getContext().getAsmInfo()->getAlignmentIsInBytes())

6104 break;

6105

6106

6107

6108 unsigned Val = AR.Val;

6109 OS << ' ' << Val;

6110 assert(Val < 10 && "Expected alignment less then 2^10.");

6111 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;

6112 break;

6113 }

6115 OS << ".even";

6116 break;

6118 OS << "\n\t";

6119 break;

6120 }

6121

6122

6123 AsmStart = Loc + AR.Len + AdditionalSkip;

6124 }

6125

6126

6127 if (AsmStart != AsmEnd)

6128 OS << StringRef(AsmStart, AsmEnd - AsmStart);

6129

6130 AsmString = OS.str();

6131 return false;

6132}

6133

6134void MasmParser::initializeBuiltinSymbolMaps() {

6135

6136 BuiltinSymbolMap["@version"] = BI_VERSION;

6137 BuiltinSymbolMap["@line"] = BI_LINE;

6138

6139

6140 BuiltinSymbolMap["@date"] = BI_DATE;

6141 BuiltinSymbolMap["@time"] = BI_TIME;

6142 BuiltinSymbolMap["@filecur"] = BI_FILECUR;

6143 BuiltinSymbolMap["@filename"] = BI_FILENAME;

6144 BuiltinSymbolMap["@curseg"] = BI_CURSEG;

6145

6146

6147 BuiltinFunctionMap["@catstr"] = BI_CATSTR;

6148

6149

6150 if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==

6152

6153

6154

6155

6156

6157

6158

6159

6160

6161

6162

6163

6164

6165 }

6166}

6167

6168const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,

6169 SMLoc StartLoc) {

6170 switch (Symbol) {

6171 default:

6172 return nullptr;

6173 case BI_VERSION:

6174

6176 case BI_LINE: {

6177 int64_t Line;

6178 if (ActiveMacros.empty())

6180 else

6182 ActiveMacros.front()->ExitBuffer);

6184 }

6185 }

6187}

6188

6189std::optionalstd::string

6190MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) {

6191 switch (Symbol) {

6192 default:

6193 return {};

6194 case BI_DATE: {

6195

6196 char TmpBuffer[sizeof("mm/dd/yy")];

6197 const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%D", &TM);

6198 return std::string(TmpBuffer, Len);

6199 }

6200 case BI_TIME: {

6201

6202 char TmpBuffer[sizeof("hh:mm:ss")];

6203 const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%T", &TM);

6204 return std::string(TmpBuffer, Len);

6205 }

6206 case BI_FILECUR:

6209 ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)

6212 case BI_FILENAME:

6216 case BI_CURSEG:

6217 return getStreamer().getCurrentSectionOnly()->getName().str();

6218 }

6220}

6221

6222bool MasmParser::evaluateBuiltinMacroFunction(BuiltinFunction Function,

6223 StringRef Name,

6224 std::string &Res) {

6225 if (parseToken(AsmToken::LParen, "invoking macro function '" + Name +

6226 "' requires arguments in parentheses")) {

6227 return true;

6228 }

6229

6231 switch (Function) {

6232 default:

6233 return true;

6234 case BI_CATSTR:

6235 break;

6236 }

6237 MCAsmMacro M(Name, "", P, {}, true);

6238

6239 MCAsmMacroArguments A;

6240 if (parseMacroArguments(&M, A, AsmToken::RParen) || parseRParen()) {

6241 return true;

6242 }

6243

6244 switch (Function) {

6245 default:

6247 case BI_CATSTR: {

6248 for (const MCAsmMacroArgument &Arg : A) {

6249 for (const AsmToken &Tok : Arg) {

6252 } else {

6254 }

6255 }

6256 }

6257 return false;

6258 }

6259 }

6261 return true;

6262}

6263

6264

6267 struct tm TM, unsigned CB) {

6268 return new MasmParser(SM, C, Out, MAI, TM, CB);

6269}

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

This file defines the StringMap class.

static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)

AMDGPU Lower Kernel Arguments

This file declares a class to represent arbitrary precision floating point values and provide a varie...

This file implements a class to represent arbitrary precision integral constant values and operations...

static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc)

This function checks if the next token is type or arithmetic.

static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI, AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)

static std::string angleBracketString(StringRef AltMacroStr)

creating a string without the escape characters '!'.

static int rewritesSort(const AsmRewrite *AsmRewriteA, const AsmRewrite *AsmRewriteB)

This file implements the BitVector class.

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

Analysis containing CSE Info

Value * getPointer(Value *Ptr)

const std::string FatArchTraits< MachO::fat_arch >::StructName

static bool isMacroParameterChar(char C)

Definition MasmParser.cpp:2441

@ DEFAULT_ADDRSPACE

Definition MasmParser.cpp:968

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

OptimizedStructLayoutField Field

static bool isValid(const char C)

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

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallString class.

This file defines the SmallVector class.

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

#define DEBUG_WITH_TYPE(TYPE,...)

DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.

static void DiagHandler(const SMDiagnostic &Diag, void *Context)

static APFloat getInf(const fltSemantics &Sem, bool Negative=false)

Factory for Positive and Negative Infinity.

static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)

Factory for NaN values.

static APFloat getZero(const fltSemantics &Sem, bool Negative=false)

Factory for Positive and Negative Zero.

unsigned getBitWidth() const

Return the number of bits in the APInt.

uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const

If this value is smaller than the specified limit, return it, otherwise return the limit value.

ConditionalAssemblyType TheCond

LLVM_ABI SMLoc getLoc() const

bool isNot(TokenKind K) const

StringRef getString() const

Get the string for the current token, this includes all characters (for example, the quotes on string...

StringRef getStringContents() const

Get the contents of a string token (without quotes).

bool is(TokenKind K) const

LLVM_ABI SMLoc getEndLoc() const

StringRef getIdentifier() const

Get the identifier string for the current token, which should be an identifier or a string.

This class is intended to be used as a base class for asm properties and features specific to the tar...

bool preserveAsmComments() const

Return true if assembly (inline or otherwise) should be parsed.

StringRef getPrivateLabelPrefix() const

bool shouldUseLogicalShr() const

virtual bool useCodeAlign(const MCSection &Sec) const

Generic assembler parser interface, for use by target specific assembly parsers.

static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

@ AShr

Arithmetic shift right.

@ LShr

Logical shift right.

@ GTE

Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).

@ GT

Signed greater than comparison (result is either 0 or some target-specific non-zero value)

@ Xor

Bitwise exclusive or.

@ LT

Signed less than comparison (result is either 0 or some target-specific non-zero value).

@ LTE

Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).

@ NE

Inequality comparison.

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

LLVM_ABI MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

LLVM_ABI MCSymbol * createDirectionalLocalSymbol(unsigned LocalLabelVal)

Create the definition of a directional local symbol for numbered label (used for "1:" definitions).

const MCAsmInfo * getAsmInfo() const

virtual void printRegName(raw_ostream &OS, MCRegister Reg)

Print the assembler register name.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

virtual bool isReg() const =0

isReg - Is this a register operand?

virtual bool needAddressOf() const

needAddressOf - Do we need to emit code to get the address of the variable/label?

virtual MCRegister getReg() const =0

virtual bool isOffsetOfLocal() const

isOffsetOfLocal - Do we need to emit code to get the offset of the local variable,...

virtual StringRef getSymName()

virtual bool isImm() const =0

isImm - Is this an immediate operand?

unsigned getMCOperandNum()

StringRef getConstraint()

virtual void * getOpDecl()

Streaming machine code generation interface.

virtual void addBlankLine()

Emit a blank line to a .s file to pretty it up.

virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI)

Create the default sections and set the initial one.

virtual void addExplicitComment(const Twine &T)

Add explicit comment T.

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

void finish(SMLoc EndLoc=SMLoc())

Finish emission of machine code.

const MCSymbol & getSymbol() const

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())

bool isUndefined() const

isUndefined - Check if this symbol undefined (i.e., implicitly defined).

StringRef getName() const

getName - Get the symbol name.

bool isVariable() const

isVariable - Check if this is a variable symbol.

LLVM_ABI void setVariableValue(const MCExpr *Value)

void setRedefinable(bool Value)

Mark this symbol as redefinable.

void redefineIfPossible()

Prepare this symbol to be redefined.

const MCExpr * getVariableValue() const

Get the expression of the variable symbol.

bool isTemporary() const

isTemporary - Check if this is an assembler temporary symbol.

static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCUnaryExpr * createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCUnaryExpr * createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())

virtual StringRef getBufferIdentifier() const

Return an identifier for this buffer, typically the filename it was read from.

static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")

Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.

StringRef getBuffer() const

constexpr bool isFailure() const

constexpr bool isSuccess() const

LLVM_ABI void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const

SourceMgr::DiagKind getKind() const

StringRef getLineContents() const

StringRef getMessage() const

ArrayRef< std::pair< unsigned, unsigned > > getRanges() const

const SourceMgr * getSourceMgr() const

Represents a location in source code.

static SMLoc getFromPointer(const char *Ptr)

constexpr const char * getPointer() const

constexpr bool isValid() const

void assign(size_type NumElts, ValueParamT Elt)

reference emplace_back(ArgTypes &&... Args)

void reserve(size_type N)

iterator erase(const_iterator CI)

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.

unsigned getMainFileID() const

const MemoryBuffer * getMemoryBuffer(unsigned i) const

LLVM_ABI void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const

Emit a message about the specified location with the specified string.

SMLoc getParentIncludeLoc(unsigned i) const

LLVM_ABI void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const

Prints the names of included files and the line of the file they were included from.

LLVM_ABI unsigned FindBufferContainingLoc(SMLoc Loc) const

Return the ID of the buffer containing the specified location.

void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy

Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...

void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)

Specify a diagnostic handler to be invoked every time PrintMessage is called.

LLVM_ABI unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)

Search for a file with the specified name in the current directory or in one of the IncludeDirs.

unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const

Find the line number for the specified location in the specified file.

unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)

Add a new source buffer to this source manager.

iterator find(StringRef Key)

bool contains(StringRef Key) const

contains - Return true if the element is in the map, false otherwise.

size_type count(StringRef Key) const

count - Return 1 if the element is in the map, 0 otherwise.

ValueTy lookup(StringRef Key) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

StringMapIterBase< ValueTy, true > const_iterator

bool insert(MapEntryTy *KeyValue)

insert - Insert the specified key/value pair into the map.

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

bool consume_back(StringRef Suffix)

Returns true if this StringRef has the given suffix and removes that suffix.

bool getAsInteger(unsigned Radix, T &Result) const

Parse the current string as an integer of the specified radix.

std::string str() const

str - Get the contents as an std::string.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

LLVM_ABI std::string upper() const

Convert the given ASCII string to uppercase.

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

LLVM_ABI std::string lower() const

bool equals_insensitive(StringRef RHS) const

Check for string equality, ignoring case.

StringRef str() const

Return a StringRef for the vector contents.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

constexpr char TypeName[]

Key for Kernel::Arg::Metadata::mTypeName.

constexpr char SymbolName[]

Key for Kernel::Metadata::mSymbolName.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

LLVM_ABI SimpleSymbol parseSymbol(StringRef SymName)

Get symbol classification by parsing the name of a symbol.

std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters

The type of MC/DC-specific parameters.

@ Parameter

An inlay hint that is for a parameter.

Context & getContext() const

LLVM_ABI Instruction & front() const

LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get stem.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

bool errorToBool(Error Err)

Helper for converting an Error to a bool.

FunctionAddr VTableAddr Value

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

LLVM_ABI raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

LLVM_ABI MCAsmParser * createMCMasmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, struct tm, unsigned CB=0)

Create an MCAsmParser instance for parsing Microsoft MASM-style assembly.

Definition MasmParser.cpp:6265

constexpr bool isUIntN(unsigned N, uint64_t x)

Checks if an unsigned integer fits into the given (dynamic) bit width.

constexpr bool isPowerOf2_64(uint64_t Value)

Return true if the argument is a power of two > 0 (64 bit edition.)

std::vector< MCAsmMacroParameter > MCAsmMacroParameters

auto unique(Range &&R, Predicate P)

unsigned Log2_64(uint64_t Value)

Return the floor log base 2 of the specified value, -1 if the value is zero.

auto dyn_cast_or_null(const Y &Val)

cl::opt< unsigned > AsmMacroMaxNestingDepth

Definition MasmParser.cpp:964

const char AsmRewritePrecedence[]

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionAddr VTableAddr Count

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

bool isAlnum(char C)

Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)

format_hex_no_prefix - Output N as a fixed width hexadecimal.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

MutableArrayRef(T &OneElt) -> MutableArrayRef< T >

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

ArrayRef(const T &OneElt) -> ArrayRef< T >

constexpr bool isIntN(unsigned N, int64_t x)

Checks if an signed integer fits into the given (dynamic) bit width.

bool isSpace(char C)

Checks whether character C is whitespace in the "C" locale.

void array_pod_sort(IteratorTy Start, IteratorTy End)

array_pod_sort - This sorts an array with the specified start and end extent.

@ MCSA_Global

.type _foo, @gnu_unique_object

@ MCSA_Extern

.extern (XCOFF)

std::vector< AsmToken > Value

uint64_t Offset

The offset of this field in the final layout.