Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/MC/MCParser/COFFAsmParser.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "llvm/MC/MCParser/MCAsmParserExtension.h" | 10 #include "llvm/ADT/StringRef.h" |
11 #include "llvm/ADT/StringSwitch.h" | 11 #include "llvm/ADT/StringSwitch.h" |
12 #include "llvm/ADT/Triple.h" | |
12 #include "llvm/ADT/Twine.h" | 13 #include "llvm/ADT/Twine.h" |
13 #include "llvm/MC/MCAsmInfo.h" | 14 #include "llvm/BinaryFormat/COFF.h" |
14 #include "llvm/MC/MCContext.h" | 15 #include "llvm/MC/MCContext.h" |
15 #include "llvm/MC/MCExpr.h" | 16 #include "llvm/MC/MCDirectives.h" |
16 #include "llvm/MC/MCObjectFileInfo.h" | 17 #include "llvm/MC/MCObjectFileInfo.h" |
17 #include "llvm/MC/MCParser/MCAsmLexer.h" | 18 #include "llvm/MC/MCParser/MCAsmLexer.h" |
19 #include "llvm/MC/MCParser/MCAsmParserExtension.h" | |
18 #include "llvm/MC/MCParser/MCTargetAsmParser.h" | 20 #include "llvm/MC/MCParser/MCTargetAsmParser.h" |
19 #include "llvm/MC/MCRegisterInfo.h" | 21 #include "llvm/MC/MCRegisterInfo.h" |
20 #include "llvm/MC/MCSectionCOFF.h" | 22 #include "llvm/MC/MCSectionCOFF.h" |
21 #include "llvm/MC/MCStreamer.h" | 23 #include "llvm/MC/MCStreamer.h" |
22 #include "llvm/Support/COFF.h" | 24 #include "llvm/MC/SectionKind.h" |
25 #include "llvm/Support/SMLoc.h" | |
26 #include <cassert> | |
27 #include <cstdint> | |
28 #include <limits> | |
29 #include <utility> | |
30 | |
23 using namespace llvm; | 31 using namespace llvm; |
24 | 32 |
25 namespace { | 33 namespace { |
26 | 34 |
27 class COFFAsmParser : public MCAsmParserExtension { | 35 class COFFAsmParser : public MCAsmParserExtension { |
96 COFF::IMAGE_SCN_CNT_CODE | 104 COFF::IMAGE_SCN_CNT_CODE |
97 | COFF::IMAGE_SCN_MEM_EXECUTE | 105 | COFF::IMAGE_SCN_MEM_EXECUTE |
98 | COFF::IMAGE_SCN_MEM_READ, | 106 | COFF::IMAGE_SCN_MEM_READ, |
99 SectionKind::getText()); | 107 SectionKind::getText()); |
100 } | 108 } |
109 | |
101 bool ParseSectionDirectiveData(StringRef, SMLoc) { | 110 bool ParseSectionDirectiveData(StringRef, SMLoc) { |
102 return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | | 111 return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
103 COFF::IMAGE_SCN_MEM_READ | | 112 COFF::IMAGE_SCN_MEM_READ | |
104 COFF::IMAGE_SCN_MEM_WRITE, | 113 COFF::IMAGE_SCN_MEM_WRITE, |
105 SectionKind::getData()); | 114 SectionKind::getData()); |
106 } | 115 } |
116 | |
107 bool ParseSectionDirectiveBSS(StringRef, SMLoc) { | 117 bool ParseSectionDirectiveBSS(StringRef, SMLoc) { |
108 return ParseSectionSwitch(".bss", | 118 return ParseSectionSwitch(".bss", |
109 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 119 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
110 | COFF::IMAGE_SCN_MEM_READ | 120 | COFF::IMAGE_SCN_MEM_READ |
111 | COFF::IMAGE_SCN_MEM_WRITE, | 121 | COFF::IMAGE_SCN_MEM_WRITE, |
139 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc); | 149 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc); |
140 | 150 |
141 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); | 151 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); |
142 bool ParseSEHRegisterNumber(unsigned &RegNo); | 152 bool ParseSEHRegisterNumber(unsigned &RegNo); |
143 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc); | 153 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc); |
154 | |
144 public: | 155 public: |
145 COFFAsmParser() {} | 156 COFFAsmParser() = default; |
146 }; | 157 }; |
147 | 158 |
148 } // end annonomous namespace. | 159 } // end annonomous namespace. |
149 | 160 |
150 static SectionKind computeSectionKind(unsigned Flags) { | 161 static SectionKind computeSectionKind(unsigned Flags) { |
275 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) | 286 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) |
276 .Case(".weak", MCSA_Weak) | 287 .Case(".weak", MCSA_Weak) |
277 .Default(MCSA_Invalid); | 288 .Default(MCSA_Invalid); |
278 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); | 289 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); |
279 if (getLexer().isNot(AsmToken::EndOfStatement)) { | 290 if (getLexer().isNot(AsmToken::EndOfStatement)) { |
280 for (;;) { | 291 while (true) { |
281 StringRef Name; | 292 StringRef Name; |
282 | 293 |
283 if (getParser().parseIdentifier(Name)) | 294 if (getParser().parseIdentifier(Name)) |
284 return TokError("expected identifier in directive"); | 295 return TokError("expected identifier in directive"); |
285 | 296 |
453 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { | 464 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { |
454 StringRef SymbolID; | 465 StringRef SymbolID; |
455 if (getParser().parseIdentifier(SymbolID)) | 466 if (getParser().parseIdentifier(SymbolID)) |
456 return TokError("expected identifier in directive"); | 467 return TokError("expected identifier in directive"); |
457 | 468 |
458 if (getLexer().isNot(AsmToken::EndOfStatement)) | 469 int64_t Offset = 0; |
459 return TokError("unexpected token in directive"); | 470 SMLoc OffsetLoc; |
471 if (getLexer().is(AsmToken::Plus)) { | |
472 OffsetLoc = getLexer().getLoc(); | |
473 if (getParser().parseAbsoluteExpression(Offset)) | |
474 return true; | |
475 } | |
476 | |
477 if (getLexer().isNot(AsmToken::EndOfStatement)) | |
478 return TokError("unexpected token in directive"); | |
479 | |
480 if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max()) | |
481 return Error( | |
482 OffsetLoc, | |
483 "invalid '.secrel32' directive offset, can't be less " | |
484 "than zero or greater than std::numeric_limits<uint32_t>::max()"); | |
460 | 485 |
461 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); | 486 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); |
462 | 487 |
463 Lex(); | 488 Lex(); |
464 getStreamer().EmitCOFFSecRel32(Symbol); | 489 getStreamer().EmitCOFFSecRel32(Symbol, Offset); |
465 return false; | 490 return false; |
466 } | 491 } |
467 | 492 |
468 bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) { | 493 bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) { |
469 StringRef SymbolID; | 494 StringRef SymbolID; |
541 return TokError("unexpected token in directive"); | 566 return TokError("unexpected token in directive"); |
542 | 567 |
543 return false; | 568 return false; |
544 } | 569 } |
545 | 570 |
546 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { | 571 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) { |
547 StringRef SymbolID; | 572 StringRef SymbolID; |
548 if (getParser().parseIdentifier(SymbolID)) | 573 if (getParser().parseIdentifier(SymbolID)) |
549 return true; | 574 return true; |
550 | 575 |
551 if (getLexer().isNot(AsmToken::EndOfStatement)) | 576 if (getLexer().isNot(AsmToken::EndOfStatement)) |
552 return TokError("unexpected token in directive"); | 577 return TokError("unexpected token in directive"); |
553 | 578 |
554 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); | 579 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); |
555 | 580 |
556 Lex(); | 581 Lex(); |
557 getStreamer().EmitWinCFIStartProc(Symbol); | 582 getStreamer().EmitWinCFIStartProc(Symbol, Loc); |
558 return false; | 583 return false; |
559 } | 584 } |
560 | 585 |
561 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) { | 586 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) { |
562 Lex(); | 587 Lex(); |
563 getStreamer().EmitWinCFIEndProc(); | 588 getStreamer().EmitWinCFIEndProc(Loc); |
564 return false; | 589 return false; |
565 } | 590 } |
566 | 591 |
567 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) { | 592 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) { |
568 Lex(); | 593 Lex(); |
569 getStreamer().EmitWinCFIStartChained(); | 594 getStreamer().EmitWinCFIStartChained(Loc); |
570 return false; | 595 return false; |
571 } | 596 } |
572 | 597 |
573 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) { | 598 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) { |
574 Lex(); | 599 Lex(); |
575 getStreamer().EmitWinCFIEndChained(); | 600 getStreamer().EmitWinCFIEndChained(Loc); |
576 return false; | 601 return false; |
577 } | 602 } |
578 | 603 |
579 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) { | 604 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) { |
580 StringRef SymbolID; | 605 StringRef SymbolID; |
581 if (getParser().parseIdentifier(SymbolID)) | 606 if (getParser().parseIdentifier(SymbolID)) |
582 return true; | 607 return true; |
583 | 608 |
584 if (getLexer().isNot(AsmToken::Comma)) | 609 if (getLexer().isNot(AsmToken::Comma)) |
596 return TokError("unexpected token in directive"); | 621 return TokError("unexpected token in directive"); |
597 | 622 |
598 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID); | 623 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID); |
599 | 624 |
600 Lex(); | 625 Lex(); |
601 getStreamer().EmitWinEHHandler(handler, unwind, except); | 626 getStreamer().EmitWinEHHandler(handler, unwind, except, Loc); |
602 return false; | 627 return false; |
603 } | 628 } |
604 | 629 |
605 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) { | 630 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) { |
606 Lex(); | 631 Lex(); |
607 getStreamer().EmitWinEHHandlerData(); | 632 getStreamer().EmitWinEHHandlerData(); |
608 return false; | 633 return false; |
609 } | 634 } |
610 | 635 |
611 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) { | 636 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) { |
612 unsigned Reg = 0; | 637 unsigned Reg = 0; |
613 if (ParseSEHRegisterNumber(Reg)) | 638 if (ParseSEHRegisterNumber(Reg)) |
614 return true; | 639 return true; |
615 | 640 |
616 if (getLexer().isNot(AsmToken::EndOfStatement)) | 641 if (getLexer().isNot(AsmToken::EndOfStatement)) |
617 return TokError("unexpected token in directive"); | 642 return TokError("unexpected token in directive"); |
618 | 643 |
619 Lex(); | 644 Lex(); |
620 getStreamer().EmitWinCFIPushReg(Reg); | 645 getStreamer().EmitWinCFIPushReg(Reg, Loc); |
621 return false; | 646 return false; |
622 } | 647 } |
623 | 648 |
624 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) { | 649 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) { |
625 unsigned Reg = 0; | 650 unsigned Reg = 0; |
626 int64_t Off; | 651 int64_t Off; |
627 if (ParseSEHRegisterNumber(Reg)) | 652 if (ParseSEHRegisterNumber(Reg)) |
628 return true; | 653 return true; |
629 if (getLexer().isNot(AsmToken::Comma)) | 654 if (getLexer().isNot(AsmToken::Comma)) |
630 return TokError("you must specify a stack pointer offset"); | 655 return TokError("you must specify a stack pointer offset"); |
631 | 656 |
632 Lex(); | 657 Lex(); |
633 SMLoc startLoc = getLexer().getLoc(); | |
634 if (getParser().parseAbsoluteExpression(Off)) | 658 if (getParser().parseAbsoluteExpression(Off)) |
635 return true; | 659 return true; |
636 | 660 |
637 if (Off & 0x0F) | 661 if (getLexer().isNot(AsmToken::EndOfStatement)) |
638 return Error(startLoc, "offset is not a multiple of 16"); | 662 return TokError("unexpected token in directive"); |
639 | 663 |
640 if (getLexer().isNot(AsmToken::EndOfStatement)) | 664 Lex(); |
641 return TokError("unexpected token in directive"); | 665 getStreamer().EmitWinCFISetFrame(Reg, Off, Loc); |
642 | 666 return false; |
643 Lex(); | 667 } |
644 getStreamer().EmitWinCFISetFrame(Reg, Off); | 668 |
645 return false; | 669 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) { |
646 } | |
647 | |
648 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) { | |
649 int64_t Size; | 670 int64_t Size; |
650 SMLoc startLoc = getLexer().getLoc(); | |
651 if (getParser().parseAbsoluteExpression(Size)) | 671 if (getParser().parseAbsoluteExpression(Size)) |
652 return true; | 672 return true; |
653 | 673 |
654 if (Size & 7) | 674 if (getLexer().isNot(AsmToken::EndOfStatement)) |
655 return Error(startLoc, "size is not a multiple of 8"); | 675 return TokError("unexpected token in directive"); |
656 | 676 |
657 if (getLexer().isNot(AsmToken::EndOfStatement)) | 677 Lex(); |
658 return TokError("unexpected token in directive"); | 678 getStreamer().EmitWinCFIAllocStack(Size, Loc); |
659 | 679 return false; |
660 Lex(); | 680 } |
661 getStreamer().EmitWinCFIAllocStack(Size); | 681 |
662 return false; | 682 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) { |
663 } | |
664 | |
665 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) { | |
666 unsigned Reg = 0; | 683 unsigned Reg = 0; |
667 int64_t Off; | 684 int64_t Off; |
668 if (ParseSEHRegisterNumber(Reg)) | 685 if (ParseSEHRegisterNumber(Reg)) |
669 return true; | 686 return true; |
670 if (getLexer().isNot(AsmToken::Comma)) | 687 if (getLexer().isNot(AsmToken::Comma)) |
671 return TokError("you must specify an offset on the stack"); | 688 return TokError("you must specify an offset on the stack"); |
672 | 689 |
673 Lex(); | 690 Lex(); |
674 SMLoc startLoc = getLexer().getLoc(); | |
675 if (getParser().parseAbsoluteExpression(Off)) | 691 if (getParser().parseAbsoluteExpression(Off)) |
676 return true; | 692 return true; |
677 | 693 |
678 if (Off & 7) | |
679 return Error(startLoc, "size is not a multiple of 8"); | |
680 | |
681 if (getLexer().isNot(AsmToken::EndOfStatement)) | 694 if (getLexer().isNot(AsmToken::EndOfStatement)) |
682 return TokError("unexpected token in directive"); | 695 return TokError("unexpected token in directive"); |
683 | 696 |
684 Lex(); | 697 Lex(); |
685 // FIXME: Err on %xmm* registers | 698 // FIXME: Err on %xmm* registers |
686 getStreamer().EmitWinCFISaveReg(Reg, Off); | 699 getStreamer().EmitWinCFISaveReg(Reg, Off, Loc); |
687 return false; | 700 return false; |
688 } | 701 } |
689 | 702 |
690 // FIXME: This method is inherently x86-specific. It should really be in the | 703 // FIXME: This method is inherently x86-specific. It should really be in the |
691 // x86 backend. | 704 // x86 backend. |
692 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) { | 705 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc Loc) { |
693 unsigned Reg = 0; | 706 unsigned Reg = 0; |
694 int64_t Off; | 707 int64_t Off; |
695 if (ParseSEHRegisterNumber(Reg)) | 708 if (ParseSEHRegisterNumber(Reg)) |
696 return true; | 709 return true; |
697 if (getLexer().isNot(AsmToken::Comma)) | 710 if (getLexer().isNot(AsmToken::Comma)) |
698 return TokError("you must specify an offset on the stack"); | 711 return TokError("you must specify an offset on the stack"); |
699 | 712 |
700 Lex(); | 713 Lex(); |
701 SMLoc startLoc = getLexer().getLoc(); | |
702 if (getParser().parseAbsoluteExpression(Off)) | 714 if (getParser().parseAbsoluteExpression(Off)) |
703 return true; | 715 return true; |
704 | 716 |
705 if (getLexer().isNot(AsmToken::EndOfStatement)) | 717 if (getLexer().isNot(AsmToken::EndOfStatement)) |
706 return TokError("unexpected token in directive"); | 718 return TokError("unexpected token in directive"); |
707 | 719 |
708 if (Off & 0x0F) | |
709 return Error(startLoc, "offset is not a multiple of 16"); | |
710 | |
711 Lex(); | 720 Lex(); |
712 // FIXME: Err on non-%xmm* registers | 721 // FIXME: Err on non-%xmm* registers |
713 getStreamer().EmitWinCFISaveXMM(Reg, Off); | 722 getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc); |
714 return false; | 723 return false; |
715 } | 724 } |
716 | 725 |
717 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) { | 726 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) { |
718 bool Code = false; | 727 bool Code = false; |
719 StringRef CodeID; | 728 StringRef CodeID; |
720 if (getLexer().is(AsmToken::At)) { | 729 if (getLexer().is(AsmToken::At)) { |
721 SMLoc startLoc = getLexer().getLoc(); | 730 SMLoc startLoc = getLexer().getLoc(); |
722 Lex(); | 731 Lex(); |
729 | 738 |
730 if (getLexer().isNot(AsmToken::EndOfStatement)) | 739 if (getLexer().isNot(AsmToken::EndOfStatement)) |
731 return TokError("unexpected token in directive"); | 740 return TokError("unexpected token in directive"); |
732 | 741 |
733 Lex(); | 742 Lex(); |
734 getStreamer().EmitWinCFIPushFrame(Code); | 743 getStreamer().EmitWinCFIPushFrame(Code, Loc); |
735 return false; | 744 return false; |
736 } | 745 } |
737 | 746 |
738 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) { | 747 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) { |
739 Lex(); | 748 Lex(); |
740 getStreamer().EmitWinCFIEndProlog(); | 749 getStreamer().EmitWinCFIEndProlog(Loc); |
741 return false; | 750 return false; |
742 } | 751 } |
743 | 752 |
744 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { | 753 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { |
745 StringRef identifier; | 754 StringRef identifier; |
802 | 811 |
803 MCAsmParserExtension *createCOFFAsmParser() { | 812 MCAsmParserExtension *createCOFFAsmParser() { |
804 return new COFFAsmParser; | 813 return new COFFAsmParser; |
805 } | 814 } |
806 | 815 |
807 } | 816 } // end namespace llvm |