LLVM: lib/MC/MCParser/AsmParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
59#include
60#include
61#include
62#include
63#include
64#include
65#include
66#include
67#include
68#include
69#include
70#include
71#include
72#include
73
74using namespace llvm;
75
77
78namespace {
79
80
81typedef std::vector MCAsmMacroArgument;
82typedef std::vector MCAsmMacroArguments;
83
84
85
86struct MacroInstantiation {
87
88 SMLoc InstantiationLoc;
89
90
91 unsigned ExitBuffer;
92
93
95
96
97 size_t CondStackDepth;
98};
99
100struct ParseStatementInfo {
101
103
104
105 unsigned Opcode = ~0U;
106
107
108 bool ParseError = false;
109
111
112 ParseStatementInfo() = delete;
114 : AsmRewrites(rewrites) {}
115};
116
117
119private:
126 void *SavedDiagContext;
127 std::unique_ptr PlatformParser;
128 SMLoc StartTokLoc;
129 std::optional CFIStartProcLoc;
130
131
132
133 unsigned CurBuffer;
134
136 std::vector TheCondStack;
137
138
139
140
142
143
144 std::vector<MacroInstantiation*> ActiveMacros;
145
146
147 std::deque MacroLikeBodies;
148
149
150 unsigned MacrosEnabledFlag : 1;
151
152
153 unsigned NumOfMacroInstantiations;
154
155
156 struct CppHashInfoTy {
158 int64_t LineNumber;
160 unsigned Buf;
161 CppHashInfoTy() : LineNumber(0), Buf(0) {}
162 };
163 CppHashInfoTy CppHashInfo;
164
165
166 bool HadCppHashFilename = false;
167
168
170
172
173
174 unsigned AssemblerDialect = ~0U;
175
176
177 bool IsDarwin = false;
178
179
180 bool ParsingMSInlineAsm = false;
181
182
183 bool ReportedInconsistentMD5 = false;
184
185
186 bool AltMacroMode = false;
187
188protected:
189 virtual bool parseStatement(ParseStatementInfo &Info,
191
192
193
194
195 bool parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
198
199
200
201
202 bool enabledGenDwarfForAssembly();
203
204public:
206 const MCAsmInfo &MAI, unsigned CB);
207 AsmParser(const AsmParser &) = delete;
208 AsmParser &operator=(const AsmParser &) = delete;
209 ~AsmParser() override;
210
211 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
212
214 ExtensionDirectiveHandler Handler) override {
215 ExtensionDirectiveMap[Directive] = Handler;
216 }
217
219 DirectiveKindMap[Directive.lower()] = DirectiveKindMap[Alias.lower()];
220 }
221
222
223
224
229
231
233 if (AssemblerDialect == ~0U)
235 else
236 return AssemblerDialect;
237 }
239 AssemblerDialect = i;
240 }
241
247
249
251 ParsingMSInlineAsm = V;
252
253
255 }
257
260 }
261
262 bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs,
263 unsigned &NumInputs,
269
276 SMLoc &EndLoc) override;
278
279
280
282
283
284
287
289
290
291
292private:
294 bool parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo = true);
295
301
302
303 bool areMacrosEnabled() {return MacrosEnabledFlag;}
304
305
306 void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
307
308
309 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
310
311
312
313
314
316
317
318 void handleMacroExit();
319
320
321 bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg);
322
323
324 bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
325
326 void printMacroInstantiations();
331 }
333
334
335 bool enterIncludeFile(const std::string &Filename);
336
337
338
339 bool processIncbinFile(const std::string &Filename, int64_t Skip = 0,
341
342
343
344
345
346
347
348 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0);
349
350
351
352
354
355
356
358
359 enum class AssignmentKind {
361 Equiv,
363 LTOSetConditional,
364 };
365
366 bool parseAssignment(StringRef Name, AssignmentKind Kind);
367
370
371 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
372 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
373 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
374
375 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
376
378 bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
379
380
381 enum DirectiveKind {
382 DK_NO_DIRECTIVE,
383 DK_SET,
384 DK_EQU,
385 DK_EQUIV,
386 DK_ASCII,
387 DK_ASCIZ,
388 DK_STRING,
389 DK_BYTE,
390 DK_SHORT,
391 DK_RELOC,
392 DK_VALUE,
393 DK_2BYTE,
394 DK_LONG,
395 DK_INT,
396 DK_4BYTE,
397 DK_QUAD,
398 DK_8BYTE,
399 DK_OCTA,
400 DK_DC,
401 DK_DC_A,
402 DK_DC_B,
403 DK_DC_D,
404 DK_DC_L,
405 DK_DC_S,
406 DK_DC_W,
407 DK_DC_X,
408 DK_DCB,
409 DK_DCB_B,
410 DK_DCB_D,
411 DK_DCB_L,
412 DK_DCB_S,
413 DK_DCB_W,
414 DK_DCB_X,
415 DK_DS,
416 DK_DS_B,
417 DK_DS_D,
418 DK_DS_L,
419 DK_DS_P,
420 DK_DS_S,
421 DK_DS_W,
422 DK_DS_X,
423 DK_SINGLE,
424 DK_FLOAT,
425 DK_DOUBLE,
426 DK_ALIGN,
427 DK_ALIGN32,
428 DK_BALIGN,
429 DK_BALIGNW,
430 DK_BALIGNL,
431 DK_P2ALIGN,
432 DK_P2ALIGNW,
433 DK_P2ALIGNL,
434 DK_ORG,
435 DK_FILL,
436 DK_ENDR,
437 DK_BUNDLE_ALIGN_MODE,
438 DK_BUNDLE_LOCK,
439 DK_BUNDLE_UNLOCK,
440 DK_ZERO,
441 DK_EXTERN,
442 DK_GLOBL,
443 DK_GLOBAL,
444 DK_LAZY_REFERENCE,
445 DK_NO_DEAD_STRIP,
446 DK_SYMBOL_RESOLVER,
447 DK_PRIVATE_EXTERN,
448 DK_REFERENCE,
449 DK_WEAK_DEFINITION,
450 DK_WEAK_REFERENCE,
451 DK_WEAK_DEF_CAN_BE_HIDDEN,
452 DK_COLD,
453 DK_COMM,
454 DK_COMMON,
455 DK_LCOMM,
456 DK_ABORT,
457 DK_INCLUDE,
458 DK_INCBIN,
459 DK_CODE16,
460 DK_CODE16GCC,
461 DK_REPT,
462 DK_IRP,
463 DK_IRPC,
464 DK_IF,
465 DK_IFEQ,
466 DK_IFGE,
467 DK_IFGT,
468 DK_IFLE,
469 DK_IFLT,
470 DK_IFNE,
471 DK_IFB,
472 DK_IFNB,
473 DK_IFC,
474 DK_IFEQS,
475 DK_IFNC,
476 DK_IFNES,
477 DK_IFDEF,
478 DK_IFNDEF,
479 DK_IFNOTDEF,
480 DK_ELSEIF,
481 DK_ELSE,
482 DK_ENDIF,
483 DK_SPACE,
484 DK_SKIP,
485 DK_FILE,
486 DK_LINE,
487 DK_LOC,
488 DK_LOC_LABEL,
489 DK_STABS,
490 DK_CV_FILE,
491 DK_CV_FUNC_ID,
492 DK_CV_INLINE_SITE_ID,
493 DK_CV_LOC,
494 DK_CV_LINETABLE,
495 DK_CV_INLINE_LINETABLE,
496 DK_CV_DEF_RANGE,
497 DK_CV_STRINGTABLE,
498 DK_CV_STRING,
499 DK_CV_FILECHECKSUMS,
500 DK_CV_FILECHECKSUM_OFFSET,
501 DK_CV_FPO_DATA,
502 DK_CFI_SECTIONS,
503 DK_CFI_STARTPROC,
504 DK_CFI_ENDPROC,
505 DK_CFI_DEF_CFA,
506 DK_CFI_DEF_CFA_OFFSET,
507 DK_CFI_ADJUST_CFA_OFFSET,
508 DK_CFI_DEF_CFA_REGISTER,
509 DK_CFI_LLVM_DEF_ASPACE_CFA,
510 DK_CFI_OFFSET,
511 DK_CFI_REL_OFFSET,
512 DK_CFI_PERSONALITY,
513 DK_CFI_LSDA,
514 DK_CFI_REMEMBER_STATE,
515 DK_CFI_RESTORE_STATE,
516 DK_CFI_SAME_VALUE,
517 DK_CFI_RESTORE,
518 DK_CFI_ESCAPE,
519 DK_CFI_RETURN_COLUMN,
520 DK_CFI_SIGNAL_FRAME,
521 DK_CFI_UNDEFINED,
522 DK_CFI_REGISTER,
523 DK_CFI_WINDOW_SAVE,
524 DK_CFI_LABEL,
525 DK_CFI_B_KEY_FRAME,
526 DK_CFI_VAL_OFFSET,
527 DK_MACROS_ON,
528 DK_MACROS_OFF,
529 DK_ALTMACRO,
530 DK_NOALTMACRO,
531 DK_MACRO,
532 DK_EXITM,
533 DK_ENDM,
534 DK_ENDMACRO,
535 DK_PURGEM,
536 DK_SLEB128,
537 DK_ULEB128,
538 DK_ERR,
539 DK_ERROR,
540 DK_WARNING,
541 DK_PRINT,
542 DK_ADDRSIG,
543 DK_ADDRSIG_SYM,
544 DK_PSEUDO_PROBE,
545 DK_LTO_DISCARD,
546 DK_LTO_SET_CONDITIONAL,
547 DK_CFI_MTE_TAGGED_FRAME,
548 DK_MEMTAG,
549 DK_END
550 };
551
552
553
555
556
557 enum CVDefRangeType {
558 CVDR_DEFRANGE = 0,
559 CVDR_DEFRANGE_REGISTER,
560 CVDR_DEFRANGE_FRAMEPOINTER_REL,
561 CVDR_DEFRANGE_SUBFIELD_REGISTER,
562 CVDR_DEFRANGE_REGISTER_REL
563 };
564
565
566
568
569
570 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
571 bool parseDirectiveReloc(SMLoc DirectiveLoc);
572 bool parseDirectiveValue(StringRef IDVal,
573 unsigned Size);
574 bool parseDirectiveOctaValue(StringRef IDVal);
575 bool parseDirectiveRealValue(StringRef IDVal,
577 bool parseDirectiveFill();
578 bool parseDirectiveZero();
579
580 bool parseDirectiveSet(StringRef IDVal, AssignmentKind Kind);
581 bool parseDirectiveOrg();
582
583 bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
584
585
586 bool parseDirectiveFile(SMLoc DirectiveLoc);
587 bool parseDirectiveLine();
588 bool parseDirectiveLoc();
589 bool parseDirectiveLocLabel(SMLoc DirectiveLoc);
590 bool parseDirectiveStabs();
591
592
593
594 bool parseDirectiveCVFile();
595 bool parseDirectiveCVFuncId();
596 bool parseDirectiveCVInlineSiteId();
597 bool parseDirectiveCVLoc();
598 bool parseDirectiveCVLinetable();
599 bool parseDirectiveCVInlineLinetable();
600 bool parseDirectiveCVDefRange();
601 bool parseDirectiveCVString();
602 bool parseDirectiveCVStringTable();
603 bool parseDirectiveCVFileChecksums();
604 bool parseDirectiveCVFileChecksumOffset();
605 bool parseDirectiveCVFPOData();
606
607
608 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
609 bool parseDirectiveCFIWindowSave(SMLoc DirectiveLoc);
610 bool parseDirectiveCFISections();
611 bool parseDirectiveCFIStartProc();
612 bool parseDirectiveCFIEndProc();
613 bool parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc);
614 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
615 bool parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc);
616 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
617 bool parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc);
618 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
619 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
620 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
621 bool parseDirectiveCFIRememberState(SMLoc DirectiveLoc);
622 bool parseDirectiveCFIRestoreState(SMLoc DirectiveLoc);
623 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
624 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
625 bool parseDirectiveCFIEscape(SMLoc DirectiveLoc);
626 bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
627 bool parseDirectiveCFISignalFrame(SMLoc DirectiveLoc);
628 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
629 bool parseDirectiveCFILabel(SMLoc DirectiveLoc);
630 bool parseDirectiveCFIValOffset(SMLoc DirectiveLoc);
631
632
633 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
636 bool parseDirectiveMacro(SMLoc DirectiveLoc);
638
640
641 bool parseDirectiveBundleAlignMode();
642
643 bool parseDirectiveBundleLock();
644
645 bool parseDirectiveBundleUnlock();
646
647
648 bool parseDirectiveSpace(StringRef IDVal);
649
650
651 bool parseDirectiveDCB(StringRef IDVal, unsigned Size);
653
654 bool parseDirectiveDS(StringRef IDVal, unsigned Size);
655
656
657 bool parseDirectiveLEB128(bool Signed);
658
659
660
661 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
662
663 bool parseDirectiveComm(bool IsLocal);
664
665 bool parseDirectiveAbort(SMLoc DirectiveLoc);
666 bool parseDirectiveInclude();
667 bool parseDirectiveIncbin();
668
669
670 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
671
672 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
673
674 bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
675
676 bool parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual);
677
678 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
679 bool parseDirectiveElseIf(SMLoc DirectiveLoc);
680 bool parseDirectiveElse(SMLoc DirectiveLoc);
681 bool parseDirectiveEndIf(SMLoc DirectiveLoc);
684
685 const MCExpr *applyModifierToExpr(const MCExpr *E,
687
688
690 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
693 bool parseDirectiveIrp(SMLoc DirectiveLoc);
694 bool parseDirectiveIrpc(SMLoc DirectiveLoc);
695 bool parseDirectiveEndr(SMLoc DirectiveLoc);
696
697
698 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
699 size_t Len);
700
701
702 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
703
704
705 bool parseDirectiveEnd(SMLoc DirectiveLoc);
706
707
708 bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
709
710
711 bool parseDirectiveWarning(SMLoc DirectiveLoc);
712
713
714 bool parseDirectivePrint(SMLoc DirectiveLoc);
715
716
717 bool parseDirectivePseudoProbe();
718
719
720 bool parseDirectiveLTODiscard();
721
722
723 bool parseDirectiveAddrsig();
724 bool parseDirectiveAddrsigSym();
725
726 void initializeDirectiveKindMap();
727 void initializeCVDefRangeTypeMap();
728};
729
730class HLASMAsmParser final : public AsmParser {
731private:
734
735 void lexLeadingSpaces() {
737 Lexer.Lex();
738 }
739
741 bool parseAsMachineInstruction(ParseStatementInfo &Info,
743
744public:
746 const MCAsmInfo &MAI, unsigned CB = 0)
747 : AsmParser(SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
752 }
753
754 ~HLASMAsmParser() { Lexer.setSkipSpace(true); }
755
756 bool parseStatement(ParseStatementInfo &Info,
758};
759
760}
761
762namespace llvm {
763
765
772
773}
774
776
778 const MCAsmInfo &MAI, unsigned CB = 0)
779 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
780 CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
781 HadError = false;
782
785
788
790
791
795 break;
798 IsDarwin = true;
799 break;
802 break;
805 break;
808 "Need to implement createSPIRVAsmParser for SPIRV format.");
809 break;
812 break;
815 break;
818 break;
819 }
820
821 PlatformParser->Initialize(*this);
822 initializeDirectiveKindMap();
823 initializeCVDefRangeTypeMap();
824
825 NumOfMacroInstantiations = 0;
826}
827
828AsmParser::~AsmParser() {
829 assert((HadError || ActiveMacros.empty()) &&
830 "Unexpected active macro instantiation!");
831
832
834
835
837}
838
839void AsmParser::printMacroInstantiations() {
840
841 for (MacroInstantiation *M : reverse(ActiveMacros))
843 "while in macro instantiation");
844}
845
847 printPendingErrors();
849 printMacroInstantiations();
850}
851
853 if(getTargetParser().getTargetOptions().MCNoWarn)
854 return false;
855 if (getTargetParser().getTargetOptions().MCFatalWarnings)
858 printMacroInstantiations();
859 return false;
860}
861
863 HadError = true;
865 printMacroInstantiations();
866 return true;
867}
868
869bool AsmParser::enterIncludeFile(const std::string &Filename) {
870 std::string IncludedFile;
871 unsigned NewBuf =
873 if (!NewBuf)
874 return true;
875
876 CurBuffer = NewBuf;
878 return false;
879}
880
881
882
883
884bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
886 std::string IncludedFile;
887 unsigned NewBuf =
889 if (!NewBuf)
890 return true;
891
892
895 if (Count) {
896 int64_t Res;
897 if (!Count->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
898 return Error(Loc, "expected absolute expression");
899 if (Res < 0)
900 return Warning(Loc, "negative count has no effect");
902 }
903 getStreamer().emitBytes(Bytes);
904 return false;
905}
906
907void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
911}
912
913const AsmToken &AsmParser::Lex() {
916
917
919
920 if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
923 }
924
926
927
931 tok = &Lexer.Lex();
932 }
933
935
936
938 if (ParentIncludeLoc != SMLoc()) {
939 jumpToLoc(ParentIncludeLoc);
940 return Lex();
941 }
942 }
943
944 return *tok;
945}
946
947bool AsmParser::enabledGenDwarfForAssembly() {
948
949 if (!getContext().getGenDwarfForAssembly())
950 return false;
951
952
953
954 if (getContext().getGenDwarfFileNumber() == 0) {
956 getContext().getMCDwarfLineTable(0).getRootFile();
957 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
958 0, getContext().getCompilationDir(), RootFile.Name,
960 }
961 return true;
962}
963
964bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
965 LTODiscardSymbols.clear();
966
967
968 if (!NoInitialTextSection)
969 Out.initSections(false, getTargetParser().getSTI());
970
971
972 Lex();
973
974 HadError = false;
975 AsmCond StartingCondState = TheCondState;
977
978
979
980
981
982 if (getContext().getGenDwarfForAssembly()) {
983 MCSection *Sec = getStreamer().getCurrentSectionOnly();
985 MCSymbol *SectionStartSym = getContext().createTempSymbol();
986 getStreamer().emitLabel(SectionStartSym);
988 }
989 bool InsertResult = getContext().addGenDwarfSection(Sec);
990 assert(InsertResult && ".text section should not have debug info yet");
991 (void)InsertResult;
992 }
993
994 getTargetParser().onBeginOfFile();
995
996
998 ParseStatementInfo Info(&AsmStrRewrites);
999 bool Parsed = parseStatement(Info, nullptr);
1000
1001
1002
1003
1005 Lex();
1006 }
1007
1008
1009 printPendingErrors();
1010
1011
1012 if (Parsed && !getLexer().isAtStartOfStatement())
1013 eatToEndOfStatement();
1014 }
1015
1016 getTargetParser().onEndOfFile();
1017 printPendingErrors();
1018
1019
1020 assert(!hasPendingError() && "unexpected error from parseStatement");
1021
1022 getTargetParser().flushPendingInstructions(getStreamer());
1023
1024 if (TheCondState.TheCond != StartingCondState.TheCond ||
1025 TheCondState.Ignore != StartingCondState.Ignore)
1026 printError(getTok().getLoc(), "unmatched .ifs or .elses");
1027
1028 const auto &LineTables = getContext().getMCDwarfLineTables();
1029 if (!LineTables.empty()) {
1030 unsigned Index = 0;
1031 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1032 if (File.Name.empty() && Index != 0)
1033 printError(getTok().getLoc(), "unassigned file number: " +
1035 " for .file directives");
1037 }
1038 }
1039
1040
1041
1042
1043
1044 if (!NoFinalize) {
1048
1049
1050
1051 if (Sym && Sym->isTemporary() && ->isVariable() &&
1052 ->isDefined())
1053
1054
1055
1056 printError(getTok().getLoc(), "assembler local symbol '" +
1057 Sym->getName() + "' not defined");
1058 }
1059 }
1060
1061
1062
1063 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1064 if (std::get<2>(LocSym)->isUndefined()) {
1065
1066
1067 CppHashInfo = std::get<1>(LocSym);
1068 printError(std::get<0>(LocSym), "directional label undefined");
1069 }
1070 }
1071 }
1072
1073
1074 if (!HadError && !NoFinalize) {
1076 TS->emitConstantPools();
1077
1079 }
1080
1081 return HadError || getContext().hadError();
1082}
1083
1084bool AsmParser::checkForValidSection() {
1085 if (!ParsingMSInlineAsm && !getStreamer().getCurrentFragment()) {
1086 Out.initSections(false, getTargetParser().getSTI());
1087 return Error(getTok().getLoc(),
1088 "expected section directive before assembly directive");
1089 }
1090 return false;
1091}
1092
1093
1094void AsmParser::eatToEndOfStatement() {
1096 Lexer.Lex();
1097
1098
1100 Lexer.Lex();
1101}
1102
1103StringRef AsmParser::parseStringToEndOfStatement() {
1104 const char *Start = getTok().getLoc().getPointer();
1105
1107 Lexer.Lex();
1108
1109 const char *End = getTok().getLoc().getPointer();
1111}
1112
1113StringRef AsmParser::parseStringToComma() {
1114 const char *Start = getTok().getLoc().getPointer();
1115
1118 Lexer.Lex();
1119
1120 const char *End = getTok().getLoc().getPointer();
1122}
1123
1124
1125
1126
1127
1128
1129bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1130 if (parseExpression(Res))
1131 return true;
1133 return parseRParen();
1134}
1135
1136
1137
1138
1139
1140
1141bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1142 if (parseExpression(Res))
1143 return true;
1144 EndLoc = getTok().getEndLoc();
1145 if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1146 return true;
1147 return false;
1148}
1149
1150
1151
1152
1153
1154
1155
1156bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
1158 SMLoc FirstTokenLoc = getLexer().getLoc();
1160 switch (FirstTokenKind) {
1161 default:
1162 return TokError("unknown token in expression");
1163
1165 return true;
1167 Lex();
1168 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1169 return true;
1171 return false;
1178 if (parseIdentifier(Identifier)) {
1179
1180
1182 bool ShouldGenerateTempSymbol = false;
1185 ShouldGenerateTempSymbol = true;
1186
1187 if (!ShouldGenerateTempSymbol)
1188 return Error(FirstTokenLoc, "invalid token in expression");
1189
1190
1191 Lex();
1192
1193
1197 getContext());
1198 EndLoc = FirstTokenLoc;
1199 return false;
1200 }
1201 }
1202
1203 std::pair<StringRef, StringRef> Split;
1207 Lex();
1208 SMLoc AtLoc = getLexer().getLoc();
1210 if (parseIdentifier(VName))
1211 return Error(AtLoc, "expected symbol variant after '@'");
1212
1213 Split = std::make_pair(Identifier, VName);
1214 }
1215 } else {
1217 }
1219 Lex();
1221 parseIdentifier(VName);
1222 if (parseRParen())
1223 return true;
1224 Split = std::make_pair(Identifier, VName);
1225 }
1226
1228
1229
1232 return Error(getLexer().getLoc(), "expected a symbol reference");
1233
1235
1236
1237 if (.second.empty()) {
1238 Variant = getTargetParser().getVariantKindForName(Split.second);
1243 } else {
1245 "invalid variant '" + Split.second + "'");
1246 }
1247 }
1248
1249 MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
1250 if ()
1252 : SymbolName);
1253
1254
1255
1256 if (Sym->isVariable()) {
1257 auto V = Sym->getVariableValue( false);
1258 bool DoInline = isa(V) && ;
1259 if (auto TV = dyn_cast(V))
1260 DoInline = TV->inlineAssignedExpr();
1261 if (DoInline) {
1262 if (Variant)
1263 return Error(EndLoc, "unexpected modifier on variable reference");
1264 Res = Sym->getVariableValue( false);
1265 return false;
1266 }
1267 }
1268
1269
1271 return false;
1272 }
1274 return TokError("literal value out of range for directive");
1276 SMLoc Loc = getTok().getLoc();
1277 int64_t IntVal = getTok().getIntVal();
1280 Lex();
1281
1283 StringRef IDVal = getTok().getString();
1284
1285 std::pair<StringRef, StringRef> Split = IDVal.split('@');
1287 if (Split.first.size() != IDVal.size()) {
1290 return TokError("invalid variant '" + Split.second + "'");
1291 IDVal = Split.first;
1292 }
1293 if (IDVal == "f" || IDVal == "b") {
1297 if (IDVal == "b" && Sym->isUndefined())
1298 return Error(Loc, "directional label undefined");
1299 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1301 Lex();
1302 }
1303 }
1304 return false;
1305 }
1307 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1308 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1311 Lex();
1312 return false;
1313 }
1316 return TokError("cannot use . as current PC");
1317
1318
1319
1324 Lex();
1325 return false;
1326 }
1328 Lex();
1329 return parseParenExpr(Res, EndLoc);
1331 if (!PlatformParser->HasBracketExpressions())
1332 return TokError("brackets expression not supported on this target");
1333 Lex();
1334 return parseBracketExpr(Res, EndLoc);
1336 Lex();
1337 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1338 return true;
1340 return false;
1342 Lex();
1343 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1344 return true;
1346 return false;
1348 Lex();
1349 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1350 return true;
1352 return false;
1353
1354
1379 Lex();
1381 return TokError("expected '(' after operator");
1382 Lex();
1383 if (parseExpression(Res, EndLoc))
1384 return true;
1385 if (parseRParen())
1386 return true;
1387 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1388 return !Res;
1389 }
1390}
1391
1392bool AsmParser::parseExpression(const MCExpr *&Res) {
1394 return parseExpression(Res, EndLoc);
1395}
1396
1398AsmParser::applyModifierToExpr(const MCExpr *E,
1400
1401 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
1402 if (NewE)
1403 return NewE;
1404
1405
1409 return nullptr;
1410
1413
1415 TokError("invalid variant on expression '" + getTok().getIdentifier() +
1416 "' (already modified)");
1417 return E;
1418 }
1419
1421 }
1422
1424 const MCUnaryExpr *UE = cast(E);
1425 const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant);
1426 if (!Sub)
1427 return nullptr;
1429 }
1430
1432 const MCBinaryExpr *BE = cast(E);
1433 const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant);
1434 const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant);
1435
1436 if (!LHS && !RHS)
1437 return nullptr;
1438
1439 if (!LHS)
1441 if (!RHS)
1443
1445 }
1446 }
1447
1449}
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1464 "Argument to the function cannot be a NULL value");
1465 const char *CharPtr = StrLoc.getPointer();
1466 while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1467 (*CharPtr != '\0')) {
1468 if (*CharPtr == '!')
1469 CharPtr++;
1470 CharPtr++;
1471 }
1472 if (*CharPtr == '>') {
1474 return true;
1475 }
1476 return false;
1477}
1478
1479
1481 std::string Res;
1482 for (size_t Pos = 0; Pos < AltMacroStr.size(); Pos++) {
1483 if (AltMacroStr[Pos] == '!')
1484 Pos++;
1485 Res += AltMacroStr[Pos];
1486 }
1487 return Res;
1488}
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1501
1502 Res = nullptr;
1503 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1504 parseBinOpRHS(1, Res, EndLoc))
1505 return true;
1506
1507
1508
1509
1512 return TokError("unexpected symbol modifier following '@'");
1513
1517 return TokError("invalid variant '" + getTok().getIdentifier() + "'");
1518
1519 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
1520 if (!ModifiedRes) {
1521 return TokError("invalid modifier '" + getTok().getIdentifier() +
1522 "' (no symbols present)");
1523 }
1524
1525 Res = ModifiedRes;
1526 Lex();
1527 }
1528
1529
1530
1532 if (Res->evaluateAsAbsolute(Value))
1534
1535 return false;
1536}
1537
1538bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1539 Res = nullptr;
1540 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1541}
1542
1543bool AsmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
1544 SMLoc &EndLoc) {
1545 if (parseParenExpr(Res, EndLoc))
1546 return true;
1547
1548 for (; ParenDepth > 0; --ParenDepth) {
1549 if (parseBinOpRHS(1, Res, EndLoc))
1550 return true;
1551
1552
1553
1554 if (ParenDepth - 1 > 0) {
1555 EndLoc = getTok().getEndLoc();
1556 if (parseRParen())
1557 return true;
1558 }
1559 }
1560 return false;
1561}
1562
1563bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1565
1567 if (parseExpression(Expr))
1568 return true;
1569
1570 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1571 return Error(StartLoc, "expected absolute expression");
1572
1573 return false;
1574}
1575
1578 bool ShouldUseLogicalShr) {
1579 switch (K) {
1580 default:
1581 return 0;
1582
1583
1586 return 1;
1589 return 1;
1590
1591
1594 return 2;
1597 return 2;
1600 return 2;
1601
1602
1605 return 3;
1609 return 3;
1612 return 3;
1615 return 3;
1618 return 3;
1621 return 3;
1622
1623
1626 return 4;
1629 return 4;
1630
1631
1634 return 5;
1637 return 5;
1638
1639
1642 return 6;
1645 return 6;
1648 return 6;
1649 }
1650}
1651
1655 bool ShouldUseLogicalShr) {
1656 switch (K) {
1657 default:
1658 return 0;
1659
1660
1663 return 2;
1666 return 1;
1667
1668
1671 return 3;
1675 return 3;
1678 return 3;
1681 return 3;
1684 return 3;
1687 return 3;
1688
1689
1692 return 4;
1695 return 4;
1696
1697
1698
1701 return 5;
1703
1704
1706 return 0;
1708 return 5;
1711 return 5;
1714 return 5;
1715
1716
1719 return 6;
1722 return 6;
1725 return 6;
1728 return 6;
1731 return 6;
1732 }
1733}
1734
1740}
1741
1742
1743
1744bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
1745 SMLoc &EndLoc) {
1747 while (true) {
1749 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
1750
1751
1752
1753 if (TokPrec < Precedence)
1754 return false;
1755
1756 Lex();
1757
1758
1760 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1761 return true;
1762
1763
1764
1766 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1767 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1768 return true;
1769
1770
1772 }
1773}
1774
1775
1776
1777
1778
1779bool AsmParser::parseStatement(ParseStatementInfo &Info,
1781 assert(!hasPendingError() && "parseStatement started with pending error");
1782
1784 Lex();
1786
1787 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
1788 getTok().getString().front() == '\n')
1790 Lex();
1791 return false;
1792 }
1793
1795 SMLoc IDLoc = ID.getLoc();
1797 int64_t LocalLabelVal = -1;
1798 StartTokLoc = ID.getLoc();
1800 return parseCppHashLineFilenameComment(IDLoc,
1801 !isInsideMacroInstantiation());
1802
1803
1805 LocalLabelVal = getTok().getIntVal();
1806 if (LocalLabelVal < 0) {
1807 if (!TheCondState.Ignore) {
1808 Lex();
1809 return Error(IDLoc, "unexpected token at start of statement");
1810 }
1811 IDVal = "";
1812 } else {
1813 IDVal = getTok().getString();
1814 Lex();
1816 if (!TheCondState.Ignore) {
1817 Lex();
1818 return Error(IDLoc, "unexpected token at start of statement");
1819 }
1820 }
1821 }
1823
1824 Lex();
1825 IDVal = ".";
1827
1828 Lex();
1829 IDVal = "{";
1830
1832
1833 Lex();
1834 IDVal = "}";
1836 getTargetParser().starIsStartOfStatement()) {
1837
1838 Lex();
1839 IDVal = "*";
1840 } else if (parseIdentifier(IDVal)) {
1841 if (!TheCondState.Ignore) {
1842 Lex();
1843 return Error(IDLoc, "unexpected token at start of statement");
1844 }
1845 IDVal = "";
1846 }
1847
1848
1849
1850
1852 DirectiveKindMap.find(IDVal.lower());
1853 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1854 ? DK_NO_DIRECTIVE
1855 : DirKindIt->getValue();
1856 switch (DirKind) {
1857 default:
1858 break;
1859 case DK_IF:
1860 case DK_IFEQ:
1861 case DK_IFGE:
1862 case DK_IFGT:
1863 case DK_IFLE:
1864 case DK_IFLT:
1865 case DK_IFNE:
1866 return parseDirectiveIf(IDLoc, DirKind);
1867 case DK_IFB:
1868 return parseDirectiveIfb(IDLoc, true);
1869 case DK_IFNB:
1870 return parseDirectiveIfb(IDLoc, false);
1871 case DK_IFC:
1872 return parseDirectiveIfc(IDLoc, true);
1873 case DK_IFEQS:
1874 return parseDirectiveIfeqs(IDLoc, true);
1875 case DK_IFNC:
1876 return parseDirectiveIfc(IDLoc, false);
1877 case DK_IFNES:
1878 return parseDirectiveIfeqs(IDLoc, false);
1879 case DK_IFDEF:
1880 return parseDirectiveIfdef(IDLoc, true);
1881 case DK_IFNDEF:
1882 case DK_IFNOTDEF:
1883 return parseDirectiveIfdef(IDLoc, false);
1884 case DK_ELSEIF:
1885 return parseDirectiveElseIf(IDLoc);
1886 case DK_ELSE:
1887 return parseDirectiveElse(IDLoc);
1888 case DK_ENDIF:
1889 return parseDirectiveEndIf(IDLoc);
1890 }
1891
1892
1893
1894 if (TheCondState.Ignore) {
1895 eatToEndOfStatement();
1896 return false;
1897 }
1898
1899
1900
1901
1902
1903
1905 if (checkForValidSection())
1906 return true;
1907
1908 Lex();
1909
1910
1911 if (IDVal == ".")
1912 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
1913
1914
1915
1916
1917
1918
1920 if (LocalLabelVal == -1) {
1921 if (ParsingMSInlineAsm && SI) {
1923 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
1925 "We should have an internal name here.");
1927 RewrittenLabel);
1928 IDVal = RewrittenLabel;
1929 }
1930 Sym = getContext().getOrCreateSymbol(IDVal);
1931 } else
1933
1934
1935
1936
1938 StringRef CommentStr = parseStringToEndOfStatement();
1939 Lexer.Lex();
1941 }
1942
1943
1944
1946 Lex();
1947 }
1948
1950 Sym->isExternal() && !cast(Sym)->isAltEntry())
1951 return Error(StartTokLoc, "non-private labels cannot appear between "
1952 ".cfi_startproc / .cfi_endproc pairs") &&
1953 Error(*CFIStartProcLoc, "previous .cfi_startproc was here");
1954
1955 if (discardLTOSymbol(IDVal))
1956 return false;
1957
1958 getTargetParser().doBeforeLabelEmit(Sym, IDLoc);
1959
1960
1961 if (!getTargetParser().isParsingMSInlineAsm())
1963
1964
1965
1966 if (enabledGenDwarfForAssembly())
1968 IDLoc);
1969
1970 getTargetParser().onLabelParsed(Sym);
1971
1972 return false;
1973 }
1974
1975
1976
1977 if (Lexer.is(AsmToken::Equal) && getTargetParser().equalIsAsmAssignment()) {
1978 Lex();
1979 return parseAssignment(IDVal, AssignmentKind::Equal);
1980 }
1981
1982
1983 if (areMacrosEnabled())
1984 if (MCAsmMacro *M = getContext().lookupMacro(IDVal))
1985 return handleMacroEntry(M, IDLoc);
1986
1987
1988
1989
1990 if (IDVal.starts_with(".") && IDVal != ".") {
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002 getTargetParser().flushPendingInstructions(getStreamer());
2003
2004 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);
2005 assert(TPDirectiveReturn.isFailure() == hasPendingError() &&
2006 "Should only return Failure iff there was an error");
2007 if (TPDirectiveReturn.isFailure())
2008 return true;
2009 if (TPDirectiveReturn.isSuccess())
2010 return false;
2011
2012
2013
2014 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2015 ExtensionDirectiveMap.lookup(IDVal);
2016 if (Handler.first)
2017 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2018
2019
2020
2021 switch (DirKind) {
2022 default:
2023 break;
2024 case DK_SET:
2025 case DK_EQU:
2026 return parseDirectiveSet(IDVal, AssignmentKind::Set);
2027 case DK_EQUIV:
2028 return parseDirectiveSet(IDVal, AssignmentKind::Equiv);
2029 case DK_LTO_SET_CONDITIONAL:
2030 return parseDirectiveSet(IDVal, AssignmentKind::LTOSetConditional);
2031 case DK_ASCII:
2032 return parseDirectiveAscii(IDVal, false);
2033 case DK_ASCIZ:
2034 case DK_STRING:
2035 return parseDirectiveAscii(IDVal, true);
2036 case DK_BYTE:
2037 case DK_DC_B:
2038 return parseDirectiveValue(IDVal, 1);
2039 case DK_DC:
2040 case DK_DC_W:
2041 case DK_SHORT:
2042 case DK_VALUE:
2043 case DK_2BYTE:
2044 return parseDirectiveValue(IDVal, 2);
2045 case DK_LONG:
2046 case DK_INT:
2047 case DK_4BYTE:
2048 case DK_DC_L:
2049 return parseDirectiveValue(IDVal, 4);
2050 case DK_QUAD:
2051 case DK_8BYTE:
2052 return parseDirectiveValue(IDVal, 8);
2053 case DK_DC_A:
2054 return parseDirectiveValue(
2055 IDVal, getContext().getAsmInfo()->getCodePointerSize());
2056 case DK_OCTA:
2057 return parseDirectiveOctaValue(IDVal);
2058 case DK_SINGLE:
2059 case DK_FLOAT:
2060 case DK_DC_S:
2061 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
2062 case DK_DOUBLE:
2063 case DK_DC_D:
2064 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
2065 case DK_ALIGN: {
2066 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2067 return parseDirectiveAlign(IsPow2, 1);
2068 }
2069 case DK_ALIGN32: {
2070 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2071 return parseDirectiveAlign(IsPow2, 4);
2072 }
2073 case DK_BALIGN:
2074 return parseDirectiveAlign(false, 1);
2075 case DK_BALIGNW:
2076 return parseDirectiveAlign(false, 2);
2077 case DK_BALIGNL:
2078 return parseDirectiveAlign(false, 4);
2079 case DK_P2ALIGN:
2080 return parseDirectiveAlign(true, 1);
2081 case DK_P2ALIGNW:
2082 return parseDirectiveAlign(true, 2);
2083 case DK_P2ALIGNL:
2084 return parseDirectiveAlign(true, 4);
2085 case DK_ORG:
2086 return parseDirectiveOrg();
2087 case DK_FILL:
2088 return parseDirectiveFill();
2089 case DK_ZERO:
2090 return parseDirectiveZero();
2091 case DK_EXTERN:
2092 eatToEndOfStatement();
2093 return false;
2094 case DK_GLOBL:
2095 case DK_GLOBAL:
2096 return parseDirectiveSymbolAttribute(MCSA_Global);
2097 case DK_LAZY_REFERENCE:
2099 case DK_NO_DEAD_STRIP:
2101 case DK_SYMBOL_RESOLVER:
2103 case DK_PRIVATE_EXTERN:
2105 case DK_REFERENCE:
2106 return parseDirectiveSymbolAttribute(MCSA_Reference);
2107 case DK_WEAK_DEFINITION:
2109 case DK_WEAK_REFERENCE:
2111 case DK_WEAK_DEF_CAN_BE_HIDDEN:
2113 case DK_COLD:
2114 return parseDirectiveSymbolAttribute(MCSA_Cold);
2115 case DK_COMM:
2116 case DK_COMMON:
2117 return parseDirectiveComm(false);
2118 case DK_LCOMM:
2119 return parseDirectiveComm(true);
2120 case DK_ABORT:
2121 return parseDirectiveAbort(IDLoc);
2122 case DK_INCLUDE:
2123 return parseDirectiveInclude();
2124 case DK_INCBIN:
2125 return parseDirectiveIncbin();
2126 case DK_CODE16:
2127 case DK_CODE16GCC:
2128 return TokError(Twine(IDVal) +
2129 " not currently supported for this target");
2130 case DK_REPT:
2131 return parseDirectiveRept(IDLoc, IDVal);
2132 case DK_IRP:
2133 return parseDirectiveIrp(IDLoc);
2134 case DK_IRPC:
2135 return parseDirectiveIrpc(IDLoc);
2136 case DK_ENDR:
2137 return parseDirectiveEndr(IDLoc);
2138 case DK_BUNDLE_ALIGN_MODE:
2139 return parseDirectiveBundleAlignMode();
2140 case DK_BUNDLE_LOCK:
2141 return parseDirectiveBundleLock();
2142 case DK_BUNDLE_UNLOCK:
2143 return parseDirectiveBundleUnlock();
2144 case DK_SLEB128:
2145 return parseDirectiveLEB128(true);
2146 case DK_ULEB128:
2147 return parseDirectiveLEB128(false);
2148 case DK_SPACE:
2149 case DK_SKIP:
2150 return parseDirectiveSpace(IDVal);
2151 case DK_FILE:
2152 return parseDirectiveFile(IDLoc);
2153 case DK_LINE:
2154 return parseDirectiveLine();
2155 case DK_LOC:
2156 return parseDirectiveLoc();
2157 case DK_LOC_LABEL:
2158 return parseDirectiveLocLabel(IDLoc);
2159 case DK_STABS:
2160 return parseDirectiveStabs();
2161 case DK_CV_FILE:
2162 return parseDirectiveCVFile();
2163 case DK_CV_FUNC_ID:
2164 return parseDirectiveCVFuncId();
2165 case DK_CV_INLINE_SITE_ID:
2166 return parseDirectiveCVInlineSiteId();
2167 case DK_CV_LOC:
2168 return parseDirectiveCVLoc();
2169 case DK_CV_LINETABLE:
2170 return parseDirectiveCVLinetable();
2171 case DK_CV_INLINE_LINETABLE:
2172 return parseDirectiveCVInlineLinetable();
2173 case DK_CV_DEF_RANGE:
2174 return parseDirectiveCVDefRange();
2175 case DK_CV_STRING:
2176 return parseDirectiveCVString();
2177 case DK_CV_STRINGTABLE:
2178 return parseDirectiveCVStringTable();
2179 case DK_CV_FILECHECKSUMS:
2180 return parseDirectiveCVFileChecksums();
2181 case DK_CV_FILECHECKSUM_OFFSET:
2182 return parseDirectiveCVFileChecksumOffset();
2183 case DK_CV_FPO_DATA:
2184 return parseDirectiveCVFPOData();
2185 case DK_CFI_SECTIONS:
2186 return parseDirectiveCFISections();
2187 case DK_CFI_STARTPROC:
2188 return parseDirectiveCFIStartProc();
2189 case DK_CFI_ENDPROC:
2190 return parseDirectiveCFIEndProc();
2191 case DK_CFI_DEF_CFA:
2192 return parseDirectiveCFIDefCfa(IDLoc);
2193 case DK_CFI_DEF_CFA_OFFSET:
2194 return parseDirectiveCFIDefCfaOffset(IDLoc);
2195 case DK_CFI_ADJUST_CFA_OFFSET:
2196 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2197 case DK_CFI_DEF_CFA_REGISTER:
2198 return parseDirectiveCFIDefCfaRegister(IDLoc);
2199 case DK_CFI_LLVM_DEF_ASPACE_CFA:
2200 return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
2201 case DK_CFI_OFFSET:
2202 return parseDirectiveCFIOffset(IDLoc);
2203 case DK_CFI_REL_OFFSET:
2204 return parseDirectiveCFIRelOffset(IDLoc);
2205 case DK_CFI_PERSONALITY:
2206 return parseDirectiveCFIPersonalityOrLsda(true);
2207 case DK_CFI_LSDA:
2208 return parseDirectiveCFIPersonalityOrLsda(false);
2209 case DK_CFI_REMEMBER_STATE:
2210 return parseDirectiveCFIRememberState(IDLoc);
2211 case DK_CFI_RESTORE_STATE:
2212 return parseDirectiveCFIRestoreState(IDLoc);
2213 case DK_CFI_SAME_VALUE:
2214 return parseDirectiveCFISameValue(IDLoc);
2215 case DK_CFI_RESTORE:
2216 return parseDirectiveCFIRestore(IDLoc);
2217 case DK_CFI_ESCAPE:
2218 return parseDirectiveCFIEscape(IDLoc);
2219 case DK_CFI_RETURN_COLUMN:
2220 return parseDirectiveCFIReturnColumn(IDLoc);
2221 case DK_CFI_SIGNAL_FRAME:
2222 return parseDirectiveCFISignalFrame(IDLoc);
2223 case DK_CFI_UNDEFINED:
2224 return parseDirectiveCFIUndefined(IDLoc);
2225 case DK_CFI_REGISTER:
2226 return parseDirectiveCFIRegister(IDLoc);
2227 case DK_CFI_WINDOW_SAVE:
2228 return parseDirectiveCFIWindowSave(IDLoc);
2229 case DK_CFI_LABEL:
2230 return parseDirectiveCFILabel(IDLoc);
2231 case DK_CFI_VAL_OFFSET:
2232 return parseDirectiveCFIValOffset(IDLoc);
2233 case DK_MACROS_ON:
2234 case DK_MACROS_OFF:
2235 return parseDirectiveMacrosOnOff(IDVal);
2236 case DK_MACRO:
2237 return parseDirectiveMacro(IDLoc);
2238 case DK_ALTMACRO:
2239 case DK_NOALTMACRO:
2240 return parseDirectiveAltmacro(IDVal);
2241 case DK_EXITM:
2242 return parseDirectiveExitMacro(IDVal);
2243 case DK_ENDM:
2244 case DK_ENDMACRO:
2245 return parseDirectiveEndMacro(IDVal);
2246 case DK_PURGEM:
2247 return parseDirectivePurgeMacro(IDLoc);
2248 case DK_END:
2249 return parseDirectiveEnd(IDLoc);
2250 case DK_ERR:
2251 return parseDirectiveError(IDLoc, false);
2252 case DK_ERROR:
2253 return parseDirectiveError(IDLoc, true);
2254 case DK_WARNING:
2255 return parseDirectiveWarning(IDLoc);
2256 case DK_RELOC:
2257 return parseDirectiveReloc(IDLoc);
2258 case DK_DCB:
2259 case DK_DCB_W:
2260 return parseDirectiveDCB(IDVal, 2);
2261 case DK_DCB_B:
2262 return parseDirectiveDCB(IDVal, 1);
2263 case DK_DCB_D:
2264 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2265 case DK_DCB_L:
2266 return parseDirectiveDCB(IDVal, 4);
2267 case DK_DCB_S:
2268 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2269 case DK_DC_X:
2270 case DK_DCB_X:
2271 return TokError(Twine(IDVal) +
2272 " not currently supported for this target");
2273 case DK_DS:
2274 case DK_DS_W:
2275 return parseDirectiveDS(IDVal, 2);
2276 case DK_DS_B:
2277 return parseDirectiveDS(IDVal, 1);
2278 case DK_DS_D:
2279 return parseDirectiveDS(IDVal, 8);
2280 case DK_DS_L:
2281 case DK_DS_S:
2282 return parseDirectiveDS(IDVal, 4);
2283 case DK_DS_P:
2284 case DK_DS_X:
2285 return parseDirectiveDS(IDVal, 12);
2286 case DK_PRINT:
2287 return parseDirectivePrint(IDLoc);
2288 case DK_ADDRSIG:
2289 return parseDirectiveAddrsig();
2290 case DK_ADDRSIG_SYM:
2291 return parseDirectiveAddrsigSym();
2292 case DK_PSEUDO_PROBE:
2293 return parseDirectivePseudoProbe();
2294 case DK_LTO_DISCARD:
2295 return parseDirectiveLTODiscard();
2296 case DK_MEMTAG:
2297 return parseDirectiveSymbolAttribute(MCSA_Memtag);
2298 }
2299
2300 return Error(IDLoc, "unknown directive");
2301 }
2302
2303
2304 if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2305 IDVal == "_EMIT" || IDVal == "__EMIT"))
2306 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2307
2308
2309 if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2310 return parseDirectiveMSAlign(IDLoc, Info);
2311
2312 if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2313 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2314 if (checkForValidSection())
2315 return true;
2316
2317 return parseAndMatchAndEmitTargetInstruction(Info, IDVal, ID, IDLoc);
2318}
2319
2320bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
2324
2325 std::string OpcodeStr = IDVal.lower();
2327 bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr, ID,
2328 Info.ParsedOperands);
2329 Info.ParseError = ParseHadError;
2330
2331
2332 if (getShowParsedOperands()) {
2335 OS << "parsed instruction: [";
2336 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2337 if (i != 0)
2338 OS << ", ";
2339 Info.ParsedOperands[i]->print(OS);
2340 }
2341 OS << "]";
2342
2344 }
2345
2346
2347 if (hasPendingError() || ParseHadError)
2348 return true;
2349
2350
2351
2352 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2353 getContext().getGenDwarfSectionSyms().count(
2354 getStreamer().getCurrentSectionOnly())) {
2355 unsigned Line;
2356 if (ActiveMacros.empty())
2358 else
2360 ActiveMacros.front()->ExitBuffer);
2361
2362
2363
2364
2365 if (!CppHashInfo.Filename.empty()) {
2366 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2367 0, StringRef(), CppHashInfo.Filename);
2368 getContext().setGenDwarfFileNumber(FileNumber);
2369
2370 unsigned CppHashLocLineNo =
2372 Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2373 }
2374
2375 getStreamer().emitDwarfLocDirective(
2376 getContext().getGenDwarfFileNumber(), Line, 0,
2379 }
2380
2381
2382 if (!ParseHadError) {
2384 if (getTargetParser().matchAndEmitInstruction(
2386 getTargetParser().isParsingMSInlineAsm()))
2387 return true;
2388 }
2389 return false;
2390}
2391
2392
2393bool
2395
2397 return false;
2398
2400 Lex();
2402 Lex();
2403
2404
2407 return true;
2408}
2409
2410
2411
2412bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
2413 Lex();
2414
2415
2417 "Lexing Cpp line comment: Expected Integer");
2418 int64_t LineNumber = getTok().getIntVal();
2419 Lex();
2421 "Lexing Cpp line comment: Expected String");
2423 Lex();
2424
2425 if (!SaveLocInfo)
2426 return false;
2427
2428
2430
2431
2432
2433 CppHashInfo.Loc = L;
2434 CppHashInfo.Filename = Filename;
2435 CppHashInfo.LineNumber = LineNumber;
2436 CppHashInfo.Buf = CurBuffer;
2437 if (!HadCppHashFilename) {
2438 HadCppHashFilename = true;
2439
2440
2441
2442 if (getContext().getGenDwarfForAssembly() &&
2443 getContext().getGenDwarfFileNumber() == 0) {
2444
2445
2446 getContext().setMCLineTableRootFile(
2447 0, getContext().getCompilationDir(), Filename,
2448 std::nullopt, std::nullopt);
2449 }
2450 }
2451 return false;
2452}
2453
2454
2455
2456void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2457 auto *Parser = static_cast<AsmParser *>(Context);
2459
2463 unsigned CppHashBuf =
2464 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2465
2466
2467
2469 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2473 }
2474
2475
2476
2477
2478 if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
2479 if (Parser->SavedDiagHandler)
2480 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2481 else
2482 Parser->getContext().diagnose(Diag);
2483 return;
2484 }
2485
2486
2487
2488
2489 const std::string &Filename = std::string(Parser->CppHashInfo.Filename);
2490
2491 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2492 int CppHashLocLineNo =
2493 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2494 int LineNo =
2495 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2496
2500
2501 if (Parser->SavedDiagHandler)
2502 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2503 else
2504 Parser->getContext().diagnose(NewDiag);
2505}
2506
2507
2508
2509
2510
2512 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
2513 c == '.';
2514}
2515
2519 bool EnableAtPseudoVariable) {
2520 unsigned NParameters = Parameters.size();
2521 auto expandArg = [&](unsigned Index) {
2522 bool HasVararg = NParameters ? Parameters.back().Vararg : false;
2523 bool VarargParameter = HasVararg && Index == (NParameters - 1);
2524 for (const AsmToken &Token : A[Index])
2525
2526
2527
2528
2529
2530
2531
2532 if (AltMacroMode && Token.getString().front() == '%' &&
2534
2535 OS << Token.getIntVal();
2536
2537
2538 else if (AltMacroMode && Token.getString().front() == '<' &&
2541 }
2542
2543
2545 OS << Token.getString();
2546 else
2547 OS << Token.getStringContents();
2548 };
2549
2550
2551
2553 size_t I = 0, End = Body.size();
2555 if (Body[I] == '\\' && I + 1 != End) {
2556
2557 if (EnableAtPseudoVariable && Body[I + 1] == '@') {
2558 OS << NumOfMacroInstantiations;
2559 I += 2;
2560 continue;
2561 }
2562 if (Body[I + 1] == '+') {
2564 I += 2;
2565 continue;
2566 }
2567 if (Body[I + 1] == '(' && Body[I + 2] == ')') {
2568 I += 3;
2569 continue;
2570 }
2571
2572 size_t Pos = ++I;
2574 ++I;
2576 if (AltMacroMode && I != End && Body[I] == '&')
2577 ++I;
2578 unsigned Index = 0;
2579 for (; Index < NParameters; ++Index)
2581 break;
2582 if (Index == NParameters)
2584 else
2585 expandArg(Index);
2586 continue;
2587 }
2588
2589
2590
2591 if (Body[I] == '$' && I + 1 != End && IsDarwin && !NParameters) {
2592
2593 switch (Body[I + 1]) {
2594
2595 case '$':
2596 OS << '$';
2597 I += 2;
2598 continue;
2599
2600 case 'n':
2602 I += 2;
2603 continue;
2604 default: {
2606 break;
2607
2608
2609 unsigned Index = Body[I + 1] - '0';
2610 if (Index < A.size())
2611 for (const AsmToken &Token : A[Index])
2612 OS << Token.getString();
2613 I += 2;
2614 continue;
2615 }
2616 }
2617 }
2618
2621 continue;
2622 }
2623
2624 const size_t Start = I;
2626 }
2628 if (AltMacroMode) {
2629 unsigned Index = 0;
2630 for (; Index != NParameters; ++Index)
2631 if (Parameters[Index].Name == Token)
2632 break;
2633 if (Index != NParameters) {
2634 expandArg(Index);
2635 if (I != End && Body[I] == '&')
2636 ++I;
2637 continue;
2638 }
2639 }
2640 OS << Token;
2641 }
2642
2644 return false;
2645}
2646
2648 switch (kind) {
2649 default:
2650 return false;
2673 return true;
2674 }
2675}
2676
2677namespace {
2678
2679class AsmLexerSkipSpaceRAII {
2680public:
2681 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2683 }
2684
2685 ~AsmLexerSkipSpaceRAII() {
2687 }
2688
2689private:
2691};
2692
2693}
2694
2695bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
2696
2697 if (Vararg) {
2699 StringRef Str = parseStringToEndOfStatement();
2701 }
2702 return false;
2703 }
2704
2705 unsigned ParenLevel = 0;
2706
2707
2708 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2709
2710 bool SpaceEaten;
2711
2712 while (true) {
2713 SpaceEaten = false;
2715 return TokError("unexpected token in macro instantiation");
2716
2717 if (ParenLevel == 0) {
2718
2720 break;
2721
2723 SpaceEaten = true;
2724
2725
2726
2727
2728 if (!IsDarwin) {
2730 MA.push_back(getTok());
2731 Lexer.Lex();
2732
2733
2735 continue;
2736 }
2737 }
2738 if (SpaceEaten)
2739 break;
2740 }
2741
2742
2743
2745 break;
2746
2747
2749 ++ParenLevel;
2751 --ParenLevel;
2752
2753
2754 MA.push_back(getTok());
2755 Lexer.Lex();
2756 }
2757
2758 if (ParenLevel != 0)
2759 return TokError("unbalanced parentheses in macro argument");
2760 return false;
2761}
2762
2763
2764bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
2765 MCAsmMacroArguments &A) {
2766 const unsigned NParameters = M ? M->Parameters.size() : 0;
2767 bool NamedParametersFound = false;
2769
2770 A.resize(NParameters);
2771 FALocs.resize(NParameters);
2772
2773
2774
2775
2776 bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
2777 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2778 ++Parameter) {
2781
2783 if (parseIdentifier(FA.Name))
2784 return Error(IDLoc, "invalid argument identifier for formal argument");
2785
2787 return TokError("expected '=' after formal parameter identifier");
2788
2789 Lex();
2790
2791 NamedParametersFound = true;
2792 }
2793 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2794
2795 if (NamedParametersFound && FA.Name.empty())
2796 return Error(IDLoc, "cannot mix positional and keyword arguments");
2797
2801 const MCExpr *AbsoluteExp;
2803
2804 Lex();
2805 if (parseExpression(AbsoluteExp, EndLoc))
2806 return false;
2807 if (!AbsoluteExp->evaluateAsAbsolute(Value,
2808 getStreamer().getAssemblerPtr()))
2809 return Error(StrLoc, "expected absolute expression");
2810 const char *StrChar = StrLoc.getPointer();
2811 const char *EndChar = EndLoc.getPointer();
2814 FA.Value.push_back(newToken);
2817 const char *StrChar = StrLoc.getPointer();
2818 const char *EndChar = EndLoc.getPointer();
2819 jumpToLoc(EndLoc, CurBuffer);
2820
2821 Lex();
2823 StringRef(StrChar, EndChar - StrChar));
2824 FA.Value.push_back(newToken);
2825 } else if(parseMacroArgument(FA.Value, Vararg))
2826 return true;
2827
2828 unsigned PI = Parameter;
2830 unsigned FAI = 0;
2831 for (FAI = 0; FAI < NParameters; ++FAI)
2832 if (M->Parameters[FAI].Name == FA.Name)
2833 break;
2834
2835 if (FAI >= NParameters) {
2836 assert(M && "expected macro to be defined");
2837 return Error(IDLoc, "parameter named '" + FA.Name +
2838 "' does not exist for macro '" + M->Name + "'");
2839 }
2840 PI = FAI;
2841 }
2842
2843 if (!FA.Value.empty()) {
2844 if (A.size() <= PI)
2845 A.resize(PI + 1);
2847
2848 if (FALocs.size() <= PI)
2849 FALocs.resize(PI + 1);
2850
2851 FALocs[PI] = Lexer.getLoc();
2852 }
2853
2854
2855
2856
2859 for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
2860 if (A[FAI].empty()) {
2861 if (M->Parameters[FAI].Required) {
2863 "missing value for required parameter "
2864 "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
2866 }
2867
2868 if (->Parameters[FAI].Value.empty())
2869 A[FAI] = M->Parameters[FAI].Value;
2870 }
2871 }
2873 }
2874
2876 }
2877
2878 return TokError("too many positional arguments");
2879}
2880
2881bool AsmParser::handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc) {
2882
2883
2885 if (ActiveMacros.size() == MaxNestingDepth) {
2886 std::ostringstream MaxNestingDepthError;
2887 MaxNestingDepthError << "macros cannot be nested more than "
2888 << MaxNestingDepth << " levels deep."
2889 << " Use -asm-macro-max-nesting-depth to increase "
2890 "this limit.";
2891 return TokError(MaxNestingDepthError.str());
2892 }
2893
2894 MCAsmMacroArguments A;
2895 if (parseMacroArguments(M, A))
2896 return true;
2897
2898
2899
2902
2903 if ((!IsDarwin || M->Parameters.size()) && M->Parameters.size() != A.size())
2904 return Error(getTok().getLoc(), "Wrong number of arguments");
2905 if (expandMacro(OS, *M, M->Parameters, A, true))
2906 return true;
2907
2908
2909
2910 OS << ".endmacro\n";
2911
2912 std::unique_ptr Instantiation =
2914
2915
2916
2917 MacroInstantiation *MI = new MacroInstantiation{
2918 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2919 ActiveMacros.push_back(MI);
2920
2921 ++NumOfMacroInstantiations;
2922
2923
2926 Lex();
2927
2928 return false;
2929}
2930
2931void AsmParser::handleMacroExit() {
2932
2933 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2934 Lex();
2935
2936
2938 Lex();
2939
2940
2941 delete ActiveMacros.back();
2942 ActiveMacros.pop_back();
2943}
2944
2945bool AsmParser::parseAssignment(StringRef Name, AssignmentKind Kind) {
2948 SMLoc ExprLoc = getTok().getLoc();
2949 bool AllowRedef =
2950 Kind == AssignmentKind::Set || Kind == AssignmentKind::Equal;
2953 return true;
2954
2955 if () {
2956
2957
2958
2959 return false;
2960 }
2961
2962 if (discardLTOSymbol(Name))
2963 return false;
2964
2965
2966 switch (Kind) {
2967 case AssignmentKind::Equal:
2969 break;
2970 case AssignmentKind::Set:
2971 case AssignmentKind::Equiv:
2974 break;
2975 case AssignmentKind::LTOSetConditional:
2977 return Error(ExprLoc, "expected identifier");
2978
2980 break;
2981 }
2982
2983 return false;
2984}
2985
2986
2987
2988
2989bool AsmParser::parseIdentifier(StringRef &Res) {
2990
2991
2992
2993
2994
2996 SMLoc PrefixLoc = getLexer().getLoc();
2997
2998
2999
3002
3004 return true;
3005
3006
3007
3008 if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
3009 return true;
3010
3011
3012 Lexer.Lex();
3013
3015 Lex();
3016 return false;
3017 }
3018
3020 return true;
3021
3022 Res = getTok().getIdentifier();
3023
3024 Lex();
3025
3026 return false;
3027}
3028
3029
3030
3031
3032
3033
3034bool AsmParser::parseDirectiveSet(StringRef IDVal, AssignmentKind Kind) {
3036 if (check(parseIdentifier(Name), "expected identifier") || parseComma() ||
3037 parseAssignment(Name, Kind))
3038 return true;
3039 return false;
3040}
3041
3042bool AsmParser::parseEscapedString(std::string &Data) {
3044 return true;
3045
3046 Data = "";
3047 StringRef Str = getTok().getStringContents();
3048 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
3049 if (Str[i] != '\\') {
3050 if ((Str[i] == '\n') || (Str[i] == '\r')) {
3051
3052 if ((Str[i] == '\n') && (i > 0) && (Str[i - 1] == '\r'))
3053 continue;
3054
3056 if (Warning(NewlineLoc, "unterminated string; newline inserted"))
3057 return true;
3058 }
3059 Data += Str[i];
3060 continue;
3061 }
3062
3063
3064
3065 ++i;
3066 if (i == e)
3067 return TokError("unexpected backslash at end of string");
3068
3069
3070 if (Str[i] == 'x' || Str[i] == 'X') {
3071 size_t length = Str.size();
3072 if (i + 1 >= length || (Str[i + 1]))
3073 return TokError("invalid hexadecimal escape sequence");
3074
3075
3076
3077 unsigned Value = 0;
3078 while (i + 1 < length && isHexDigit(Str[i + 1]))
3079 Value = Value * 16 + hexDigitValue(Str[++i]);
3080
3081 Data += (unsigned char)(Value & 0xFF);
3082 continue;
3083 }
3084
3085
3086 if ((unsigned)(Str[i] - '0') <= 7) {
3087
3088 unsigned Value = Str[i] - '0';
3089
3090 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
3091 ++i;
3093
3094 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
3095 ++i;
3097 }
3098 }
3099
3100 if (Value > 255)
3101 return TokError("invalid octal escape sequence (out of range)");
3102
3104 continue;
3105 }
3106
3107
3108 switch (Str[i]) {
3109 default:
3110
3111 return TokError("invalid escape sequence (unrecognized character)");
3112
3113 case 'b': Data += '\b'; break;
3114 case 'f': Data += '\f'; break;
3115 case 'n': Data += '\n'; break;
3116 case 'r': Data += '\r'; break;
3117 case 't': Data += '\t'; break;
3118 case '"': Data += '"'; break;
3119 case '\\': Data += '\\'; break;
3120 }
3121 }
3122
3123 Lex();
3124 return false;
3125}
3126
3127bool AsmParser::parseAngleBracketString(std::string &Data) {
3128 SMLoc EndLoc, StartLoc = getTok().getLoc();
3130 const char *StartChar = StartLoc.getPointer() + 1;
3131 const char *EndChar = EndLoc.getPointer() - 1;
3132 jumpToLoc(EndLoc, CurBuffer);
3133
3134 Lex();
3135
3137 return false;
3138 }
3139 return true;
3140}
3141
3142
3143
3144
3145bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
3146 auto parseOp = [&]() -> bool {
3147 std::string Data;
3148 if (checkForValidSection())
3149 return true;
3150
3151
3152 do {
3153 if (parseEscapedString(Data))
3154 return true;
3155 getStreamer().emitBytes(Data);
3157 if (ZeroTerminated)
3158 getStreamer().emitBytes(StringRef("\0", 1));
3159 return false;
3160 };
3161
3162 return parseMany(parseOp);
3163}
3164
3165
3166
3167bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
3169 const MCExpr *Expr = nullptr;
3171
3172 if (parseExpression(Offset))
3173 return true;
3174 if (parseComma() ||
3176 return true;
3177
3180 Lex();
3181
3183 Lex();
3185 if (parseExpression(Expr))
3186 return true;
3187
3190 return Error(ExprLoc, "expression must be relocatable");
3191 }
3192
3193 if (parseEOL())
3194 return true;
3195
3198 if (std::optional<std::pair<bool, std::string>> Err =
3199 getStreamer().emitRelocDirective(*Offset, Name, Expr, DirectiveLoc,
3200 STI))
3201 return Error(Err->first ? NameLoc : OffsetLoc, Err->second);
3202
3203 return false;
3204}
3205
3206
3207
3208bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
3209 auto parseOp = [&]() -> bool {
3211 SMLoc ExprLoc = getLexer().getLoc();
3212 if (checkForValidSection() || parseExpression(Value))
3213 return true;
3214
3216 assert(Size <= 8 && "Invalid size");
3217 uint64_t IntValue = MCE->getValue();
3219 return Error(ExprLoc, "out of range literal value");
3220 getStreamer().emitIntValue(IntValue, Size);
3221 } else
3222 getStreamer().emitValue(Value, Size, ExprLoc);
3223 return false;
3224 };
3225
3226 return parseMany(parseOp);
3227}
3228
3232 return Asm.TokError("unknown token in expression");
3233 SMLoc ExprLoc = Asm.getTok().getLoc();
3234 APInt IntValue = Asm.getTok().getAPIntVal();
3235 Asm.Lex();
3236 if (!IntValue.isIntN(128))
3237 return Asm.Error(ExprLoc, "out of range literal value");
3238 if (!IntValue.isIntN(64)) {
3241 } else {
3242 hi = 0;
3244 }
3245 return false;
3246}
3247
3248
3249
3250
3251bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
3252 auto parseOp = [&]() -> bool {
3253 if (checkForValidSection())
3254 return true;
3257 return true;
3259 getStreamer().emitInt64(lo);
3260 getStreamer().emitInt64(hi);
3261 } else {
3262 getStreamer().emitInt64(hi);
3263 getStreamer().emitInt64(lo);
3264 }
3265 return false;
3266 };
3267
3268 return parseMany(parseOp);
3269}
3270
3271bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3272
3273
3274 bool IsNeg = false;
3276 Lexer.Lex();
3277 IsNeg = true;
3279 Lexer.Lex();
3280
3282 return TokError(Lexer.getErr());
3285 return TokError("unexpected token in directive");
3286
3287
3289 StringRef IDVal = getTok().getString();
3296 else
3297 return TokError("invalid floating point literal");
3299 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3300 .takeError()))
3301 return TokError("invalid floating point literal");
3302 if (IsNeg)
3303 Value.changeSign();
3304
3305
3306 Lex();
3307
3308 Res = Value.bitcastToAPInt();
3309
3310 return false;
3311}
3312
3313
3314
3315bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
3317 auto parseOp = [&]() -> bool {
3319 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3320 return true;
3323 return false;
3324 };
3325
3326 return parseMany(parseOp);
3327}
3328
3329
3330
3331bool AsmParser::parseDirectiveZero() {
3333 const MCExpr *NumBytes;
3334 if (checkForValidSection() || parseExpression(NumBytes))
3335 return true;
3336
3337 int64_t Val = 0;
3339 Lex();
3340 if (parseAbsoluteExpression(Val))
3341 return true;
3342 }
3343
3344 if (parseEOL())
3345 return true;
3346 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3347
3348 return false;
3349}
3350
3351
3352
3353bool AsmParser::parseDirectiveFill() {
3355 const MCExpr *NumValues;
3356 if (checkForValidSection() || parseExpression(NumValues))
3357 return true;
3358
3359 int64_t FillSize = 1;
3360 int64_t FillExpr = 0;
3361
3362 SMLoc SizeLoc, ExprLoc;
3363
3365 SizeLoc = getTok().getLoc();
3366 if (parseAbsoluteExpression(FillSize))
3367 return true;
3369 ExprLoc = getTok().getLoc();
3370 if (parseAbsoluteExpression(FillExpr))
3371 return true;
3372 }
3373 }
3374 if (parseEOL())
3375 return true;
3376
3377 if (FillSize < 0) {
3378 Warning(SizeLoc, "'.fill' directive with negative size has no effect");
3379 return false;
3380 }
3381 if (FillSize > 8) {
3382 Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
3383 FillSize = 8;
3384 }
3385
3386 if (!isUInt<32>(FillExpr) && FillSize > 4)
3387 Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
3388
3389 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3390
3391 return false;
3392}
3393
3394
3395
3396bool AsmParser::parseDirectiveOrg() {
3399 if (checkForValidSection() || parseExpression(Offset))
3400 return true;
3401
3402
3403 int64_t FillExpr = 0;
3405 if (parseAbsoluteExpression(FillExpr))
3406 return true;
3407 if (parseEOL())
3408 return true;
3409
3410 getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
3411 return false;
3412}
3413
3414
3415
3416bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
3417 SMLoc AlignmentLoc = getLexer().getLoc();
3418 int64_t Alignment;
3419 SMLoc MaxBytesLoc;
3420 bool HasFillExpr = false;
3421 int64_t FillExpr = 0;
3422 int64_t MaxBytesToFill = 0;
3423 SMLoc FillExprLoc;
3424
3425 auto parseAlign = [&]() -> bool {
3426 if (parseAbsoluteExpression(Alignment))
3427 return true;
3429
3430
3431
3433 HasFillExpr = true;
3434 if (parseTokenLoc(FillExprLoc) || parseAbsoluteExpression(FillExpr))
3435 return true;
3436 }
3438 if (parseTokenLoc(MaxBytesLoc) ||
3439 parseAbsoluteExpression(MaxBytesToFill))
3440 return true;
3441 }
3442 return parseEOL();
3443 };
3444
3445 if (checkForValidSection())
3446 return true;
3447
3449 Warning(AlignmentLoc, "p2align directive with no operand(s) is ignored");
3450 return parseEOL();
3451 }
3452 if (parseAlign())
3453 return true;
3454
3455
3456 bool ReturnVal = false;
3457
3458
3459 if (IsPow2) {
3460
3461 if (Alignment >= 32) {
3462 ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
3463 Alignment = 31;
3464 }
3465
3466 Alignment = 1ULL << Alignment;
3467 } else {
3468
3469
3470
3471 if (Alignment == 0)
3472 Alignment = 1;
3474 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
3475 Alignment = llvm::bit_floor<uint64_t>(Alignment);
3476 }
3477 if (!isUInt<32>(Alignment)) {
3478 ReturnVal |= Error(AlignmentLoc, "alignment must be smaller than 2**32");
3479 Alignment = 1u << 31;
3480 }
3481 }
3482
3483
3484 if (MaxBytesLoc.isValid()) {
3485 if (MaxBytesToFill < 1) {
3486 ReturnVal |= Error(MaxBytesLoc,
3487 "alignment directive can never be satisfied in this "
3488 "many bytes, ignoring maximum bytes expression");
3489 MaxBytesToFill = 0;
3490 }
3491
3492 if (MaxBytesToFill >= Alignment) {
3493 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
3494 "has no effect");
3495 MaxBytesToFill = 0;
3496 }
3497 }
3498
3499 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3500 assert(Section && "must have section to emit alignment");
3501
3502 if (HasFillExpr && FillExpr != 0 && Section->isVirtualSection()) {
3503 ReturnVal |=
3504 Warning(FillExprLoc, "ignoring non-zero fill value in " +
3505 Section->getVirtualSectionKind() +
3506 " section '" + Section->getName() + "'");
3507 FillExpr = 0;
3508 }
3509
3510
3511
3512 if (Section->useCodeAlign() && !HasFillExpr) {
3513 getStreamer().emitCodeAlignment(
3514 Align(Alignment), &getTargetParser().getSTI(), MaxBytesToFill);
3515 } else {
3516
3517 getStreamer().emitValueToAlignment(Align(Alignment), FillExpr, ValueSize,
3518 MaxBytesToFill);
3519 }
3520
3521 return ReturnVal;
3522}
3523
3524
3525
3526
3527bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
3528
3529 int64_t FileNumber = -1;
3531 FileNumber = getTok().getIntVal();
3532 Lex();
3533
3534 if (FileNumber < 0)
3535 return TokError("negative file number");
3536 }
3537
3538 std::string Path;
3539
3540
3541
3542 if (parseEscapedString(Path))
3543 return true;
3544
3547 std::string FilenameData;
3549 if (check(FileNumber == -1,
3550 "explicit path specified, but no file number") ||
3551 parseEscapedString(FilenameData))
3552 return true;
3554 Directory = Path;
3555 } else {
3557 }
3558
3560 bool HasMD5 = false;
3561
3562 std::optional Source;
3563 bool HasSource = false;
3564 std::string SourceString;
3565
3569 "unexpected token in '.file' directive") ||
3570 parseIdentifier(Keyword))
3571 return true;
3572 if (Keyword == "md5") {
3573 HasMD5 = true;
3574 if (check(FileNumber == -1,
3575 "MD5 checksum specified, but no file number") ||
3577 return true;
3578 } else if (Keyword == "source") {
3579 HasSource = true;
3580 if (check(FileNumber == -1,
3581 "source specified, but no file number") ||
3583 "unexpected token in '.file' directive") ||
3584 parseEscapedString(SourceString))
3585 return true;
3586 } else {
3587 return TokError("unexpected token in '.file' directive");
3588 }
3589 }
3590
3591 if (FileNumber == -1) {
3592
3593
3594
3595 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
3596 getStreamer().emitFileDirective(Filename);
3597 } else {
3598
3599
3600
3604 }
3605
3606 std::optionalMD5::MD5Result CKMem;
3607 if (HasMD5) {
3609 for (unsigned i = 0; i != 8; ++i) {
3610 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3611 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3612 }
3613 CKMem = Sum;
3614 }
3615 if (HasSource) {
3616 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
3617 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3619 }
3620 if (FileNumber == 0) {
3621
3624 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3625 } else {
3626 Expected FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3627 FileNumber, Directory, Filename, CKMem, Source);
3628 if (!FileNumOrErr)
3630 }
3631
3632
3634 ReportedInconsistentMD5 = true;
3635 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
3636 }
3637 }
3638
3639 return false;
3640}
3641
3642
3643
3644bool AsmParser::parseDirectiveLine() {
3645 int64_t LineNumber;
3647 if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
3648 return true;
3649 (void)LineNumber;
3650
3651 }
3652 return parseEOL();
3653}
3654
3655
3656
3657
3658
3659
3660
3661
3662bool AsmParser::parseDirectiveLoc() {
3663 int64_t FileNumber = 0, LineNumber = 0;
3664 SMLoc Loc = getTok().getLoc();
3665 if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
3667 "file number less than one in '.loc' directive") ||
3668 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3669 "unassigned file number in '.loc' directive"))
3670 return true;
3671
3672
3674 LineNumber = getTok().getIntVal();
3675 if (LineNumber < 0)
3676 return TokError("line number less than zero in '.loc' directive");
3677 Lex();
3678 }
3679
3680 int64_t ColumnPos = 0;
3682 ColumnPos = getTok().getIntVal();
3683 if (ColumnPos < 0)
3684 return TokError("column position less than zero in '.loc' directive");
3685 Lex();
3686 }
3687
3688 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
3690 unsigned Isa = 0;
3692
3693 auto parseLocOp = [&]() -> bool {
3695 SMLoc Loc = getTok().getLoc();
3696 if (parseIdentifier(Name))
3697 return TokError("unexpected token in '.loc' directive");
3698
3699 if (Name == "basic_block")
3701 else if (Name == "prologue_end")
3703 else if (Name == "epilogue_begin")
3705 else if (Name == "is_stmt") {
3706 Loc = getTok().getLoc();
3708 if (parseExpression(Value))
3709 return true;
3710
3712 int Value = MCE->getValue();
3714 Flags &= ~DWARF2_FLAG_IS_STMT;
3715 else if (Value == 1)
3717 else
3718 return Error(Loc, "is_stmt value not 0 or 1");
3719 } else {
3720 return Error(Loc, "is_stmt value not the constant value of 0 or 1");
3721 }
3722 } else if (Name == "isa") {
3723 Loc = getTok().getLoc();
3725 if (parseExpression(Value))
3726 return true;
3727
3729 int Value = MCE->getValue();
3731 return Error(Loc, "isa number less than zero");
3733 } else {
3734 return Error(Loc, "isa number not a constant value");
3735 }
3736 } else if (Name == "discriminator") {
3737 if (parseAbsoluteExpression(Discriminator))
3738 return true;
3739 } else {
3740 return Error(Loc, "unknown sub-directive in '.loc' directive");
3741 }
3742 return false;
3743 };
3744
3745 if (parseMany(parseLocOp, false ))
3746 return true;
3747
3748 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3749 Isa, Discriminator, StringRef());
3750
3751 return false;
3752}
3753
3754
3755
3756bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) {
3758 DirectiveLoc = Lexer.getLoc();
3759 if (parseIdentifier(Name))
3760 return TokError("expected identifier");
3761 if (parseEOL())
3762 return true;
3763 getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name);
3764 return false;
3765}
3766
3767
3768
3769bool AsmParser::parseDirectiveStabs() {
3770 return TokError("unsupported directive '.stabs'");
3771}
3772
3773
3774
3775bool AsmParser::parseDirectiveCVFile() {
3776 SMLoc FileNumberLoc = getTok().getLoc();
3777 int64_t FileNumber;
3779 std::string Checksum;
3781
3782 if (parseIntToken(FileNumber,
3783 "expected file number in '.cv_file' directive") ||
3784 check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
3786 "unexpected token in '.cv_file' directive") ||
3787 parseEscapedString(Filename))
3788 return true;
3791 "unexpected token in '.cv_file' directive") ||
3792 parseEscapedString(Checksum) ||
3793 parseIntToken(ChecksumKind,
3794 "expected checksum kind in '.cv_file' directive") ||
3795 parseEOL())
3796 return true;
3797 }
3798
3799 Checksum = fromHex(Checksum);
3800 void *CKMem = Ctx.allocate(Checksum.size(), 1);
3801 memcpy(CKMem, Checksum.data(), Checksum.size());
3803 Checksum.size());
3804
3805 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3806 static_cast<uint8_t>(ChecksumKind)))
3807 return Error(FileNumberLoc, "file number already allocated");
3808
3809 return false;
3810}
3811
3812bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
3815 return parseTokenLoc(Loc) ||
3816 parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
3817 "' directive") ||
3818 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3819 "expected function id within range [0, UINT_MAX)");
3820}
3821
3822bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3824 return parseTokenLoc(Loc) ||
3825 parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
3826 "' directive") ||
3827 check(FileNumber < 1, Loc, "file number less than one in '" +
3828 DirectiveName + "' directive") ||
3829 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3830 "unassigned file number in '" + DirectiveName + "' directive");
3831}
3832
3833
3834
3835
3836
3837bool AsmParser::parseDirectiveCVFuncId() {
3838 SMLoc FunctionIdLoc = getTok().getLoc();
3840
3841 if (parseCVFunctionId(FunctionId, ".cv_func_id") || parseEOL())
3842 return true;
3843
3844 if (!getStreamer().emitCVFuncIdDirective(FunctionId))
3845 return Error(FunctionIdLoc, "function id already allocated");
3846
3847 return false;
3848}
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858bool AsmParser::parseDirectiveCVInlineSiteId() {
3859 SMLoc FunctionIdLoc = getTok().getLoc();
3861 int64_t IAFunc;
3862 int64_t IAFile;
3863 int64_t IALine;
3864 int64_t IACol = 0;
3865
3866
3867 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
3868 return true;
3869
3870
3872 getTok().getIdentifier() != "within"),
3873 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3874 return true;
3875 Lex();
3876
3877
3878 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
3879 return true;
3880
3881
3883 getTok().getIdentifier() != "inlined_at"),
3884 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3885 "directive") )
3886 return true;
3887 Lex();
3888
3889
3890 if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
3891 parseIntToken(IALine, "expected line number after 'inlined_at'"))
3892 return true;
3893
3894
3896 IACol = getTok().getIntVal();
3897 Lex();
3898 }
3899
3900 if (parseEOL())
3901 return true;
3902
3903 if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3904 IALine, IACol, FunctionIdLoc))
3905 return Error(FunctionIdLoc, "function id already allocated");
3906
3907 return false;
3908}
3909
3910
3911
3912
3913
3914
3915
3916
3917bool AsmParser::parseDirectiveCVLoc() {
3918 SMLoc DirectiveLoc = getTok().getLoc();
3920 if (parseCVFunctionId(FunctionId, ".cv_loc") ||
3921 parseCVFileId(FileNumber, ".cv_loc"))
3922 return true;
3923
3924 int64_t LineNumber = 0;
3926 LineNumber = getTok().getIntVal();
3927 if (LineNumber < 0)
3928 return TokError("line number less than zero in '.cv_loc' directive");
3929 Lex();
3930 }
3931
3932 int64_t ColumnPos = 0;
3934 ColumnPos = getTok().getIntVal();
3935 if (ColumnPos < 0)
3936 return TokError("column position less than zero in '.cv_loc' directive");
3937 Lex();
3938 }
3939
3940 bool PrologueEnd = false;
3942
3943 auto parseOp = [&]() -> bool {
3945 SMLoc Loc = getTok().getLoc();
3946 if (parseIdentifier(Name))
3947 return TokError("unexpected token in '.cv_loc' directive");
3948 if (Name == "prologue_end")
3949 PrologueEnd = true;
3950 else if (Name == "is_stmt") {
3951 Loc = getTok().getLoc();
3953 if (parseExpression(Value))
3954 return true;
3955
3956 IsStmt = ~0ULL;
3957 if (const auto *MCE = dyn_cast(Value))
3958 IsStmt = MCE->getValue();
3959
3960 if (IsStmt > 1)
3961 return Error(Loc, "is_stmt value not 0 or 1");
3962 } else {
3963 return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
3964 }
3965 return false;
3966 };
3967
3968 if (parseMany(parseOp, false ))
3969 return true;
3970
3971 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
3972 ColumnPos, PrologueEnd, IsStmt, StringRef(),
3973 DirectiveLoc);
3974 return false;
3975}
3976
3977
3978
3979bool AsmParser::parseDirectiveCVLinetable() {
3981 StringRef FnStartName, FnEndName;
3982 SMLoc Loc = getTok().getLoc();
3983 if (parseCVFunctionId(FunctionId, ".cv_linetable") || parseComma() ||
3984 parseTokenLoc(Loc) ||
3985 check(parseIdentifier(FnStartName), Loc,
3986 "expected identifier in directive") ||
3987 parseComma() || parseTokenLoc(Loc) ||
3988 check(parseIdentifier(FnEndName), Loc,
3989 "expected identifier in directive"))
3990 return true;
3991
3992 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3993 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3994
3995 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
3996 return false;
3997}
3998
3999
4000
4001bool AsmParser::parseDirectiveCVInlineLinetable() {
4002 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
4003 StringRef FnStartName, FnEndName;
4004 SMLoc Loc = getTok().getLoc();
4005 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
4006 parseTokenLoc(Loc) ||
4007 parseIntToken(
4008 SourceFileId,
4009 "expected SourceField in '.cv_inline_linetable' directive") ||
4010 check(SourceFileId <= 0, Loc,
4011 "File id less than zero in '.cv_inline_linetable' directive") ||
4012 parseTokenLoc(Loc) ||
4013 parseIntToken(
4014 SourceLineNum,
4015 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
4016 check(SourceLineNum < 0, Loc,
4017 "Line number less than zero in '.cv_inline_linetable' directive") ||
4018 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
4019 "expected identifier in directive") ||
4020 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
4021 "expected identifier in directive"))
4022 return true;
4023
4024 if (parseEOL())
4025 return true;
4026
4027 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4028 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4029 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
4030 SourceLineNum, FnStartSym,
4031 FnEndSym);
4032 return false;
4033}
4034
4035void AsmParser::initializeCVDefRangeTypeMap() {
4036 CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
4037 CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4038 CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4039 CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4040}
4041
4042
4043
4044bool AsmParser::parseDirectiveCVDefRange() {
4046 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
4048 Loc = getLexer().getLoc();
4050 if (parseIdentifier(GapStartName))
4051 return Error(Loc, "expected identifier in directive");
4052 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
4053
4054 Loc = getLexer().getLoc();
4056 if (parseIdentifier(GapEndName))
4057 return Error(Loc, "expected identifier in directive");
4058 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
4059
4060 Ranges.push_back({GapStartSym, GapEndSym});
4061 }
4062
4064 if (parseToken(
4066 "expected comma before def_range type in .cv_def_range directive") ||
4067 parseIdentifier(CVDefRangeTypeStr))
4068 return Error(Loc, "expected def_range type in directive");
4069
4071 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4072 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4073 ? CVDR_DEFRANGE
4074 : CVTypeIt->getValue();
4075 switch (CVDRType) {
4076 case CVDR_DEFRANGE_REGISTER: {
4077 int64_t DRRegister;
4078 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4079 ".cv_def_range directive") ||
4080 parseAbsoluteExpression(DRRegister))
4081 return Error(Loc, "expected register number");
4082
4084 DRHdr.Register = DRRegister;
4086 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4087 break;
4088 }
4089 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4090 int64_t DROffset;
4092 "expected comma before offset in .cv_def_range directive") ||
4093 parseAbsoluteExpression(DROffset))
4094 return Error(Loc, "expected offset value");
4095
4097 DRHdr.Offset = DROffset;
4098 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4099 break;
4100 }
4101 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4102 int64_t DRRegister;
4103 int64_t DROffsetInParent;
4104 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4105 ".cv_def_range directive") ||
4106 parseAbsoluteExpression(DRRegister))
4107 return Error(Loc, "expected register number");
4109 "expected comma before offset in .cv_def_range directive") ||
4110 parseAbsoluteExpression(DROffsetInParent))
4111 return Error(Loc, "expected offset value");
4112
4114 DRHdr.Register = DRRegister;
4117 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4118 break;
4119 }
4120 case CVDR_DEFRANGE_REGISTER_REL: {
4121 int64_t DRRegister;
4122 int64_t DRFlags;
4123 int64_t DRBasePointerOffset;
4124 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4125 ".cv_def_range directive") ||
4126 parseAbsoluteExpression(DRRegister))
4127 return Error(Loc, "expected register value");
4128 if (parseToken(
4130 "expected comma before flag value in .cv_def_range directive") ||
4131 parseAbsoluteExpression(DRFlags))
4132 return Error(Loc, "expected flag value");
4133 if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
4134 "in .cv_def_range directive") ||
4135 parseAbsoluteExpression(DRBasePointerOffset))
4136 return Error(Loc, "expected base pointer offset value");
4137
4139 DRHdr.Register = DRRegister;
4140 DRHdr.Flags = DRFlags;
4142 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4143 break;
4144 }
4145 default:
4146 return Error(Loc, "unexpected def_range type in .cv_def_range directive");
4147 }
4148 return true;
4149}
4150
4151
4152
4153bool AsmParser::parseDirectiveCVString() {
4154 std::string Data;
4155 if (checkForValidSection() || parseEscapedString(Data))
4156 return true;
4157
4158
4159 std::pair<StringRef, unsigned> Insertion =
4160 getCVContext().addToStringTable(Data);
4161 getStreamer().emitInt32(Insertion.second);
4162 return false;
4163}
4164
4165
4166
4167bool AsmParser::parseDirectiveCVStringTable() {
4168 getStreamer().emitCVStringTableDirective();
4169 return false;
4170}
4171
4172
4173
4174bool AsmParser::parseDirectiveCVFileChecksums() {
4175 getStreamer().emitCVFileChecksumsDirective();
4176 return false;
4177}
4178
4179
4180
4181bool AsmParser::parseDirectiveCVFileChecksumOffset() {
4182 int64_t FileNo;
4183 if (parseIntToken(FileNo, "expected identifier in directive"))
4184 return true;
4185 if (parseEOL())
4186 return true;
4187 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4188 return false;
4189}
4190
4191
4192
4193bool AsmParser::parseDirectiveCVFPOData() {
4194 SMLoc DirLoc = getLexer().getLoc();
4196 if (parseIdentifier(ProcName))
4197 return TokError("expected symbol name");
4198 if (parseEOL())
4199 return true;
4200 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4201 getStreamer().emitCVFPOData(ProcSym, DirLoc);
4202 return false;
4203}
4204
4205
4206
4207bool AsmParser::parseDirectiveCFISections() {
4209 bool EH = false;
4210 bool Debug = false;
4211
4213 for (;;) {
4214 if (parseIdentifier(Name))
4215 return TokError("expected .eh_frame or .debug_frame");
4216 if (Name == ".eh_frame")
4217 EH = true;
4218 else if (Name == ".debug_frame")
4221 break;
4222 if (parseComma())
4223 return true;
4224 }
4225 }
4226 getStreamer().emitCFISections(EH, Debug);
4227 return false;
4228}
4229
4230
4231
4232bool AsmParser::parseDirectiveCFIStartProc() {
4233 CFIStartProcLoc = StartTokLoc;
4234
4237 if (check(parseIdentifier(Simple) || Simple != "simple",
4238 "unexpected token") ||
4239 parseEOL())
4240 return true;
4241 }
4242
4243
4244
4245
4246
4247
4248 getStreamer().emitCFIStartProc(.empty(), Lexer.getLoc());
4249 return false;
4250}
4251
4252
4253
4254bool AsmParser::parseDirectiveCFIEndProc() {
4255 CFIStartProcLoc = std::nullopt;
4256
4257 if (parseEOL())
4258 return true;
4259
4260 getStreamer().emitCFIEndProc();
4261 return false;
4262}
4263
4264
4265bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
4266 SMLoc DirectiveLoc) {
4268
4270 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4271 return true;
4272 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
4273 } else
4274 return parseAbsoluteExpression(Register);
4275
4276 return false;
4277}
4278
4279
4280
4281bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
4283 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4284 parseAbsoluteExpression(Offset) || parseEOL())
4285 return true;
4286
4287 getStreamer().emitCFIDefCfa(Register, Offset, DirectiveLoc);
4288 return false;
4289}
4290
4291
4292
4293bool AsmParser::parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc) {
4295 if (parseAbsoluteExpression(Offset) || parseEOL())
4296 return true;
4297
4298 getStreamer().emitCFIDefCfaOffset(Offset, DirectiveLoc);
4299 return false;
4300}
4301
4302
4303
4304bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
4305 int64_t Register1 = 0, Register2 = 0;
4306 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
4307 parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
4308 return true;
4309
4310 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
4311 return false;
4312}
4313
4314
4315
4316bool AsmParser::parseDirectiveCFIWindowSave(SMLoc DirectiveLoc) {
4317 if (parseEOL())
4318 return true;
4319 getStreamer().emitCFIWindowSave(DirectiveLoc);
4320 return false;
4321}
4322
4323
4324
4325bool AsmParser::parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc) {
4326 int64_t Adjustment = 0;
4327 if (parseAbsoluteExpression(Adjustment) || parseEOL())
4328 return true;
4329
4330 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
4331 return false;
4332}
4333
4334
4335
4336bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
4338 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4339 return true;
4340
4341 getStreamer().emitCFIDefCfaRegister(Register, DirectiveLoc);
4342 return false;
4343}
4344
4345
4346
4347bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc) {
4349 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4350 parseAbsoluteExpression(Offset) || parseComma() ||
4351 parseAbsoluteExpression(AddressSpace) || parseEOL())
4352 return true;
4353
4355 DirectiveLoc);
4356 return false;
4357}
4358
4359
4360
4361bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
4364
4365 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4366 parseAbsoluteExpression(Offset) || parseEOL())
4367 return true;
4368
4369 getStreamer().emitCFIOffset(Register, Offset, DirectiveLoc);
4370 return false;
4371}
4372
4373
4374
4375bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
4377
4378 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4379 parseAbsoluteExpression(Offset) || parseEOL())
4380 return true;
4381
4382 getStreamer().emitCFIRelOffset(Register, Offset, DirectiveLoc);
4383 return false;
4384}
4385
4387 if (Encoding & ~0xff)
4388 return false;
4389
4391 return true;
4392
4393 const unsigned Format = Encoding & 0xf;
4398 return false;
4399
4400 const unsigned Application = Encoding & 0x70;
4403 return false;
4404
4405 return true;
4406}
4407
4408
4409
4410
4411
4412bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
4413 int64_t Encoding = 0;
4414 if (parseAbsoluteExpression(Encoding))
4415 return true;
4417 return false;
4418
4420 if (check((Encoding), "unsupported encoding.") ||
4421 parseComma() ||
4422 check(parseIdentifier(Name), "expected identifier in directive") ||
4423 parseEOL())
4424 return true;
4425
4427
4428 if (IsPersonality)
4429 getStreamer().emitCFIPersonality(Sym, Encoding);
4430 else
4431 getStreamer().emitCFILsda(Sym, Encoding);
4432 return false;
4433}
4434
4435
4436
4437bool AsmParser::parseDirectiveCFIRememberState(SMLoc DirectiveLoc) {
4438 if (parseEOL())
4439 return true;
4440 getStreamer().emitCFIRememberState(DirectiveLoc);
4441 return false;
4442}
4443
4444
4445
4446bool AsmParser::parseDirectiveCFIRestoreState(SMLoc DirectiveLoc) {
4447 if (parseEOL())
4448 return true;
4449 getStreamer().emitCFIRestoreState(DirectiveLoc);
4450 return false;
4451}
4452
4453
4454
4455bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
4457
4458 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4459 return true;
4460
4461 getStreamer().emitCFISameValue(Register, DirectiveLoc);
4462 return false;
4463}
4464
4465
4466
4467bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
4469 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4470 return true;
4471
4472 getStreamer().emitCFIRestore(Register, DirectiveLoc);
4473 return false;
4474}
4475
4476
4477
4478bool AsmParser::parseDirectiveCFIEscape(SMLoc DirectiveLoc) {
4479 std::string Values;
4480 int64_t CurrValue;
4481 if (parseAbsoluteExpression(CurrValue))
4482 return true;
4483
4484 Values.push_back((uint8_t)CurrValue);
4485
4487 Lex();
4488
4489 if (parseAbsoluteExpression(CurrValue))
4490 return true;
4491
4492 Values.push_back((uint8_t)CurrValue);
4493 }
4494
4495 getStreamer().emitCFIEscape(Values, DirectiveLoc);
4496 return false;
4497}
4498
4499
4500
4501bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4503 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4504 return true;
4505 getStreamer().emitCFIReturnColumn(Register);
4506 return false;
4507}
4508
4509
4510
4511bool AsmParser::parseDirectiveCFISignalFrame(SMLoc DirectiveLoc) {
4512 if (parseEOL())
4513 return true;
4514
4515 getStreamer().emitCFISignalFrame();
4516 return false;
4517}
4518
4519
4520
4521bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4523
4524 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4525 return true;
4526
4527 getStreamer().emitCFIUndefined(Register, DirectiveLoc);
4528 return false;
4529}
4530
4531
4532
4533bool AsmParser::parseDirectiveCFILabel(SMLoc Loc) {
4535 Loc = Lexer.getLoc();
4536 if (parseIdentifier(Name))
4537 return TokError("expected identifier");
4538 if (parseEOL())
4539 return true;
4540 getStreamer().emitCFILabelDirective(Loc, Name);
4541 return false;
4542}
4543
4544
4545
4546bool AsmParser::parseDirectiveCFIValOffset(SMLoc DirectiveLoc) {
4549
4550 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4551 parseAbsoluteExpression(Offset) || parseEOL())
4552 return true;
4553
4554 getStreamer().emitCFIValOffset(Register, Offset, DirectiveLoc);
4555 return false;
4556}
4557
4558
4559
4560
4562 if (parseEOL())
4563 return true;
4564 AltMacroMode = (Directive == ".altmacro");
4565 return false;
4566}
4567
4568
4569
4570
4572 if (parseEOL())
4573 return true;
4574 setMacrosEnabled(Directive == ".macros_on");
4575 return false;
4576}
4577
4578
4579
4580bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4582 if (parseIdentifier(Name))
4583 return TokError("expected identifier in '.macro' directive");
4584
4586 Lex();
4587
4590
4592 return Error(Lexer.getLoc(), "vararg parameter '" +
4594 "' should be the last parameter");
4595
4597 if (parseIdentifier(Parameter.Name))
4598 return TokError("expected identifier in '.macro' directive");
4599
4600
4602 if (CurrParam.Name == Parameter.Name)
4603 return TokError("macro '" + Name + "' has multiple parameters"
4604 " named '" + Parameter.Name + "'");
4605
4607 Lex();
4608
4611
4612 QualLoc = Lexer.getLoc();
4613 if (parseIdentifier(Qualifier))
4614 return Error(QualLoc, "missing parameter qualifier for "
4615 "'" + Parameter.Name + "' in macro '" + Name + "'");
4616
4617 if (Qualifier == "req")
4619 else if (Qualifier == "vararg")
4620 Parameter.Vararg = true;
4621 else
4622 return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
4623 "for '" + Parameter.Name + "' in macro '" + Name + "'");
4624 }
4625
4627 Lex();
4628
4630
4631 ParamLoc = Lexer.getLoc();
4632 if (parseMacroArgument(Parameter.Value, false ))
4633 return true;
4634
4636 Warning(ParamLoc, "pointless default value for required parameter "
4637 "'" + Parameter.Name + "' in macro '" + Name + "'");
4638 }
4639
4640 Parameters.push_back(std::move(Parameter));
4641
4643 Lex();
4644 }
4645
4646
4647 Lexer.Lex();
4648
4649
4650 AsmToken EndToken, StartToken = getTok();
4651 unsigned MacroDepth = 0;
4652
4653 while (true) {
4654
4656 Lexer.Lex();
4657 }
4658
4659
4661 return Error(DirectiveLoc, "no matching '.endmacro' in definition");
4662
4663
4664
4666 if (getTok().getIdentifier() == ".endm" ||
4667 getTok().getIdentifier() == ".endmacro") {
4668 if (MacroDepth == 0) {
4669 EndToken = getTok();
4670 Lexer.Lex();
4672 return TokError("unexpected token in '" + EndToken.getIdentifier() +
4673 "' directive");
4674 break;
4675 } else {
4676
4677 --MacroDepth;
4678 }
4679 } else if (getTok().getIdentifier() == ".macro") {
4680
4681
4682 ++MacroDepth;
4683 }
4685 (void)parseCppHashLineFilenameComment(getLexer().getLoc());
4686 }
4687
4688
4689 eatToEndOfStatement();
4690 }
4691
4692 if (getContext().lookupMacro(Name)) {
4693 return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
4694 }
4695
4699 checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4703 getContext().defineMacro(Name, std::move(Macro));
4704 return false;
4705}
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4724
4725
4726 unsigned NParameters = Parameters.size();
4727 if (NParameters == 0)
4728 return;
4729
4730 bool NamedParametersFound = false;
4731 bool PositionalParametersFound = false;
4732
4733
4734
4735
4736 while (!Body.empty()) {
4737
4738 std::size_t End = Body.size(), Pos = 0;
4739 for (; Pos != End; ++Pos) {
4740
4741
4742 if (Body[Pos] == '\\' && Pos + 1 != End)
4743 break;
4744
4745
4746 if (Body[Pos] != '$' || Pos + 1 == End)
4747 continue;
4748 char Next = Body[Pos + 1];
4749 if (Next == '$' || Next == 'n' ||
4750 isdigit(static_cast<unsigned char>(Next)))
4751 break;
4752 }
4753
4754
4755 if (Pos == End)
4756 break;
4757
4758 if (Body[Pos] == '$') {
4759 switch (Body[Pos + 1]) {
4760
4761 case '$':
4762 break;
4763
4764
4765 case 'n':
4766 PositionalParametersFound = true;
4767 break;
4768
4769
4770 default: {
4771 PositionalParametersFound = true;
4772 break;
4773 }
4774 }
4775 Pos += 2;
4776 } else {
4777 unsigned I = Pos + 1;
4779 ++I;
4780
4781 const char *Begin = Body.data() + Pos + 1;
4783 unsigned Index = 0;
4784 for (; Index < NParameters; ++Index)
4786 break;
4787
4788 if (Index == NParameters) {
4789 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
4790 Pos += 3;
4791 else {
4792 Pos = I;
4793 }
4794 } else {
4795 NamedParametersFound = true;
4797 }
4798 }
4799
4800 Body = Body.substr(Pos);
4801 }
4802
4803 if (!NamedParametersFound && PositionalParametersFound)
4804 Warning(DirectiveLoc, "macro defined with named parameters which are not "
4805 "used in macro body, possible positional parameter "
4806 "found in body which will have no effect");
4807}
4808
4809
4810
4812 if (parseEOL())
4813 return true;
4814
4815 if (!isInsideMacroInstantiation())
4816 return TokError("unexpected '" + Directive + "' in file, "
4817 "no current macro definition");
4818
4819
4820 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4821 TheCondState = TheCondStack.back();
4822 TheCondStack.pop_back();
4823 }
4824
4825 handleMacroExit();
4826 return false;
4827}
4828
4829
4830
4831
4834 return TokError("unexpected token in '" + Directive + "' directive");
4835
4836
4837
4838 if (isInsideMacroInstantiation()) {
4839 handleMacroExit();
4840 return false;
4841 }
4842
4843
4844
4845 return TokError("unexpected '" + Directive + "' in file, "
4846 "no current macro definition");
4847}
4848
4849
4850
4851bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4854 if (parseTokenLoc(Loc) ||
4855 check(parseIdentifier(Name), Loc,
4856 "expected identifier in '.purgem' directive") ||
4857 parseEOL())
4858 return true;
4859
4860 if (!getContext().lookupMacro(Name))
4861 return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
4862
4863 getContext().undefineMacro(Name);
4865 << "Un-defining macro: " << Name << "\n");
4866 return false;
4867}
4868
4869
4870
4871bool AsmParser::parseDirectiveBundleAlignMode() {
4872
4873
4874 SMLoc ExprLoc = getLexer().getLoc();
4875 int64_t AlignSizePow2;
4876 if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4877 parseEOL() ||
4878 check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4879 "invalid bundle alignment size (expected between 0 and 30)"))
4880 return true;
4881
4882 getStreamer().emitBundleAlignMode(Align(1ULL << AlignSizePow2));
4883 return false;
4884}
4885
4886
4887
4888bool AsmParser::parseDirectiveBundleLock() {
4889 if (checkForValidSection())
4890 return true;
4891 bool AlignToEnd = false;
4892
4894 SMLoc Loc = getTok().getLoc();
4895 const char *kInvalidOptionError =
4896 "invalid option for '.bundle_lock' directive";
4897
4899 if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4900 check(Option != "align_to_end", Loc, kInvalidOptionError) || parseEOL())
4901 return true;
4902 AlignToEnd = true;
4903 }
4904
4905 getStreamer().emitBundleLock(AlignToEnd);
4906 return false;
4907}
4908
4909
4910
4911bool AsmParser::parseDirectiveBundleUnlock() {
4912 if (checkForValidSection() || parseEOL())
4913 return true;
4914
4915 getStreamer().emitBundleUnlock();
4916 return false;
4917}
4918
4919
4920
4921bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
4923 const MCExpr *NumBytes;
4924 if (checkForValidSection() || parseExpression(NumBytes))
4925 return true;
4926
4927 int64_t FillExpr = 0;
4929 if (parseAbsoluteExpression(FillExpr))
4930 return true;
4931 if (parseEOL())
4932 return true;
4933
4934
4935 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4936
4937 return false;
4938}
4939
4940
4941
4942bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
4944 int64_t NumValues;
4945 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4946 return true;
4947
4948 if (NumValues < 0) {
4949 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4950 return false;
4951 }
4952
4953 if (parseComma())
4954 return true;
4955
4957 SMLoc ExprLoc = getLexer().getLoc();
4958 if (parseExpression(Value))
4959 return true;
4960
4961
4963 assert(Size <= 8 && "Invalid size");
4964 uint64_t IntValue = MCE->getValue();
4966 return Error(ExprLoc, "literal value out of range for directive");
4967 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4968 getStreamer().emitIntValue(IntValue, Size);
4969 } else {
4970 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4971 getStreamer().emitValue(Value, Size, ExprLoc);
4972 }
4973
4974 return parseEOL();
4975}
4976
4977
4978
4979bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
4981 int64_t NumValues;
4982 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4983 return true;
4984
4985 if (NumValues < 0) {
4986 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4987 return false;
4988 }
4989
4990 if (parseComma())
4991 return true;
4992
4994 if (parseRealValue(Semantics, AsInt) || parseEOL())
4995 return true;
4996
4997 for (uint64_t i = 0, e = NumValues; i != e; ++i)
5000
5001 return false;
5002}
5003
5004
5005
5006bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
5008 int64_t NumValues;
5009 if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
5010 parseEOL())
5011 return true;
5012
5013 if (NumValues < 0) {
5014 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
5015 return false;
5016 }
5017
5018 for (uint64_t i = 0, e = NumValues; i != e; ++i)
5019 getStreamer().emitFill(Size, 0);
5020
5021 return false;
5022}
5023
5024
5025
5026bool AsmParser::parseDirectiveLEB128(bool Signed) {
5027 if (checkForValidSection())
5028 return true;
5029
5030 auto parseOp = [&]() -> bool {
5032 if (parseExpression(Value))
5033 return true;
5035 getStreamer().emitSLEB128Value(Value);
5036 else
5037 getStreamer().emitULEB128Value(Value);
5038 return false;
5039 };
5040
5041 return parseMany(parseOp);
5042}
5043
5044
5045
5046bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
5047 auto parseOp = [&]() -> bool {
5049 SMLoc Loc = getTok().getLoc();
5050 if (parseIdentifier(Name))
5051 return Error(Loc, "expected identifier");
5052
5053 if (discardLTOSymbol(Name))
5054 return false;
5055
5057
5058
5059
5061 return Error(Loc, "non-local symbol required");
5062
5063 if (!getStreamer().emitSymbolAttribute(Sym, Attr))
5064 return Error(Loc, "unable to emit symbol attribute");
5065 return false;
5066 };
5067
5068 return parseMany(parseOp);
5069}
5070
5071
5072
5073bool AsmParser::parseDirectiveComm(bool IsLocal) {
5074 if (checkForValidSection())
5075 return true;
5076
5077 SMLoc IDLoc = getLexer().getLoc();
5079 if (parseIdentifier(Name))
5080 return TokError("expected identifier in directive");
5081
5082
5084
5085 if (parseComma())
5086 return true;
5087
5088 int64_t Size;
5089 SMLoc SizeLoc = getLexer().getLoc();
5090 if (parseAbsoluteExpression(Size))
5091 return true;
5092
5093 int64_t Pow2Alignment = 0;
5094 SMLoc Pow2AlignmentLoc;
5096 Lex();
5097 Pow2AlignmentLoc = getLexer().getLoc();
5098 if (parseAbsoluteExpression(Pow2Alignment))
5099 return true;
5100
5101 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
5103 return Error(Pow2AlignmentLoc, "alignment not supported on this target");
5104
5105
5106 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5109 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
5110 Pow2Alignment = Log2_64(Pow2Alignment);
5111 }
5112 }
5113
5114 if (parseEOL())
5115 return true;
5116
5117
5118
5119 if (Size < 0)
5120 return Error(SizeLoc, "size must be non-negative");
5121
5122 Sym->redefineIfPossible();
5123 if (->isUndefined())
5124 return Error(IDLoc, "invalid symbol redefinition");
5125
5126
5127 if (IsLocal) {
5128 getStreamer().emitLocalCommonSymbol(Sym, Size,
5129 Align(1ULL << Pow2Alignment));
5130 return false;
5131 }
5132
5133 getStreamer().emitCommonSymbol(Sym, Size, Align(1ULL << Pow2Alignment));
5134 return false;
5135}
5136
5137
5138
5139bool AsmParser::parseDirectiveAbort(SMLoc DirectiveLoc) {
5140 StringRef Str = parseStringToEndOfStatement();
5141 if (parseEOL())
5142 return true;
5143
5144 if (Str.empty())
5145 return Error(DirectiveLoc, ".abort detected. Assembly stopping");
5146
5147
5148 return Error(DirectiveLoc,
5149 ".abort '" + Str + "' detected. Assembly stopping");
5150}
5151
5152
5153
5154bool AsmParser::parseDirectiveInclude() {
5155
5157 SMLoc IncludeLoc = getTok().getLoc();
5158
5160 "expected string in '.include' directive") ||
5161 parseEscapedString(Filename) ||
5163 "unexpected token in '.include' directive") ||
5164
5165
5166 check(enterIncludeFile(Filename), IncludeLoc,
5167 "Could not find include file '" + Filename + "'"))
5168 return true;
5169
5170 return false;
5171}
5172
5173
5174
5175bool AsmParser::parseDirectiveIncbin() {
5176
5178 SMLoc IncbinLoc = getTok().getLoc();
5180 "expected string in '.incbin' directive") ||
5181 parseEscapedString(Filename))
5182 return true;
5183
5184 int64_t Skip = 0;
5185 const MCExpr *Count = nullptr;
5186 SMLoc SkipLoc, CountLoc;
5188
5189
5191 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
5192 return true;
5193 }
5195 CountLoc = getTok().getLoc();
5196 if (parseExpression(Count))
5197 return true;
5198 }
5199 }
5200
5201 if (parseEOL())
5202 return true;
5203
5204 if (check(Skip < 0, SkipLoc, "skip is negative"))
5205 return true;
5206
5207
5208 if (processIncbinFile(Filename, Skip, Count, CountLoc))
5209 return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
5210 return false;
5211}
5212
5213
5214
5215bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
5216 TheCondStack.push_back(TheCondState);
5218 if (TheCondState.Ignore) {
5219 eatToEndOfStatement();
5220 } else {
5221 int64_t ExprValue;
5222 if (parseAbsoluteExpression(ExprValue) || parseEOL())
5223 return true;
5224
5225 switch (DirKind) {
5226 default:
5228 case DK_IF:
5229 case DK_IFNE:
5230 break;
5231 case DK_IFEQ:
5232 ExprValue = ExprValue == 0;
5233 break;
5234 case DK_IFGE:
5235 ExprValue = ExprValue >= 0;
5236 break;
5237 case DK_IFGT:
5238 ExprValue = ExprValue > 0;
5239 break;
5240 case DK_IFLE:
5241 ExprValue = ExprValue <= 0;
5242 break;
5243 case DK_IFLT:
5244 ExprValue = ExprValue < 0;
5245 break;
5246 }
5247
5248 TheCondState.CondMet = ExprValue;
5250 }
5251
5252 return false;
5253}
5254
5255
5256
5257bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5258 TheCondStack.push_back(TheCondState);
5260
5261 if (TheCondState.Ignore) {
5262 eatToEndOfStatement();
5263 } else {
5264 StringRef Str = parseStringToEndOfStatement();
5265
5266 if (parseEOL())
5267 return true;
5268
5269 TheCondState.CondMet = ExpectBlank == Str.empty();
5271 }
5272
5273 return false;
5274}
5275
5276
5277
5278
5279bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
5280 TheCondStack.push_back(TheCondState);
5282
5283 if (TheCondState.Ignore) {
5284 eatToEndOfStatement();
5285 } else {
5286 StringRef Str1 = parseStringToComma();
5287
5288 if (parseComma())
5289 return true;
5290
5291 StringRef Str2 = parseStringToEndOfStatement();
5292
5293 if (parseEOL())
5294 return true;
5295
5296 TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
5298 }
5299
5300 return false;
5301}
5302
5303
5304
5305bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
5307 if (ExpectEqual)
5308 return TokError("expected string parameter for '.ifeqs' directive");
5309 return TokError("expected string parameter for '.ifnes' directive");
5310 }
5311
5312 StringRef String1 = getTok().getStringContents();
5313 Lex();
5314
5316 if (ExpectEqual)
5317 return TokError(
5318 "expected comma after first string for '.ifeqs' directive");
5319 return TokError("expected comma after first string for '.ifnes' directive");
5320 }
5321
5322 Lex();
5323
5325 if (ExpectEqual)
5326 return TokError("expected string parameter for '.ifeqs' directive");
5327 return TokError("expected string parameter for '.ifnes' directive");
5328 }
5329
5330 StringRef String2 = getTok().getStringContents();
5331 Lex();
5332
5333 TheCondStack.push_back(TheCondState);
5335 TheCondState.CondMet = ExpectEqual == (String1 == String2);
5337
5338 return false;
5339}
5340
5341
5342
5343bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
5345 TheCondStack.push_back(TheCondState);
5347
5348 if (TheCondState.Ignore) {
5349 eatToEndOfStatement();
5350 } else {
5351 if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
5352 parseEOL())
5353 return true;
5354
5356
5357 if (expect_defined)
5358 TheCondState.CondMet = (Sym && ->isUndefined(false));
5359 else
5360 TheCondState.CondMet = ( || Sym->isUndefined(false));
5362 }
5363
5364 return false;
5365}
5366
5367
5368
5369bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
5372 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5373 " .if or an .elseif");
5375
5376 bool LastIgnoreState = false;
5377 if (!TheCondStack.empty())
5378 LastIgnoreState = TheCondStack.back().Ignore;
5379 if (LastIgnoreState || TheCondState.CondMet) {
5380 TheCondState.Ignore = true;
5381 eatToEndOfStatement();
5382 } else {
5383 int64_t ExprValue;
5384 if (parseAbsoluteExpression(ExprValue))
5385 return true;
5386
5387 if (parseEOL())
5388 return true;
5389
5390 TheCondState.CondMet = ExprValue;
5392 }
5393
5394 return false;
5395}
5396
5397
5398
5399bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5400 if (parseEOL())
5401 return true;
5402
5405 return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
5406 " an .if or an .elseif");
5408 bool LastIgnoreState = false;
5409 if (!TheCondStack.empty())
5410 LastIgnoreState = TheCondStack.back().Ignore;
5411 if (LastIgnoreState || TheCondState.CondMet)
5412 TheCondState.Ignore = true;
5413 else
5414 TheCondState.Ignore = false;
5415
5416 return false;
5417}
5418
5419
5420
5421bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5422 if (parseEOL())
5423 return true;
5424
5426 Lexer.Lex();
5427
5428 return false;
5429}
5430
5431
5432
5433
5434bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
5435 if (!TheCondStack.empty()) {
5436 if (TheCondStack.back().Ignore) {
5437 eatToEndOfStatement();
5438 return false;
5439 }
5440 }
5441
5442 if (!WithMessage)
5443 return Error(L, ".err encountered");
5444
5445 StringRef Message = ".error directive invoked in source file";
5448 return TokError(".error argument must be a string");
5449
5450 Message = getTok().getStringContents();
5451 Lex();
5452 }
5453
5454 return Error(L, Message);
5455}
5456
5457
5458
5459bool AsmParser::parseDirectiveWarning(SMLoc L) {
5460 if (!TheCondStack.empty()) {
5461 if (TheCondStack.back().Ignore) {
5462 eatToEndOfStatement();
5463 return false;
5464 }
5465 }
5466
5467 StringRef Message = ".warning directive invoked in source file";
5468
5471 return TokError(".warning argument must be a string");
5472
5473 Message = getTok().getStringContents();
5474 Lex();
5475 if (parseEOL())
5476 return true;
5477 }
5478
5479 return Warning(L, Message);
5480}
5481
5482
5483
5484bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5485 if (parseEOL())
5486 return true;
5487
5489 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
5490 "an .if or .else");
5491 if (!TheCondStack.empty()) {
5492 TheCondState = TheCondStack.back();
5493 TheCondStack.pop_back();
5494 }
5495
5496 return false;
5497}
5498
5499void AsmParser::initializeDirectiveKindMap() {
5500
5501
5502
5503
5504
5505
5506 DirectiveKindMap[".set"] = DK_SET;
5507 DirectiveKindMap[".equ"] = DK_EQU;
5508 DirectiveKindMap[".equiv"] = DK_EQUIV;
5509 DirectiveKindMap[".ascii"] = DK_ASCII;
5510 DirectiveKindMap[".asciz"] = DK_ASCIZ;
5511 DirectiveKindMap[".string"] = DK_STRING;
5512 DirectiveKindMap[".byte"] = DK_BYTE;
5513 DirectiveKindMap[".short"] = DK_SHORT;
5514 DirectiveKindMap[".value"] = DK_VALUE;
5515 DirectiveKindMap[".2byte"] = DK_2BYTE;
5516 DirectiveKindMap[".long"] = DK_LONG;
5517 DirectiveKindMap[".int"] = DK_INT;
5518 DirectiveKindMap[".4byte"] = DK_4BYTE;
5519 DirectiveKindMap[".quad"] = DK_QUAD;
5520 DirectiveKindMap[".8byte"] = DK_8BYTE;
5521 DirectiveKindMap[".octa"] = DK_OCTA;
5522 DirectiveKindMap[".single"] = DK_SINGLE;
5523 DirectiveKindMap[".float"] = DK_FLOAT;
5524 DirectiveKindMap[".double"] = DK_DOUBLE;
5525 DirectiveKindMap[".align"] = DK_ALIGN;
5526 DirectiveKindMap[".align32"] = DK_ALIGN32;
5527 DirectiveKindMap[".balign"] = DK_BALIGN;
5528 DirectiveKindMap[".balignw"] = DK_BALIGNW;
5529 DirectiveKindMap[".balignl"] = DK_BALIGNL;
5530 DirectiveKindMap[".p2align"] = DK_P2ALIGN;
5531 DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
5532 DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
5533 DirectiveKindMap[".org"] = DK_ORG;
5534 DirectiveKindMap[".fill"] = DK_FILL;
5535 DirectiveKindMap[".zero"] = DK_ZERO;
5536 DirectiveKindMap[".extern"] = DK_EXTERN;
5537 DirectiveKindMap[".globl"] = DK_GLOBL;
5538 DirectiveKindMap[".global"] = DK_GLOBAL;
5539 DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
5540 DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
5541 DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5542 DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
5543 DirectiveKindMap[".reference"] = DK_REFERENCE;
5544 DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
5545 DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
5546 DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5547 DirectiveKindMap[".cold"] = DK_COLD;
5548 DirectiveKindMap[".comm"] = DK_COMM;
5549 DirectiveKindMap[".common"] = DK_COMMON;
5550 DirectiveKindMap[".lcomm"] = DK_LCOMM;
5551 DirectiveKindMap[".abort"] = DK_ABORT;
5552 DirectiveKindMap[".include"] = DK_INCLUDE;
5553 DirectiveKindMap[".incbin"] = DK_INCBIN;
5554 DirectiveKindMap[".code16"] = DK_CODE16;
5555 DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
5556 DirectiveKindMap[".rept"] = DK_REPT;
5557 DirectiveKindMap[".rep"] = DK_REPT;
5558 DirectiveKindMap[".irp"] = DK_IRP;
5559 DirectiveKindMap[".irpc"] = DK_IRPC;
5560 DirectiveKindMap[".endr"] = DK_ENDR;
5561 DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5562 DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
5563 DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5564 DirectiveKindMap[".if"] = DK_IF;
5565 DirectiveKindMap[".ifeq"] = DK_IFEQ;
5566 DirectiveKindMap[".ifge"] = DK_IFGE;
5567 DirectiveKindMap[".ifgt"] = DK_IFGT;
5568 DirectiveKindMap[".ifle"] = DK_IFLE;
5569 DirectiveKindMap[".iflt"] = DK_IFLT;
5570 DirectiveKindMap[".ifne"] = DK_IFNE;
5571 DirectiveKindMap[".ifb"] = DK_IFB;
5572 DirectiveKindMap[".ifnb"] = DK_IFNB;
5573 DirectiveKindMap[".ifc"] = DK_IFC;
5574 DirectiveKindMap[".ifeqs"] = DK_IFEQS;
5575 DirectiveKindMap[".ifnc"] = DK_IFNC;
5576 DirectiveKindMap[".ifnes"] = DK_IFNES;
5577 DirectiveKindMap[".ifdef"] = DK_IFDEF;
5578 DirectiveKindMap[".ifndef"] = DK_IFNDEF;
5579 DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
5580 DirectiveKindMap[".elseif"] = DK_ELSEIF;
5581 DirectiveKindMap[".else"] = DK_ELSE;
5582 DirectiveKindMap[".end"] = DK_END;
5583 DirectiveKindMap[".endif"] = DK_ENDIF;
5584 DirectiveKindMap[".skip"] = DK_SKIP;
5585 DirectiveKindMap[".space"] = DK_SPACE;
5586 DirectiveKindMap[".file"] = DK_FILE;
5587 DirectiveKindMap[".line"] = DK_LINE;
5588 DirectiveKindMap[".loc"] = DK_LOC;
5589 DirectiveKindMap[".loc_label"] = DK_LOC_LABEL;
5590 DirectiveKindMap[".stabs"] = DK_STABS;
5591 DirectiveKindMap[".cv_file"] = DK_CV_FILE;
5592 DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
5593 DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
5594 DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
5595 DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5596 DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5597 DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
5598 DirectiveKindMap[".cv_string"] = DK_CV_STRING;
5599 DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
5600 DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5601 DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5602 DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
5603 DirectiveKindMap[".sleb128"] = DK_SLEB128;
5604 DirectiveKindMap[".uleb128"] = DK_ULEB128;
5605 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
5606 DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
5607 DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
5608 DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5609 DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5610 DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5611 DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5612 DirectiveKindMap[".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
5613 DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
5614 DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5615 DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
5616 DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
5617 DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5618 DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5619 DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
5620 DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
5621 DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
5622 DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5623 DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5624 DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
5625 DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
5626 DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5627 DirectiveKindMap[".cfi_label"] = DK_CFI_LABEL;
5628 DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5629 DirectiveKindMap[".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
5630 DirectiveKindMap[".cfi_val_offset"] = DK_CFI_VAL_OFFSET;
5631 DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
5632 DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
5633 DirectiveKindMap[".macro"] = DK_MACRO;
5634 DirectiveKindMap[".exitm"] = DK_EXITM;
5635 DirectiveKindMap[".endm"] = DK_ENDM;
5636 DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
5637 DirectiveKindMap[".purgem"] = DK_PURGEM;
5638 DirectiveKindMap[".err"] = DK_ERR;
5639 DirectiveKindMap[".error"] = DK_ERROR;
5640 DirectiveKindMap[".warning"] = DK_WARNING;
5641 DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
5642 DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
5643 DirectiveKindMap[".reloc"] = DK_RELOC;
5644 DirectiveKindMap[".dc"] = DK_DC;
5645 DirectiveKindMap[".dc.a"] = DK_DC_A;
5646 DirectiveKindMap[".dc.b"] = DK_DC_B;
5647 DirectiveKindMap[".dc.d"] = DK_DC_D;
5648 DirectiveKindMap[".dc.l"] = DK_DC_L;
5649 DirectiveKindMap[".dc.s"] = DK_DC_S;
5650 DirectiveKindMap[".dc.w"] = DK_DC_W;
5651 DirectiveKindMap[".dc.x"] = DK_DC_X;
5652 DirectiveKindMap[".dcb"] = DK_DCB;
5653 DirectiveKindMap[".dcb.b"] = DK_DCB_B;
5654 DirectiveKindMap[".dcb.d"] = DK_DCB_D;
5655 DirectiveKindMap[".dcb.l"] = DK_DCB_L;
5656 DirectiveKindMap[".dcb.s"] = DK_DCB_S;
5657 DirectiveKindMap[".dcb.w"] = DK_DCB_W;
5658 DirectiveKindMap[".dcb.x"] = DK_DCB_X;
5659 DirectiveKindMap[".ds"] = DK_DS;
5660 DirectiveKindMap[".ds.b"] = DK_DS_B;
5661 DirectiveKindMap[".ds.d"] = DK_DS_D;
5662 DirectiveKindMap[".ds.l"] = DK_DS_L;
5663 DirectiveKindMap[".ds.p"] = DK_DS_P;
5664 DirectiveKindMap[".ds.s"] = DK_DS_S;
5665 DirectiveKindMap[".ds.w"] = DK_DS_W;
5666 DirectiveKindMap[".ds.x"] = DK_DS_X;
5667 DirectiveKindMap[".print"] = DK_PRINT;
5668 DirectiveKindMap[".addrsig"] = DK_ADDRSIG;
5669 DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM;
5670 DirectiveKindMap[".pseudoprobe"] = DK_PSEUDO_PROBE;
5671 DirectiveKindMap[".lto_discard"] = DK_LTO_DISCARD;
5672 DirectiveKindMap[".lto_set_conditional"] = DK_LTO_SET_CONDITIONAL;
5673 DirectiveKindMap[".memtag"] = DK_MEMTAG;
5674}
5675
5676MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5677 AsmToken EndToken, StartToken = getTok();
5678
5679 unsigned NestLevel = 0;
5680 while (true) {
5681
5683 printError(DirectiveLoc, "no matching '.endr' in definition");
5684 return nullptr;
5685 }
5686
5688 StringRef Ident = getTok().getIdentifier();
5689 if (Ident == ".rep" || Ident == ".rept" || Ident == ".irp" ||
5690 Ident == ".irpc") {
5691 ++NestLevel;
5692 } else if (Ident == ".endr") {
5693 if (NestLevel == 0) {
5694 EndToken = getTok();
5695 Lex();
5697 break;
5698 printError(getTok().getLoc(), "expected newline");
5699 return nullptr;
5700 }
5701 --NestLevel;
5702 }
5703 }
5704
5705
5706 eatToEndOfStatement();
5707 }
5708
5712
5713
5715 return &MacroLikeBodies.back();
5716}
5717
5718void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5720 OS << ".endr\n";
5721
5722 std::unique_ptr Instantiation =
5724
5725
5726
5727 MacroInstantiation *MI = new MacroInstantiation{
5728 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5729 ActiveMacros.push_back(MI);
5730
5731
5734 Lex();
5735}
5736
5737
5738
5739bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5740 const MCExpr *CountExpr;
5741 SMLoc CountLoc = getTok().getLoc();
5742 if (parseExpression(CountExpr))
5743 return true;
5744
5745 int64_t Count;
5746 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5747 return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
5748 }
5749
5750 if (check(Count < 0, CountLoc, "Count is negative") || parseEOL())
5751 return true;
5752
5753
5754 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5755 if (!M)
5756 return true;
5757
5758
5759
5762 while (Count--) {
5763
5764 if (expandMacro(OS, *M, {}, {}, false))
5765 return true;
5766 }
5767 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5768
5769 return false;
5770}
5771
5772
5773
5774bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5776 MCAsmMacroArguments A;
5777 if (check(parseIdentifier(Parameter.Name),
5778 "expected identifier in '.irp' directive") ||
5779 parseComma() || parseMacroArguments(nullptr, A) || parseEOL())
5780 return true;
5781
5782
5783 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5784 if (!M)
5785 return true;
5786
5787
5788
5791
5792 for (const MCAsmMacroArgument &Arg : A) {
5793
5794
5795 if (expandMacro(OS, *M, Parameter, Arg, true))
5796 return true;
5797 }
5798
5799 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5800
5801 return false;
5802}
5803
5804
5805
5806bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5808 MCAsmMacroArguments A;
5809
5810 if (check(parseIdentifier(Parameter.Name),
5811 "expected identifier in '.irpc' directive") ||
5812 parseComma() || parseMacroArguments(nullptr, A))
5813 return true;
5814
5815 if (A.size() != 1 || A.front().size() != 1)
5816 return TokError("unexpected token in '.irpc' directive");
5817 if (parseEOL())
5818 return true;
5819
5820
5821 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5822 if (!M)
5823 return true;
5824
5825
5826
5829
5831 : A[0][0].getString();
5832 for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
5833 MCAsmMacroArgument Arg;
5835
5836
5837
5838 if (expandMacro(OS, *M, Parameter, Arg, true))
5839 return true;
5840 }
5841
5842 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5843
5844 return false;
5845}
5846
5847bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5848 if (ActiveMacros.empty())
5849 return TokError("unmatched '.endr' directive");
5850
5851
5852
5854
5855 handleMacroExit();
5856 return false;
5857}
5858
5859bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5860 size_t Len) {
5862 SMLoc ExprLoc = getLexer().getLoc();
5863 if (parseExpression(Value))
5864 return true;
5866 if (!MCE)
5867 return Error(ExprLoc, "unexpected expression in _emit");
5869 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5870 return Error(ExprLoc, "literal value out of range for directive");
5871
5872 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
5873 return false;
5874}
5875
5876bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5878 SMLoc ExprLoc = getLexer().getLoc();
5879 if (parseExpression(Value))
5880 return true;
5882 if (!MCE)
5883 return Error(ExprLoc, "unexpected expression in align");
5886 return Error(ExprLoc, "literal value not a power of two greater then zero");
5887
5889 return false;
5890}
5891
5892bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
5893 const AsmToken StrTok = getTok();
5894 Lex();
5896 return Error(DirectiveLoc, "expected double quoted string after .print");
5897 if (parseEOL())
5898 return true;
5900 return false;
5901}
5902
5903bool AsmParser::parseDirectiveAddrsig() {
5904 if (parseEOL())
5905 return true;
5906 getStreamer().emitAddrsig();
5907 return false;
5908}
5909
5910bool AsmParser::parseDirectiveAddrsigSym() {
5912 if (check(parseIdentifier(Name), "expected identifier") || parseEOL())
5913 return true;
5915 getStreamer().emitAddrsigSym(Sym);
5916 return false;
5917}
5918
5919bool AsmParser::parseDirectivePseudoProbe() {
5920 int64_t Guid;
5922 int64_t Type;
5923 int64_t Attr;
5925
5926 if (parseIntToken(Guid, "unexpected token in '.pseudoprobe' directive"))
5927 return true;
5928
5929 if (parseIntToken(Index, "unexpected token in '.pseudoprobe' directive"))
5930 return true;
5931
5932 if (parseIntToken(Type, "unexpected token in '.pseudoprobe' directive"))
5933 return true;
5934
5935 if (parseIntToken(Attr, "unexpected token in '.pseudoprobe' directive"))
5936 return true;
5937
5939 if (parseIntToken(Discriminator,
5940 "unexpected token in '.pseudoprobe' directive"))
5941 return true;
5942 }
5943
5944
5946
5948
5949 Lex();
5950
5951 int64_t CallerGuid = 0;
5953 if (parseIntToken(CallerGuid,
5954 "unexpected token in '.pseudoprobe' directive"))
5955 return true;
5956 }
5957
5958
5960 Lex();
5961
5962 int64_t CallerProbeId = 0;
5964 if (parseIntToken(CallerProbeId,
5965 "unexpected token in '.pseudoprobe' directive"))
5966 return true;
5967 }
5968
5969 InlineSite Site(CallerGuid, CallerProbeId);
5971 }
5972
5973
5975 if (parseIdentifier(FnName))
5976 return Error(getLexer().getLoc(), "unexpected token in '.pseudoprobe' directive");
5977 MCSymbol *FnSym = getContext().lookupSymbol(FnName);
5978
5979 if (parseEOL())
5980 return true;
5981
5982 getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, Discriminator,
5983 InlineStack, FnSym);
5984 return false;
5985}
5986
5987
5988
5989
5990
5991
5992bool AsmParser::parseDirectiveLTODiscard() {
5993 auto ParseOp = [&]() -> bool {
5995 SMLoc Loc = getTok().getLoc();
5996 if (parseIdentifier(Name))
5997 return Error(Loc, "expected identifier");
5999 return false;
6000 };
6001
6002 LTODiscardSymbols.clear();
6003 return parseMany(ParseOp);
6004}
6005
6006
6007
6011 return -1;
6013 return 1;
6014
6015
6016
6017
6018
6021 return -1;
6022
6025 return 1;
6027}
6028
6029bool AsmParser::parseMSInlineAsm(
6030 std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs,
6042
6044
6045
6046 Lex();
6047
6048
6049 unsigned InputIdx = 0;
6050 unsigned OutputIdx = 0;
6052
6053 if (parseCurlyBlockScope(AsmStrRewrites))
6054 continue;
6055
6056 ParseStatementInfo Info(&AsmStrRewrites);
6057 bool StatementErr = parseStatement(Info, &SI);
6058
6059 if (StatementErr || Info.ParseError) {
6060
6061 printPendingErrors();
6062 return true;
6063 }
6064
6065
6066 assert(!hasPendingError() && "unexpected error from parseStatement");
6067
6068 if (Info.Opcode == ~0U)
6069 continue;
6070
6072
6073
6074 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
6076
6077
6079 !getTargetParser().omitRegisterFromClobberLists(Operand.getReg())) {
6080 unsigned NumDefs = Desc.getNumDefs();
6081
6084 continue;
6085 }
6086
6087
6089 if (SymName.empty())
6090 continue;
6091
6092 void *OpDecl = Operand.getOpDecl();
6093 if (!OpDecl)
6094 continue;
6095
6097 if (Operand.isImm()) {
6098
6100 Constraint = "r";
6101 else
6102 Constraint = "i";
6103 }
6104
6105 bool isOutput = (i == 1) && Desc.mayStore();
6108 if (isOutput) {
6109 ++InputIdx;
6112 OutputConstraints.push_back(("=" + Constraint).str());
6114 Restricted);
6115 } else {
6118 InputConstraints.push_back(Constraint.str());
6119 if (Desc.operands()[i - 1].isBranchTarget())
6121 Restricted);
6122 else
6124 Restricted);
6125 }
6126 }
6127
6128
6130 }
6131
6132
6133 NumOutputs = OutputDecls.size();
6134 NumInputs = InputDecls.size();
6135
6136
6139 Clobbers.assign(ClobberRegs.size(), std::string());
6140 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
6143 }
6144
6145
6146 if (NumOutputs || NumInputs) {
6147 unsigned NumExprs = NumOutputs + NumInputs;
6148 OpDecls.resize(NumExprs);
6149 Constraints.resize(NumExprs);
6150 for (unsigned i = 0; i < NumOutputs; ++i) {
6151 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6152 Constraints[i] = OutputConstraints[i];
6153 }
6154 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
6155 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6156 Constraints[j] = InputConstraints[i];
6157 }
6158 }
6159
6160
6161 std::string AsmStringIR;
6165 const char *AsmStart = ASMString.begin();
6166 const char *AsmEnd = ASMString.end();
6168 for (auto I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) {
6170
6171 if (AR.Done)
6172 continue;
6174
6176 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
6177
6178
6179 if (unsigned Len = Loc - AsmStart)
6181
6182
6184 AsmStart = Loc + AR.Len;
6185 continue;
6186 }
6187
6188 unsigned AdditionalSkip = 0;
6189
6190 switch (Kind) {
6191 default:
6192 break;
6196 OS << "[";
6206 OS << " + ";
6207
6210 size_t OffsetLen = OffsetName.size();
6211 auto rewrite_it = std::find_if(
6212 I, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
6213 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6214 (FusingAR.Kind == AOK_Input ||
6215 FusingAR.Kind == AOK_CallInput);
6216 });
6217 if (rewrite_it == AsmStrRewrites.end()) {
6218 OS << "offset " << OffsetName;
6220 OS << "${" << InputIdx++ << ":P}";
6221 rewrite_it->Done = true;
6222 } else {
6223 OS << '$' << InputIdx++;
6224 rewrite_it->Done = true;
6225 }
6226 }
6230 OS << "]";
6231 break;
6234 break;
6237 OS << "${" << InputIdx++ << ":P}";
6238 else
6239 OS << '$' << InputIdx++;
6240 break;
6242 OS << "${" << InputIdx++ << ":P}";
6243 break;
6246 OS << "${" << OutputIdx++ << ":P}";
6247 else
6248 OS << '$' << OutputIdx++;
6249 break;
6251 switch (AR.Val) {
6252 default: break;
6253 case 8: OS << "byte ptr "; break;
6254 case 16: OS << "word ptr "; break;
6255 case 32: OS << "dword ptr "; break;
6256 case 64: OS << "qword ptr "; break;
6257 case 80: OS << "xword ptr "; break;
6258 case 128: OS << "xmmword ptr "; break;
6259 case 256: OS << "ymmword ptr "; break;
6260 }
6261 break;
6263 OS << ".byte";
6264 break;
6266
6267
6268 OS << ".align";
6269 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6270 break;
6271
6272
6273
6274 unsigned Val = AR.Val;
6275 OS << ' ' << Val;
6276 assert(Val < 10 && "Expected alignment less then 2^10.");
6277 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6278 break;
6279 }
6281 OS << ".even";
6282 break;
6284 OS << "\n\t";
6285 break;
6286 }
6287
6288
6289 AsmStart = Loc + AR.Len + AdditionalSkip;
6290 }
6291
6292
6293 if (AsmStart != AsmEnd)
6294 OS << StringRef(AsmStart, AsmEnd - AsmStart);
6295
6296 AsmString = std::move(AsmStringIR);
6297 return false;
6298}
6299
6300bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
6302 AsmToken LabelTok = getTok();
6305
6306 if (parseIdentifier(LabelVal))
6307 return Error(LabelLoc, "The HLASM Label has to be an Identifier");
6308
6309
6310
6311
6312 if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
6313 return true;
6314
6315
6316 lexLeadingSpaces();
6317
6318
6319
6321 return Error(LabelLoc,
6322 "Cannot have just a label for an HLASM inline asm statement");
6323
6324 MCSymbol *Sym = getContext().getOrCreateSymbol(
6325 getContext().getAsmInfo()->isHLASM() ? LabelVal.upper() : LabelVal);
6326
6327 getTargetParser().doBeforeLabelEmit(Sym, LabelLoc);
6328
6329
6331
6332
6333
6334 if (enabledGenDwarfForAssembly())
6336 LabelLoc);
6337
6338 getTargetParser().onLabelParsed(Sym);
6339
6340 return false;
6341}
6342
6343bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
6346 SMLoc OperationEntryLoc = OperationEntryTok.getLoc();
6348
6349
6350 if (parseIdentifier(OperationEntryVal))
6351 return Error(OperationEntryLoc, "unexpected token at start of statement");
6352
6353
6354
6355 lexLeadingSpaces();
6356
6357 return parseAndMatchAndEmitTargetInstruction(
6358 Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
6359}
6360
6361bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
6363 assert(!hasPendingError() && "parseStatement started with pending error");
6364
6365
6366 bool ShouldParseAsHLASMLabel = false;
6367
6368
6369
6370
6371
6372
6373
6375 ShouldParseAsHLASMLabel = true;
6376
6377
6378
6380
6381 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
6382 getTok().getString().front() == '\n')
6384 Lex();
6385 return false;
6386 }
6387
6388
6389
6390
6391 lexLeadingSpaces();
6392
6393
6394
6395
6397 if (getTok().getString().front() == '\n' ||
6398 getTok().getString().front() == '\r') {
6400 Lex();
6401 return false;
6402 }
6403 }
6404
6405
6406
6407 if (ShouldParseAsHLASMLabel) {
6408
6409
6410 if (parseAsHLASMLabel(Info, SI)) {
6411
6412
6413 eatToEndOfStatement();
6414 return true;
6415 }
6416 }
6417
6418 return parseAsMachineInstruction(Info, SI);
6419}
6420
6421namespace llvm {
6422namespace MCParserUtils {
6423
6427
6428
6431 return Parser.TokError("missing expression");
6432
6433
6434
6435
6436
6438 return true;
6439
6440
6441
6443 if (Sym) {
6444
6445
6446
6447
6448 if (Value->isSymbolUsedInExpression(Sym))
6449 return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
6450 else if (Sym->isUndefined( false) && ->isUsed() &&
6451 ->isVariable())
6452 ;
6453 else if (Sym->isVariable() && ->isUsed() && allow_redef)
6454 ;
6455 else if (->isUndefined() && (
->isVariable() || !allow_redef))
6456 return Parser.Error(EqualLoc, "redefinition of '" + Name + "'");
6457 else if (->isVariable())
6458 return Parser.Error(EqualLoc, "invalid assignment to '" + Name + "'");
6459 else if (!isa(Sym->getVariableValue()))
6460 return Parser.Error(EqualLoc,
6461 "invalid reassignment of non-absolute variable '" +
6462 Name + "'");
6463 } else if (Name == ".") {
6465 return false;
6466 } else
6468
6469 Sym->setRedefinable(allow_redef);
6470
6471 return false;
6472}
6473
6474}
6475}
6476
6477
6480 unsigned CB) {
6481 if (C.getTargetTriple().isSystemZ() && C.getTargetTriple().isOSzOS())
6482 return new HLASMAsmParser(SM, C, Out, MAI, CB);
6483
6484 return new AsmParser(SM, C, Out, MAI, CB);
6485}
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
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 Expected< std::vector< unsigned > > getSymbols(SymbolicFile *Obj, uint16_t Index, raw_ostream &SymNames, SymMap *SymMap)
static bool isValidEncoding(int64_t Encoding)
static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc)
This function checks if the next token is type or arithmetic.
static unsigned getDarwinBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)
static bool isIdentifierChar(char c)
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)
static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo)
static bool isOperator(AsmToken::TokenKind kind)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This file contains constants used for implementing Dwarf debug support.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static bool isDigit(const char C)
static bool isHexDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
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.
Class for arbitrary precision integers.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
APInt getHiBits(unsigned numBits) const
Compute an APInt containing numBits highbits from this APInt.
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.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
AsmCond - Class to support conditional assembly.
ConditionalAssemblyType TheCond
AsmLexer - Lexer class for assembly files.
Target independent representation for an assembler token.
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
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Holds state from .cv_file and .cv_loc directives for later emission.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool useParensForSymbolVariant() const
bool preserveAsmComments() const
Return true if assembly (inline or otherwise) should be parsed.
bool isLittleEndian() const
True if the target is little endian.
unsigned getAssemblerDialect() const
bool doesAllowAtInName() const
StringRef getPrivateLabelPrefix() const
bool shouldUseLogicalShr() const
StringRef getCommentString() const
bool hasSubsectionsViaSymbols() const
bool getDollarIsPC() const
Generic assembler lexer interface, for use by target specific assembly lexers.
void UnLex(AsmToken const &Token)
void setAllowHashInIdentifier(bool V)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void setLexHLASMIntegers(bool V)
Set whether to lex HLASM-flavour integers. For now this is only [0-9]*.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
SMLoc getLoc() const
Get the current source location.
SMLoc getErrLoc()
Get the current error location.
void setLexMasmIntegers(bool V)
Set whether to lex masm-style binary (e.g., 0b1101) and radix-specified literals (e....
const AsmToken & getTok() const
Get the current (last) lexed token.
AsmToken::TokenKind getKind() const
Get the kind of current token.
void setLexHLASMStrings(bool V)
Set whether to "lex" HLASM-flavour character and string literals.
void setSkipSpace(bool val)
Set whether spaces should be ignored by the lexer.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
const std::string & getErr()
Get the current error string.
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
Generic Sema callback for assembly parser.
virtual ~MCAsmParserSemaCallback()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)=0
Emit an error at the location L, with the message Msg.
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual StringRef parseStringToEndOfStatement()=0
Parse up to the end of statement and return the contents from the current token until the end of the ...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual SourceMgr & getSourceManager()=0
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo)=0
Parse a primary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool checkForValidSection()=0
Ensure that we have a valid section set in the streamer.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual bool discardLTOSymbol(StringRef) const
MCAsmParser & operator=(const MCAsmParser &)=delete
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
virtual bool isParsingMSInlineAsm()=0
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression of a specified parenthesis depth, assuming that the initial '(' charact...
virtual unsigned getAssemblerDialect()
virtual MCAsmLexer & getLexer()=0
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAngleBracketString(std::string &Data)=0
Parse an angle-bracket delimited string at the current position if one is present,...
bool TokError(const Twine &Msg, SMRange Range=std::nullopt)
Report an error at the current lexer location.
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual void setAssemblerDialect(unsigned i)
virtual MCContext & getContext()=0
virtual void setParsingMSInlineAsm(bool V)=0
virtual bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl< std::pair< void *, bool > > &OpDecls, SmallVectorImpl< std::string > &Constraints, SmallVectorImpl< std::string > &Clobbers, const MCInstrInfo *MII, MCInstPrinter *IP, MCAsmParserSemaCallback &SI)=0
Parse MS-style inline assembly.
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
bool Error(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)
Return an error at the location L, with the message Msg.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Opcode getOpcode() const
Get the kind of this binary expression.
static 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 const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
void * allocate(unsigned Size, unsigned Align=8)
Environment getObjectFileType() const
bool isDwarfMD5UsageConsistent(unsigned CUID) const
Reports whether MD5 checksum usage is consistent (all-or-none).
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
bool getGenDwarfForAssembly()
void setGenDwarfForAssembly(bool Value)
void setDwarfVersion(uint16_t v)
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
MCSymbol * lookupSymbol(const Twine &Name) const
Get the symbol for Name, or null.
CodeViewContext & getCVContext()
MCSymbol * createDirectionalLocalSymbol(unsigned LocalLabelVal)
Create the definition of a directional local symbol for numbered label (used for "1:" definitions).
uint16_t getDwarfVersion() const
const MCAsmInfo * getAsmInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
MCSymbol * getDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before)
Create and return a directional local symbol for numbered label (used for "1b" or 1f" references).
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printRegName(raw_ostream &OS, MCRegister Reg)
Print the assembler register name.
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isMemUseUpRegs() const
isMemUseUpRegs - Is memory operand use up regs, for example, intel MS inline asm may use ARR[baseReg ...
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? Only valid when par...
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()
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setBeginSymbol(MCSymbol *Sym)
MCSymbol * getBeginSymbol()
Streaming machine code generation interface.
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
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.
void setStartTokLocPtr(const SMLoc *Loc)
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
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.
MCTargetStreamer * getTargetStreamer()
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static VariantKind getVariantKindForName(StringRef Name)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSubtargetInfo & getSTI() const
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
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())
This represents an "assembler immediate".
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
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
constexpr bool isSuccess() const
Wrapper class representing virtual and physical registers.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
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
Represents a range in source code.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
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.
void * getDiagContext() const
unsigned getMainFileID() const
DiagHandlerTy getDiagHandler() const
const MemoryBuffer * getMemoryBuffer(unsigned i) const
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
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
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.
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.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
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.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
std::string lower() const
int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
This class represents a function that is read from a sample profile.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
@ C
The default llvm calling convention, compatible with C.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
MCAsmParserExtension * createCOFFAsmParser()
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.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::tuple< uint64_t, uint32_t > InlineSite
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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.
MCAsmParserExtension * createXCOFFAsmParser()
MCAsmParserExtension * createGOFFAsmParser()
auto reverse(ContainerTy &&C)
cl::opt< unsigned > AsmMacroMaxNestingDepth
const char AsmRewritePrecedence[]
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
static bool hasDiscriminator(uint32_t Flags)
MCAsmParserExtension * createWasmAsmParser()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance for parsing assembly similar to gas syntax.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
const char * toString(DWARFSectionKind Kind)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
MCAsmParserExtension * createELFAsmParser()
MCAsmParserExtension * createDarwinAsmParser()
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
@ MCSA_Memtag
.memtag (ELF)
@ MCSA_PrivateExtern
.private_extern (MachO)
@ MCSA_WeakReference
.weak_reference (MachO)
@ MCSA_LazyReference
.lazy_reference (MachO)
@ MCSA_Reference
.reference (MachO)
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
@ MCSA_WeakDefinition
.weak_definition (MachO)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
ArrayRef< int > hi(ArrayRef< int > Vuu)
ArrayRef< int > lo(ArrayRef< int > Vuu)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
std::vector< AsmToken > Value
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
std::optional< StringRef > Source
The source code of the file.