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
94 SMLoc ExitLoc;
95
96
97 size_t CondStackDepth;
98};
99
100struct ParseStatementInfo {
101
103
104
105 unsigned Opcode = ~0U;
106
107
108 bool ParseError = false;
109
110 SmallVectorImpl *AsmRewrites = nullptr;
111
112 ParseStatementInfo() = delete;
113 ParseStatementInfo(SmallVectorImpl *rewrites)
114 : AsmRewrites(rewrites) {}
115};
116
117
119private:
121 void *SavedDiagContext;
122 std::unique_ptr PlatformParser;
123 SMLoc StartTokLoc;
124 std::optional CFIStartProcLoc;
125
126
127
128 unsigned CurBuffer;
129
130 AsmCond TheCondState;
131 std::vector TheCondStack;
132
133
134
135
136 StringMap ExtensionDirectiveMap;
137
138
139 std::vector<MacroInstantiation*> ActiveMacros;
140
141
142 std::deque MacroLikeBodies;
143
144
145 unsigned MacrosEnabledFlag : 1;
146
147
148 unsigned NumOfMacroInstantiations = 0;
149
150
151 struct CppHashInfoTy {
152 StringRef Filename;
153 int64_t LineNumber;
154 SMLoc Loc;
155 unsigned Buf;
156 CppHashInfoTy() : LineNumber(0), Buf(0) {}
157 };
158 CppHashInfoTy CppHashInfo;
159
160
161 bool HadCppHashFilename = false;
162
163
165
166 SmallSet<StringRef, 2> LTODiscardSymbols;
167
168
169 unsigned AssemblerDialect = ~0U;
170
171
172 bool IsDarwin = false;
173
174
175 bool ParsingMSInlineAsm = false;
176
177
178 bool ReportedInconsistentMD5 = false;
179
180
181 bool AltMacroMode = false;
182
183protected:
184 virtual bool parseStatement(ParseStatementInfo &Info,
185 MCAsmParserSemaCallback *SI);
186
187
188
189
190 bool parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
191 StringRef IDVal, AsmToken ID,
192 SMLoc IDLoc);
193
194
195
196
197 bool enabledGenDwarfForAssembly();
198
199public:
200 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
201 const MCAsmInfo &MAI, unsigned CB);
202 AsmParser(const AsmParser &) = delete;
203 AsmParser &operator=(const AsmParser &) = delete;
204 ~AsmParser() override;
205
206 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
207
208 void addDirectiveHandler(StringRef Directive,
209 ExtensionDirectiveHandler Handler) override {
210 ExtensionDirectiveMap[Directive] = Handler;
211 }
212
213 void addAliasForDirective(StringRef Directive, StringRef Alias) override {
214 DirectiveKindMap[Directive.lower()] = DirectiveKindMap[Alias.lower()];
215 }
216
217
218
219
220 CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
221
222 unsigned getAssemblerDialect() override {
223 if (AssemblerDialect == ~0U)
224 return MAI.getAssemblerDialect();
225 else
226 return AssemblerDialect;
227 }
228 void setAssemblerDialect(unsigned i) override {
229 AssemblerDialect = i;
230 }
231
232 void Note(SMLoc L, const Twine &Msg, SMRange Range = {}) override;
233 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = {}) override;
234 bool printError(SMLoc L, const Twine &Msg, SMRange Range = {}) override;
235
236 const AsmToken &Lex() override;
237
238 void setParsingMSInlineAsm(bool V) override {
239 ParsingMSInlineAsm = V;
240
241
242 Lexer.setLexMasmIntegers(V);
243 }
244 bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
245
246 bool discardLTOSymbol(StringRef Name) const override {
247 return LTODiscardSymbols.contains(Name);
248 }
249
250 bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs,
251 unsigned &NumInputs,
252 SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
253 SmallVectorImplstd::string &Constraints,
254 SmallVectorImplstd::string &Clobbers,
255 const MCInstrInfo *MII, MCInstPrinter *IP,
256 MCAsmParserSemaCallback &SI) override;
257
258 bool parseExpression(const MCExpr *&Res);
259 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
260 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
261 AsmTypeInfo *TypeInfo) override;
262 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
263 bool parseAbsoluteExpression(int64_t &Res) override;
264
265
266
267 bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
268
269
270
271 bool parseIdentifier(StringRef &Res) override;
272 void eatToEndOfStatement() override;
273
274 bool checkForValidSection() override;
275
276
277
278private:
279 bool parseCurlyBlockScope(SmallVectorImpl& AsmStrRewrites);
280 bool parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo = true);
281
282 void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
284 bool expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
287
288
289 bool areMacrosEnabled() {return MacrosEnabledFlag;}
290
291
292 void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
293
294
295 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
296
297
298
299
300
301 bool handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc);
302
303
304 void handleMacroExit();
305
306
307 bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg);
308
309
310 bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
311
312 void printMacroInstantiations();
314 SMRange Range = {}) const {
317 }
319
320
321 bool enterIncludeFile(const std::string &Filename);
322
323
324
325 bool processIncbinFile(const std::string &Filename, int64_t Skip = 0,
326 const MCExpr *Count = nullptr, SMLoc Loc = SMLoc());
327
328
329
330
331
332
333
334 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0);
335
336
337
338
339 StringRef parseStringToEndOfStatement() override;
340
341
342
343 StringRef parseStringToComma();
344
345 enum class AssignmentKind {
347 Equiv,
349 LTOSetConditional,
350 };
351
352 bool parseAssignment(StringRef Name, AssignmentKind Kind);
353
356
357 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
358 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
359 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
360
361 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
362
363 bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
364 bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
365
366
367 enum DirectiveKind {
368 DK_NO_DIRECTIVE,
369 DK_SET,
370 DK_EQU,
371 DK_EQUIV,
372 DK_ASCII,
373 DK_ASCIZ,
374 DK_STRING,
375 DK_BYTE,
376 DK_SHORT,
377 DK_RELOC,
378 DK_VALUE,
379 DK_2BYTE,
380 DK_LONG,
381 DK_INT,
382 DK_4BYTE,
383 DK_QUAD,
384 DK_8BYTE,
385 DK_OCTA,
386 DK_DC,
387 DK_DC_A,
388 DK_DC_B,
389 DK_DC_D,
390 DK_DC_L,
391 DK_DC_S,
392 DK_DC_W,
393 DK_DC_X,
394 DK_DCB,
395 DK_DCB_B,
396 DK_DCB_D,
397 DK_DCB_L,
398 DK_DCB_S,
399 DK_DCB_W,
400 DK_DCB_X,
401 DK_DS,
402 DK_DS_B,
403 DK_DS_D,
404 DK_DS_L,
405 DK_DS_P,
406 DK_DS_S,
407 DK_DS_W,
408 DK_DS_X,
409 DK_SINGLE,
410 DK_FLOAT,
411 DK_DOUBLE,
412 DK_ALIGN,
413 DK_ALIGN32,
414 DK_BALIGN,
415 DK_BALIGNW,
416 DK_BALIGNL,
417 DK_P2ALIGN,
418 DK_P2ALIGNW,
419 DK_P2ALIGNL,
420 DK_ORG,
421 DK_FILL,
422 DK_ENDR,
423 DK_ZERO,
424 DK_EXTERN,
425 DK_GLOBL,
426 DK_GLOBAL,
427 DK_LAZY_REFERENCE,
428 DK_NO_DEAD_STRIP,
429 DK_SYMBOL_RESOLVER,
430 DK_PRIVATE_EXTERN,
431 DK_REFERENCE,
432 DK_WEAK_DEFINITION,
433 DK_WEAK_REFERENCE,
434 DK_WEAK_DEF_CAN_BE_HIDDEN,
435 DK_COLD,
436 DK_COMM,
437 DK_COMMON,
438 DK_LCOMM,
439 DK_ABORT,
440 DK_INCLUDE,
441 DK_INCBIN,
442 DK_CODE16,
443 DK_CODE16GCC,
444 DK_REPT,
445 DK_IRP,
446 DK_IRPC,
447 DK_IF,
448 DK_IFEQ,
449 DK_IFGE,
450 DK_IFGT,
451 DK_IFLE,
452 DK_IFLT,
453 DK_IFNE,
454 DK_IFB,
455 DK_IFNB,
456 DK_IFC,
457 DK_IFEQS,
458 DK_IFNC,
459 DK_IFNES,
460 DK_IFDEF,
461 DK_IFNDEF,
462 DK_IFNOTDEF,
463 DK_ELSEIF,
464 DK_ELSE,
465 DK_ENDIF,
466 DK_SPACE,
467 DK_SKIP,
468 DK_FILE,
469 DK_LINE,
470 DK_LOC,
471 DK_LOC_LABEL,
472 DK_STABS,
473 DK_CV_FILE,
474 DK_CV_FUNC_ID,
475 DK_CV_INLINE_SITE_ID,
476 DK_CV_LOC,
477 DK_CV_LINETABLE,
478 DK_CV_INLINE_LINETABLE,
479 DK_CV_DEF_RANGE,
480 DK_CV_STRINGTABLE,
481 DK_CV_STRING,
482 DK_CV_FILECHECKSUMS,
483 DK_CV_FILECHECKSUM_OFFSET,
484 DK_CV_FPO_DATA,
485 DK_CFI_SECTIONS,
486 DK_CFI_STARTPROC,
487 DK_CFI_ENDPROC,
488 DK_CFI_DEF_CFA,
489 DK_CFI_DEF_CFA_OFFSET,
490 DK_CFI_ADJUST_CFA_OFFSET,
491 DK_CFI_DEF_CFA_REGISTER,
492 DK_CFI_LLVM_DEF_ASPACE_CFA,
493 DK_CFI_OFFSET,
494 DK_CFI_REL_OFFSET,
495 DK_CFI_PERSONALITY,
496 DK_CFI_LSDA,
497 DK_CFI_REMEMBER_STATE,
498 DK_CFI_RESTORE_STATE,
499 DK_CFI_SAME_VALUE,
500 DK_CFI_RESTORE,
501 DK_CFI_ESCAPE,
502 DK_CFI_RETURN_COLUMN,
503 DK_CFI_SIGNAL_FRAME,
504 DK_CFI_UNDEFINED,
505 DK_CFI_REGISTER,
506 DK_CFI_WINDOW_SAVE,
507 DK_CFI_LABEL,
508 DK_CFI_B_KEY_FRAME,
509 DK_CFI_VAL_OFFSET,
510 DK_MACROS_ON,
511 DK_MACROS_OFF,
512 DK_ALTMACRO,
513 DK_NOALTMACRO,
514 DK_MACRO,
515 DK_EXITM,
516 DK_ENDM,
517 DK_ENDMACRO,
518 DK_PURGEM,
519 DK_SLEB128,
520 DK_ULEB128,
521 DK_ERR,
522 DK_ERROR,
523 DK_WARNING,
524 DK_PRINT,
525 DK_ADDRSIG,
526 DK_ADDRSIG_SYM,
527 DK_PSEUDO_PROBE,
528 DK_LTO_DISCARD,
529 DK_LTO_SET_CONDITIONAL,
530 DK_CFI_MTE_TAGGED_FRAME,
531 DK_MEMTAG,
532 DK_BASE64,
533 DK_END
534 };
535
536
537
538 StringMap DirectiveKindMap;
539
540
541 enum CVDefRangeType {
542 CVDR_DEFRANGE = 0,
543 CVDR_DEFRANGE_REGISTER,
544 CVDR_DEFRANGE_FRAMEPOINTER_REL,
545 CVDR_DEFRANGE_SUBFIELD_REGISTER,
546 CVDR_DEFRANGE_REGISTER_REL
547 };
548
549
550
551 StringMap CVDefRangeTypeMap;
552
553
554 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
555 bool parseDirectiveBase64();
556 bool parseDirectiveReloc(SMLoc DirectiveLoc);
557 bool parseDirectiveValue(StringRef IDVal,
558 unsigned Size);
559 bool parseDirectiveOctaValue(StringRef IDVal);
560 bool parseDirectiveRealValue(StringRef IDVal,
561 const fltSemantics &);
562 bool parseDirectiveFill();
563 bool parseDirectiveZero();
564
565 bool parseDirectiveSet(StringRef IDVal, AssignmentKind Kind);
566 bool parseDirectiveOrg();
567
568 bool parseDirectiveAlign(bool IsPow2, uint8_t ValueSize);
569
570
571 bool parseDirectiveFile(SMLoc DirectiveLoc);
572 bool parseDirectiveLine();
573 bool parseDirectiveLoc();
574 bool parseDirectiveLocLabel(SMLoc DirectiveLoc);
575 bool parseDirectiveStabs();
576
577
578
579 bool parseDirectiveCVFile();
580 bool parseDirectiveCVFuncId();
581 bool parseDirectiveCVInlineSiteId();
582 bool parseDirectiveCVLoc();
583 bool parseDirectiveCVLinetable();
584 bool parseDirectiveCVInlineLinetable();
585 bool parseDirectiveCVDefRange();
586 bool parseDirectiveCVString();
587 bool parseDirectiveCVStringTable();
588 bool parseDirectiveCVFileChecksums();
589 bool parseDirectiveCVFileChecksumOffset();
590 bool parseDirectiveCVFPOData();
591
592
593 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
594 bool parseDirectiveCFIWindowSave(SMLoc DirectiveLoc);
595 bool parseDirectiveCFISections();
596 bool parseDirectiveCFIStartProc();
597 bool parseDirectiveCFIEndProc();
598 bool parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc);
599 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
600 bool parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc);
601 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
602 bool parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc);
603 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
604 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
605 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
606 bool parseDirectiveCFIRememberState(SMLoc DirectiveLoc);
607 bool parseDirectiveCFIRestoreState(SMLoc DirectiveLoc);
608 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
609 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
610 bool parseDirectiveCFIEscape(SMLoc DirectiveLoc);
611 bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
612 bool parseDirectiveCFISignalFrame(SMLoc DirectiveLoc);
613 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
614 bool parseDirectiveCFILabel(SMLoc DirectiveLoc);
615 bool parseDirectiveCFIValOffset(SMLoc DirectiveLoc);
616
617
618 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
619 bool parseDirectiveExitMacro(StringRef Directive);
620 bool parseDirectiveEndMacro(StringRef Directive);
621 bool parseDirectiveMacro(SMLoc DirectiveLoc);
622 bool parseDirectiveMacrosOnOff(StringRef Directive);
623
624 bool parseDirectiveAltmacro(StringRef Directive);
625
626
627 bool parseDirectiveSpace(StringRef IDVal);
628
629
630 bool parseDirectiveDCB(StringRef IDVal, unsigned Size);
631 bool parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &);
632
633 bool parseDirectiveDS(StringRef IDVal, unsigned Size);
634
635
636 bool parseDirectiveLEB128(bool Signed);
637
638
639
640 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
641
642 bool parseDirectiveComm(bool IsLocal);
643
644 bool parseDirectiveAbort(SMLoc DirectiveLoc);
645 bool parseDirectiveInclude();
646 bool parseDirectiveIncbin();
647
648
649 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
650
651 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
652
653 bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
654
655 bool parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual);
656
657 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
658 bool parseDirectiveElseIf(SMLoc DirectiveLoc);
659 bool parseDirectiveElse(SMLoc DirectiveLoc);
660 bool parseDirectiveEndIf(SMLoc DirectiveLoc);
661 bool parseEscapedString(std::string &Data) override;
662 bool parseAngleBracketString(std::string &Data) override;
663
664
665 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
666 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
667 raw_svector_ostream &OS);
668 bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive);
669 bool parseDirectiveIrp(SMLoc DirectiveLoc);
670 bool parseDirectiveIrpc(SMLoc DirectiveLoc);
671 bool parseDirectiveEndr(SMLoc DirectiveLoc);
672
673
674 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
675 size_t Len);
676
677
678 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
679
680
681 bool parseDirectiveEnd(SMLoc DirectiveLoc);
682
683
684 bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
685
686
687 bool parseDirectiveWarning(SMLoc DirectiveLoc);
688
689
690 bool parseDirectivePrint(SMLoc DirectiveLoc);
691
692
693 bool parseDirectivePseudoProbe();
694
695
696 bool parseDirectiveLTODiscard();
697
698
699 bool parseDirectiveAddrsig();
700 bool parseDirectiveAddrsigSym();
701
702 void initializeDirectiveKindMap();
703 void initializeCVDefRangeTypeMap();
704};
705
706class HLASMAsmParser final : public AsmParser {
707private:
708 AsmLexer &Lexer;
709 MCStreamer &Out;
710
711 void lexLeadingSpaces() {
713 Lexer.Lex();
714 }
715
716 bool parseAsHLASMLabel(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI);
717 bool parseAsMachineInstruction(ParseStatementInfo &Info,
718 MCAsmParserSemaCallback *SI);
719
720public:
721 HLASMAsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
722 const MCAsmInfo &MAI, unsigned CB = 0)
723 : AsmParser(SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
724 Lexer.setSkipSpace(false);
725 Lexer.setAllowHashInIdentifier(true);
726 Lexer.setLexHLASMIntegers(true);
727 Lexer.setLexHLASMStrings(true);
728 }
729
730 ~HLASMAsmParser() override { Lexer.setSkipSpace(true); }
731
732 bool parseStatement(ParseStatementInfo &Info,
733 MCAsmParserSemaCallback *SI) override;
734};
735
736}
737
738namespace llvm {
739
741
742}
743
745 const MCAsmInfo &MAI, unsigned CB = 0)
746 : MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),
747 MacrosEnabledFlag(true) {
748 HadError = false;
749
750 SavedDiagHandler = SrcMgr.getDiagHandler();
751 SavedDiagContext = SrcMgr.getDiagContext();
752
754 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
755
757
758
759 switch (Ctx.getObjectFileType()) {
760 case MCContext::IsCOFF:
761 PlatformParser.reset(createCOFFAsmParser());
762 break;
763 case MCContext::IsMachO:
764 PlatformParser.reset(createDarwinAsmParser());
765 IsDarwin = true;
766 break;
767 case MCContext::IsELF:
768 PlatformParser.reset(createELFAsmParser());
769 break;
770 case MCContext::IsGOFF:
771 PlatformParser.reset(createGOFFAsmParser());
772 break;
773 case MCContext::IsSPIRV:
774 report_fatal_error(
775 "Need to implement createSPIRVAsmParser for SPIRV format.");
776 break;
777 case MCContext::IsWasm:
778 PlatformParser.reset(createWasmAsmParser());
779 break;
780 case MCContext::IsXCOFF:
781 PlatformParser.reset(createXCOFFAsmParser());
782 break;
783 case MCContext::IsDXContainer:
784 report_fatal_error("DXContainer is not supported yet");
785 break;
786 }
787
788 PlatformParser->Initialize(*this);
789 initializeDirectiveKindMap();
790 initializeCVDefRangeTypeMap();
791}
792
793AsmParser::~AsmParser() {
794 assert((HadError || ActiveMacros.empty()) &&
795 "Unexpected active macro instantiation!");
796
797
799
800
802}
803
804void AsmParser::printMacroInstantiations() {
805
806 for (MacroInstantiation *M : reverse(ActiveMacros))
808 "while in macro instantiation");
809}
810
811void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
812 printPendingErrors();
814 printMacroInstantiations();
815}
816
817bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
818 if(getTargetParser().getTargetOptions().MCNoWarn)
819 return false;
820 if (getTargetParser().getTargetOptions().MCFatalWarnings)
823 printMacroInstantiations();
824 return false;
825}
826
827bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
828 HadError = true;
830 printMacroInstantiations();
831 return true;
832}
833
834bool AsmParser::enterIncludeFile(const std::string &Filename) {
835 std::string IncludedFile;
836 unsigned NewBuf =
838 if (!NewBuf)
839 return true;
840
841 CurBuffer = NewBuf;
843 return false;
844}
845
846
847
848
849bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
850 const MCExpr *Count, SMLoc Loc) {
851 std::string IncludedFile;
852 unsigned NewBuf =
854 if (!NewBuf)
855 return true;
856
857
861 int64_t Res;
862 if (->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
863 return Error(Loc, "expected absolute expression");
864 if (Res < 0)
865 return Warning(Loc, "negative count has no effect");
867 }
868 getStreamer().emitBytes(Bytes);
869 return false;
870}
871
872void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
876}
877
878const AsmToken &AsmParser::Lex() {
881
882
884
885 if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
888 }
889
890 const AsmToken *tok = &Lexer.Lex();
891
892
896 tok = &Lexer.Lex();
897 }
898
900
901
903 if (ParentIncludeLoc != SMLoc()) {
904 jumpToLoc(ParentIncludeLoc);
905 return Lex();
906 }
907 }
908
909 return *tok;
910}
911
912bool AsmParser::enabledGenDwarfForAssembly() {
913
914 if (().getGenDwarfForAssembly())
915 return false;
916
917
918
919 if (getContext().getGenDwarfFileNumber() == 0) {
920 const MCDwarfFile &RootFile =
921 getContext().getMCDwarfLineTable(0).getRootFile();
922 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
923 0, getContext().getCompilationDir(), RootFile.Name,
925 }
926 return true;
927}
928
929bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
930 LTODiscardSymbols.clear();
931
932
933 if (!NoInitialTextSection)
934 Out.initSections(false, getTargetParser().getSTI());
935
936
937 Lex();
938
939 HadError = false;
940 AsmCond StartingCondState = TheCondState;
942
943
944
945
946
947 if (getContext().getGenDwarfForAssembly()) {
948 MCSection *Sec = getStreamer().getCurrentSectionOnly();
951 getStreamer().emitLabel(SectionStartSym);
953 }
954 bool InsertResult = getContext().addGenDwarfSection(Sec);
955 assert(InsertResult && ".text section should not have debug info yet");
956 (void)InsertResult;
957 }
958
959 getTargetParser().onBeginOfFile();
960
961
963 ParseStatementInfo Info(&AsmStrRewrites);
964 bool HasError = parseStatement(Info, nullptr);
965
966
967
968
970 Lex();
971
972
973 printPendingErrors();
974
975
976 if (HasError && !getLexer().justConsumedEOL())
977 eatToEndOfStatement();
978 }
979
980 getTargetParser().onEndOfFile();
981 printPendingErrors();
982
983
984 assert(!hasPendingError() && "unexpected error from parseStatement");
985
986 if (TheCondState.TheCond != StartingCondState.TheCond ||
987 TheCondState.Ignore != StartingCondState.Ignore)
988 printError(getTok().getLoc(), "unmatched .ifs or .elses");
989
990 const auto &LineTables = getContext().getMCDwarfLineTables();
991 if (!LineTables.empty()) {
992 unsigned Index = 0;
993 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
994 if (File.Name.empty() && Index != 0)
995 printError(getTok().getLoc(), "unassigned file number: " +
996 Twine(Index) +
997 " for .file directives");
999 }
1000 }
1001
1002
1003
1004
1005
1006 if (!NoFinalize) {
1009 MCSymbol *Sym = TableEntry.getValue().Symbol;
1010
1011
1012
1015
1016
1017
1018 printError(getTok().getLoc(), "assembler local symbol '" +
1019 Sym->getName() + "' not defined");
1020 }
1021 }
1022
1023
1024
1025 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1026 if (std::get<2>(LocSym)->isUndefined()) {
1027
1028
1029 CppHashInfo = std::get<1>(LocSym);
1030 printError(std::get<0>(LocSym), "directional label undefined");
1031 }
1032 }
1033 }
1034
1035
1036 if (!HadError && !NoFinalize) {
1038 TS->emitConstantPools();
1039
1041 }
1042
1043 return HadError || getContext().hadError();
1044}
1045
1046bool AsmParser::checkForValidSection() {
1047 if (!ParsingMSInlineAsm && !getStreamer().getCurrentFragment()) {
1048 Out.initSections(false, getTargetParser().getSTI());
1049 return Error(getTok().getLoc(),
1050 "expected section directive before assembly directive");
1051 }
1052 return false;
1053}
1054
1055
1056void AsmParser::eatToEndOfStatement() {
1058 Lexer.Lex();
1059
1060
1062 Lexer.Lex();
1063}
1064
1065StringRef AsmParser::parseStringToEndOfStatement() {
1066 const char *Start = getTok().getLoc().getPointer();
1067
1069 Lexer.Lex();
1070
1072 return StringRef(Start, End - Start);
1073}
1074
1075StringRef AsmParser::parseStringToComma() {
1076 const char *Start = getTok().getLoc().getPointer();
1077
1080 Lexer.Lex();
1081
1082 const char *End = getTok().getLoc().getPointer();
1083 return StringRef(Start, End - Start);
1084}
1085
1086
1087
1088
1089
1090
1091bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1092 if (parseExpression(Res))
1093 return true;
1095 return parseRParen();
1096}
1097
1098
1099
1100
1101
1102
1103bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1104 if (parseExpression(Res))
1105 return true;
1106 EndLoc = getTok().getEndLoc();
1107 if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1108 return true;
1109 return false;
1110}
1111
1112
1113
1114
1115
1116
1117
1118bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
1119 AsmTypeInfo *TypeInfo) {
1120 SMLoc FirstTokenLoc = getLexer().getLoc();
1122 switch (FirstTokenKind) {
1123 default:
1124 return TokError("unknown token in expression");
1125
1127 return true;
1129 Lex();
1130 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1131 return true;
1133 return false;
1140 if (parseIdentifier(Identifier)) {
1141
1142
1144 bool ShouldGenerateTempSymbol = false;
1147 ShouldGenerateTempSymbol = true;
1148
1149 if (!ShouldGenerateTempSymbol)
1150 return Error(FirstTokenLoc, "invalid token in expression");
1151
1152
1153 Lex();
1154
1155
1159 EndLoc = FirstTokenLoc;
1160 return false;
1161 }
1162 }
1163
1164 std::pair<StringRef, StringRef> Split;
1168 Lex();
1169 SMLoc AtLoc = getLexer().getLoc();
1170 StringRef VName;
1171 if (parseIdentifier(VName))
1172 return Error(AtLoc, "expected symbol variant after '@'");
1173
1174 Split = std::make_pair(Identifier, VName);
1175 }
1178 }
1181 StringRef VName;
1182 parseIdentifier(VName);
1183 if (parseRParen())
1184 return true;
1185 Split = std::make_pair(Identifier, VName);
1186 }
1187
1189
1190
1193 return Error(getLexer().getLoc(), "expected a symbol reference");
1194
1195
1196 uint16_t Spec = 0;
1197 if (.second.empty()) {
1199 if (MaybeSpecifier) {
1201 Spec = *MaybeSpecifier;
1204 "invalid variant '" + Split.second + "'");
1205 }
1206 }
1207
1209 if (!Sym)
1211 : SymbolName);
1212
1213
1214
1219 DoInline = TV->inlineAssignedExpr();
1220 if (DoInline) {
1221 if (Spec)
1222 return Error(EndLoc, "unexpected modifier on variable reference");
1224 return false;
1225 }
1226 }
1227
1228
1230 return false;
1231 }
1233 return TokError("literal value out of range for directive");
1235 SMLoc Loc = getTok().getLoc();
1236 int64_t IntVal = getTok().getIntVal();
1239 Lex();
1240
1242 StringRef IDVal = getTok().getString();
1243
1244 std::pair<StringRef, StringRef> Split = IDVal.split('@');
1245 uint16_t Spec = 0;
1246 if (Split.first.size() != IDVal.size()) {
1248 if (!MaybeSpec)
1249 return TokError("invalid variant '" + Split.second + "'");
1250 IDVal = Split.first;
1251 Spec = *MaybeSpec;
1252 }
1253 if (IDVal == "f" || IDVal == "b") {
1258 return Error(Loc, "directional label undefined");
1259 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1261 Lex();
1262 }
1263 }
1264 return false;
1265 }
1267 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1268 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1271 Lex();
1272 return false;
1273 }
1276 return TokError("cannot use . as current PC");
1277
1278
1279
1284 Lex();
1285 return false;
1286 }
1288 Lex();
1289 return parseParenExpr(Res, EndLoc);
1291 if (!PlatformParser->HasBracketExpressions())
1292 return TokError("brackets expression not supported on this target");
1293 Lex();
1294 return parseBracketExpr(Res, EndLoc);
1296 Lex();
1297 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1298 return true;
1300 return false;
1302 Lex();
1303 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1304 return true;
1306 return false;
1308 Lex();
1309 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1310 return true;
1312 return false;
1313 }
1314}
1315
1316bool AsmParser::parseExpression(const MCExpr *&Res) {
1317 SMLoc EndLoc;
1318 return parseExpression(Res, EndLoc);
1319}
1320
1322
1324 if (NewE)
1325 return NewE;
1326
1327
1328 switch (E->getKind()) {
1330 llvm_unreachable("cannot apply another specifier to MCSpecifierExpr");
1333 return nullptr;
1334
1337
1339 TokError("invalid variant on expression '" + getTok().getIdentifier() +
1340 "' (already modified)");
1341 return E;
1342 }
1343
1346 }
1347
1351 if ()
1352 return nullptr;
1355 }
1356
1361
1362 if (!LHS && !RHS)
1363 return nullptr;
1364
1365 if (!LHS)
1367 if (!RHS)
1369
1372 }
1373 }
1374
1376}
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1391 "Argument to the function cannot be a NULL value");
1392 const char *CharPtr = StrLoc.getPointer();
1393 while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1394 (*CharPtr != '\0')) {
1395 if (*CharPtr == '!')
1396 CharPtr++;
1397 CharPtr++;
1398 }
1399 if (*CharPtr == '>') {
1401 return true;
1402 }
1403 return false;
1404}
1405
1406
1408 std::string Res;
1409 for (size_t Pos = 0; Pos < AltMacroStr.size(); Pos++) {
1410 if (AltMacroStr[Pos] == '!')
1411 Pos++;
1412 Res += AltMacroStr[Pos];
1413 }
1414 return Res;
1415}
1416
1420 return TokError("expected specifier following '@'");
1421
1422 auto Spec = MAI.getSpecifierForName(getTok().getIdentifier());
1424 return TokError("invalid specifier '@" + getTok().getIdentifier() + "'");
1425
1427 if (ModifiedRes)
1428 Res = ModifiedRes;
1430 }
1431 return false;
1432}
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1445
1446 Res = nullptr;
1447 auto &TS = getTargetParser();
1448 if (TS.parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc))
1449 return true;
1450
1451
1452
1453
1456 return TokError("unexpected symbol modifier following '@'");
1457
1460 return TokError("invalid variant '" + getTok().getIdentifier() + "'");
1461
1462 const MCExpr *ModifiedRes = applySpecifier(Res, *Spec);
1463 if (!ModifiedRes) {
1464 return TokError("invalid modifier '" + getTok().getIdentifier() +
1465 "' (no symbols present)");
1466 }
1467
1468 Res = ModifiedRes;
1469 Lex();
1470 }
1471
1472
1473
1475 if (Res->evaluateAsAbsolute(Value))
1477
1478 return false;
1479}
1480
1481bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1482 Res = nullptr;
1483 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1484}
1485
1486bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1487 const MCExpr *Expr;
1488
1489 SMLoc StartLoc = Lexer.getLoc();
1490 if (parseExpression(Expr))
1491 return true;
1492
1493 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1494 return Error(StartLoc, "expected absolute expression");
1495
1496 return false;
1497}
1498
1501 bool ShouldUseLogicalShr) {
1502 switch (K) {
1503 default:
1504 return 0;
1505
1506
1509 return 1;
1512 return 1;
1513
1514
1517 return 2;
1520 return 2;
1523 return 2;
1524
1525
1528 return 3;
1532 return 3;
1535 return 3;
1538 return 3;
1541 return 3;
1544 return 3;
1545
1546
1549 return 4;
1552 return 4;
1553
1554
1557 return 5;
1560 return 5;
1561
1562
1565 return 6;
1568 return 6;
1571 return 6;
1572 }
1573}
1574
1578 bool ShouldUseLogicalShr) {
1579 switch (K) {
1580 default:
1581 return 0;
1582
1583
1586 return 2;
1589 return 1;
1590
1591
1594 return 3;
1598 return 3;
1601 return 3;
1604 return 3;
1607 return 3;
1610 return 3;
1611
1612
1615 return 4;
1618 return 4;
1619
1620
1621
1624 return 5;
1626
1627
1629 return 0;
1631 return 5;
1634 return 5;
1637 return 5;
1638
1639
1642 return 6;
1645 return 6;
1648 return 6;
1651 return 6;
1654 return 6;
1655 }
1656}
1657
1663}
1664
1665
1666
1667bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
1668 SMLoc &EndLoc) {
1669 SMLoc StartLoc = Lexer.getLoc();
1670 while (true) {
1672 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
1673
1674
1675
1676 if (TokPrec < Precedence)
1677 return false;
1678
1679 Lex();
1680
1681
1682 const MCExpr *RHS;
1683 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1684 return true;
1685
1686
1687
1689 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1690 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1691 return true;
1692
1693
1695 }
1696}
1697
1698
1699
1700
1701
1702bool AsmParser::parseStatement(ParseStatementInfo &Info,
1703 MCAsmParserSemaCallback *SI) {
1704 assert(!hasPendingError() && "parseStatement started with pending error");
1705
1707 Lex();
1709
1710 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
1711 getTok().getString().front() == '\n')
1713 Lex();
1714 return false;
1715 }
1716
1717 AsmToken ID = getTok();
1718 SMLoc IDLoc = ID.getLoc();
1719 StringRef IDVal;
1720 int64_t LocalLabelVal = -1;
1721 StartTokLoc = ID.getLoc();
1723 return parseCppHashLineFilenameComment(IDLoc,
1724 !isInsideMacroInstantiation());
1725
1726
1728 LocalLabelVal = getTok().getIntVal();
1729 if (LocalLabelVal < 0) {
1730 if (!TheCondState.Ignore) {
1731 Lex();
1732 return Error(IDLoc, "unexpected token at start of statement");
1733 }
1734 IDVal = "";
1735 } else {
1736 IDVal = getTok().getString();
1737 Lex();
1739 if (!TheCondState.Ignore) {
1740 Lex();
1741 return Error(IDLoc, "unexpected token at start of statement");
1742 }
1743 }
1744 }
1746
1747 Lex();
1748 IDVal = ".";
1749 } else if (getTargetParser().tokenIsStartOfStatement(ID.getKind())) {
1750 Lex();
1751 IDVal = ID.getString();
1752 } else if (parseIdentifier(IDVal)) {
1753 if (!TheCondState.Ignore) {
1754 Lex();
1755 return Error(IDLoc, "unexpected token at start of statement");
1756 }
1757 IDVal = "";
1758 }
1759
1760
1761
1762
1764 DirectiveKindMap.find(IDVal.lower());
1765 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1766 ? DK_NO_DIRECTIVE
1767 : DirKindIt->getValue();
1768 switch (DirKind) {
1769 default:
1770 break;
1771 case DK_IF:
1772 case DK_IFEQ:
1773 case DK_IFGE:
1774 case DK_IFGT:
1775 case DK_IFLE:
1776 case DK_IFLT:
1777 case DK_IFNE:
1778 return parseDirectiveIf(IDLoc, DirKind);
1779 case DK_IFB:
1780 return parseDirectiveIfb(IDLoc, true);
1781 case DK_IFNB:
1782 return parseDirectiveIfb(IDLoc, false);
1783 case DK_IFC:
1784 return parseDirectiveIfc(IDLoc, true);
1785 case DK_IFEQS:
1786 return parseDirectiveIfeqs(IDLoc, true);
1787 case DK_IFNC:
1788 return parseDirectiveIfc(IDLoc, false);
1789 case DK_IFNES:
1790 return parseDirectiveIfeqs(IDLoc, false);
1791 case DK_IFDEF:
1792 return parseDirectiveIfdef(IDLoc, true);
1793 case DK_IFNDEF:
1794 case DK_IFNOTDEF:
1795 return parseDirectiveIfdef(IDLoc, false);
1796 case DK_ELSEIF:
1797 return parseDirectiveElseIf(IDLoc);
1798 case DK_ELSE:
1799 return parseDirectiveElse(IDLoc);
1800 case DK_ENDIF:
1801 return parseDirectiveEndIf(IDLoc);
1802 }
1803
1804
1805
1806 if (TheCondState.Ignore) {
1807 eatToEndOfStatement();
1808 return false;
1809 }
1810
1811
1812
1813
1814
1815
1817 if (checkForValidSection())
1818 return true;
1819
1820 Lex();
1821
1822
1823 if (IDVal == ".")
1824 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
1825
1826
1827
1828
1829
1830
1832 if (LocalLabelVal == -1) {
1833 if (ParsingMSInlineAsm && SI) {
1834 StringRef RewrittenLabel =
1835 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
1837 "We should have an internal name here.");
1839 RewrittenLabel);
1840 IDVal = RewrittenLabel;
1841 }
1842 Sym = getContext().parseSymbol(IDVal);
1843 } else
1845
1846
1847
1848
1850 StringRef CommentStr = parseStringToEndOfStatement();
1851 Lexer.Lex();
1853 }
1854
1855
1856
1858 Lex();
1859 }
1860
1861 if (MAI.isMachO() && CFIStartProcLoc) {
1862 auto *SymM = static_cast<MCSymbolMachO *>(Sym);
1863 if (SymM->isExternal() && !SymM->isAltEntry())
1864 return Error(StartTokLoc, "non-private labels cannot appear between "
1865 ".cfi_startproc / .cfi_endproc pairs") &&
1866 Error(*CFIStartProcLoc, "previous .cfi_startproc was here");
1867 }
1868
1869 if (discardLTOSymbol(IDVal))
1870 return false;
1871
1872 getTargetParser().doBeforeLabelEmit(Sym, IDLoc);
1873
1874
1875 if (!getTargetParser().isParsingMSInlineAsm())
1877
1878
1879
1880 if (enabledGenDwarfForAssembly())
1882 IDLoc);
1883
1884 getTargetParser().onLabelParsed(Sym);
1885
1886 return false;
1887 }
1888
1889
1890
1891 if (Lexer.is(AsmToken::Equal) && getTargetParser().equalIsAsmAssignment()) {
1892 Lex();
1893 return parseAssignment(IDVal, AssignmentKind::Equal);
1894 }
1895
1896
1897 if (areMacrosEnabled())
1898 if (MCAsmMacro *M = getContext().lookupMacro(IDVal))
1899 return handleMacroEntry(M, IDLoc);
1900
1901
1902
1903
1904 if (IDVal.starts_with(".") && IDVal != ".") {
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916 getTargetParser().flushPendingInstructions(getStreamer());
1917
1918 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);
1919 assert(TPDirectiveReturn.isFailure() == hasPendingError() &&
1920 "Should only return Failure iff there was an error");
1921 if (TPDirectiveReturn.isFailure())
1922 return true;
1923 if (TPDirectiveReturn.isSuccess())
1924 return false;
1925
1926
1927
1928 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
1929 ExtensionDirectiveMap.lookup(IDVal);
1930 if (Handler.first)
1931 return (*Handler.second)(Handler.first, IDVal, IDLoc);
1932
1933
1934
1935 switch (DirKind) {
1936 default:
1937 break;
1938 case DK_SET:
1939 case DK_EQU:
1940 return parseDirectiveSet(IDVal, AssignmentKind::Set);
1941 case DK_EQUIV:
1942 return parseDirectiveSet(IDVal, AssignmentKind::Equiv);
1943 case DK_LTO_SET_CONDITIONAL:
1944 return parseDirectiveSet(IDVal, AssignmentKind::LTOSetConditional);
1945 case DK_ASCII:
1946 return parseDirectiveAscii(IDVal, false);
1947 case DK_ASCIZ:
1948 case DK_STRING:
1949 return parseDirectiveAscii(IDVal, true);
1950 case DK_BASE64:
1951 return parseDirectiveBase64();
1952 case DK_BYTE:
1953 case DK_DC_B:
1954 return parseDirectiveValue(IDVal, 1);
1955 case DK_DC:
1956 case DK_DC_W:
1957 case DK_SHORT:
1958 case DK_VALUE:
1959 case DK_2BYTE:
1960 return parseDirectiveValue(IDVal, 2);
1961 case DK_LONG:
1962 case DK_INT:
1963 case DK_4BYTE:
1964 case DK_DC_L:
1965 return parseDirectiveValue(IDVal, 4);
1966 case DK_QUAD:
1967 case DK_8BYTE:
1968 return parseDirectiveValue(IDVal, 8);
1969 case DK_DC_A:
1970 return parseDirectiveValue(
1971 IDVal, getContext().getAsmInfo()->getCodePointerSize());
1972 case DK_OCTA:
1973 return parseDirectiveOctaValue(IDVal);
1974 case DK_SINGLE:
1975 case DK_FLOAT:
1976 case DK_DC_S:
1977 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
1978 case DK_DOUBLE:
1979 case DK_DC_D:
1980 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
1981 case DK_ALIGN: {
1982 bool IsPow2 = ().getAsmInfo()->getAlignmentIsInBytes();
1983 return parseDirectiveAlign(IsPow2, 1);
1984 }
1985 case DK_ALIGN32: {
1986 bool IsPow2 = ().getAsmInfo()->getAlignmentIsInBytes();
1987 return parseDirectiveAlign(IsPow2, 4);
1988 }
1989 case DK_BALIGN:
1990 return parseDirectiveAlign(false, 1);
1991 case DK_BALIGNW:
1992 return parseDirectiveAlign(false, 2);
1993 case DK_BALIGNL:
1994 return parseDirectiveAlign(false, 4);
1995 case DK_P2ALIGN:
1996 return parseDirectiveAlign(true, 1);
1997 case DK_P2ALIGNW:
1998 return parseDirectiveAlign(true, 2);
1999 case DK_P2ALIGNL:
2000 return parseDirectiveAlign(true, 4);
2001 case DK_ORG:
2002 return parseDirectiveOrg();
2003 case DK_FILL:
2004 return parseDirectiveFill();
2005 case DK_ZERO:
2006 return parseDirectiveZero();
2007 case DK_EXTERN:
2008 eatToEndOfStatement();
2009 return false;
2010 case DK_GLOBL:
2011 case DK_GLOBAL:
2012 return parseDirectiveSymbolAttribute(MCSA_Global);
2013 case DK_LAZY_REFERENCE:
2015 case DK_NO_DEAD_STRIP:
2017 case DK_SYMBOL_RESOLVER:
2019 case DK_PRIVATE_EXTERN:
2021 case DK_REFERENCE:
2022 return parseDirectiveSymbolAttribute(MCSA_Reference);
2023 case DK_WEAK_DEFINITION:
2025 case DK_WEAK_REFERENCE:
2027 case DK_WEAK_DEF_CAN_BE_HIDDEN:
2029 case DK_COLD:
2030 return parseDirectiveSymbolAttribute(MCSA_Cold);
2031 case DK_COMM:
2032 case DK_COMMON:
2033 return parseDirectiveComm(false);
2034 case DK_LCOMM:
2035 return parseDirectiveComm(true);
2036 case DK_ABORT:
2037 return parseDirectiveAbort(IDLoc);
2038 case DK_INCLUDE:
2039 return parseDirectiveInclude();
2040 case DK_INCBIN:
2041 return parseDirectiveIncbin();
2042 case DK_CODE16:
2043 case DK_CODE16GCC:
2044 return TokError(Twine(IDVal) +
2045 " not currently supported for this target");
2046 case DK_REPT:
2047 return parseDirectiveRept(IDLoc, IDVal);
2048 case DK_IRP:
2049 return parseDirectiveIrp(IDLoc);
2050 case DK_IRPC:
2051 return parseDirectiveIrpc(IDLoc);
2052 case DK_ENDR:
2053 return parseDirectiveEndr(IDLoc);
2054 case DK_SLEB128:
2055 return parseDirectiveLEB128(true);
2056 case DK_ULEB128:
2057 return parseDirectiveLEB128(false);
2058 case DK_SPACE:
2059 case DK_SKIP:
2060 return parseDirectiveSpace(IDVal);
2061 case DK_FILE:
2062 return parseDirectiveFile(IDLoc);
2063 case DK_LINE:
2064 return parseDirectiveLine();
2065 case DK_LOC:
2066 return parseDirectiveLoc();
2067 case DK_LOC_LABEL:
2068 return parseDirectiveLocLabel(IDLoc);
2069 case DK_STABS:
2070 return parseDirectiveStabs();
2071 case DK_CV_FILE:
2072 return parseDirectiveCVFile();
2073 case DK_CV_FUNC_ID:
2074 return parseDirectiveCVFuncId();
2075 case DK_CV_INLINE_SITE_ID:
2076 return parseDirectiveCVInlineSiteId();
2077 case DK_CV_LOC:
2078 return parseDirectiveCVLoc();
2079 case DK_CV_LINETABLE:
2080 return parseDirectiveCVLinetable();
2081 case DK_CV_INLINE_LINETABLE:
2082 return parseDirectiveCVInlineLinetable();
2083 case DK_CV_DEF_RANGE:
2084 return parseDirectiveCVDefRange();
2085 case DK_CV_STRING:
2086 return parseDirectiveCVString();
2087 case DK_CV_STRINGTABLE:
2088 return parseDirectiveCVStringTable();
2089 case DK_CV_FILECHECKSUMS:
2090 return parseDirectiveCVFileChecksums();
2091 case DK_CV_FILECHECKSUM_OFFSET:
2092 return parseDirectiveCVFileChecksumOffset();
2093 case DK_CV_FPO_DATA:
2094 return parseDirectiveCVFPOData();
2095 case DK_CFI_SECTIONS:
2096 return parseDirectiveCFISections();
2097 case DK_CFI_STARTPROC:
2098 return parseDirectiveCFIStartProc();
2099 case DK_CFI_ENDPROC:
2100 return parseDirectiveCFIEndProc();
2101 case DK_CFI_DEF_CFA:
2102 return parseDirectiveCFIDefCfa(IDLoc);
2103 case DK_CFI_DEF_CFA_OFFSET:
2104 return parseDirectiveCFIDefCfaOffset(IDLoc);
2105 case DK_CFI_ADJUST_CFA_OFFSET:
2106 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2107 case DK_CFI_DEF_CFA_REGISTER:
2108 return parseDirectiveCFIDefCfaRegister(IDLoc);
2109 case DK_CFI_LLVM_DEF_ASPACE_CFA:
2110 return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
2111 case DK_CFI_OFFSET:
2112 return parseDirectiveCFIOffset(IDLoc);
2113 case DK_CFI_REL_OFFSET:
2114 return parseDirectiveCFIRelOffset(IDLoc);
2115 case DK_CFI_PERSONALITY:
2116 return parseDirectiveCFIPersonalityOrLsda(true);
2117 case DK_CFI_LSDA:
2118 return parseDirectiveCFIPersonalityOrLsda(false);
2119 case DK_CFI_REMEMBER_STATE:
2120 return parseDirectiveCFIRememberState(IDLoc);
2121 case DK_CFI_RESTORE_STATE:
2122 return parseDirectiveCFIRestoreState(IDLoc);
2123 case DK_CFI_SAME_VALUE:
2124 return parseDirectiveCFISameValue(IDLoc);
2125 case DK_CFI_RESTORE:
2126 return parseDirectiveCFIRestore(IDLoc);
2127 case DK_CFI_ESCAPE:
2128 return parseDirectiveCFIEscape(IDLoc);
2129 case DK_CFI_RETURN_COLUMN:
2130 return parseDirectiveCFIReturnColumn(IDLoc);
2131 case DK_CFI_SIGNAL_FRAME:
2132 return parseDirectiveCFISignalFrame(IDLoc);
2133 case DK_CFI_UNDEFINED:
2134 return parseDirectiveCFIUndefined(IDLoc);
2135 case DK_CFI_REGISTER:
2136 return parseDirectiveCFIRegister(IDLoc);
2137 case DK_CFI_WINDOW_SAVE:
2138 return parseDirectiveCFIWindowSave(IDLoc);
2139 case DK_CFI_LABEL:
2140 return parseDirectiveCFILabel(IDLoc);
2141 case DK_CFI_VAL_OFFSET:
2142 return parseDirectiveCFIValOffset(IDLoc);
2143 case DK_MACROS_ON:
2144 case DK_MACROS_OFF:
2145 return parseDirectiveMacrosOnOff(IDVal);
2146 case DK_MACRO:
2147 return parseDirectiveMacro(IDLoc);
2148 case DK_ALTMACRO:
2149 case DK_NOALTMACRO:
2150 return parseDirectiveAltmacro(IDVal);
2151 case DK_EXITM:
2152 return parseDirectiveExitMacro(IDVal);
2153 case DK_ENDM:
2154 case DK_ENDMACRO:
2155 return parseDirectiveEndMacro(IDVal);
2156 case DK_PURGEM:
2157 return parseDirectivePurgeMacro(IDLoc);
2158 case DK_END:
2159 return parseDirectiveEnd(IDLoc);
2160 case DK_ERR:
2161 return parseDirectiveError(IDLoc, false);
2162 case DK_ERROR:
2163 return parseDirectiveError(IDLoc, true);
2164 case DK_WARNING:
2165 return parseDirectiveWarning(IDLoc);
2166 case DK_RELOC:
2167 return parseDirectiveReloc(IDLoc);
2168 case DK_DCB:
2169 case DK_DCB_W:
2170 return parseDirectiveDCB(IDVal, 2);
2171 case DK_DCB_B:
2172 return parseDirectiveDCB(IDVal, 1);
2173 case DK_DCB_D:
2174 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2175 case DK_DCB_L:
2176 return parseDirectiveDCB(IDVal, 4);
2177 case DK_DCB_S:
2178 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2179 case DK_DC_X:
2180 case DK_DCB_X:
2181 return TokError(Twine(IDVal) +
2182 " not currently supported for this target");
2183 case DK_DS:
2184 case DK_DS_W:
2185 return parseDirectiveDS(IDVal, 2);
2186 case DK_DS_B:
2187 return parseDirectiveDS(IDVal, 1);
2188 case DK_DS_D:
2189 return parseDirectiveDS(IDVal, 8);
2190 case DK_DS_L:
2191 case DK_DS_S:
2192 return parseDirectiveDS(IDVal, 4);
2193 case DK_DS_P:
2194 case DK_DS_X:
2195 return parseDirectiveDS(IDVal, 12);
2196 case DK_PRINT:
2197 return parseDirectivePrint(IDLoc);
2198 case DK_ADDRSIG:
2199 return parseDirectiveAddrsig();
2200 case DK_ADDRSIG_SYM:
2201 return parseDirectiveAddrsigSym();
2202 case DK_PSEUDO_PROBE:
2203 return parseDirectivePseudoProbe();
2204 case DK_LTO_DISCARD:
2205 return parseDirectiveLTODiscard();
2206 case DK_MEMTAG:
2207 return parseDirectiveSymbolAttribute(MCSA_Memtag);
2208 }
2209
2210 return Error(IDLoc, "unknown directive");
2211 }
2212
2213
2214 if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2215 IDVal == "_EMIT" || IDVal == "__EMIT"))
2216 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2217
2218
2219 if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2220 return parseDirectiveMSAlign(IDLoc, Info);
2221
2222 if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2223 Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2224 if (checkForValidSection())
2225 return true;
2226
2227 return parseAndMatchAndEmitTargetInstruction(Info, IDVal, ID, IDLoc);
2228}
2229
2230bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
2231 StringRef IDVal,
2232 AsmToken ID,
2233 SMLoc IDLoc) {
2234
2235 std::string OpcodeStr = IDVal.lower();
2236 ParseInstructionInfo IInfo(Info.AsmRewrites);
2237 bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr, ID,
2238 Info.ParsedOperands);
2239 Info.ParseError = ParseHadError;
2240
2241
2242 if (getShowParsedOperands()) {
2243 SmallString<256> Str;
2244 raw_svector_ostream OS(Str);
2245 OS << "parsed instruction: [";
2246 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2247 if (i != 0)
2248 OS << ", ";
2249 Info.ParsedOperands[i]->print(OS, MAI);
2250 }
2251 OS << "]";
2252
2254 }
2255
2256
2257 if (hasPendingError() || ParseHadError)
2258 return true;
2259
2260
2261
2262 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2264 getStreamer().getCurrentSectionOnly())) {
2265 unsigned Line;
2266 if (ActiveMacros.empty())
2268 else
2270 ActiveMacros.front()->ExitBuffer);
2271
2272
2273
2274
2275 if (!CppHashInfo.Filename.empty()) {
2276 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2277 0, StringRef(), CppHashInfo.Filename);
2278 getContext().setGenDwarfFileNumber(FileNumber);
2279
2280 unsigned CppHashLocLineNo =
2282 Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2283 }
2284
2285 getStreamer().emitDwarfLocDirective(
2286 getContext().getGenDwarfFileNumber(), Line, 0,
2288 StringRef());
2289 }
2290
2291
2292 if (!ParseHadError) {
2293 uint64_t ErrorInfo;
2294 if (getTargetParser().matchAndEmitInstruction(
2295 IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
2296 getTargetParser().isParsingMSInlineAsm()))
2297 return true;
2298 }
2299 return false;
2300}
2301
2302
2303bool
2304AsmParser::parseCurlyBlockScope(SmallVectorImpl &AsmStrRewrites) {
2305
2307 return false;
2308
2309 SMLoc StartLoc = Lexer.getLoc();
2310 Lex();
2312 Lex();
2313
2314
2317 return true;
2318}
2319
2320
2321
2322bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
2323 Lex();
2324
2325
2327 "Lexing Cpp line comment: Expected Integer");
2328 int64_t LineNumber = getTok().getIntVal();
2329 Lex();
2331 "Lexing Cpp line comment: Expected String");
2332 StringRef Filename = getTok().getString();
2333 Lex();
2334
2335 if (!SaveLocInfo)
2336 return false;
2337
2338
2340
2341
2342
2343 CppHashInfo.Loc = L;
2344 CppHashInfo.Filename = Filename;
2345 CppHashInfo.LineNumber = LineNumber;
2346 CppHashInfo.Buf = CurBuffer;
2347 if (!HadCppHashFilename) {
2348 HadCppHashFilename = true;
2349
2350
2351
2352 if (getContext().getGenDwarfForAssembly() &&
2353 getContext().getGenDwarfFileNumber() == 0) {
2354
2355
2356 getContext().setMCLineTableRootFile(
2357 0, getContext().getCompilationDir(), Filename,
2358 std::nullopt, std::nullopt);
2359 }
2360 }
2361 return false;
2362}
2363
2364
2365
2366void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2367 auto *Parser = static_cast<AsmParser *>(Context);
2368 raw_ostream &OS = errs();
2369
2370 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
2371 SMLoc DiagLoc = Diag.getLoc();
2373 unsigned CppHashBuf =
2374 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2375
2376
2377
2379 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2383 }
2384
2385
2386
2387
2388 if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
2389 if (Parser->SavedDiagHandler)
2390 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2391 else
2392 Parser->getContext().diagnose(Diag);
2393 return;
2394 }
2395
2396
2397
2398
2399 const std::string &Filename = std::string(Parser->CppHashInfo.Filename);
2400
2401 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2402 int CppHashLocLineNo =
2403 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2404 int LineNo =
2405 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2406
2407 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
2410
2411 if (Parser->SavedDiagHandler)
2412 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2413 else
2414 Parser->getContext().diagnose(NewDiag);
2415}
2416
2417
2418
2419
2420
2422 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
2423 c == '.';
2424}
2425
2426bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
2429 bool EnableAtPseudoVariable) {
2430 unsigned NParameters = Parameters.size();
2431 auto expandArg = [&](unsigned Index) {
2432 bool HasVararg = NParameters ? Parameters.back().Vararg : false;
2433 bool VarargParameter = HasVararg && Index == (NParameters - 1);
2434 for (const AsmToken &Token : A[Index])
2435
2436
2437
2438
2439
2440
2441
2442 if (AltMacroMode && Token.getString().front() == '%' &&
2444
2445 OS << Token.getIntVal();
2446
2447
2448 else if (AltMacroMode && Token.getString().front() == '<' &&
2451 }
2452
2453
2455 OS << Token.getString();
2456 else
2457 OS << Token.getStringContents();
2458 };
2459
2460
2461
2462 StringRef Body = Macro.Body;
2463 size_t I = 0, End = Body.size();
2464 while (I != End) {
2465 if (Body[I] == '\\' && I + 1 != End) {
2466
2467 if (EnableAtPseudoVariable && Body[I + 1] == '@') {
2468 OS << NumOfMacroInstantiations;
2469 I += 2;
2470 continue;
2471 }
2472 if (Body[I + 1] == '+') {
2473 OS << Macro.Count;
2474 I += 2;
2475 continue;
2476 }
2477 if (Body[I + 1] == '(' && Body[I + 2] == ')') {
2478 I += 3;
2479 continue;
2480 }
2481
2482 size_t Pos = ++I;
2484 ++I;
2486 if (AltMacroMode && I != End && Body[I] == '&')
2487 ++I;
2488 unsigned Index = 0;
2489 for (; Index < NParameters; ++Index)
2490 if (Parameters[Index].Name == Argument)
2491 break;
2492 if (Index == NParameters)
2494 else
2495 expandArg(Index);
2496 continue;
2497 }
2498
2499
2500
2501 if (Body[I] == '$' && I + 1 != End && IsDarwin && !NParameters) {
2502
2503 switch (Body[I + 1]) {
2504
2505 case '$':
2506 OS << '$';
2507 I += 2;
2508 continue;
2509
2510 case 'n':
2511 OS << A.size();
2512 I += 2;
2513 continue;
2514 default: {
2516 break;
2517
2518
2519 unsigned Index = Body[I + 1] - '0';
2520 if (Index < A.size())
2521 for (const AsmToken &Token : A[Index])
2522 OS << Token.getString();
2523 I += 2;
2524 continue;
2525 }
2526 }
2527 }
2528
2530 OS << Body[I++];
2531 continue;
2532 }
2533
2536 }
2537 StringRef Token(Body.data() + Start, I - Start);
2538 if (AltMacroMode) {
2539 unsigned Index = 0;
2540 for (; Index != NParameters; ++Index)
2541 if (Parameters[Index].Name == Token)
2542 break;
2543 if (Index != NParameters) {
2544 expandArg(Index);
2545 if (I != End && Body[I] == '&')
2546 ++I;
2547 continue;
2548 }
2549 }
2550 OS << Token;
2551 }
2552
2554 return false;
2555}
2556
2558 switch (kind) {
2559 default:
2560 return false;
2583 return true;
2584 }
2585}
2586
2587namespace {
2588
2589class AsmLexerSkipSpaceRAII {
2590public:
2591 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2593 }
2594
2595 ~AsmLexerSkipSpaceRAII() {
2597 }
2598
2599private:
2600 AsmLexer &Lexer;
2601};
2602
2603}
2604
2605bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
2606
2607 if (Vararg) {
2609 StringRef Str = parseStringToEndOfStatement();
2611 }
2612 return false;
2613 }
2614
2615 unsigned ParenLevel = 0;
2616
2617
2618 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2619
2620 bool SpaceEaten;
2621
2622 while (true) {
2623 SpaceEaten = false;
2625 return TokError("unexpected token in macro instantiation");
2626
2627 if (ParenLevel == 0) {
2628
2630 break;
2631
2633 SpaceEaten = true;
2634
2635
2636
2637
2638 if (!IsDarwin) {
2640 MA.push_back(getTok());
2641 Lexer.Lex();
2642
2643
2645 continue;
2646 }
2647 }
2648 if (SpaceEaten)
2649 break;
2650 }
2651
2652
2653
2655 break;
2656
2657
2659 ++ParenLevel;
2661 --ParenLevel;
2662
2663
2664 MA.push_back(getTok());
2665 Lexer.Lex();
2666 }
2667
2668 if (ParenLevel != 0)
2669 return TokError("unbalanced parentheses in macro argument");
2670 return false;
2671}
2672
2673
2674bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
2675 MCAsmMacroArguments &A) {
2676 const unsigned NParameters = M ? M->Parameters.size() : 0;
2677 bool NamedParametersFound = false;
2678 SmallVector<SMLoc, 4> FALocs;
2679
2680 A.resize(NParameters);
2681 FALocs.resize(NParameters);
2682
2683
2684
2685
2686 bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
2687 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2689 SMLoc IDLoc = Lexer.getLoc();
2690 MCAsmMacroParameter FA;
2691
2693 if (parseIdentifier(FA.Name))
2694 return Error(IDLoc, "invalid argument identifier for formal argument");
2695
2697 return TokError("expected '=' after formal parameter identifier");
2698
2699 Lex();
2700
2701 NamedParametersFound = true;
2702 }
2703 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2704
2705 if (NamedParametersFound && FA.Name.empty())
2706 return Error(IDLoc, "cannot mix positional and keyword arguments");
2707
2708 SMLoc StrLoc = Lexer.getLoc();
2709 SMLoc EndLoc;
2711 const MCExpr *AbsoluteExp;
2713
2714 Lex();
2715 if (parseExpression(AbsoluteExp, EndLoc))
2716 return false;
2717 if (!AbsoluteExp->evaluateAsAbsolute(Value,
2718 getStreamer().getAssemblerPtr()))
2719 return Error(StrLoc, "expected absolute expression");
2720 const char *StrChar = StrLoc.getPointer();
2721 const char *EndChar = EndLoc.getPointer();
2723 StringRef(StrChar, EndChar - StrChar), Value);
2724 FA.Value.push_back(newToken);
2727 const char *StrChar = StrLoc.getPointer();
2728 const char *EndChar = EndLoc.getPointer();
2729 jumpToLoc(EndLoc, CurBuffer);
2730
2731 Lex();
2733 StringRef(StrChar, EndChar - StrChar));
2734 FA.Value.push_back(newToken);
2735 } else if(parseMacroArgument(FA.Value, Vararg))
2736 return true;
2737
2740 unsigned FAI = 0;
2741 for (FAI = 0; FAI < NParameters; ++FAI)
2742 if (M->Parameters[FAI].Name == FA.Name)
2743 break;
2744
2745 if (FAI >= NParameters) {
2746 assert(M && "expected macro to be defined");
2747 return Error(IDLoc, "parameter named '" + FA.Name +
2748 "' does not exist for macro '" + M->Name + "'");
2749 }
2750 PI = FAI;
2751 }
2752
2753 if (!FA.Value.empty()) {
2754 if (A.size() <= PI)
2755 A.resize(PI + 1);
2757
2758 if (FALocs.size() <= PI)
2759 FALocs.resize(PI + 1);
2760
2761 FALocs[PI] = Lexer.getLoc();
2762 }
2763
2764
2765
2766
2769 for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
2771 if (M->Parameters[FAI].Required) {
2773 "missing value for required parameter "
2774 "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
2776 }
2777
2778 if (->Parameters[FAI].Value.empty())
2779 A[FAI] = M->Parameters[FAI].Value;
2780 }
2781 }
2783 }
2784
2786 }
2787
2788 return TokError("too many positional arguments");
2789}
2790
2791bool AsmParser::handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc) {
2792
2793
2795 if (ActiveMacros.size() == MaxNestingDepth) {
2796 std::ostringstream MaxNestingDepthError;
2797 MaxNestingDepthError << "macros cannot be nested more than "
2798 << MaxNestingDepth << " levels deep."
2799 << " Use -asm-macro-max-nesting-depth to increase "
2800 "this limit.";
2801 return TokError(MaxNestingDepthError.str());
2802 }
2803
2804 MCAsmMacroArguments A;
2805 if (parseMacroArguments(M, A))
2806 return true;
2807
2808
2809
2810 SmallString<256> Buf;
2811 raw_svector_ostream OS(Buf);
2812
2813 if ((!IsDarwin || M->Parameters.size()) && M->Parameters.size() != A.size())
2814 return Error(getTok().getLoc(), "Wrong number of arguments");
2815 if (expandMacro(OS, *M, M->Parameters, A, true))
2816 return true;
2817
2818
2819
2820 OS << ".endmacro\n";
2821
2822 std::unique_ptr Instantiation =
2824
2825
2826
2827 MacroInstantiation *MI = new MacroInstantiation{
2828 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2829 ActiveMacros.push_back(MI);
2830
2831 ++NumOfMacroInstantiations;
2832
2833
2836 Lex();
2837
2838 return false;
2839}
2840
2841void AsmParser::handleMacroExit() {
2842
2843 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2844 Lex();
2845
2846
2848 Lex();
2849
2850
2851 delete ActiveMacros.back();
2852 ActiveMacros.pop_back();
2853}
2854
2855bool AsmParser::parseAssignment(StringRef Name, AssignmentKind Kind) {
2857 const MCExpr *Value;
2858 SMLoc ExprLoc = getTok().getLoc();
2859 bool AllowRedef =
2860 Kind == AssignmentKind::Set || Kind == AssignmentKind::Equal;
2863 return true;
2864
2865 if (!Sym) {
2866
2867
2868
2869 return false;
2870 }
2871
2872 if (discardLTOSymbol(Name))
2873 return false;
2874
2875
2876 switch (Kind) {
2877 case AssignmentKind::Equal:
2879 break;
2880 case AssignmentKind::Set:
2881 case AssignmentKind::Equiv:
2884 break;
2885 case AssignmentKind::LTOSetConditional:
2887 return Error(ExprLoc, "expected identifier");
2888
2890 break;
2891 }
2892
2893 return false;
2894}
2895
2896
2897
2898
2899bool AsmParser::parseIdentifier(StringRef &Res) {
2900
2901
2902
2903
2904
2906 SMLoc PrefixLoc = getLexer().getLoc();
2907
2908
2909
2910 AsmToken Buf[1];
2912
2914 return true;
2915
2916
2917
2918 if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
2919 return true;
2920
2921
2922 Lexer.Lex();
2923
2924 Res = StringRef(PrefixLoc.getPointer(), getTok().getString().size() + 1);
2925 Lex();
2926 return false;
2927 }
2928
2930 return true;
2931
2932 Res = getTok().getIdentifier();
2933
2934 Lex();
2935
2936 return false;
2937}
2938
2939
2940
2941
2942
2943
2944bool AsmParser::parseDirectiveSet(StringRef IDVal, AssignmentKind Kind) {
2945 StringRef Name;
2946 if (check(parseIdentifier(Name), "expected identifier") || parseComma() ||
2947 parseAssignment(Name, Kind))
2948 return true;
2949 return false;
2950}
2951
2952bool AsmParser::parseEscapedString(std::string &Data) {
2954 return true;
2955
2957 StringRef Str = getTok().getStringContents();
2958 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
2959 if (Str[i] != '\\') {
2960 if ((Str[i] == '\n') || (Str[i] == '\r')) {
2961
2962 if ((Str[i] == '\n') && (i > 0) && (Str[i - 1] == '\r'))
2963 continue;
2964
2966 if (Warning(NewlineLoc, "unterminated string; newline inserted"))
2967 return true;
2968 }
2969 Data += Str[i];
2970 continue;
2971 }
2972
2973
2974
2975 ++i;
2976 if (i == e)
2977 return TokError("unexpected backslash at end of string");
2978
2979
2980 if (Str[i] == 'x' || Str[i] == 'X') {
2981 size_t length = Str.size();
2982 if (i + 1 >= length || (Str[i + 1]))
2983 return TokError("invalid hexadecimal escape sequence");
2984
2985
2986
2987 unsigned Value = 0;
2988 while (i + 1 < length && isHexDigit(Str[i + 1]))
2990
2991 Data += (unsigned char)(Value & 0xFF);
2992 continue;
2993 }
2994
2995
2996 if ((unsigned)(Str[i] - '0') <= 7) {
2997
2998 unsigned Value = Str[i] - '0';
2999
3000 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
3001 ++i;
3003
3004 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
3005 ++i;
3007 }
3008 }
3009
3010 if (Value > 255)
3011 return TokError("invalid octal escape sequence (out of range)");
3012
3014 continue;
3015 }
3016
3017
3018 switch (Str[i]) {
3019 default:
3020
3021 return TokError("invalid escape sequence (unrecognized character)");
3022
3023 case 'b': Data += '\b'; break;
3024 case 'f': Data += '\f'; break;
3025 case 'n': Data += '\n'; break;
3026 case 'r': Data += '\r'; break;
3027 case 't': Data += '\t'; break;
3028 case '"': Data += '"'; break;
3029 case '\\': Data += '\\'; break;
3030 }
3031 }
3032
3033 Lex();
3034 return false;
3035}
3036
3037bool AsmParser::parseAngleBracketString(std::string &Data) {
3038 SMLoc EndLoc, StartLoc = getTok().getLoc();
3040 const char *StartChar = StartLoc.getPointer() + 1;
3041 const char *EndChar = EndLoc.getPointer() - 1;
3042 jumpToLoc(EndLoc, CurBuffer);
3043
3044 Lex();
3045
3047 return false;
3048 }
3049 return true;
3050}
3051
3052
3053
3054
3055bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
3056 auto parseOp = [&]() -> bool {
3057 std::string Data;
3058 if (checkForValidSection())
3059 return true;
3060
3061
3062 do {
3063 if (parseEscapedString(Data))
3064 return true;
3065 getStreamer().emitBytes(Data);
3067 if (ZeroTerminated)
3068 getStreamer().emitBytes(StringRef("\0", 1));
3069 return false;
3070 };
3071
3072 return parseMany(parseOp);
3073}
3074
3075
3076
3077bool AsmParser::parseDirectiveBase64() {
3078 auto parseOp = [&]() -> bool {
3079 if (checkForValidSection())
3080 return true;
3081
3083 return true;
3084 }
3085
3086 std::vector Decoded;
3087 std::string const str = getTok().getStringContents().str();
3088 if (check(str.empty(), "expected nonempty string")) {
3089 return true;
3090 }
3091
3093 if (e) {
3095 return Error(Lexer.getLoc(), "failed to base64 decode string data");
3096 }
3097
3098 getStreamer().emitBytes(std::string(Decoded.begin(), Decoded.end()));
3099 Lex();
3100 return false;
3101 };
3102
3103 return check(parseMany(parseOp), "expected string");
3104}
3105
3106
3107
3108bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
3109 const MCExpr *Offset;
3110 const MCExpr *Expr = nullptr;
3111
3112 if (parseExpression(Offset))
3113 return true;
3114 if (parseComma() ||
3116 return true;
3117
3120 Lex();
3121
3123 Lex();
3124 SMLoc ExprLoc = Lexer.getLoc();
3125 if (parseExpression(Expr))
3126 return true;
3127
3130 return Error(ExprLoc, "expression must be relocatable");
3131 }
3132
3133 if (parseEOL())
3134 return true;
3135
3136 getStreamer().emitRelocDirective(*Offset, Name, Expr, NameLoc);
3137 return false;
3138}
3139
3140
3141
3142bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
3143 auto parseOp = [&]() -> bool {
3144 const MCExpr *Value;
3145 SMLoc ExprLoc = getLexer().getLoc();
3146 if (checkForValidSection() || getTargetParser().parseDataExpr(Value))
3147 return true;
3148
3150 assert(Size <= 8 && "Invalid size");
3151 uint64_t IntValue = MCE->getValue();
3153 return Error(ExprLoc, "out of range literal value");
3154 getStreamer().emitIntValue(IntValue, Size);
3155 } else
3156 getStreamer().emitValue(Value, Size, ExprLoc);
3157 return false;
3158 };
3159
3160 return parseMany(parseOp);
3161}
3162
3166 return Asm.TokError("unknown token in expression");
3167 SMLoc ExprLoc = Asm.getTok().getLoc();
3168 APInt IntValue = Asm.getTok().getAPIntVal();
3169 Asm.Lex();
3170 if (!IntValue.isIntN(128))
3171 return Asm.Error(ExprLoc, "out of range literal value");
3172 if (!IntValue.isIntN(64)) {
3175 } else {
3176 hi = 0;
3178 }
3179 return false;
3180}
3181
3182
3183
3184
3185bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
3186 auto parseOp = [&]() -> bool {
3187 if (checkForValidSection())
3188 return true;
3191 return true;
3193 getStreamer().emitInt64(lo);
3194 getStreamer().emitInt64(hi);
3195 } else {
3196 getStreamer().emitInt64(hi);
3197 getStreamer().emitInt64(lo);
3198 }
3199 return false;
3200 };
3201
3202 return parseMany(parseOp);
3203}
3204
3205bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3206
3207
3208 bool IsNeg = false;
3210 Lexer.Lex();
3211 IsNeg = true;
3213 Lexer.Lex();
3214
3216 return TokError(Lexer.getErr());
3219 return TokError("unexpected token in directive");
3220
3221
3223 StringRef IDVal = getTok().getString();
3230 else
3231 return TokError("invalid floating point literal");
3233 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3234 .takeError()))
3235 return TokError("invalid floating point literal");
3236 if (IsNeg)
3237 Value.changeSign();
3238
3239
3240 Lex();
3241
3242 Res = Value.bitcastToAPInt();
3243
3244 return false;
3245}
3246
3247
3248
3249bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
3250 const fltSemantics &Semantics) {
3251 auto parseOp = [&]() -> bool {
3252 APInt AsInt;
3253 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3254 return true;
3257 return false;
3258 };
3259
3260 return parseMany(parseOp);
3261}
3262
3263
3264
3265bool AsmParser::parseDirectiveZero() {
3266 SMLoc NumBytesLoc = Lexer.getLoc();
3267 const MCExpr *NumBytes;
3268 if (checkForValidSection() || parseExpression(NumBytes))
3269 return true;
3270
3271 int64_t Val = 0;
3273 Lex();
3274 if (parseAbsoluteExpression(Val))
3275 return true;
3276 }
3277
3278 if (parseEOL())
3279 return true;
3280 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3281
3282 return false;
3283}
3284
3285
3286
3287bool AsmParser::parseDirectiveFill() {
3288 SMLoc NumValuesLoc = Lexer.getLoc();
3289 const MCExpr *NumValues;
3290 if (checkForValidSection() || parseExpression(NumValues))
3291 return true;
3292
3293 int64_t FillSize = 1;
3294 int64_t FillExpr = 0;
3295
3296 SMLoc SizeLoc, ExprLoc;
3297
3299 SizeLoc = getTok().getLoc();
3300 if (parseAbsoluteExpression(FillSize))
3301 return true;
3303 ExprLoc = getTok().getLoc();
3304 if (parseAbsoluteExpression(FillExpr))
3305 return true;
3306 }
3307 }
3308 if (parseEOL())
3309 return true;
3310
3311 if (FillSize < 0) {
3312 Warning(SizeLoc, "'.fill' directive with negative size has no effect");
3313 return false;
3314 }
3315 if (FillSize > 8) {
3316 Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
3317 FillSize = 8;
3318 }
3319
3320 if ((FillExpr) && FillSize > 4)
3321 Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
3322
3323 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3324
3325 return false;
3326}
3327
3328
3329
3330bool AsmParser::parseDirectiveOrg() {
3331 const MCExpr *Offset;
3332 SMLoc OffsetLoc = Lexer.getLoc();
3333 if (checkForValidSection() || parseExpression(Offset))
3334 return true;
3335
3336
3337 int64_t FillExpr = 0;
3339 if (parseAbsoluteExpression(FillExpr))
3340 return true;
3341 if (parseEOL())
3342 return true;
3343
3344 getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
3345 return false;
3346}
3347
3348
3349
3350bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) {
3351 SMLoc AlignmentLoc = getLexer().getLoc();
3352 int64_t Alignment;
3353 SMLoc MaxBytesLoc;
3354 bool HasFillExpr = false;
3355 int64_t FillExpr = 0;
3356 int64_t MaxBytesToFill = 0;
3357 SMLoc FillExprLoc;
3358
3359 auto parseAlign = [&]() -> bool {
3360 if (parseAbsoluteExpression(Alignment))
3361 return true;
3363
3364
3365
3367 HasFillExpr = true;
3368 if (parseTokenLoc(FillExprLoc) || parseAbsoluteExpression(FillExpr))
3369 return true;
3370 }
3372 if (parseTokenLoc(MaxBytesLoc) ||
3373 parseAbsoluteExpression(MaxBytesToFill))
3374 return true;
3375 }
3376 return parseEOL();
3377 };
3378
3379 if (checkForValidSection())
3380 return true;
3381
3383 Warning(AlignmentLoc, "p2align directive with no operand(s) is ignored");
3384 return parseEOL();
3385 }
3386 if (parseAlign())
3387 return true;
3388
3389
3390 bool ReturnVal = false;
3391
3392
3393 if (IsPow2) {
3394
3395 if (Alignment >= 32) {
3396 ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
3397 Alignment = 31;
3398 }
3399
3400 Alignment = 1ULL << Alignment;
3401 } else {
3402
3403
3404
3405 if (Alignment == 0)
3406 Alignment = 1;
3408 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
3410 }
3412 ReturnVal |= Error(AlignmentLoc, "alignment must be smaller than 2**32");
3413 Alignment = 1u << 31;
3414 }
3415 }
3416
3417
3418 if (MaxBytesLoc.isValid()) {
3419 if (MaxBytesToFill < 1) {
3420 ReturnVal |= Error(MaxBytesLoc,
3421 "alignment directive can never be satisfied in this "
3422 "many bytes, ignoring maximum bytes expression");
3423 MaxBytesToFill = 0;
3424 }
3425
3426 if (MaxBytesToFill >= Alignment) {
3427 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
3428 "has no effect");
3429 MaxBytesToFill = 0;
3430 }
3431 }
3432
3433 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3434 assert(Section && "must have section to emit alignment");
3435
3436 if (HasFillExpr && FillExpr != 0 && Section->isBssSection()) {
3437 ReturnVal |=
3438 Warning(FillExprLoc, "ignoring non-zero fill value in BSS section '" +
3439 Section->getName() + "'");
3440 FillExpr = 0;
3441 }
3442
3443
3444
3445 if (MAI.useCodeAlign(*Section) && !HasFillExpr) {
3446 getStreamer().emitCodeAlignment(
3447 Align(Alignment), &getTargetParser().getSTI(), MaxBytesToFill);
3448 } else {
3449
3450 getStreamer().emitValueToAlignment(Align(Alignment), FillExpr, ValueSize,
3451 MaxBytesToFill);
3452 }
3453
3454 return ReturnVal;
3455}
3456
3457
3458
3459
3460bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
3461
3462 int64_t FileNumber = -1;
3464 FileNumber = getTok().getIntVal();
3465 Lex();
3466
3467 if (FileNumber < 0)
3468 return TokError("negative file number");
3469 }
3470
3471 std::string Path;
3472
3473
3474
3475 if (parseEscapedString(Path))
3476 return true;
3477
3478 StringRef Directory;
3480 std::string FilenameData;
3482 if (check(FileNumber == -1,
3483 "explicit path specified, but no file number") ||
3484 parseEscapedString(FilenameData))
3485 return true;
3487 Directory = Path;
3488 } else {
3490 }
3491
3492 uint64_t MD5Hi, MD5Lo;
3493 bool HasMD5 = false;
3494
3495 std::optional Source;
3496 bool HasSource = false;
3497 std::string SourceString;
3498
3502 "unexpected token in '.file' directive") ||
3503 parseIdentifier(Keyword))
3504 return true;
3505 if (Keyword == "md5") {
3506 HasMD5 = true;
3507 if (check(FileNumber == -1,
3508 "MD5 checksum specified, but no file number") ||
3510 return true;
3511 } else if (Keyword == "source") {
3512 HasSource = true;
3513 if (check(FileNumber == -1,
3514 "source specified, but no file number") ||
3516 "unexpected token in '.file' directive") ||
3517 parseEscapedString(SourceString))
3518 return true;
3519 } else {
3520 return TokError("unexpected token in '.file' directive");
3521 }
3522 }
3523
3524 if (FileNumber == -1) {
3525
3526
3527
3528 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
3529 getStreamer().emitFileDirective(Filename);
3530 } else {
3531
3532
3533
3537 }
3538
3539 std::optionalMD5::MD5Result CKMem;
3540 if (HasMD5) {
3541 MD5::MD5Result Sum;
3542 for (unsigned i = 0; i != 8; ++i) {
3543 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3544 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3545 }
3546 CKMem = Sum;
3547 }
3548 if (HasSource) {
3549 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
3550 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3551 Source = StringRef(SourceBuf, SourceString.size());
3552 }
3553 if (FileNumber == 0) {
3554
3557 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3558 } else {
3559 Expected FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3560 FileNumber, Directory, Filename, CKMem, Source);
3561 if (!FileNumOrErr)
3563 }
3564
3565
3567 ReportedInconsistentMD5 = true;
3568 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
3569 }
3570 }
3571
3572 return false;
3573}
3574
3575
3576
3577bool AsmParser::parseDirectiveLine() {
3579 return parseEOL();
3580}
3581
3582
3583
3584
3585
3586
3587
3588
3589bool AsmParser::parseDirectiveLoc() {
3590 int64_t FileNumber = 0, LineNumber = 0;
3591 SMLoc Loc = getTok().getLoc();
3592 if (parseIntToken(FileNumber) ||
3594 "file number less than one in '.loc' directive") ||
3595 check(().isValidDwarfFileNumber(FileNumber), Loc,
3596 "unassigned file number in '.loc' directive"))
3597 return true;
3598
3599
3601 LineNumber = getTok().getIntVal();
3602 if (LineNumber < 0)
3603 return TokError("line number less than zero in '.loc' directive");
3604 Lex();
3605 }
3606
3607 int64_t ColumnPos = 0;
3609 ColumnPos = getTok().getIntVal();
3610 if (ColumnPos < 0)
3611 return TokError("column position less than zero in '.loc' directive");
3612 Lex();
3613 }
3614
3615 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
3617 unsigned Isa = 0;
3619
3620 auto parseLocOp = [&]() -> bool {
3621 StringRef Name;
3622 SMLoc Loc = getTok().getLoc();
3623 if (parseIdentifier(Name))
3624 return TokError("unexpected token in '.loc' directive");
3625
3626 if (Name == "basic_block")
3628 else if (Name == "prologue_end")
3630 else if (Name == "epilogue_begin")
3632 else if (Name == "is_stmt") {
3633 Loc = getTok().getLoc();
3634 const MCExpr *Value;
3635 if (parseExpression(Value))
3636 return true;
3637
3639 int Value = MCE->getValue();
3641 Flags &= ~DWARF2_FLAG_IS_STMT;
3642 else if (Value == 1)
3644 else
3645 return Error(Loc, "is_stmt value not 0 or 1");
3646 } else {
3647 return Error(Loc, "is_stmt value not the constant value of 0 or 1");
3648 }
3649 } else if (Name == "isa") {
3650 Loc = getTok().getLoc();
3651 const MCExpr *Value;
3652 if (parseExpression(Value))
3653 return true;
3654
3656 int Value = MCE->getValue();
3658 return Error(Loc, "isa number less than zero");
3660 } else {
3661 return Error(Loc, "isa number not a constant value");
3662 }
3663 } else if (Name == "discriminator") {
3664 if (parseAbsoluteExpression(Discriminator))
3665 return true;
3666 } else {
3667 return Error(Loc, "unknown sub-directive in '.loc' directive");
3668 }
3669 return false;
3670 };
3671
3672 if (parseMany(parseLocOp, false ))
3673 return true;
3674
3675 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3676 Isa, Discriminator, StringRef());
3677
3678 return false;
3679}
3680
3681
3682
3683bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) {
3684 StringRef Name;
3685 DirectiveLoc = Lexer.getLoc();
3686 if (parseIdentifier(Name))
3687 return TokError("expected identifier");
3688 if (parseEOL())
3689 return true;
3690 getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name);
3691 return false;
3692}
3693
3694
3695
3696bool AsmParser::parseDirectiveStabs() {
3697 return TokError("unsupported directive '.stabs'");
3698}
3699
3700
3701
3702bool AsmParser::parseDirectiveCVFile() {
3703 SMLoc FileNumberLoc = getTok().getLoc();
3704 int64_t FileNumber;
3706 std::string Checksum;
3708
3709 if (parseIntToken(FileNumber, "expected file number") ||
3710 check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
3712 "unexpected token in '.cv_file' directive") ||
3713 parseEscapedString(Filename))
3714 return true;
3717 "unexpected token in '.cv_file' directive") ||
3718 parseEscapedString(Checksum) ||
3719 parseIntToken(ChecksumKind,
3720 "expected checksum kind in '.cv_file' directive") ||
3721 parseEOL())
3722 return true;
3723 }
3724
3725 Checksum = fromHex(Checksum);
3726 void *CKMem = Ctx.allocate(Checksum.size(), 1);
3727 memcpy(CKMem, Checksum.data(), Checksum.size());
3728 ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
3729 Checksum.size());
3730
3731 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3732 static_cast<uint8_t>(ChecksumKind)))
3733 return Error(FileNumberLoc, "file number already allocated");
3734
3735 return false;
3736}
3737
3738bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
3739 StringRef DirectiveName) {
3740 SMLoc Loc;
3741 return parseTokenLoc(Loc) ||
3742 parseIntToken(FunctionId, "expected function id") ||
3743 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3744 "expected function id within range [0, UINT_MAX)");
3745}
3746
3747bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3748 SMLoc Loc;
3749 return parseTokenLoc(Loc) ||
3750 parseIntToken(FileNumber, "expected file number") ||
3751 check(FileNumber < 1, Loc,
3752 "file number less than one in '" + DirectiveName +
3753 "' directive") ||
3754 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3755 "unassigned file number in '" + DirectiveName + "' directive");
3756}
3757
3758
3759
3760
3761
3762bool AsmParser::parseDirectiveCVFuncId() {
3763 SMLoc FunctionIdLoc = getTok().getLoc();
3764 int64_t FunctionId;
3765
3766 if (parseCVFunctionId(FunctionId, ".cv_func_id") || parseEOL())
3767 return true;
3768
3769 if (!getStreamer().emitCVFuncIdDirective(FunctionId))
3770 return Error(FunctionIdLoc, "function id already allocated");
3771
3772 return false;
3773}
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783bool AsmParser::parseDirectiveCVInlineSiteId() {
3784 SMLoc FunctionIdLoc = getTok().getLoc();
3785 int64_t FunctionId;
3786 int64_t IAFunc;
3787 int64_t IAFile;
3788 int64_t IALine;
3789 int64_t IACol = 0;
3790
3791
3792 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
3793 return true;
3794
3795
3797 getTok().getIdentifier() != "within"),
3798 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3799 return true;
3800 Lex();
3801
3802
3803 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
3804 return true;
3805
3806
3808 getTok().getIdentifier() != "inlined_at"),
3809 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3810 "directive") )
3811 return true;
3812 Lex();
3813
3814
3815 if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
3816 parseIntToken(IALine, "expected line number after 'inlined_at'"))
3817 return true;
3818
3819
3821 IACol = getTok().getIntVal();
3822 Lex();
3823 }
3824
3825 if (parseEOL())
3826 return true;
3827
3828 if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3829 IALine, IACol, FunctionIdLoc))
3830 return Error(FunctionIdLoc, "function id already allocated");
3831
3832 return false;
3833}
3834
3835
3836
3837
3838
3839
3840
3841
3842bool AsmParser::parseDirectiveCVLoc() {
3843 SMLoc DirectiveLoc = getTok().getLoc();
3844 int64_t FunctionId, FileNumber;
3845 if (parseCVFunctionId(FunctionId, ".cv_loc") ||
3846 parseCVFileId(FileNumber, ".cv_loc"))
3847 return true;
3848
3849 int64_t LineNumber = 0;
3851 LineNumber = getTok().getIntVal();
3852 if (LineNumber < 0)
3853 return TokError("line number less than zero in '.cv_loc' directive");
3854 Lex();
3855 }
3856
3857 int64_t ColumnPos = 0;
3859 ColumnPos = getTok().getIntVal();
3860 if (ColumnPos < 0)
3861 return TokError("column position less than zero in '.cv_loc' directive");
3862 Lex();
3863 }
3864
3865 bool PrologueEnd = false;
3866 uint64_t IsStmt = 0;
3867
3868 auto parseOp = [&]() -> bool {
3869 StringRef Name;
3870 SMLoc Loc = getTok().getLoc();
3871 if (parseIdentifier(Name))
3872 return TokError("unexpected token in '.cv_loc' directive");
3873 if (Name == "prologue_end")
3874 PrologueEnd = true;
3875 else if (Name == "is_stmt") {
3876 Loc = getTok().getLoc();
3877 const MCExpr *Value;
3878 if (parseExpression(Value))
3879 return true;
3880
3881 IsStmt = ~0ULL;
3883 IsStmt = MCE->getValue();
3884
3885 if (IsStmt > 1)
3886 return Error(Loc, "is_stmt value not 0 or 1");
3887 } else {
3888 return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
3889 }
3890 return false;
3891 };
3892
3893 if (parseMany(parseOp, false ))
3894 return true;
3895
3896 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
3897 ColumnPos, PrologueEnd, IsStmt, StringRef(),
3898 DirectiveLoc);
3899 return false;
3900}
3901
3902
3903
3904bool AsmParser::parseDirectiveCVLinetable() {
3905 int64_t FunctionId;
3906 MCSymbol *FnStartSym, *FnEndSym;
3907 SMLoc Loc = getTok().getLoc();
3908 if (parseCVFunctionId(FunctionId, ".cv_linetable") || parseComma() ||
3909 parseTokenLoc(Loc) ||
3910 check(parseSymbol(FnStartSym), Loc, "expected identifier in directive") ||
3911 parseComma() || parseTokenLoc(Loc) ||
3912 check(parseSymbol(FnEndSym), Loc, "expected identifier in directive"))
3913 return true;
3914
3915 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
3916 return false;
3917}
3918
3919
3920
3921bool AsmParser::parseDirectiveCVInlineLinetable() {
3922 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3923 MCSymbol *FnStartSym, *FnEndSym;
3924 SMLoc Loc = getTok().getLoc();
3925 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
3926 parseTokenLoc(Loc) ||
3927 parseIntToken(SourceFileId, "expected SourceField") ||
3928 check(SourceFileId <= 0, Loc, "File id less than zero") ||
3929 parseTokenLoc(Loc) ||
3930 parseIntToken(SourceLineNum, "expected SourceLineNum") ||
3931 check(SourceLineNum < 0, Loc, "Line number less than zero") ||
3932 parseTokenLoc(Loc) ||
3933 check(parseSymbol(FnStartSym), Loc, "expected identifier") ||
3934 parseTokenLoc(Loc) ||
3935 check(parseSymbol(FnEndSym), Loc, "expected identifier"))
3936 return true;
3937
3938 if (parseEOL())
3939 return true;
3940
3941 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
3942 SourceLineNum, FnStartSym,
3943 FnEndSym);
3944 return false;
3945}
3946
3947void AsmParser::initializeCVDefRangeTypeMap() {
3948 CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
3949 CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
3950 CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
3951 CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
3952}
3953
3954
3955
3956bool AsmParser::parseDirectiveCVDefRange() {
3957 SMLoc Loc;
3958 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
3960 Loc = getLexer().getLoc();
3963 return Error(Loc, "expected identifier in directive");
3964
3965 Loc = getLexer().getLoc();
3968 return Error(Loc, "expected identifier in directive");
3969
3970 Ranges.push_back({GapStartSym, GapEndSym});
3971 }
3972
3973 StringRef CVDefRangeTypeStr;
3974 if (parseToken(
3976 "expected comma before def_range type in .cv_def_range directive") ||
3977 parseIdentifier(CVDefRangeTypeStr))
3978 return Error(Loc, "expected def_range type in directive");
3979
3981 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
3982 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
3983 ? CVDR_DEFRANGE
3984 : CVTypeIt->getValue();
3985 switch (CVDRType) {
3986 case CVDR_DEFRANGE_REGISTER: {
3987 int64_t DRRegister;
3988 if (parseToken(AsmToken::Comma, "expected comma before register number in "
3989 ".cv_def_range directive") ||
3990 parseAbsoluteExpression(DRRegister))
3991 return Error(Loc, "expected register number");
3992
3993 codeview::DefRangeRegisterHeader DRHdr;
3994 DRHdr.Register = DRRegister;
3996 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
3997 break;
3998 }
3999 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4000 int64_t DROffset;
4002 "expected comma before offset in .cv_def_range directive") ||
4003 parseAbsoluteExpression(DROffset))
4004 return Error(Loc, "expected offset value");
4005
4006 codeview::DefRangeFramePointerRelHeader DRHdr;
4007 DRHdr.Offset = DROffset;
4008 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4009 break;
4010 }
4011 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4012 int64_t DRRegister;
4013 int64_t DROffsetInParent;
4014 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4015 ".cv_def_range directive") ||
4016 parseAbsoluteExpression(DRRegister))
4017 return Error(Loc, "expected register number");
4019 "expected comma before offset in .cv_def_range directive") ||
4020 parseAbsoluteExpression(DROffsetInParent))
4021 return Error(Loc, "expected offset value");
4022
4023 codeview::DefRangeSubfieldRegisterHeader DRHdr;
4024 DRHdr.Register = DRRegister;
4027 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4028 break;
4029 }
4030 case CVDR_DEFRANGE_REGISTER_REL: {
4031 int64_t DRRegister;
4032 int64_t DRFlags;
4033 int64_t DRBasePointerOffset;
4034 if (parseToken(AsmToken::Comma, "expected comma before register number in "
4035 ".cv_def_range directive") ||
4036 parseAbsoluteExpression(DRRegister))
4037 return Error(Loc, "expected register value");
4038 if (parseToken(
4040 "expected comma before flag value in .cv_def_range directive") ||
4041 parseAbsoluteExpression(DRFlags))
4042 return Error(Loc, "expected flag value");
4043 if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
4044 "in .cv_def_range directive") ||
4045 parseAbsoluteExpression(DRBasePointerOffset))
4046 return Error(Loc, "expected base pointer offset value");
4047
4048 codeview::DefRangeRegisterRelHeader DRHdr;
4049 DRHdr.Register = DRRegister;
4050 DRHdr.Flags = DRFlags;
4052 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4053 break;
4054 }
4055 default:
4056 return Error(Loc, "unexpected def_range type in .cv_def_range directive");
4057 }
4058 return true;
4059}
4060
4061
4062
4063bool AsmParser::parseDirectiveCVString() {
4064 std::string Data;
4065 if (checkForValidSection() || parseEscapedString(Data))
4066 return true;
4067
4068
4069 std::pair<StringRef, unsigned> Insertion =
4070 getCVContext().addToStringTable(Data);
4071 getStreamer().emitInt32(Insertion.second);
4072 return false;
4073}
4074
4075
4076
4077bool AsmParser::parseDirectiveCVStringTable() {
4078 getStreamer().emitCVStringTableDirective();
4079 return false;
4080}
4081
4082
4083
4084bool AsmParser::parseDirectiveCVFileChecksums() {
4085 getStreamer().emitCVFileChecksumsDirective();
4086 return false;
4087}
4088
4089
4090
4091bool AsmParser::parseDirectiveCVFileChecksumOffset() {
4092 int64_t FileNo;
4093 if (parseIntToken(FileNo))
4094 return true;
4095 if (parseEOL())
4096 return true;
4097 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4098 return false;
4099}
4100
4101
4102
4103bool AsmParser::parseDirectiveCVFPOData() {
4104 SMLoc DirLoc = getLexer().getLoc();
4107 return TokError("expected symbol name");
4108 if (parseEOL())
4109 return true;
4110 getStreamer().emitCVFPOData(ProcSym, DirLoc);
4111 return false;
4112}
4113
4114
4115
4116bool AsmParser::parseDirectiveCFISections() {
4117 StringRef Name;
4118 bool EH = false;
4119 bool Debug = false;
4120 bool SFrame = false;
4121
4123 for (;;) {
4124 if (parseIdentifier(Name))
4125 return TokError("expected .eh_frame, .debug_frame, or .sframe");
4126 if (Name == ".eh_frame")
4127 EH = true;
4128 else if (Name == ".debug_frame")
4130 else if (Name == ".sframe")
4131 SFrame = true;
4133 break;
4134 if (parseComma())
4135 return true;
4136 }
4137 }
4138 getStreamer().emitCFISections(EH, Debug, SFrame);
4139 return false;
4140}
4141
4142
4143
4144bool AsmParser::parseDirectiveCFIStartProc() {
4145 CFIStartProcLoc = StartTokLoc;
4146
4149 if (check(parseIdentifier(Simple) || Simple != "simple",
4150 "unexpected token") ||
4151 parseEOL())
4152 return true;
4153 }
4154
4155
4156
4157
4158
4159
4160 getStreamer().emitCFIStartProc(.empty(), Lexer.getLoc());
4161 return false;
4162}
4163
4164
4165
4166bool AsmParser::parseDirectiveCFIEndProc() {
4167 CFIStartProcLoc = std::nullopt;
4168
4169 if (parseEOL())
4170 return true;
4171
4172 getStreamer().emitCFIEndProc();
4173 return false;
4174}
4175
4176
4177bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
4178 SMLoc DirectiveLoc) {
4179 MCRegister RegNo;
4180
4182 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4183 return true;
4184 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
4185 } else
4186 return parseAbsoluteExpression(Register);
4187
4188 return false;
4189}
4190
4191
4192
4193bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
4195 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4196 parseAbsoluteExpression(Offset) || parseEOL())
4197 return true;
4198
4199 getStreamer().emitCFIDefCfa(Register, Offset, DirectiveLoc);
4200 return false;
4201}
4202
4203
4204
4205bool AsmParser::parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc) {
4207 if (parseAbsoluteExpression(Offset) || parseEOL())
4208 return true;
4209
4210 getStreamer().emitCFIDefCfaOffset(Offset, DirectiveLoc);
4211 return false;
4212}
4213
4214
4215
4216bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
4217 int64_t Register1 = 0, Register2 = 0;
4218 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
4219 parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
4220 return true;
4221
4222 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
4223 return false;
4224}
4225
4226
4227
4228bool AsmParser::parseDirectiveCFIWindowSave(SMLoc DirectiveLoc) {
4229 if (parseEOL())
4230 return true;
4231 getStreamer().emitCFIWindowSave(DirectiveLoc);
4232 return false;
4233}
4234
4235
4236
4237bool AsmParser::parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc) {
4238 int64_t Adjustment = 0;
4239 if (parseAbsoluteExpression(Adjustment) || parseEOL())
4240 return true;
4241
4242 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
4243 return false;
4244}
4245
4246
4247
4248bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
4250 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4251 return true;
4252
4253 getStreamer().emitCFIDefCfaRegister(Register, DirectiveLoc);
4254 return false;
4255}
4256
4257
4258
4259bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc) {
4261 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4262 parseAbsoluteExpression(Offset) || parseComma() ||
4263 parseAbsoluteExpression(AddressSpace) || parseEOL())
4264 return true;
4265
4267 DirectiveLoc);
4268 return false;
4269}
4270
4271
4272
4273bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
4276
4277 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4278 parseAbsoluteExpression(Offset) || parseEOL())
4279 return true;
4280
4281 getStreamer().emitCFIOffset(Register, Offset, DirectiveLoc);
4282 return false;
4283}
4284
4285
4286
4287bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
4289
4290 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4291 parseAbsoluteExpression(Offset) || parseEOL())
4292 return true;
4293
4294 getStreamer().emitCFIRelOffset(Register, Offset, DirectiveLoc);
4295 return false;
4296}
4297
4299 if (Encoding & ~0xff)
4300 return false;
4301
4303 return true;
4304
4305 const unsigned Format = Encoding & 0xf;
4310 return false;
4311
4312 const unsigned Application = Encoding & 0x70;
4315 return false;
4316
4317 return true;
4318}
4319
4320
4321
4322
4323
4324bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
4325 int64_t Encoding = 0;
4326 if (parseAbsoluteExpression(Encoding))
4327 return true;
4329 return false;
4330
4332 if (check((Encoding), "unsupported encoding.") ||
4333 parseComma() ||
4334 check(parseSymbol(Sym), "expected identifier in directive") || parseEOL())
4335 return true;
4336
4337 if (IsPersonality)
4338 getStreamer().emitCFIPersonality(Sym, Encoding);
4339 else
4340 getStreamer().emitCFILsda(Sym, Encoding);
4341 return false;
4342}
4343
4344
4345
4346bool AsmParser::parseDirectiveCFIRememberState(SMLoc DirectiveLoc) {
4347 if (parseEOL())
4348 return true;
4349 getStreamer().emitCFIRememberState(DirectiveLoc);
4350 return false;
4351}
4352
4353
4354
4355bool AsmParser::parseDirectiveCFIRestoreState(SMLoc DirectiveLoc) {
4356 if (parseEOL())
4357 return true;
4358 getStreamer().emitCFIRestoreState(DirectiveLoc);
4359 return false;
4360}
4361
4362
4363
4364bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
4366
4367 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4368 return true;
4369
4370 getStreamer().emitCFISameValue(Register, DirectiveLoc);
4371 return false;
4372}
4373
4374
4375
4376bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
4378 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4379 return true;
4380
4381 getStreamer().emitCFIRestore(Register, DirectiveLoc);
4382 return false;
4383}
4384
4385
4386
4387bool AsmParser::parseDirectiveCFIEscape(SMLoc DirectiveLoc) {
4388 std::string Values;
4389 int64_t CurrValue;
4390 if (parseAbsoluteExpression(CurrValue))
4391 return true;
4392
4393 Values.push_back((uint8_t)CurrValue);
4394
4396 Lex();
4397
4398 if (parseAbsoluteExpression(CurrValue))
4399 return true;
4400
4401 Values.push_back((uint8_t)CurrValue);
4402 }
4403
4404 getStreamer().emitCFIEscape(Values, DirectiveLoc);
4405 return false;
4406}
4407
4408
4409
4410bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4412 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4413 return true;
4414 getStreamer().emitCFIReturnColumn(Register);
4415 return false;
4416}
4417
4418
4419
4420bool AsmParser::parseDirectiveCFISignalFrame(SMLoc DirectiveLoc) {
4421 if (parseEOL())
4422 return true;
4423
4424 getStreamer().emitCFISignalFrame();
4425 return false;
4426}
4427
4428
4429
4430bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4432
4433 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
4434 return true;
4435
4436 getStreamer().emitCFIUndefined(Register, DirectiveLoc);
4437 return false;
4438}
4439
4440
4441
4442bool AsmParser::parseDirectiveCFILabel(SMLoc Loc) {
4443 StringRef Name;
4444 Loc = Lexer.getLoc();
4445 if (parseIdentifier(Name))
4446 return TokError("expected identifier");
4447 if (parseEOL())
4448 return true;
4449 getStreamer().emitCFILabelDirective(Loc, Name);
4450 return false;
4451}
4452
4453
4454
4455bool AsmParser::parseDirectiveCFIValOffset(SMLoc DirectiveLoc) {
4458
4459 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
4460 parseAbsoluteExpression(Offset) || parseEOL())
4461 return true;
4462
4463 getStreamer().emitCFIValOffset(Register, Offset, DirectiveLoc);
4464 return false;
4465}
4466
4467
4468
4469
4470bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
4471 if (parseEOL())
4472 return true;
4473 AltMacroMode = (Directive == ".altmacro");
4474 return false;
4475}
4476
4477
4478
4479
4480bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
4481 if (parseEOL())
4482 return true;
4483 setMacrosEnabled(Directive == ".macros_on");
4484 return false;
4485}
4486
4487
4488
4489bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4490 StringRef Name;
4491 if (parseIdentifier(Name))
4492 return TokError("expected identifier in '.macro' directive");
4493
4495 Lex();
4496
4499
4501 return Error(Lexer.getLoc(), "vararg parameter '" +
4503 "' should be the last parameter");
4504
4506 if (parseIdentifier(Parameter.Name))
4507 return TokError("expected identifier in '.macro' directive");
4508
4509
4510 for (const MCAsmMacroParameter& CurrParam : Parameters)
4511 if (CurrParam.Name == Parameter.Name)
4512 return TokError("macro '" + Name + "' has multiple parameters"
4513 " named '" + Parameter.Name + "'");
4514
4516 Lex();
4517
4518 SMLoc QualLoc;
4520
4521 QualLoc = Lexer.getLoc();
4522 if (parseIdentifier(Qualifier))
4523 return Error(QualLoc, "missing parameter qualifier for "
4524 "'" + Parameter.Name + "' in macro '" + Name + "'");
4525
4526 if (Qualifier == "req")
4528 else if (Qualifier == "vararg")
4530 else
4531 return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
4532 "for '" + Parameter.Name + "' in macro '" + Name + "'");
4533 }
4534
4536 Lex();
4537
4538 SMLoc ParamLoc;
4539
4540 ParamLoc = Lexer.getLoc();
4541 if (parseMacroArgument(Parameter.Value, false ))
4542 return true;
4543
4545 Warning(ParamLoc, "pointless default value for required parameter "
4546 "'" + Parameter.Name + "' in macro '" + Name + "'");
4547 }
4548
4549 Parameters.push_back(std::move(Parameter));
4550
4552 Lex();
4553 }
4554
4555
4556 Lexer.Lex();
4557
4558
4559 AsmToken EndToken, StartToken = getTok();
4560 unsigned MacroDepth = 0;
4561
4562 while (true) {
4563
4565 Lexer.Lex();
4566 }
4567
4568
4570 return Error(DirectiveLoc, "no matching '.endmacro' in definition");
4571
4572
4573
4575 if (getTok().getIdentifier() == ".endm" ||
4576 getTok().getIdentifier() == ".endmacro") {
4577 if (MacroDepth == 0) {
4578 EndToken = getTok();
4579 Lexer.Lex();
4581 return TokError("unexpected token in '" + EndToken.getIdentifier() +
4582 "' directive");
4583 break;
4584 } else {
4585
4586 --MacroDepth;
4587 }
4588 } else if (getTok().getIdentifier() == ".macro") {
4589
4590
4591 ++MacroDepth;
4592 }
4594 (void)parseCppHashLineFilenameComment(getLexer().getLoc());
4595 }
4596
4597
4598 eatToEndOfStatement();
4599 }
4600
4601 if (getContext().lookupMacro(Name)) {
4602 return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
4603 }
4604
4607 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
4608 checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4609 MCAsmMacro Macro(Name, Body, std::move(Parameters));
4613 return false;
4614}
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
4631 StringRef Body,
4633
4634
4635 unsigned NParameters = Parameters.size();
4636 if (NParameters == 0)
4637 return;
4638
4639 bool NamedParametersFound = false;
4640 bool PositionalParametersFound = false;
4641
4642
4643
4644
4645 while (!Body.empty()) {
4646
4647 std::size_t End = Body.size(), Pos = 0;
4648 for (; Pos != End; ++Pos) {
4649
4650
4651 if (Body[Pos] == '\\' && Pos + 1 != End)
4652 break;
4653
4654
4655 if (Body[Pos] != '$' || Pos + 1 == End)
4656 continue;
4657 char Next = Body[Pos + 1];
4658 if (Next == '$' || Next == 'n' ||
4659 isdigit(static_cast<unsigned char>(Next)))
4660 break;
4661 }
4662
4663
4664 if (Pos == End)
4665 break;
4666
4667 if (Body[Pos] == '$') {
4668 switch (Body[Pos + 1]) {
4669
4670 case '$':
4671 break;
4672
4673
4674 case 'n':
4675 PositionalParametersFound = true;
4676 break;
4677
4678
4679 default: {
4680 PositionalParametersFound = true;
4681 break;
4682 }
4683 }
4684 Pos += 2;
4685 } else {
4686 unsigned I = Pos + 1;
4688 ++I;
4689
4690 const char *Begin = Body.data() + Pos + 1;
4691 StringRef Argument(Begin, I - (Pos + 1));
4692 unsigned Index = 0;
4693 for (; Index < NParameters; ++Index)
4694 if (Parameters[Index].Name == Argument)
4695 break;
4696
4697 if (Index == NParameters) {
4698 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
4699 Pos += 3;
4700 else {
4701 Pos = I;
4702 }
4703 } else {
4704 NamedParametersFound = true;
4706 }
4707 }
4708
4709 Body = Body.substr(Pos);
4710 }
4711
4712 if (!NamedParametersFound && PositionalParametersFound)
4713 Warning(DirectiveLoc, "macro defined with named parameters which are not "
4714 "used in macro body, possible positional parameter "
4715 "found in body which will have no effect");
4716}
4717
4718
4719
4720bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
4721 if (parseEOL())
4722 return true;
4723
4724 if (!isInsideMacroInstantiation())
4725 return TokError("unexpected '" + Directive + "' in file, "
4726 "no current macro definition");
4727
4728
4729 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4730 TheCondState = TheCondStack.back();
4731 TheCondStack.pop_back();
4732 }
4733
4734 handleMacroExit();
4735 return false;
4736}
4737
4738
4739
4740
4741bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
4743 return TokError("unexpected token in '" + Directive + "' directive");
4744
4745
4746
4747 if (isInsideMacroInstantiation()) {
4748 handleMacroExit();
4749 return false;
4750 }
4751
4752
4753
4754 return TokError("unexpected '" + Directive + "' in file, "
4755 "no current macro definition");
4756}
4757
4758
4759
4760bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4761 StringRef Name;
4762 SMLoc Loc;
4763 if (parseTokenLoc(Loc) ||
4764 check(parseIdentifier(Name), Loc,
4765 "expected identifier in '.purgem' directive") ||
4766 parseEOL())
4767 return true;
4768
4769 if (().lookupMacro(Name))
4770 return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
4771
4774 << "Un-defining macro: " << Name << "\n");
4775 return false;
4776}
4777
4778
4779
4780bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
4781 SMLoc NumBytesLoc = Lexer.getLoc();
4782 const MCExpr *NumBytes;
4783 if (checkForValidSection() || parseExpression(NumBytes))
4784 return true;
4785
4786 int64_t FillExpr = 0;
4788 if (parseAbsoluteExpression(FillExpr))
4789 return true;
4790 if (parseEOL())
4791 return true;
4792
4793
4794 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4795
4796 return false;
4797}
4798
4799
4800
4801bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
4802 SMLoc NumValuesLoc = Lexer.getLoc();
4803 int64_t NumValues;
4804 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4805 return true;
4806
4807 if (NumValues < 0) {
4808 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4809 return false;
4810 }
4811
4812 if (parseComma())
4813 return true;
4814
4815 const MCExpr *Value;
4816 SMLoc ExprLoc = getLexer().getLoc();
4817 if (parseExpression(Value))
4818 return true;
4819
4820
4822 assert(Size <= 8 && "Invalid size");
4823 uint64_t IntValue = MCE->getValue();
4825 return Error(ExprLoc, "literal value out of range for directive");
4826 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4827 getStreamer().emitIntValue(IntValue, Size);
4828 } else {
4829 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4830 getStreamer().emitValue(Value, Size, ExprLoc);
4831 }
4832
4833 return parseEOL();
4834}
4835
4836
4837
4838bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
4839 SMLoc NumValuesLoc = Lexer.getLoc();
4840 int64_t NumValues;
4841 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4842 return true;
4843
4844 if (NumValues < 0) {
4845 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4846 return false;
4847 }
4848
4849 if (parseComma())
4850 return true;
4851
4852 APInt AsInt;
4853 if (parseRealValue(Semantics, AsInt) || parseEOL())
4854 return true;
4855
4856 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4859
4860 return false;
4861}
4862
4863
4864
4865bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
4866 SMLoc NumValuesLoc = Lexer.getLoc();
4867 int64_t NumValues;
4868 if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
4869 parseEOL())
4870 return true;
4871
4872 if (NumValues < 0) {
4873 Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4874 return false;
4875 }
4876
4877 for (uint64_t i = 0, e = NumValues; i != e; ++i)
4878 getStreamer().emitFill(Size, 0);
4879
4880 return false;
4881}
4882
4883
4884
4885bool AsmParser::parseDirectiveLEB128(bool Signed) {
4886 if (checkForValidSection())
4887 return true;
4888
4889 auto parseOp = [&]() -> bool {
4890 const MCExpr *Value;
4891 if (parseExpression(Value))
4892 return true;
4894 getStreamer().emitSLEB128Value(Value);
4895 else
4896 getStreamer().emitULEB128Value(Value);
4897 return false;
4898 };
4899
4900 return parseMany(parseOp);
4901}
4902
4903
4904
4905bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
4906 auto parseOp = [&]() -> bool {
4907 StringRef Name;
4908 SMLoc Loc = getTok().getLoc();
4909 if (parseIdentifier(Name))
4910 return Error(Loc, "expected identifier");
4911
4912 if (discardLTOSymbol(Name))
4913 return false;
4914
4916
4917
4918
4920 return Error(Loc, "non-local symbol required");
4921
4922 if (!getStreamer().emitSymbolAttribute(Sym, Attr))
4923 return Error(Loc, "unable to emit symbol attribute");
4924 return false;
4925 };
4926
4927 return parseMany(parseOp);
4928}
4929
4930
4931
4932bool AsmParser::parseDirectiveComm(bool IsLocal) {
4933 if (checkForValidSection())
4934 return true;
4935
4936 SMLoc IDLoc = getLexer().getLoc();
4939 return TokError("expected identifier in directive");
4940
4941 if (parseComma())
4942 return true;
4943
4944 int64_t Size;
4945 SMLoc SizeLoc = getLexer().getLoc();
4946 if (parseAbsoluteExpression(Size))
4947 return true;
4948
4949 int64_t Pow2Alignment = 0;
4950 SMLoc Pow2AlignmentLoc;
4952 Lex();
4953 Pow2AlignmentLoc = getLexer().getLoc();
4954 if (parseAbsoluteExpression(Pow2Alignment))
4955 return true;
4956
4959 return Error(Pow2AlignmentLoc, "alignment not supported on this target");
4960
4961
4965 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
4966 Pow2Alignment = Log2_64(Pow2Alignment);
4967 }
4968 }
4969
4970 if (parseEOL())
4971 return true;
4972
4973
4974
4975 if (Size < 0)
4976 return Error(SizeLoc, "size must be non-negative");
4977
4980 return Error(IDLoc, "invalid symbol redefinition");
4981
4982
4983 if (IsLocal) {
4984 getStreamer().emitLocalCommonSymbol(Sym, Size,
4985 Align(1ULL << Pow2Alignment));
4986 return false;
4987 }
4988
4989 getStreamer().emitCommonSymbol(Sym, Size, Align(1ULL << Pow2Alignment));
4990 return false;
4991}
4992
4993
4994
4995bool AsmParser::parseDirectiveAbort(SMLoc DirectiveLoc) {
4996 StringRef Str = parseStringToEndOfStatement();
4997 if (parseEOL())
4998 return true;
4999
5000 if (Str.empty())
5001 return Error(DirectiveLoc, ".abort detected. Assembly stopping");
5002
5003
5004 return Error(DirectiveLoc,
5005 ".abort '" + Str + "' detected. Assembly stopping");
5006}
5007
5008
5009
5010bool AsmParser::parseDirectiveInclude() {
5011
5013 SMLoc IncludeLoc = getTok().getLoc();
5014
5016 "expected string in '.include' directive") ||
5017 parseEscapedString(Filename) ||
5019 "unexpected token in '.include' directive") ||
5020
5021
5022 check(enterIncludeFile(Filename), IncludeLoc,
5023 "Could not find include file '" + Filename + "'"))
5024 return true;
5025
5026 return false;
5027}
5028
5029
5030
5031bool AsmParser::parseDirectiveIncbin() {
5032
5034 SMLoc IncbinLoc = getTok().getLoc();
5036 "expected string in '.incbin' directive") ||
5037 parseEscapedString(Filename))
5038 return true;
5039
5040 int64_t Skip = 0;
5041 const MCExpr *Count = nullptr;
5042 SMLoc SkipLoc, CountLoc;
5044
5045
5047 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
5048 return true;
5049 }
5051 CountLoc = getTok().getLoc();
5052 if (parseExpression(Count))
5053 return true;
5054 }
5055 }
5056
5057 if (parseEOL())
5058 return true;
5059
5060 if (check(Skip < 0, SkipLoc, "skip is negative"))
5061 return true;
5062
5063
5064 if (processIncbinFile(Filename, Skip, Count, CountLoc))
5065 return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
5066 return false;
5067}
5068
5069
5070
5071bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
5072 TheCondStack.push_back(TheCondState);
5074 if (TheCondState.Ignore) {
5075 eatToEndOfStatement();
5076 } else {
5077 int64_t ExprValue;
5078 if (parseAbsoluteExpression(ExprValue) || parseEOL())
5079 return true;
5080
5081 switch (DirKind) {
5082 default:
5084 case DK_IF:
5085 case DK_IFNE:
5086 break;
5087 case DK_IFEQ:
5088 ExprValue = ExprValue == 0;
5089 break;
5090 case DK_IFGE:
5091 ExprValue = ExprValue >= 0;
5092 break;
5093 case DK_IFGT:
5094 ExprValue = ExprValue > 0;
5095 break;
5096 case DK_IFLE:
5097 ExprValue = ExprValue <= 0;
5098 break;
5099 case DK_IFLT:
5100 ExprValue = ExprValue < 0;
5101 break;
5102 }
5103
5104 TheCondState.CondMet = ExprValue;
5106 }
5107
5108 return false;
5109}
5110
5111
5112
5113bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5114 TheCondStack.push_back(TheCondState);
5116
5117 if (TheCondState.Ignore) {
5118 eatToEndOfStatement();
5119 } else {
5120 StringRef Str = parseStringToEndOfStatement();
5121
5122 if (parseEOL())
5123 return true;
5124
5125 TheCondState.CondMet = ExpectBlank == Str.empty();
5127 }
5128
5129 return false;
5130}
5131
5132
5133
5134
5135bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
5136 TheCondStack.push_back(TheCondState);
5138
5139 if (TheCondState.Ignore) {
5140 eatToEndOfStatement();
5141 } else {
5142 StringRef Str1 = parseStringToComma();
5143
5144 if (parseComma())
5145 return true;
5146
5147 StringRef Str2 = parseStringToEndOfStatement();
5148
5149 if (parseEOL())
5150 return true;
5151
5152 TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
5154 }
5155
5156 return false;
5157}
5158
5159
5160
5161bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
5162 TheCondStack.push_back(TheCondState);
5164
5165 if (TheCondState.Ignore) {
5166 eatToEndOfStatement();
5167 } else {
5169 if (ExpectEqual)
5170 return TokError("expected string parameter for '.ifeqs' directive");
5171 return TokError("expected string parameter for '.ifnes' directive");
5172 }
5173
5174 StringRef String1 = getTok().getStringContents();
5175 Lex();
5176
5178 if (ExpectEqual)
5179 return TokError(
5180 "expected comma after first string for '.ifeqs' directive");
5181 return TokError(
5182 "expected comma after first string for '.ifnes' directive");
5183 }
5184
5185 Lex();
5186
5188 if (ExpectEqual)
5189 return TokError("expected string parameter for '.ifeqs' directive");
5190 return TokError("expected string parameter for '.ifnes' directive");
5191 }
5192
5193 StringRef String2 = getTok().getStringContents();
5194 Lex();
5195
5196 TheCondState.CondMet = ExpectEqual == (String1 == String2);
5198 }
5199
5200 return false;
5201}
5202
5203
5204
5205bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
5206 StringRef Name;
5207 TheCondStack.push_back(TheCondState);
5209
5210 if (TheCondState.Ignore) {
5211 eatToEndOfStatement();
5212 } else {
5213 if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
5214 parseEOL())
5215 return true;
5216
5218
5219 if (expect_defined)
5221 else
5224 }
5225
5226 return false;
5227}
5228
5229
5230
5231bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
5234 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5235 " .if or an .elseif");
5237
5238 bool LastIgnoreState = false;
5239 if (!TheCondStack.empty())
5240 LastIgnoreState = TheCondStack.back().Ignore;
5241 if (LastIgnoreState || TheCondState.CondMet) {
5242 TheCondState.Ignore = true;
5243 eatToEndOfStatement();
5244 } else {
5245 int64_t ExprValue;
5246 if (parseAbsoluteExpression(ExprValue))
5247 return true;
5248
5249 if (parseEOL())
5250 return true;
5251
5252 TheCondState.CondMet = ExprValue;
5254 }
5255
5256 return false;
5257}
5258
5259
5260
5261bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5262 if (parseEOL())
5263 return true;
5264
5267 return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
5268 " an .if or an .elseif");
5270 bool LastIgnoreState = false;
5271 if (!TheCondStack.empty())
5272 LastIgnoreState = TheCondStack.back().Ignore;
5273 if (LastIgnoreState || TheCondState.CondMet)
5274 TheCondState.Ignore = true;
5275 else
5276 TheCondState.Ignore = false;
5277
5278 return false;
5279}
5280
5281
5282
5283bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5284 if (parseEOL())
5285 return true;
5286
5288 Lexer.Lex();
5289
5290 return false;
5291}
5292
5293
5294
5295
5296bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
5297 if (!TheCondStack.empty()) {
5298 if (TheCondStack.back().Ignore) {
5299 eatToEndOfStatement();
5300 return false;
5301 }
5302 }
5303
5304 if (!WithMessage)
5305 return Error(L, ".err encountered");
5306
5307 StringRef Message = ".error directive invoked in source file";
5310 return TokError(".error argument must be a string");
5311
5312 Message = getTok().getStringContents();
5313 Lex();
5314 }
5315
5316 return Error(L, Message);
5317}
5318
5319
5320
5321bool AsmParser::parseDirectiveWarning(SMLoc L) {
5322 if (!TheCondStack.empty()) {
5323 if (TheCondStack.back().Ignore) {
5324 eatToEndOfStatement();
5325 return false;
5326 }
5327 }
5328
5329 StringRef Message = ".warning directive invoked in source file";
5330
5333 return TokError(".warning argument must be a string");
5334
5335 Message = getTok().getStringContents();
5336 Lex();
5337 if (parseEOL())
5338 return true;
5339 }
5340
5341 return Warning(L, Message);
5342}
5343
5344
5345
5346bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5347 if (parseEOL())
5348 return true;
5349
5351 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
5352 "an .if or .else");
5353 if (!TheCondStack.empty()) {
5354 TheCondState = TheCondStack.back();
5355 TheCondStack.pop_back();
5356 }
5357
5358 return false;
5359}
5360
5361void AsmParser::initializeDirectiveKindMap() {
5362
5363
5364
5365
5366
5367
5368 DirectiveKindMap[".set"] = DK_SET;
5369 DirectiveKindMap[".equ"] = DK_EQU;
5370 DirectiveKindMap[".equiv"] = DK_EQUIV;
5371 DirectiveKindMap[".ascii"] = DK_ASCII;
5372 DirectiveKindMap[".asciz"] = DK_ASCIZ;
5373 DirectiveKindMap[".string"] = DK_STRING;
5374 DirectiveKindMap[".byte"] = DK_BYTE;
5375 DirectiveKindMap[".base64"] = DK_BASE64;
5376 DirectiveKindMap[".short"] = DK_SHORT;
5377 DirectiveKindMap[".value"] = DK_VALUE;
5378 DirectiveKindMap[".2byte"] = DK_2BYTE;
5379 DirectiveKindMap[".long"] = DK_LONG;
5380 DirectiveKindMap[".int"] = DK_INT;
5381 DirectiveKindMap[".4byte"] = DK_4BYTE;
5382 DirectiveKindMap[".quad"] = DK_QUAD;
5383 DirectiveKindMap[".8byte"] = DK_8BYTE;
5384 DirectiveKindMap[".octa"] = DK_OCTA;
5385 DirectiveKindMap[".single"] = DK_SINGLE;
5386 DirectiveKindMap[".float"] = DK_FLOAT;
5387 DirectiveKindMap[".double"] = DK_DOUBLE;
5388 DirectiveKindMap[".align"] = DK_ALIGN;
5389 DirectiveKindMap[".align32"] = DK_ALIGN32;
5390 DirectiveKindMap[".balign"] = DK_BALIGN;
5391 DirectiveKindMap[".balignw"] = DK_BALIGNW;
5392 DirectiveKindMap[".balignl"] = DK_BALIGNL;
5393 DirectiveKindMap[".p2align"] = DK_P2ALIGN;
5394 DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
5395 DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
5396 DirectiveKindMap[".org"] = DK_ORG;
5397 DirectiveKindMap[".fill"] = DK_FILL;
5398 DirectiveKindMap[".zero"] = DK_ZERO;
5399 DirectiveKindMap[".extern"] = DK_EXTERN;
5400 DirectiveKindMap[".globl"] = DK_GLOBL;
5401 DirectiveKindMap[".global"] = DK_GLOBAL;
5402 DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
5403 DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
5404 DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5405 DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
5406 DirectiveKindMap[".reference"] = DK_REFERENCE;
5407 DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
5408 DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
5409 DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5410 DirectiveKindMap[".cold"] = DK_COLD;
5411 DirectiveKindMap[".comm"] = DK_COMM;
5412 DirectiveKindMap[".common"] = DK_COMMON;
5413 DirectiveKindMap[".lcomm"] = DK_LCOMM;
5414 DirectiveKindMap[".abort"] = DK_ABORT;
5415 DirectiveKindMap[".include"] = DK_INCLUDE;
5416 DirectiveKindMap[".incbin"] = DK_INCBIN;
5417 DirectiveKindMap[".code16"] = DK_CODE16;
5418 DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
5419 DirectiveKindMap[".rept"] = DK_REPT;
5420 DirectiveKindMap[".rep"] = DK_REPT;
5421 DirectiveKindMap[".irp"] = DK_IRP;
5422 DirectiveKindMap[".irpc"] = DK_IRPC;
5423 DirectiveKindMap[".endr"] = DK_ENDR;
5424 DirectiveKindMap[".if"] = DK_IF;
5425 DirectiveKindMap[".ifeq"] = DK_IFEQ;
5426 DirectiveKindMap[".ifge"] = DK_IFGE;
5427 DirectiveKindMap[".ifgt"] = DK_IFGT;
5428 DirectiveKindMap[".ifle"] = DK_IFLE;
5429 DirectiveKindMap[".iflt"] = DK_IFLT;
5430 DirectiveKindMap[".ifne"] = DK_IFNE;
5431 DirectiveKindMap[".ifb"] = DK_IFB;
5432 DirectiveKindMap[".ifnb"] = DK_IFNB;
5433 DirectiveKindMap[".ifc"] = DK_IFC;
5434 DirectiveKindMap[".ifeqs"] = DK_IFEQS;
5435 DirectiveKindMap[".ifnc"] = DK_IFNC;
5436 DirectiveKindMap[".ifnes"] = DK_IFNES;
5437 DirectiveKindMap[".ifdef"] = DK_IFDEF;
5438 DirectiveKindMap[".ifndef"] = DK_IFNDEF;
5439 DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
5440 DirectiveKindMap[".elseif"] = DK_ELSEIF;
5441 DirectiveKindMap[".else"] = DK_ELSE;
5442 DirectiveKindMap[".end"] = DK_END;
5443 DirectiveKindMap[".endif"] = DK_ENDIF;
5444 DirectiveKindMap[".skip"] = DK_SKIP;
5445 DirectiveKindMap[".space"] = DK_SPACE;
5446 DirectiveKindMap[".file"] = DK_FILE;
5447 DirectiveKindMap[".line"] = DK_LINE;
5448 DirectiveKindMap[".loc"] = DK_LOC;
5449 DirectiveKindMap[".loc_label"] = DK_LOC_LABEL;
5450 DirectiveKindMap[".stabs"] = DK_STABS;
5451 DirectiveKindMap[".cv_file"] = DK_CV_FILE;
5452 DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
5453 DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
5454 DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
5455 DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5456 DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5457 DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
5458 DirectiveKindMap[".cv_string"] = DK_CV_STRING;
5459 DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
5460 DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5461 DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5462 DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
5463 DirectiveKindMap[".sleb128"] = DK_SLEB128;
5464 DirectiveKindMap[".uleb128"] = DK_ULEB128;
5465 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
5466 DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
5467 DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
5468 DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5469 DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5470 DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5471 DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5472 DirectiveKindMap[".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
5473 DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
5474 DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5475 DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
5476 DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
5477 DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5478 DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5479 DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
5480 DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
5481 DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
5482 DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5483 DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5484 DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
5485 DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
5486 DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5487 DirectiveKindMap[".cfi_label"] = DK_CFI_LABEL;
5488 DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5489 DirectiveKindMap[".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
5490 DirectiveKindMap[".cfi_val_offset"] = DK_CFI_VAL_OFFSET;
5491 DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
5492 DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
5493 DirectiveKindMap[".macro"] = DK_MACRO;
5494 DirectiveKindMap[".exitm"] = DK_EXITM;
5495 DirectiveKindMap[".endm"] = DK_ENDM;
5496 DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
5497 DirectiveKindMap[".purgem"] = DK_PURGEM;
5498 DirectiveKindMap[".err"] = DK_ERR;
5499 DirectiveKindMap[".error"] = DK_ERROR;
5500 DirectiveKindMap[".warning"] = DK_WARNING;
5501 DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
5502 DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
5503 DirectiveKindMap[".reloc"] = DK_RELOC;
5504 DirectiveKindMap[".dc"] = DK_DC;
5505 DirectiveKindMap[".dc.a"] = DK_DC_A;
5506 DirectiveKindMap[".dc.b"] = DK_DC_B;
5507 DirectiveKindMap[".dc.d"] = DK_DC_D;
5508 DirectiveKindMap[".dc.l"] = DK_DC_L;
5509 DirectiveKindMap[".dc.s"] = DK_DC_S;
5510 DirectiveKindMap[".dc.w"] = DK_DC_W;
5511 DirectiveKindMap[".dc.x"] = DK_DC_X;
5512 DirectiveKindMap[".dcb"] = DK_DCB;
5513 DirectiveKindMap[".dcb.b"] = DK_DCB_B;
5514 DirectiveKindMap[".dcb.d"] = DK_DCB_D;
5515 DirectiveKindMap[".dcb.l"] = DK_DCB_L;
5516 DirectiveKindMap[".dcb.s"] = DK_DCB_S;
5517 DirectiveKindMap[".dcb.w"] = DK_DCB_W;
5518 DirectiveKindMap[".dcb.x"] = DK_DCB_X;
5519 DirectiveKindMap[".ds"] = DK_DS;
5520 DirectiveKindMap[".ds.b"] = DK_DS_B;
5521 DirectiveKindMap[".ds.d"] = DK_DS_D;
5522 DirectiveKindMap[".ds.l"] = DK_DS_L;
5523 DirectiveKindMap[".ds.p"] = DK_DS_P;
5524 DirectiveKindMap[".ds.s"] = DK_DS_S;
5525 DirectiveKindMap[".ds.w"] = DK_DS_W;
5526 DirectiveKindMap[".ds.x"] = DK_DS_X;
5527 DirectiveKindMap[".print"] = DK_PRINT;
5528 DirectiveKindMap[".addrsig"] = DK_ADDRSIG;
5529 DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM;
5530 DirectiveKindMap[".pseudoprobe"] = DK_PSEUDO_PROBE;
5531 DirectiveKindMap[".lto_discard"] = DK_LTO_DISCARD;
5532 DirectiveKindMap[".lto_set_conditional"] = DK_LTO_SET_CONDITIONAL;
5533 DirectiveKindMap[".memtag"] = DK_MEMTAG;
5534}
5535
5536MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5537 AsmToken EndToken, StartToken = getTok();
5538
5539 unsigned NestLevel = 0;
5540 while (true) {
5541
5543 printError(DirectiveLoc, "no matching '.endr' in definition");
5544 return nullptr;
5545 }
5546
5548 StringRef Ident = getTok().getIdentifier();
5549 if (Ident == ".rep" || Ident == ".rept" || Ident == ".irp" ||
5550 Ident == ".irpc") {
5551 ++NestLevel;
5552 } else if (Ident == ".endr") {
5553 if (NestLevel == 0) {
5554 EndToken = getTok();
5555 Lex();
5557 break;
5558 printError(getTok().getLoc(), "expected newline");
5559 return nullptr;
5560 }
5561 --NestLevel;
5562 }
5563 }
5564
5565
5566 eatToEndOfStatement();
5567 }
5568
5571 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5572
5573
5575 return &MacroLikeBodies.back();
5576}
5577
5578void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5579 raw_svector_ostream &OS) {
5580 OS << ".endr\n";
5581
5582 std::unique_ptr Instantiation =
5584
5585
5586
5587 MacroInstantiation *MI = new MacroInstantiation{
5588 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5589 ActiveMacros.push_back(MI);
5590
5591
5594 Lex();
5595}
5596
5597
5598
5599bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5600 const MCExpr *CountExpr;
5601 SMLoc CountLoc = getTok().getLoc();
5602 if (parseExpression(CountExpr))
5603 return true;
5604
5606 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5607 return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
5608 }
5609
5610 if (check(Count < 0, CountLoc, "Count is negative") || parseEOL())
5611 return true;
5612
5613
5614 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5615 if (!M)
5616 return true;
5617
5618
5619
5620 SmallString<256> Buf;
5621 raw_svector_ostream OS(Buf);
5622 while (Count--) {
5623
5624 if (expandMacro(OS, *M, {}, {}, false))
5625 return true;
5626 }
5627 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5628
5629 return false;
5630}
5631
5632
5633
5634bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5636 MCAsmMacroArguments A;
5637 if (check(parseIdentifier(Parameter.Name),
5638 "expected identifier in '.irp' directive") ||
5639 parseComma() || parseMacroArguments(nullptr, A) || parseEOL())
5640 return true;
5641
5642
5643 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5644 if (!M)
5645 return true;
5646
5647
5648
5649 SmallString<256> Buf;
5650 raw_svector_ostream OS(Buf);
5651
5652 for (const MCAsmMacroArgument &Arg : A) {
5653
5654
5655 if (expandMacro(OS, *M, Parameter, Arg, true))
5656 return true;
5657 }
5658
5659 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5660
5661 return false;
5662}
5663
5664
5665
5666bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5668 MCAsmMacroArguments A;
5669
5670 if (check(parseIdentifier(Parameter.Name),
5671 "expected identifier in '.irpc' directive") ||
5672 parseComma() || parseMacroArguments(nullptr, A))
5673 return true;
5674
5675 if (A.size() != 1 || A.front().size() != 1)
5676 return TokError("unexpected token in '.irpc' directive");
5677 if (parseEOL())
5678 return true;
5679
5680
5681 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5682 if (!M)
5683 return true;
5684
5685
5686
5687 SmallString<256> Buf;
5688 raw_svector_ostream OS(Buf);
5689
5690 StringRef Values = A[0][0].is(AsmToken::String) ? A[0][0].getStringContents()
5691 : A[0][0].getString();
5692 for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
5693 MCAsmMacroArgument Arg;
5695
5696
5697
5698 if (expandMacro(OS, *M, Parameter, Arg, true))
5699 return true;
5700 }
5701
5702 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5703
5704 return false;
5705}
5706
5707bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5708 if (ActiveMacros.empty())
5709 return TokError("unmatched '.endr' directive");
5710
5711
5712
5714
5715 handleMacroExit();
5716 return false;
5717}
5718
5719bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5720 size_t Len) {
5721 const MCExpr *Value;
5722 SMLoc ExprLoc = getLexer().getLoc();
5723 if (parseExpression(Value))
5724 return true;
5726 if (!MCE)
5727 return Error(ExprLoc, "unexpected expression in _emit");
5728 uint64_t IntValue = MCE->getValue();
5730 return Error(ExprLoc, "literal value out of range for directive");
5731
5732 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
5733 return false;
5734}
5735
5736bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5737 const MCExpr *Value;
5738 SMLoc ExprLoc = getLexer().getLoc();
5739 if (parseExpression(Value))
5740 return true;
5742 if (!MCE)
5743 return Error(ExprLoc, "unexpected expression in align");
5744 uint64_t IntValue = MCE->getValue();
5746 return Error(ExprLoc, "literal value not a power of two greater then zero");
5747
5749 return false;
5750}
5751
5752bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
5753 const AsmToken StrTok = getTok();
5754 Lex();
5756 return Error(DirectiveLoc, "expected double quoted string after .print");
5757 if (parseEOL())
5758 return true;
5760 return false;
5761}
5762
5763bool AsmParser::parseDirectiveAddrsig() {
5764 if (parseEOL())
5765 return true;
5766 getStreamer().emitAddrsig();
5767 return false;
5768}
5769
5770bool AsmParser::parseDirectiveAddrsigSym() {
5772 if (check(parseSymbol(Sym), "expected identifier") || parseEOL())
5773 return true;
5774 getStreamer().emitAddrsigSym(Sym);
5775 return false;
5776}
5777
5778bool AsmParser::parseDirectivePseudoProbe() {
5779 int64_t Guid;
5781 int64_t Type;
5782 int64_t Attr;
5784 if (parseIntToken(Guid))
5785 return true;
5786 if (parseIntToken(Index))
5787 return true;
5788 if (parseIntToken(Type))
5789 return true;
5790 if (parseIntToken(Attr))
5791 return true;
5793 return true;
5794
5795
5797
5799
5800 Lex();
5801
5802 int64_t CallerGuid = 0;
5804 CallerGuid = getTok().getIntVal();
5805 Lex();
5806 }
5807
5808
5810 Lex();
5811
5812 int64_t CallerProbeId = 0;
5814 CallerProbeId = getTok().getIntVal();
5815 Lex();
5816 }
5817
5818 InlineSite Site(CallerGuid, CallerProbeId);
5820 }
5821
5822
5823 StringRef FnName;
5824 if (parseIdentifier(FnName))
5825 return Error(getLexer().getLoc(), "expected identifier");
5827
5828 if (parseEOL())
5829 return true;
5830
5831 getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, Discriminator,
5832 InlineStack, FnSym);
5833 return false;
5834}
5835
5836
5837
5838
5839
5840
5841bool AsmParser::parseDirectiveLTODiscard() {
5842 auto ParseOp = [&]() -> bool {
5843 StringRef Name;
5844 SMLoc Loc = getTok().getLoc();
5845 if (parseIdentifier(Name))
5846 return Error(Loc, "expected identifier");
5847 LTODiscardSymbols.insert(Name);
5848 return false;
5849 };
5850
5851 LTODiscardSymbols.clear();
5852 return parseMany(ParseOp);
5853}
5854
5855
5856
5860 return -1;
5862 return 1;
5863
5864
5865
5866
5867
5870 return -1;
5871
5874 return 1;
5876}
5877
5878bool AsmParser::parseMSInlineAsm(
5879 std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs,
5880 SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
5881 SmallVectorImplstd::string &Constraints,
5882 SmallVectorImplstd::string &Clobbers, const MCInstrInfo *MII,
5883 MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
5884 SmallVector<void *, 4> InputDecls;
5885 SmallVector<void *, 4> OutputDecls;
5888 SmallVector<std::string, 4> InputConstraints;
5889 SmallVector<std::string, 4> OutputConstraints;
5891
5893
5894
5895 Lex();
5896
5897
5898 unsigned InputIdx = 0;
5899 unsigned OutputIdx = 0;
5901
5902 if (parseCurlyBlockScope(AsmStrRewrites))
5903 continue;
5904
5905 ParseStatementInfo Info(&AsmStrRewrites);
5906 bool StatementErr = parseStatement(Info, &SI);
5907
5908 if (StatementErr || Info.ParseError) {
5909
5910 printPendingErrors();
5911 return true;
5912 }
5913
5914
5915 assert(!hasPendingError() && "unexpected error from parseStatement");
5916
5917 if (Info.Opcode == ~0U)
5918 continue;
5919
5920 const MCInstrDesc &Desc = MII->get(Info.Opcode);
5921
5922
5923 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
5924 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
5925
5926
5928 !getTargetParser().omitRegisterFromClobberLists(Operand.getReg())) {
5929 unsigned NumDefs = Desc.getNumDefs();
5930
5933 continue;
5934 }
5935
5936
5937 StringRef SymName = Operand.getSymName();
5938 if (SymName.empty())
5939 continue;
5940
5941 void *OpDecl = Operand.getOpDecl();
5942 if (!OpDecl)
5943 continue;
5944
5946 if (Operand.isImm()) {
5947
5949 Constraint = "r";
5950 else
5951 Constraint = "i";
5952 }
5953
5954 bool isOutput = (i == 1) && Desc.mayStore();
5957 if (isOutput) {
5958 ++InputIdx;
5961 OutputConstraints.push_back(("=" + Constraint).str());
5963 Restricted);
5964 } else {
5967 InputConstraints.push_back(Constraint.str());
5968 if (Desc.operands()[i - 1].isBranchTarget())
5970 Restricted);
5971 else
5973 Restricted);
5974 }
5975 }
5976
5977
5979 }
5980
5981
5982 NumOutputs = OutputDecls.size();
5983 NumInputs = InputDecls.size();
5984
5985
5988 Clobbers.assign(ClobberRegs.size(), std::string());
5989 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
5990 raw_string_ostream OS(Clobbers[I]);
5992 }
5993
5994
5995 if (NumOutputs || NumInputs) {
5996 unsigned NumExprs = NumOutputs + NumInputs;
5997 OpDecls.resize(NumExprs);
5998 Constraints.resize(NumExprs);
5999 for (unsigned i = 0; i < NumOutputs; ++i) {
6000 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6001 Constraints[i] = OutputConstraints[i];
6002 }
6003 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
6004 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6005 Constraints[j] = InputConstraints[i];
6006 }
6007 }
6008
6009
6010 std::string AsmStringIR;
6011 raw_string_ostream OS(AsmStringIR);
6012 StringRef ASMString =
6014 const char *AsmStart = ASMString.begin();
6015 const char *AsmEnd = ASMString.end();
6017 for (auto I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) {
6018 const AsmRewrite &AR = *I;
6019
6020 if (AR.Done)
6021 continue;
6023
6025 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
6026
6027
6028 if (unsigned Len = Loc - AsmStart)
6029 OS << StringRef(AsmStart, Len);
6030
6031
6033 AsmStart = Loc + AR.Len;
6034 continue;
6035 }
6036
6037 unsigned AdditionalSkip = 0;
6038
6039 switch (Kind) {
6040 default:
6041 break;
6045 OS << "[";
6055 OS << " + ";
6056
6059 size_t OffsetLen = OffsetName.size();
6060 auto rewrite_it = std::find_if(
6061 I, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
6062 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6063 (FusingAR.Kind == AOK_Input ||
6064 FusingAR.Kind == AOK_CallInput);
6065 });
6066 if (rewrite_it == AsmStrRewrites.end()) {
6067 OS << "offset " << OffsetName;
6069 OS << "${" << InputIdx++ << ":P}";
6070 rewrite_it->Done = true;
6071 } else {
6072 OS << '$' << InputIdx++;
6073 rewrite_it->Done = true;
6074 }
6075 }
6079 OS << "]";
6080 break;
6083 break;
6086 OS << "${" << InputIdx++ << ":P}";
6087 else
6088 OS << '$' << InputIdx++;
6089 break;
6091 OS << "${" << InputIdx++ << ":P}";
6092 break;
6095 OS << "${" << OutputIdx++ << ":P}";
6096 else
6097 OS << '$' << OutputIdx++;
6098 break;
6100 switch (AR.Val) {
6101 default: break;
6102 case 8: OS << "byte ptr "; break;
6103 case 16: OS << "word ptr "; break;
6104 case 32: OS << "dword ptr "; break;
6105 case 64: OS << "qword ptr "; break;
6106 case 80: OS << "xword ptr "; break;
6107 case 128: OS << "xmmword ptr "; break;
6108 case 256: OS << "ymmword ptr "; break;
6109 }
6110 break;
6112 OS << ".byte";
6113 break;
6115
6116
6117 OS << ".align";
6118 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6119 break;
6120
6121
6122
6123 unsigned Val = AR.Val;
6124 OS << ' ' << Val;
6125 assert(Val < 10 && "Expected alignment less then 2^10.");
6126 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6127 break;
6128 }
6130 OS << ".even";
6131 break;
6133 OS << "\n\t";
6134 break;
6135 }
6136
6137
6138 AsmStart = Loc + AR.Len + AdditionalSkip;
6139 }
6140
6141
6142 if (AsmStart != AsmEnd)
6143 OS << StringRef(AsmStart, AsmEnd - AsmStart);
6144
6145 AsmString = std::move(AsmStringIR);
6146 return false;
6147}
6148
6149bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
6150 MCAsmParserSemaCallback *SI) {
6151 AsmToken LabelTok = getTok();
6152 SMLoc LabelLoc = LabelTok.getLoc();
6153 StringRef LabelVal;
6154
6155 if (parseIdentifier(LabelVal))
6156 return Error(LabelLoc, "The HLASM Label has to be an Identifier");
6157
6158
6159
6160
6161 if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
6162 return true;
6163
6164
6165 lexLeadingSpaces();
6166
6167
6168
6170 return Error(LabelLoc,
6171 "Cannot have just a label for an HLASM inline asm statement");
6172
6174 getContext().getAsmInfo()->isHLASM() ? LabelVal.upper() : LabelVal);
6175
6176
6178
6179
6180
6181 if (enabledGenDwarfForAssembly())
6183 LabelLoc);
6184
6185 return false;
6186}
6187
6188bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
6189 MCAsmParserSemaCallback *SI) {
6190 AsmToken OperationEntryTok = Lexer.getTok();
6191 SMLoc OperationEntryLoc = OperationEntryTok.getLoc();
6192 StringRef OperationEntryVal;
6193
6194
6195 if (parseIdentifier(OperationEntryVal))
6196 return Error(OperationEntryLoc, "unexpected token at start of statement");
6197
6198
6199
6200 lexLeadingSpaces();
6201
6202 return parseAndMatchAndEmitTargetInstruction(
6203 Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
6204}
6205
6206bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
6207 MCAsmParserSemaCallback *SI) {
6208 assert(!hasPendingError() && "parseStatement started with pending error");
6209
6210
6211 bool ShouldParseAsHLASMLabel = false;
6212
6213
6214
6215
6216
6217
6218
6220 ShouldParseAsHLASMLabel = true;
6221
6222
6223
6225
6226 if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
6227 getTok().getString().front() == '\n')
6229 Lex();
6230 return false;
6231 }
6232
6233
6234
6235
6236 lexLeadingSpaces();
6237
6238
6239
6240
6242 if (getTok().getString().front() == '\n' ||
6243 getTok().getString().front() == '\r') {
6245 Lex();
6246 return false;
6247 }
6248 }
6249
6250
6251
6252 if (ShouldParseAsHLASMLabel) {
6253
6254
6255 if (parseAsHLASMLabel(Info, SI)) {
6256
6257
6258 eatToEndOfStatement();
6259 return true;
6260 }
6261 }
6262
6263 return parseAsMachineInstruction(Info, SI);
6264}
6265
6267 bool allow_redef,
6271
6272
6275 return Parser.TokError("missing expression");
6277 return true;
6278
6279
6281 return Parser.Error(
6282 EqualLoc, "relocation specifier not permitted in symbol equating");
6283
6284
6285
6287 if (Sym) {
6290 return Parser.Error(EqualLoc, "redefinition of '" + Name + "'");
6291
6292
6293
6296 } else if (Name == ".") {
6298 return false;
6299 } else
6301
6303
6304 return false;
6305}
6306
6307
6310 unsigned CB) {
6311 if (C.getTargetTriple().isSystemZ() && C.getTargetTriple().isOSzOS())
6312 return new HLASMAsmParser(SM, C, Out, MAI, CB);
6313
6314 return new AsmParser(SM, C, Out, MAI, CB);
6315}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
Definition AsmParser.cpp:4298
static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc)
This function checks if the next token is type or arithmetic.
Definition AsmParser.cpp:1389
static unsigned getDarwinBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)
Definition AsmParser.cpp:1499
static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI, AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)
Definition AsmParser.cpp:1575
static std::string angleBracketString(StringRef AltMacroStr)
creating a string without the escape characters '!'.
Definition AsmParser.cpp:1407
static int rewritesSort(const AsmRewrite *AsmRewriteA, const AsmRewrite *AsmRewriteB)
Definition AsmParser.cpp:5857
static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo)
Definition AsmParser.cpp:3163
static bool isOperator(AsmToken::TokenKind kind)
Definition AsmParser.cpp:2557
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
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
static bool isIdentifierChar(char C)
Return true if the given character satisfies the following regular expression: [-a-zA-Z$....
Promote Memory to Register
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_>.
This file defines the SmallSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)
Factory for NaN values.
Class for arbitrary precision integers.
LLVM_ABI APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI 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.
ConditionalAssemblyType TheCond
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool getAllowAtInIdentifier()
void UnLex(AsmToken const &Token)
AsmToken::TokenKind getKind() const
Get the kind of current token.
const MCAsmInfo & getMAI() const
const AsmToken & getTok() const
Get the current (last) lexed token.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
SMLoc getErrLoc()
Get the current error location.
const std::string & getErr()
Get the current error string.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
void setSkipSpace(bool val)
Set whether spaces should be ignored by the lexer.
LLVM_ABI void setBuffer(StringRef Buf, const char *ptr=nullptr, bool EndStatementAtEOF=true)
Set buffer to be lexed.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)
Look ahead an arbitrary number of tokens.
LLVM_ABI SMLoc getLoc() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
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 preserveAsmComments() const
Return true if assembly (inline or otherwise) should be parsed.
bool isLittleEndian() const
True if the target is little endian.
bool useAtForSpecifier() const
bool doesAllowAtInName() const
StringRef getPrivateLabelPrefix() const
std::optional< uint32_t > getSpecifierForName(StringRef Name) const
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
bool shouldUseLogicalShr() const
StringRef getCommentString() const
bool hasSubsectionsViaSymbols() const
bool getCOMMDirectiveAlignmentIsInBytes() const
virtual bool useCodeAlign(const MCSection &Sec) const
bool useParensForSpecifier() const
bool getDollarIsPC() const
virtual ~MCAsmParserSemaCallback()
Generic assembler parser interface, for use by target specific assembly parsers.
bool Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
bool parseAtSpecifier(const MCExpr *&Res, SMLoc &EndLoc)
Definition AsmParser.cpp:1417
const AsmToken & getTok() const
Get the current AsmToken from the stream.
const MCExpr * applySpecifier(const MCExpr *E, uint32_t Variant)
Definition AsmParser.cpp:1321
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
MCStreamer & getStreamer()
MCTargetAsmParser & getTargetParser() const
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 LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ AShr
Arithmetic shift right.
@ LShr
Logical shift right.
@ GTE
Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).
@ GT
Signed greater than comparison (result is either 0 or some target-specific non-zero value)
@ Xor
Bitwise exclusive or.
@ LT
Signed less than comparison (result is either 0 or some target-specific non-zero value).
@ LTE
Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).
@ NE
Inequality comparison.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
void * allocate(unsigned Size, unsigned Align=8)
bool isDwarfMD5UsageConsistent(unsigned CUID) const
Reports whether MD5 checksum usage is consistent (all-or-none).
LLVM_ABI 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)
LLVM_ABI MCSymbol * lookupSymbol(const Twine &Name) const
Get the symbol for Name, or null.
LLVM_ABI 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
LLVM_ABI MCSymbol * cloneSymbol(MCSymbol &Sym)
Clone a symbol for the .set directive, replacing it in the symbol table.
LLVM_ABI MCSymbol * parseSymbol(const Twine &Name)
Variant of getOrCreateSymbol that handles backslash-escaped symbols.
LLVM_ABI 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.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
static LLVM_ABI void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
virtual void printRegName(raw_ostream &OS, MCRegister Reg)
Print the assembler register name.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
virtual bool 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?
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()
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.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
bool isRedefinable() const
Check if this symbol is redefinable.
void setRedefinable(bool Value)
Mark this symbol as redefinable.
void redefineIfPossible()
Prepare this symbol to be redefined.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static LLVM_ABI 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())
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
StringRef getBuffer() const
constexpr bool isFailure() const
constexpr bool isSuccess() const
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
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
unsigned getMainFileID() const
const MemoryBuffer * getMemoryBuffer(unsigned i) const
LLVM_ABI void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
SMLoc getParentIncludeLoc(unsigned i) const
LLVM_ABI void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
LLVM_ABI unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
LLVM_ABI unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
StringMapIterBase< ValueTy, true > const_iterator
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.
LLVM_ABI 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.
LLVM_ABI std::string lower() const
LLVM_ABI int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
LLVM Value Representation.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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.
Definition AsmParser.cpp:6266
LLVM_ABI SimpleSymbol parseSymbol(StringRef SymName)
Get symbol classification by parsing the name of a symbol.
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
@ Parameter
An inlay hint that is for a parameter.
Context & getContext() const
LLVM_ABI Instruction & front() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation. The return string is half the size of ...
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
unsigned hexDigitValue(char C)
Interpret the given character C as a hexadecimal digit and return its value.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
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 isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
std::vector< MCAsmMacroParameter > MCAsmMacroParameters
auto unique(Range &&R, Predicate P)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
auto reverse(ContainerTy &&C)
cl::opt< unsigned > AsmMacroMaxNestingDepth
SmallVector< InlineSite, 8 > MCPseudoProbeInlineStack
const char AsmRewritePrecedence[]
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool hasDiscriminator(uint32_t Flags)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
LLVM_ABI llvm::Error decodeBase64(llvm::StringRef Input, std::vector< char > &Output)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance for parsing assembly similar to gas syntax.
Definition AsmParser.cpp:6308
FunctionAddr VTableAddr uintptr_t uintptr_t Data
@ Sub
Subtraction of integers.
FunctionAddr VTableAddr Next
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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
bool isHexDigit(char C)
Checks if character C is a hexadecimal numeric character.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
void consumeError(Error Err)
Consume a Error without doing anything.
@ 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)
std::vector< AsmToken > Value
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
std::optional< StringRef > Source
The source code of the file.