81typedef std::vector<AsmToken> MCAsmMacroArgument;
82typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
86struct MacroInstantiation {
88 SMLoc InstantiationLoc;
97 size_t CondStackDepth;
100struct ParseStatementInfo {
105 unsigned Opcode = ~0
U;
108 bool ParseError =
false;
110 SmallVectorImpl<AsmRewrite> *AsmRewrites =
nullptr;
112 ParseStatementInfo() =
delete;
113 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
114 : AsmRewrites(rewrites) {}
121 void *SavedDiagContext;
122 std::unique_ptr<MCAsmParserExtension> PlatformParser;
123 std::unique_ptr<MCAsmParserExtension> LFIParser;
125 std::optional<SMLoc> CFIStartProcLoc;
131 AsmCond TheCondState;
132 std::vector<AsmCond> TheCondStack;
137 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
140 std::vector<MacroInstantiation*> ActiveMacros;
143 std::deque<MCAsmMacro> MacroLikeBodies;
146 unsigned MacrosEnabledFlag : 1;
149 unsigned NumOfMacroInstantiations = 0;
152 struct CppHashInfoTy {
157 CppHashInfoTy() : LineNumber(0), Buf(0) {}
159 CppHashInfoTy CppHashInfo;
162 bool HadCppHashFilename =
false;
167 SmallSet<StringRef, 2> LTODiscardSymbols;
170 unsigned AssemblerDialect = ~0
U;
173 bool IsDarwin =
false;
176 bool ParsingMSInlineAsm =
false;
179 bool ReportedInconsistentMD5 =
false;
182 bool AltMacroMode =
false;
185 virtual bool parseStatement(ParseStatementInfo &Info,
186 MCAsmParserSemaCallback *SI);
191 bool parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
192 StringRef IDVal, AsmToken ID,
198 bool enabledGenDwarfForAssembly();
201 AsmParser(SourceMgr &
SM, MCContext &Ctx, MCStreamer &Out,
202 const MCAsmInfo &MAI,
unsigned CB);
203 AsmParser(
const AsmParser &) =
delete;
204 AsmParser &operator=(
const AsmParser &) =
delete;
205 ~AsmParser()
override;
207 bool Run(
bool NoInitialTextSection,
bool NoFinalize =
false)
override;
209 void addDirectiveHandler(StringRef Directive,
210 ExtensionDirectiveHandler Handler)
override {
211 ExtensionDirectiveMap[Directive] = std::move(Handler);
214 void addAliasForDirective(StringRef Directive, StringRef Alias)
override {
215 DirectiveKindMap[Directive.
lower()] = DirectiveKindMap[Alias.
lower()];
221 CodeViewContext &getCVContext() {
return Ctx.getCVContext(); }
223 unsigned getAssemblerDialect()
override {
224 if (AssemblerDialect == ~0U)
225 return MAI.getAssemblerDialect();
227 return AssemblerDialect;
229 void setAssemblerDialect(
unsigned i)
override {
230 AssemblerDialect = i;
233 void Note(SMLoc L,
const Twine &
Msg, SMRange
Range = {})
override;
235 bool printError(SMLoc L,
const Twine &
Msg, SMRange
Range = {})
override;
237 const AsmToken &Lex()
override;
239 void setParsingMSInlineAsm(
bool V)
override {
240 ParsingMSInlineAsm =
V;
243 Lexer.setLexMasmIntegers(V);
245 bool isParsingMSInlineAsm()
override {
return ParsingMSInlineAsm; }
247 bool discardLTOSymbol(StringRef Name)
const override {
248 return LTODiscardSymbols.contains(Name);
251 bool parseMSInlineAsm(std::string &AsmString,
unsigned &NumOutputs,
253 SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
254 SmallVectorImpl<std::string> &Constraints,
255 SmallVectorImpl<std::string> &Clobbers,
256 const MCInstrInfo *MII, MCInstPrinter *IP,
257 MCAsmParserSemaCallback &SI)
override;
259 bool parseExpression(
const MCExpr *&Res);
260 bool parseExpression(
const MCExpr *&Res, SMLoc &EndLoc)
override;
261 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc,
262 AsmTypeInfo *TypeInfo)
override;
263 bool parseParenExpression(
const MCExpr *&Res, SMLoc &EndLoc)
override;
264 bool parseAbsoluteExpression(int64_t &Res)
override;
268 bool parseRealValue(
const fltSemantics &Semantics, APInt &Res);
272 bool parseIdentifier(StringRef &Res)
override;
273 void eatToEndOfStatement()
override;
275 bool checkForValidSection()
override;
280 bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
281 bool parseCppHashLineFilenameComment(SMLoc L,
bool SaveLocInfo =
true);
283 void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
285 bool expandMacro(raw_svector_ostream &OS, MCAsmMacro &
Macro,
290 bool areMacrosEnabled() {
return MacrosEnabledFlag;}
293 void setMacrosEnabled(
bool Flag) {MacrosEnabledFlag =
Flag;}
296 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
302 bool handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc);
305 void handleMacroExit();
308 bool parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg);
311 bool parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A);
313 void printMacroInstantiations();
315 SMRange
Range = {})
const {
322 bool enterIncludeFile(
const std::string &
Filename);
326 bool processIncbinFile(
const std::string &
Filename, int64_t Skip = 0,
327 const MCExpr *
Count =
nullptr, SMLoc Loc = SMLoc());
335 void jumpToLoc(SMLoc Loc,
unsigned InBuffer = 0);
340 StringRef parseStringToEndOfStatement()
override;
344 StringRef parseStringToComma();
346 enum class AssignmentKind {
353 bool parseAssignment(StringRef Name, AssignmentKind Kind);
358 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res, SMLoc &EndLoc);
359 bool parseParenExpr(
const MCExpr *&Res, SMLoc &EndLoc);
360 bool parseBracketExpr(
const MCExpr *&Res, SMLoc &EndLoc);
362 bool parseRegisterOrRegisterNumber(int64_t &
Register, SMLoc DirectiveLoc);
364 bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
365 bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
425 DK_BUNDLE_ALIGN_MODE,
439 DK_WEAK_DEF_CAN_BE_HIDDEN,
480 DK_CV_INLINE_SITE_ID,
483 DK_CV_INLINE_LINETABLE,
488 DK_CV_FILECHECKSUM_OFFSET,
494 DK_CFI_DEF_CFA_OFFSET,
495 DK_CFI_ADJUST_CFA_OFFSET,
496 DK_CFI_DEF_CFA_REGISTER,
497 DK_CFI_LLVM_DEF_ASPACE_CFA,
500 DK_CFI_LLVM_REGISTER_PAIR,
501 DK_CFI_LLVM_VECTOR_REGISTERS,
502 DK_CFI_LLVM_VECTOR_OFFSET,
503 DK_CFI_LLVM_VECTOR_REGISTER_MASK,
506 DK_CFI_REMEMBER_STATE,
507 DK_CFI_RESTORE_STATE,
511 DK_CFI_RETURN_COLUMN,
538 DK_LTO_SET_CONDITIONAL,
539 DK_CFI_MTE_TAGGED_FRAME,
547 StringMap<DirectiveKind> DirectiveKindMap;
550 enum CVDefRangeType {
552 CVDR_DEFRANGE_REGISTER,
553 CVDR_DEFRANGE_FRAMEPOINTER_REL,
554 CVDR_DEFRANGE_SUBFIELD_REGISTER,
555 CVDR_DEFRANGE_REGISTER_REL,
556 CVDR_DEFRANGE_REGISTER_REL_INDIR
561 StringMap<CVDefRangeType> CVDefRangeTypeMap;
564 bool parseDirectiveAscii(StringRef IDVal,
bool ZeroTerminated);
565 bool parseDirectiveBase64();
566 bool parseDirectiveReloc(SMLoc DirectiveLoc);
567 bool parseDirectiveValue(StringRef IDVal,
569 bool parseDirectiveOctaValue(StringRef IDVal);
570 bool parseDirectiveRealValue(StringRef IDVal,
571 const fltSemantics &);
572 bool parseDirectiveFill();
573 bool parseDirectiveZero();
575 bool parseDirectiveSet(StringRef IDVal, AssignmentKind Kind);
576 bool parseDirectiveOrg();
578 bool parseDirectiveAlign(
bool IsPow2, uint8_t ValueSize);
579 bool parseDirectivePrefAlign();
582 bool parseDirectiveFile(SMLoc DirectiveLoc);
583 bool parseDirectiveLine();
584 bool parseDirectiveLoc();
585 bool parseDirectiveLocLabel(SMLoc DirectiveLoc);
586 bool parseDirectiveStabs();
590 bool parseDirectiveCVFile();
591 bool parseDirectiveCVFuncId();
592 bool parseDirectiveCVInlineSiteId();
593 bool parseDirectiveCVLoc();
594 bool parseDirectiveCVLinetable();
595 bool parseDirectiveCVInlineLinetable();
596 bool parseDirectiveCVDefRange();
597 bool parseDirectiveCVString();
598 bool parseDirectiveCVStringTable();
599 bool parseDirectiveCVFileChecksums();
600 bool parseDirectiveCVFileChecksumOffset();
601 bool parseDirectiveCVFPOData();
604 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
605 bool parseDirectiveCFIWindowSave(SMLoc DirectiveLoc);
606 bool parseDirectiveCFISections();
607 bool parseDirectiveCFIStartProc();
608 bool parseDirectiveCFIEndProc();
609 bool parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc);
610 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
611 bool parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc);
612 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
613 bool parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc);
614 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
615 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
616 bool parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality);
617 bool parseDirectiveCFIRememberState(SMLoc DirectiveLoc);
618 bool parseDirectiveCFIRestoreState(SMLoc DirectiveLoc);
619 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
620 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
621 bool parseDirectiveCFIEscape(SMLoc DirectiveLoc);
622 bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
623 bool parseDirectiveCFISignalFrame(SMLoc DirectiveLoc);
624 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
625 bool parseDirectiveCFILLVMRegisterPair(SMLoc DirectiveLoc);
626 bool parseDirectiveCFILLVMVectorRegisters(SMLoc DirectiveLoc);
627 bool parseDirectiveCFILLVMVectorOffset(SMLoc DirectiveLoc);
628 bool parseDirectiveCFILLVMVectorRegisterMask(SMLoc DirectiveLoc);
629 bool parseDirectiveCFILabel(SMLoc DirectiveLoc);
630 bool parseDirectiveCFIValOffset(SMLoc DirectiveLoc);
633 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
634 bool parseDirectiveExitMacro(StringRef Directive);
635 bool parseDirectiveEndMacro(StringRef Directive);
636 bool parseDirectiveMacro(SMLoc DirectiveLoc);
637 bool parseDirectiveMacrosOnOff(StringRef Directive);
639 bool parseDirectiveAltmacro(StringRef Directive);
642 bool parseDirectiveSpace(StringRef IDVal);
645 bool parseDirectiveDCB(StringRef IDVal,
unsigned Size);
646 bool parseDirectiveRealDCB(StringRef IDVal,
const fltSemantics &);
648 bool parseDirectiveDS(StringRef IDVal,
unsigned Size);
651 bool parseDirectiveLEB128(
bool Signed);
657 bool parseDirectiveComm(
bool IsLocal);
659 bool parseDirectiveAbort(SMLoc DirectiveLoc);
660 bool parseDirectiveInclude();
661 bool parseDirectiveIncbin();
664 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
666 bool parseDirectiveIfb(SMLoc DirectiveLoc,
bool ExpectBlank);
668 bool parseDirectiveIfc(SMLoc DirectiveLoc,
bool ExpectEqual);
670 bool parseDirectiveIfeqs(SMLoc DirectiveLoc,
bool ExpectEqual);
672 bool parseDirectiveIfdef(SMLoc DirectiveLoc,
bool expect_defined);
673 bool parseDirectiveElseIf(SMLoc DirectiveLoc);
674 bool parseDirectiveElse(SMLoc DirectiveLoc);
675 bool parseDirectiveEndIf(SMLoc DirectiveLoc);
676 bool parseEscapedString(std::string &
Data)
override;
677 bool parseAngleBracketString(std::string &
Data)
override;
680 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
681 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
682 raw_svector_ostream &OS);
683 bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive);
684 bool parseDirectiveIrp(SMLoc DirectiveLoc);
685 bool parseDirectiveIrpc(SMLoc DirectiveLoc);
686 bool parseDirectiveEndr(SMLoc DirectiveLoc);
689 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
693 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
696 bool parseDirectiveEnd(SMLoc DirectiveLoc);
699 bool parseDirectiveError(SMLoc DirectiveLoc,
bool WithMessage);
702 bool parseDirectiveWarning(SMLoc DirectiveLoc);
705 bool parseDirectivePrint(SMLoc DirectiveLoc);
708 bool parseDirectivePseudoProbe();
711 bool parseDirectiveLTODiscard();
714 bool parseDirectiveAddrsig();
715 bool parseDirectiveAddrsigSym();
718 bool parseDirectiveBundleAlignMode();
720 bool parseDirectiveBundleLock();
722 bool parseDirectiveBundleUnlock();
724 void initializeDirectiveKindMap();
725 void initializeCVDefRangeTypeMap();
728class HLASMAsmParser final :
public AsmParser {
733 void lexLeadingSpaces() {
738 bool parseAsHLASMLabel(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI);
739 bool parseAsMachineInstruction(ParseStatementInfo &Info,
740 MCAsmParserSemaCallback *SI);
743 HLASMAsmParser(SourceMgr &
SM, MCContext &Ctx, MCStreamer &Out,
744 const MCAsmInfo &MAI,
unsigned CB = 0)
745 : AsmParser(
SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
746 Lexer.setSkipSpace(
false);
747 Lexer.setAllowHashInIdentifier(
true);
748 Lexer.setLexHLASMIntegers(
true);
749 Lexer.setLexHLASMStrings(
true);
752 ~HLASMAsmParser()
override { Lexer.setSkipSpace(
true); }
754 bool parseStatement(ParseStatementInfo &Info,
755 MCAsmParserSemaCallback *SI)
override;
768 :
MCAsmParser(Ctx, Out,
SM, MAI), CurBuffer(CB ? CB :
SM.getMainFileID()),
769 MacrosEnabledFlag(
true) {
772 SavedDiagHandler =
SrcMgr.getDiagHandler();
773 SavedDiagContext =
SrcMgr.getDiagContext();
781 switch (Ctx.getObjectFileType()) {
782 case MCContext::IsCOFF:
783 PlatformParser.reset(createCOFFAsmParser());
785 case MCContext::IsMachO:
786 PlatformParser.reset(createDarwinAsmParser());
789 case MCContext::IsELF:
790 PlatformParser.reset(createELFAsmParser());
792 case MCContext::IsGOFF:
793 PlatformParser.reset(createGOFFAsmParser());
795 case MCContext::IsSPIRV:
797 "Need to implement createSPIRVAsmParser for SPIRV format.");
799 case MCContext::IsWasm:
800 PlatformParser.reset(createWasmAsmParser());
802 case MCContext::IsXCOFF:
803 PlatformParser.reset(createXCOFFAsmParser());
805 case MCContext::IsDXContainer:
806 report_fatal_error(
"DXContainer is not supported yet");
810 PlatformParser->Initialize(*
this);
812 LFIParser.reset(createLFIAsmParser(Out.getLFIRewriter()));
813 LFIParser->Initialize(*this);
815 initializeDirectiveKindMap();
816 initializeCVDefRangeTypeMap();
819AsmParser::~AsmParser() {
820 assert((HadError || ActiveMacros.empty()) &&
821 "Unexpected active macro instantiation!");
830void AsmParser::printMacroInstantiations() {
832 for (MacroInstantiation *M :
reverse(ActiveMacros))
834 "while in macro instantiation");
837void AsmParser::Note(SMLoc L,
const Twine &
Msg, SMRange
Range) {
838 printPendingErrors();
840 printMacroInstantiations();
843bool AsmParser::Warning(SMLoc L,
const Twine &
Msg, SMRange
Range) {
844 if(getTargetParser().getTargetOptions().MCNoWarn)
846 if (getTargetParser().getTargetOptions().MCFatalWarnings)
849 printMacroInstantiations();
853bool AsmParser::printError(SMLoc L,
const Twine &
Msg, SMRange
Range) {
856 printMacroInstantiations();
860bool AsmParser::enterIncludeFile(
const std::string &
Filename) {
861 std::string IncludedFile;
875bool AsmParser::processIncbinFile(
const std::string &
Filename, int64_t Skip,
876 const MCExpr *
Count, SMLoc Loc) {
878 if (SymbolScanningMode)
884 std::string IncludedFile;
891 StringRef Bytes = (*BufOrErr)->getBuffer();
895 if (!
Count->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
896 return Error(Loc,
"expected absolute expression");
898 return Warning(Loc,
"negative count has no effect");
901 getStreamer().emitBytes(Bytes);
905void AsmParser::jumpToLoc(SMLoc Loc,
unsigned InBuffer) {
911const AsmToken &AsmParser::Lex() {
918 if (!getTok().getString().
empty() && getTok().getString().
front() !=
'\n' &&
923 const AsmToken *tok = &Lexer.
Lex();
936 if (ParentIncludeLoc != SMLoc()) {
937 jumpToLoc(ParentIncludeLoc);
945bool AsmParser::enabledGenDwarfForAssembly() {
952 if (
getContext().getGenDwarfFileNumber() == 0) {
953 const MCDwarfFile &RootFile =
954 getContext().getMCDwarfLineTable(0).getRootFile();
955 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
962bool AsmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
963 LTODiscardSymbols.
clear();
966 if (!NoInitialTextSection)
973 AsmCond StartingCondState = TheCondState;
981 MCSection *Sec = getStreamer().getCurrentSectionOnly();
984 getStreamer().emitLabel(SectionStartSym);
987 bool InsertResult =
getContext().addGenDwarfSection(Sec);
988 assert(InsertResult &&
".text section should not have debug info yet");
992 getTargetParser().onBeginOfFile();
996 ParseStatementInfo
Info(&AsmStrRewrites);
997 bool HasError = parseStatement(Info,
nullptr);
1006 printPendingErrors();
1009 if (HasError && !getLexer().justConsumedEOL())
1010 eatToEndOfStatement();
1013 getTargetParser().onEndOfFile();
1014 printPendingErrors();
1017 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1021 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1023 const auto &LineTables =
getContext().getMCDwarfLineTables();
1024 if (!LineTables.empty()) {
1026 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1027 if (
File.Name.empty() && Index != 0)
1028 printError(getTok().getLoc(),
"unassigned file number: " +
1030 " for .file directives");
1042 MCSymbol *Sym = TableEntry.getValue().Symbol;
1051 printError(getTok().getLoc(),
"assembler local symbol '" +
1052 Sym->
getName() +
"' not defined");
1058 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1059 if (std::get<2>(LocSym)->isUndefined()) {
1062 CppHashInfo = std::get<1>(LocSym);
1063 printError(std::get<0>(LocSym),
"directional label undefined");
1069 if (!HadError && !NoFinalize) {
1071 TS->emitConstantPools();
1079bool AsmParser::checkForValidSection() {
1080 if (!ParsingMSInlineAsm && !getStreamer().getCurrentFragment()) {
1082 return Error(getTok().getLoc(),
1083 "expected section directive before assembly directive");
1089void AsmParser::eatToEndOfStatement() {
1098StringRef AsmParser::parseStringToEndOfStatement() {
1099 const char *
Start = getTok().getLoc().getPointer();
1105 return StringRef(Start, End - Start);
1108StringRef AsmParser::parseStringToComma() {
1109 const char *
Start = getTok().getLoc().getPointer();
1115 const char *End = getTok().getLoc().getPointer();
1116 return StringRef(Start, End - Start);
1124bool AsmParser::parseParenExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
1125 if (parseExpression(Res))
1128 return parseRParen();
1136bool AsmParser::parseBracketExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
1137 if (parseExpression(Res))
1139 EndLoc = getTok().getEndLoc();
1140 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1151bool AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc,
1152 AsmTypeInfo *TypeInfo) {
1153 SMLoc FirstTokenLoc = getLexer().getLoc();
1155 switch (FirstTokenKind) {
1157 return TokError(
"unknown token in expression");
1163 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1173 if (parseIdentifier(Identifier)) {
1177 bool ShouldGenerateTempSymbol =
false;
1180 ShouldGenerateTempSymbol =
true;
1182 if (!ShouldGenerateTempSymbol)
1183 return Error(FirstTokenLoc,
"invalid token in expression");
1192 EndLoc = FirstTokenLoc;
1197 std::pair<StringRef, StringRef>
Split;
1202 SMLoc AtLoc = getLexer().getLoc();
1204 if (parseIdentifier(VName))
1205 return Error(AtLoc,
"expected symbol variant after '@'");
1207 Split = std::make_pair(Identifier, VName);
1215 parseIdentifier(VName);
1218 Split = std::make_pair(Identifier, VName);
1226 return Error(getLexer().getLoc(),
"expected a symbol reference");
1230 if (!
Split.second.empty()) {
1232 if (MaybeSpecifier) {
1234 Spec = *MaybeSpecifier;
1237 "invalid variant '" +
Split.second +
"'");
1252 DoInline = TV->inlineAssignedExpr();
1255 return Error(EndLoc,
"unexpected modifier on variable reference");
1266 return TokError(
"literal value out of range for directive");
1268 SMLoc Loc = getTok().getLoc();
1269 int64_t
IntVal = getTok().getIntVal();
1275 StringRef IDVal = getTok().getString();
1277 std::pair<StringRef, StringRef>
Split = IDVal.
split(
'@');
1279 if (
Split.first.size() != IDVal.
size()) {
1282 return TokError(
"invalid variant '" +
Split.second +
"'");
1283 IDVal =
Split.first;
1286 if (IDVal ==
"f" || IDVal ==
"b") {
1291 return Error(Loc,
"directional label undefined");
1292 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1300 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1301 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
1309 return TokError(
"cannot use . as current PC");
1322 return parseParenExpr(Res, EndLoc);
1324 if (!PlatformParser->HasBracketExpressions())
1325 return TokError(
"brackets expression not supported on this target");
1327 return parseBracketExpr(Res, EndLoc);
1330 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1336 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1342 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1349bool AsmParser::parseExpression(
const MCExpr *&Res) {
1351 return parseExpression(Res, EndLoc);
1361 switch (E->getKind()) {
1372 TokError(
"invalid variant on expression '" +
getTok().getIdentifier() +
1373 "' (already modified)");
1424 "Argument to the function cannot be a NULL value");
1426 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1427 (*CharPtr !=
'\0')) {
1428 if (*CharPtr ==
'!')
1432 if (*CharPtr ==
'>') {
1442 for (
size_t Pos = 0; Pos < AltMacroStr.
size(); Pos++) {
1443 if (AltMacroStr[Pos] ==
'!')
1445 Res += AltMacroStr[Pos];
1453 return TokError(
"expected specifier following '@'");
1455 auto Spec =
MAI.getSpecifierForName(
getTok().getIdentifier());
1457 return TokError(
"invalid specifier '@" +
getTok().getIdentifier() +
"'");
1477bool AsmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1480 auto &TS = getTargetParser();
1481 if (TS.parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc))
1489 return TokError(
"unexpected symbol modifier following '@'");
1493 return TokError(
"invalid variant '" + getTok().getIdentifier() +
"'");
1495 const MCExpr *ModifiedRes = applySpecifier(Res, *
Spec);
1497 return TokError(
"invalid modifier '" + getTok().getIdentifier() +
1498 "' (no symbols present)");
1508 if (Res->evaluateAsAbsolute(
Value))
1514bool AsmParser::parseParenExpression(
const MCExpr *&Res, SMLoc &EndLoc) {
1516 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1519bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1522 SMLoc StartLoc = Lexer.
getLoc();
1523 if (parseExpression(Expr))
1526 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1527 return Error(StartLoc,
"expected absolute expression");
1534 bool ShouldUseLogicalShr) {
1611 bool ShouldUseLogicalShr) {
1700bool AsmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
1702 SMLoc StartLoc = Lexer.
getLoc();
1705 unsigned TokPrec = getBinOpPrecedence(Lexer.
getKind(), Kind);
1709 if (TokPrec < Precedence)
1716 if (getTargetParser().parsePrimaryExpr(
RHS, EndLoc))
1722 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
1723 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1,
RHS, EndLoc))
1735bool AsmParser::parseStatement(ParseStatementInfo &Info,
1736 MCAsmParserSemaCallback *SI) {
1737 assert(!hasPendingError() &&
"parseStatement started with pending error");
1743 if (getTok().getString().
empty() || getTok().getString().
front() ==
'\r' ||
1744 getTok().getString().
front() ==
'\n')
1750 AsmToken
ID = getTok();
1751 SMLoc IDLoc =
ID.getLoc();
1753 int64_t LocalLabelVal = -1;
1754 StartTokLoc =
ID.getLoc();
1756 return parseCppHashLineFilenameComment(IDLoc,
1757 !isInsideMacroInstantiation());
1761 LocalLabelVal = getTok().getIntVal();
1762 if (LocalLabelVal < 0) {
1763 if (!TheCondState.
Ignore) {
1765 return Error(IDLoc,
"unexpected token at start of statement");
1769 IDVal = getTok().getString();
1772 if (!TheCondState.
Ignore) {
1774 return Error(IDLoc,
"unexpected token at start of statement");
1782 }
else if (getTargetParser().tokenIsStartOfStatement(
ID.getKind())) {
1784 IDVal =
ID.getString();
1785 }
else if (parseIdentifier(IDVal)) {
1786 if (!TheCondState.
Ignore) {
1788 return Error(IDLoc,
"unexpected token at start of statement");
1797 DirectiveKindMap.find(IDVal.
lower());
1798 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1800 : DirKindIt->getValue();
1811 return parseDirectiveIf(IDLoc, DirKind);
1813 return parseDirectiveIfb(IDLoc,
true);
1815 return parseDirectiveIfb(IDLoc,
false);
1817 return parseDirectiveIfc(IDLoc,
true);
1819 return parseDirectiveIfeqs(IDLoc,
true);
1821 return parseDirectiveIfc(IDLoc,
false);
1823 return parseDirectiveIfeqs(IDLoc,
false);
1825 return parseDirectiveIfdef(IDLoc,
true);
1828 return parseDirectiveIfdef(IDLoc,
false);
1830 return parseDirectiveElseIf(IDLoc);
1832 return parseDirectiveElse(IDLoc);
1834 return parseDirectiveEndIf(IDLoc);
1839 if (TheCondState.
Ignore) {
1840 eatToEndOfStatement();
1850 if (checkForValidSection())
1857 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
1865 if (LocalLabelVal == -1) {
1866 if (ParsingMSInlineAsm && SI) {
1867 StringRef RewrittenLabel =
1868 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
1870 "We should have an internal name here.");
1873 IDVal = RewrittenLabel;
1883 StringRef CommentStr = parseStringToEndOfStatement();
1894 if (MAI.
isMachO() && CFIStartProcLoc) {
1895 auto *SymM =
static_cast<MCSymbolMachO *
>(Sym);
1896 if (SymM->isExternal() && !SymM->isAltEntry())
1897 return Error(StartTokLoc,
"non-private labels cannot appear between "
1898 ".cfi_startproc / .cfi_endproc pairs") &&
1899 Error(*CFIStartProcLoc,
"previous .cfi_startproc was here");
1902 if (discardLTOSymbol(IDVal))
1905 getTargetParser().doBeforeLabelEmit(Sym, IDLoc);
1908 if (!getTargetParser().isParsingMSInlineAsm())
1913 if (enabledGenDwarfForAssembly())
1917 getTargetParser().onLabelParsed(Sym);
1926 return parseAssignment(IDVal, AssignmentKind::Equal);
1930 if (areMacrosEnabled())
1931 if (MCAsmMacro *M =
getContext().lookupMacro(IDVal))
1932 return handleMacroEntry(M, IDLoc);
1949 getTargetParser().flushPendingInstructions(getStreamer());
1951 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);
1953 "Should only return Failure iff there was an error");
1961 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
1962 ExtensionDirectiveMap.
lookup(IDVal);
1964 return (*Handler.second)(Handler.first, IDVal, IDLoc);
1973 return parseDirectiveSet(IDVal, AssignmentKind::Set);
1975 return parseDirectiveSet(IDVal, AssignmentKind::Equiv);
1976 case DK_LTO_SET_CONDITIONAL:
1977 return parseDirectiveSet(IDVal, AssignmentKind::LTOSetConditional);
1979 return parseDirectiveAscii(IDVal,
false);
1982 return parseDirectiveAscii(IDVal,
true);
1984 return parseDirectiveBase64();
1987 return parseDirectiveValue(IDVal, 1);
1993 return parseDirectiveValue(IDVal, 2);
1998 return parseDirectiveValue(IDVal, 4);
2001 return parseDirectiveValue(IDVal, 8);
2003 return parseDirectiveValue(
2004 IDVal,
getContext().getAsmInfo().getCodePointerSize());
2006 return parseDirectiveOctaValue(IDVal);
2010 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
2013 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
2015 bool IsPow2 = !
getContext().getAsmInfo().getAlignmentIsInBytes();
2016 return parseDirectiveAlign(IsPow2, 1);
2019 bool IsPow2 = !
getContext().getAsmInfo().getAlignmentIsInBytes();
2020 return parseDirectiveAlign(IsPow2, 4);
2023 return parseDirectiveAlign(
false, 1);
2025 return parseDirectiveAlign(
false, 2);
2027 return parseDirectiveAlign(
false, 4);
2029 return parseDirectiveAlign(
true, 1);
2031 return parseDirectiveAlign(
true, 2);
2033 return parseDirectiveAlign(
true, 4);
2035 return parseDirectivePrefAlign();
2037 return parseDirectiveOrg();
2039 return parseDirectiveFill();
2041 return parseDirectiveZero();
2043 eatToEndOfStatement();
2047 return parseDirectiveSymbolAttribute(
MCSA_Global);
2048 case DK_LAZY_REFERENCE:
2050 case DK_NO_DEAD_STRIP:
2052 case DK_SYMBOL_RESOLVER:
2054 case DK_PRIVATE_EXTERN:
2058 case DK_WEAK_DEFINITION:
2060 case DK_WEAK_REFERENCE:
2062 case DK_WEAK_DEF_CAN_BE_HIDDEN:
2065 return parseDirectiveSymbolAttribute(
MCSA_Cold);
2068 return parseDirectiveComm(
false);
2070 return parseDirectiveComm(
true);
2072 return parseDirectiveAbort(IDLoc);
2074 return parseDirectiveInclude();
2076 return parseDirectiveIncbin();
2079 return TokError(Twine(IDVal) +
2080 " not currently supported for this target");
2082 return parseDirectiveRept(IDLoc, IDVal);
2084 return parseDirectiveIrp(IDLoc);
2086 return parseDirectiveIrpc(IDLoc);
2088 return parseDirectiveEndr(IDLoc);
2089 case DK_BUNDLE_ALIGN_MODE:
2090 return parseDirectiveBundleAlignMode();
2091 case DK_BUNDLE_LOCK:
2092 return parseDirectiveBundleLock();
2093 case DK_BUNDLE_UNLOCK:
2094 return parseDirectiveBundleUnlock();
2096 return parseDirectiveLEB128(
true);
2098 return parseDirectiveLEB128(
false);
2101 return parseDirectiveSpace(IDVal);
2103 return parseDirectiveFile(IDLoc);
2105 return parseDirectiveLine();
2107 return parseDirectiveLoc();
2109 return parseDirectiveLocLabel(IDLoc);
2111 return parseDirectiveStabs();
2113 return parseDirectiveCVFile();
2115 return parseDirectiveCVFuncId();
2116 case DK_CV_INLINE_SITE_ID:
2117 return parseDirectiveCVInlineSiteId();
2119 return parseDirectiveCVLoc();
2120 case DK_CV_LINETABLE:
2121 return parseDirectiveCVLinetable();
2122 case DK_CV_INLINE_LINETABLE:
2123 return parseDirectiveCVInlineLinetable();
2124 case DK_CV_DEF_RANGE:
2125 return parseDirectiveCVDefRange();
2127 return parseDirectiveCVString();
2128 case DK_CV_STRINGTABLE:
2129 return parseDirectiveCVStringTable();
2130 case DK_CV_FILECHECKSUMS:
2131 return parseDirectiveCVFileChecksums();
2132 case DK_CV_FILECHECKSUM_OFFSET:
2133 return parseDirectiveCVFileChecksumOffset();
2134 case DK_CV_FPO_DATA:
2135 return parseDirectiveCVFPOData();
2136 case DK_CFI_SECTIONS:
2137 return parseDirectiveCFISections();
2138 case DK_CFI_STARTPROC:
2139 return parseDirectiveCFIStartProc();
2140 case DK_CFI_ENDPROC:
2141 return parseDirectiveCFIEndProc();
2142 case DK_CFI_DEF_CFA:
2143 return parseDirectiveCFIDefCfa(IDLoc);
2144 case DK_CFI_DEF_CFA_OFFSET:
2145 return parseDirectiveCFIDefCfaOffset(IDLoc);
2146 case DK_CFI_ADJUST_CFA_OFFSET:
2147 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2148 case DK_CFI_DEF_CFA_REGISTER:
2149 return parseDirectiveCFIDefCfaRegister(IDLoc);
2150 case DK_CFI_LLVM_DEF_ASPACE_CFA:
2151 return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
2153 return parseDirectiveCFIOffset(IDLoc);
2154 case DK_CFI_REL_OFFSET:
2155 return parseDirectiveCFIRelOffset(IDLoc);
2156 case DK_CFI_LLVM_REGISTER_PAIR:
2157 return parseDirectiveCFILLVMRegisterPair(IDLoc);
2158 case DK_CFI_LLVM_VECTOR_REGISTERS:
2159 return parseDirectiveCFILLVMVectorRegisters(IDLoc);
2160 case DK_CFI_LLVM_VECTOR_OFFSET:
2161 return parseDirectiveCFILLVMVectorOffset(IDLoc);
2162 case DK_CFI_LLVM_VECTOR_REGISTER_MASK:
2163 return parseDirectiveCFILLVMVectorRegisterMask(IDLoc);
2164 case DK_CFI_PERSONALITY:
2165 return parseDirectiveCFIPersonalityOrLsda(
true);
2167 return parseDirectiveCFIPersonalityOrLsda(
false);
2168 case DK_CFI_REMEMBER_STATE:
2169 return parseDirectiveCFIRememberState(IDLoc);
2170 case DK_CFI_RESTORE_STATE:
2171 return parseDirectiveCFIRestoreState(IDLoc);
2172 case DK_CFI_SAME_VALUE:
2173 return parseDirectiveCFISameValue(IDLoc);
2174 case DK_CFI_RESTORE:
2175 return parseDirectiveCFIRestore(IDLoc);
2177 return parseDirectiveCFIEscape(IDLoc);
2178 case DK_CFI_RETURN_COLUMN:
2179 return parseDirectiveCFIReturnColumn(IDLoc);
2180 case DK_CFI_SIGNAL_FRAME:
2181 return parseDirectiveCFISignalFrame(IDLoc);
2182 case DK_CFI_UNDEFINED:
2183 return parseDirectiveCFIUndefined(IDLoc);
2184 case DK_CFI_REGISTER:
2185 return parseDirectiveCFIRegister(IDLoc);
2186 case DK_CFI_WINDOW_SAVE:
2187 return parseDirectiveCFIWindowSave(IDLoc);
2189 return parseDirectiveCFILabel(IDLoc);
2190 case DK_CFI_VAL_OFFSET:
2191 return parseDirectiveCFIValOffset(IDLoc);
2194 return parseDirectiveMacrosOnOff(IDVal);
2196 return parseDirectiveMacro(IDLoc);
2199 return parseDirectiveAltmacro(IDVal);
2201 return parseDirectiveExitMacro(IDVal);
2204 return parseDirectiveEndMacro(IDVal);
2206 return parseDirectivePurgeMacro(IDLoc);
2208 return parseDirectiveEnd(IDLoc);
2210 return parseDirectiveError(IDLoc,
false);
2212 return parseDirectiveError(IDLoc,
true);
2214 return parseDirectiveWarning(IDLoc);
2216 return parseDirectiveReloc(IDLoc);
2219 return parseDirectiveDCB(IDVal, 2);
2221 return parseDirectiveDCB(IDVal, 1);
2223 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2225 return parseDirectiveDCB(IDVal, 4);
2227 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2230 return TokError(Twine(IDVal) +
2231 " not currently supported for this target");
2234 return parseDirectiveDS(IDVal, 2);
2236 return parseDirectiveDS(IDVal, 1);
2238 return parseDirectiveDS(IDVal, 8);
2241 return parseDirectiveDS(IDVal, 4);
2244 return parseDirectiveDS(IDVal, 12);
2246 return parseDirectivePrint(IDLoc);
2248 return parseDirectiveAddrsig();
2249 case DK_ADDRSIG_SYM:
2250 return parseDirectiveAddrsigSym();
2251 case DK_PSEUDO_PROBE:
2252 return parseDirectivePseudoProbe();
2253 case DK_LTO_DISCARD:
2254 return parseDirectiveLTODiscard();
2256 return parseDirectiveSymbolAttribute(
MCSA_Memtag);
2259 return Error(IDLoc,
"unknown directive");
2263 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2264 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2265 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2268 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2269 return parseDirectiveMSAlign(IDLoc, Info);
2271 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2273 if (checkForValidSection())
2276 return parseAndMatchAndEmitTargetInstruction(Info, IDVal, ID, IDLoc);
2279bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
2284 std::string OpcodeStr = IDVal.
lower();
2285 ParseInstructionInfo IInfo(
Info.AsmRewrites);
2286 bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr, ID,
2287 Info.ParsedOperands);
2288 Info.ParseError = ParseHadError;
2291 if (getShowParsedOperands()) {
2292 SmallString<256> Str;
2293 raw_svector_ostream OS(Str);
2294 OS <<
"parsed instruction: [";
2295 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2298 Info.ParsedOperands[i]->print(OS, MAI);
2306 if (hasPendingError() || ParseHadError)
2311 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2313 getStreamer().getCurrentSectionOnly())) {
2315 if (ActiveMacros.empty())
2319 ActiveMacros.front()->ExitBuffer);
2324 if (!CppHashInfo.Filename.empty()) {
2325 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2326 0, StringRef(), CppHashInfo.Filename);
2327 getContext().setGenDwarfFileNumber(FileNumber);
2329 unsigned CppHashLocLineNo =
2331 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2334 getStreamer().emitDwarfLocDirective(
2335 getContext().getGenDwarfFileNumber(), Line, 0,
2341 if (!ParseHadError) {
2343 if (getTargetParser().matchAndEmitInstruction(
2344 IDLoc,
Info.Opcode,
Info.ParsedOperands, Out, ErrorInfo,
2345 getTargetParser().isParsingMSInlineAsm()))
2353AsmParser::parseCurlyBlockScope(SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
2358 SMLoc StartLoc = Lexer.
getLoc();
2371bool AsmParser::parseCppHashLineFilenameComment(SMLoc L,
bool SaveLocInfo) {
2376 "Lexing Cpp line comment: Expected Integer");
2377 int64_t LineNumber = getTok().getIntVal();
2380 "Lexing Cpp line comment: Expected String");
2381 StringRef
Filename = getTok().getString();
2392 CppHashInfo.Loc =
L;
2394 CppHashInfo.LineNumber = LineNumber;
2395 CppHashInfo.Buf = CurBuffer;
2396 if (!HadCppHashFilename) {
2397 HadCppHashFilename =
true;
2407 std::nullopt, std::nullopt);
2415void AsmParser::DiagHandler(
const SMDiagnostic &Diag,
void *
Context) {
2416 auto *Parser =
static_cast<AsmParser *
>(
Context);
2417 raw_ostream &OS =
errs();
2420 SMLoc DiagLoc = Diag.
getLoc();
2422 unsigned CppHashBuf =
2423 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2427 if (!Parser->SavedDiagHandler)
2433 if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
2434 if (Parser->SavedDiagHandler)
2435 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2437 Parser->getContext().diagnose(Diag);
2444 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2447 int CppHashLocLineNo =
2448 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2450 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2456 if (Parser->SavedDiagHandler)
2457 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2459 Parser->getContext().diagnose(NewDiag);
2467 return isalnum(
static_cast<unsigned char>(c)) || c ==
'_' || c ==
'$' ||
2471bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &
Macro,
2474 bool EnableAtPseudoVariable) {
2476 auto expandArg = [&](
unsigned Index) {
2477 bool HasVararg = NParameters ?
Parameters.back().Vararg :
false;
2478 bool VarargParameter = HasVararg &&
Index == (NParameters - 1);
2479 for (
const AsmToken &Token :
A[Index])
2487 if (AltMacroMode && Token.getString().front() ==
'%' &&
2490 OS << Token.getIntVal();
2493 else if (AltMacroMode && Token.getString().front() ==
'<' &&
2500 OS << Token.getString();
2502 OS << Token.getStringContents();
2507 StringRef Body =
Macro.Body;
2508 size_t I = 0, End = Body.
size();
2510 if (Body[
I] ==
'\\' &&
I + 1 != End) {
2512 if (EnableAtPseudoVariable && Body[
I + 1] ==
'@') {
2513 OS << NumOfMacroInstantiations;
2517 if (Body[
I + 1] ==
'+') {
2522 if (Body[
I + 1] ==
'(' && Body[
I + 2] ==
')') {
2531 if (AltMacroMode &&
I != End && Body[
I] ==
'&')
2535 if (Parameters[Index].Name == Argument)
2537 if (Index == NParameters)
2546 if (Body[
I] ==
'$' &&
I + 1 != End && IsDarwin && !NParameters) {
2548 switch (Body[
I + 1]) {
2564 unsigned Index = Body[
I + 1] -
'0';
2565 if (Index <
A.size())
2566 for (
const AsmToken &Token :
A[Index])
2567 OS << Token.getString();
2582 StringRef Token(Body.
data() + Start,
I - Start);
2586 if (Parameters[Index].Name == Token)
2588 if (Index != NParameters) {
2590 if (
I != End && Body[
I] ==
'&')
2634class AsmLexerSkipSpaceRAII {
2636 AsmLexerSkipSpaceRAII(AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2640 ~AsmLexerSkipSpaceRAII() {
2650bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg) {
2654 StringRef Str = parseStringToEndOfStatement();
2660 unsigned ParenLevel = 0;
2663 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2670 return TokError(
"unexpected token in macro instantiation");
2672 if (ParenLevel == 0) {
2685 MA.push_back(getTok());
2709 MA.push_back(getTok());
2713 if (ParenLevel != 0)
2714 return TokError(
"unbalanced parentheses in macro argument");
2719bool AsmParser::parseMacroArguments(
const MCAsmMacro *M,
2720 MCAsmMacroArguments &
A) {
2721 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
2722 bool NamedParametersFound =
false;
2723 SmallVector<SMLoc, 4> FALocs;
2725 A.resize(NParameters);
2726 FALocs.
resize(NParameters);
2731 bool HasVararg = NParameters ?
M->Parameters.back().Vararg :
false;
2732 for (
unsigned Parameter = 0; !NParameters ||
Parameter < NParameters;
2734 SMLoc IDLoc = Lexer.
getLoc();
2735 MCAsmMacroParameter FA;
2738 if (parseIdentifier(FA.
Name))
2739 return Error(IDLoc,
"invalid argument identifier for formal argument");
2742 return TokError(
"expected '=' after formal parameter identifier");
2746 NamedParametersFound =
true;
2748 bool Vararg = HasVararg &&
Parameter == (NParameters - 1);
2750 if (NamedParametersFound && FA.
Name.
empty())
2751 return Error(IDLoc,
"cannot mix positional and keyword arguments");
2753 SMLoc StrLoc = Lexer.
getLoc();
2756 const MCExpr *AbsoluteExp;
2760 if (parseExpression(AbsoluteExp, EndLoc))
2762 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
2763 getStreamer().getAssemblerPtr()))
2764 return Error(StrLoc,
"expected absolute expression");
2768 StringRef(StrChar, EndChar - StrChar),
Value);
2769 FA.
Value.push_back(newToken);
2774 jumpToLoc(EndLoc, CurBuffer);
2778 StringRef(StrChar, EndChar - StrChar));
2779 FA.
Value.push_back(newToken);
2780 }
else if(parseMacroArgument(FA.
Value, Vararg))
2786 for (FAI = 0; FAI < NParameters; ++FAI)
2787 if (
M->Parameters[FAI].Name == FA.
Name)
2790 if (FAI >= NParameters) {
2791 assert(M &&
"expected macro to be defined");
2792 return Error(IDLoc,
"parameter named '" + FA.
Name +
2793 "' does not exist for macro '" +
M->Name +
"'");
2798 if (!FA.
Value.empty()) {
2803 if (FALocs.
size() <= PI)
2806 FALocs[PI] = Lexer.
getLoc();
2814 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
2816 if (
M->Parameters[FAI].Required) {
2818 "missing value for required parameter "
2819 "'" +
M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
2823 if (!
M->Parameters[FAI].Value.empty())
2824 A[FAI] =
M->Parameters[FAI].Value;
2833 return TokError(
"too many positional arguments");
2836bool AsmParser::handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc) {
2840 if (ActiveMacros.size() == MaxNestingDepth) {
2841 std::ostringstream MaxNestingDepthError;
2842 MaxNestingDepthError <<
"macros cannot be nested more than "
2843 << MaxNestingDepth <<
" levels deep."
2844 <<
" Use -asm-macro-max-nesting-depth to increase "
2846 return TokError(MaxNestingDepthError.str());
2849 MCAsmMacroArguments
A;
2850 if (parseMacroArguments(M,
A))
2855 SmallString<256> Buf;
2856 raw_svector_ostream OS(Buf);
2858 if ((!IsDarwin ||
M->Parameters.size()) &&
M->Parameters.size() !=
A.size())
2859 return Error(getTok().getLoc(),
"Wrong number of arguments");
2860 if (expandMacro(OS, *M,
M->Parameters,
A,
true))
2865 OS <<
".endmacro\n";
2867 std::unique_ptr<MemoryBuffer> Instantiation =
2872 MacroInstantiation *
MI =
new MacroInstantiation{
2873 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2874 ActiveMacros.push_back(
MI);
2876 ++NumOfMacroInstantiations;
2886void AsmParser::handleMacroExit() {
2888 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2896 delete ActiveMacros.back();
2897 ActiveMacros.pop_back();
2900bool AsmParser::parseAssignment(StringRef Name, AssignmentKind Kind) {
2903 if (discardLTOSymbol(Name)) {
2904 eatToEndOfStatement();
2909 const MCExpr *
Value;
2910 SMLoc ExprLoc = getTok().getLoc();
2912 Kind == AssignmentKind::Set ||
Kind == AssignmentKind::Equal;
2926 case AssignmentKind::Equal:
2929 case AssignmentKind::Set:
2930 case AssignmentKind::Equiv:
2934 case AssignmentKind::LTOSetConditional:
2936 return Error(ExprLoc,
"expected identifier");
2948bool AsmParser::parseIdentifier(StringRef &Res) {
2955 SMLoc PrefixLoc = getLexer().getLoc();
2967 if (PrefixLoc.
getPointer() + 1 != Buf[0].getLoc().getPointer())
2973 Res = StringRef(PrefixLoc.
getPointer(), getTok().getString().
size() + 1);
2981 Res = getTok().getIdentifier();
2993bool AsmParser::parseDirectiveSet(StringRef IDVal, AssignmentKind Kind) {
2995 if (check(parseIdentifier(Name),
"expected identifier") || parseComma() ||
2996 parseAssignment(Name, Kind))
3001bool AsmParser::parseEscapedString(std::string &
Data) {
3006 StringRef Str = getTok().getStringContents();
3007 for (
unsigned i = 0, e = Str.size(); i != e; ++i) {
3008 if (Str[i] !=
'\\') {
3009 if ((Str[i] ==
'\n') || (Str[i] ==
'\r')) {
3011 if ((Str[i] ==
'\n') && (i > 0) && (Str[i - 1] ==
'\r'))
3015 if (
Warning(NewlineLoc,
"unterminated string; newline inserted"))
3026 return TokError(
"unexpected backslash at end of string");
3029 if (Str[i] ==
'x' || Str[i] ==
'X') {
3030 size_t length = Str.size();
3031 if (i + 1 >= length || !
isHexDigit(Str[i + 1]))
3032 return TokError(
"invalid hexadecimal escape sequence");
3037 while (i + 1 < length &&
isHexDigit(Str[i + 1]))
3045 if ((
unsigned)(Str[i] -
'0') <= 7) {
3047 unsigned Value = Str[i] -
'0';
3049 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3053 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3060 return TokError(
"invalid octal escape sequence (out of range)");
3070 return TokError(
"invalid escape sequence (unrecognized character)");
3072 case 'b':
Data +=
'\b';
break;
3073 case 'f':
Data +=
'\f';
break;
3074 case 'n':
Data +=
'\n';
break;
3075 case 'r':
Data +=
'\r';
break;
3076 case 't':
Data +=
'\t';
break;
3077 case '"':
Data +=
'"';
break;
3078 case '\\':
Data +=
'\\';
break;
3086bool AsmParser::parseAngleBracketString(std::string &
Data) {
3087 SMLoc EndLoc, StartLoc = getTok().getLoc();
3089 const char *StartChar = StartLoc.
getPointer() + 1;
3090 const char *EndChar = EndLoc.
getPointer() - 1;
3091 jumpToLoc(EndLoc, CurBuffer);
3104bool AsmParser::parseDirectiveAscii(StringRef IDVal,
bool ZeroTerminated) {
3105 auto parseOp = [&]() ->
bool {
3107 if (checkForValidSection())
3112 if (parseEscapedString(
Data))
3114 getStreamer().emitBytes(
Data);
3117 getStreamer().emitBytes(StringRef(
"\0", 1));
3121 return parseMany(parseOp);
3126bool AsmParser::parseDirectiveBase64() {
3127 auto parseOp = [&]() ->
bool {
3128 if (checkForValidSection())
3135 std::vector<char> Decoded;
3136 std::string
const str = getTok().getStringContents().str();
3137 if (check(str.empty(),
"expected nonempty string")) {
3144 return Error(Lexer.
getLoc(),
"failed to base64 decode string data");
3147 getStreamer().emitBytes(std::string(Decoded.begin(), Decoded.end()));
3152 return check(parseMany(parseOp),
"expected string");
3157bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
3159 const MCExpr *Expr =
nullptr;
3161 if (parseExpression(
Offset))
3173 SMLoc ExprLoc = Lexer.
getLoc();
3174 if (parseExpression(Expr))
3179 return Error(ExprLoc,
"expression must be relocatable");
3185 getStreamer().emitRelocDirective(*
Offset, Name, Expr, NameLoc);
3191bool AsmParser::parseDirectiveValue(StringRef IDVal,
unsigned Size) {
3192 auto parseOp = [&]() ->
bool {
3193 const MCExpr *
Value;
3194 SMLoc ExprLoc = getLexer().getLoc();
3195 if (checkForValidSection() || getTargetParser().parseDataExpr(
Value))
3200 uint64_t IntValue = MCE->getValue();
3202 return Error(ExprLoc,
"out of range literal value");
3203 getStreamer().emitIntValue(IntValue,
Size);
3205 getStreamer().emitValue(
Value,
Size, ExprLoc);
3209 return parseMany(parseOp);
3215 return Asm.TokError(
"unknown token in expression");
3216 SMLoc ExprLoc = Asm.getTok().getLoc();
3217 APInt IntValue = Asm.getTok().getAPIntVal();
3219 if (!IntValue.
isIntN(128))
3220 return Asm.Error(ExprLoc,
"out of range literal value");
3221 if (!IntValue.
isIntN(64)) {
3234bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
3235 auto parseOp = [&]() ->
bool {
3236 if (checkForValidSection())
3242 getStreamer().emitInt64(lo);
3243 getStreamer().emitInt64(hi);
3245 getStreamer().emitInt64(hi);
3246 getStreamer().emitInt64(lo);
3251 return parseMany(parseOp);
3254bool AsmParser::parseRealValue(
const fltSemantics &Semantics, APInt &Res) {
3265 return TokError(Lexer.
getErr());
3268 return TokError(
"unexpected token in directive");
3272 StringRef IDVal = getTok().getString();
3280 return TokError(
"invalid floating point literal");
3282 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3284 return TokError(
"invalid floating point literal");
3291 Res =
Value.bitcastToAPInt();
3298bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
3299 const fltSemantics &Semantics) {
3300 auto parseOp = [&]() ->
bool {
3302 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3309 return parseMany(parseOp);
3314bool AsmParser::parseDirectiveZero() {
3315 SMLoc NumBytesLoc = Lexer.
getLoc();
3316 const MCExpr *NumBytes;
3317 if (checkForValidSection() || parseExpression(NumBytes))
3323 if (parseAbsoluteExpression(Val))
3329 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3336bool AsmParser::parseDirectiveFill() {
3337 SMLoc NumValuesLoc = Lexer.
getLoc();
3338 const MCExpr *NumValues;
3339 if (checkForValidSection() || parseExpression(NumValues))
3342 int64_t FillSize = 1;
3343 int64_t FillExpr = 0;
3345 SMLoc SizeLoc, ExprLoc;
3348 SizeLoc = getTok().getLoc();
3349 if (parseAbsoluteExpression(FillSize))
3352 ExprLoc = getTok().getLoc();
3353 if (parseAbsoluteExpression(FillExpr))
3361 Warning(SizeLoc,
"'.fill' directive with negative size has no effect");
3365 Warning(SizeLoc,
"'.fill' directive with size greater than 8 has been truncated to 8");
3370 Warning(ExprLoc,
"'.fill' directive pattern has been truncated to 32-bits");
3372 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3379bool AsmParser::parseDirectiveOrg() {
3381 SMLoc OffsetLoc = Lexer.
getLoc();
3382 if (checkForValidSection() || parseExpression(
Offset))
3386 int64_t FillExpr = 0;
3388 if (parseAbsoluteExpression(FillExpr))
3393 getStreamer().emitValueToOffset(
Offset, FillExpr, OffsetLoc);
3399bool AsmParser::parseDirectiveAlign(
bool IsPow2, uint8_t ValueSize) {
3400 SMLoc AlignmentLoc = getLexer().getLoc();
3403 bool HasFillExpr =
false;
3404 int64_t FillExpr = 0;
3405 int64_t MaxBytesToFill = 0;
3408 auto parseAlign = [&]() ->
bool {
3409 if (parseAbsoluteExpression(Alignment))
3417 if (parseTokenLoc(FillExprLoc) || parseAbsoluteExpression(FillExpr))
3421 if (parseTokenLoc(MaxBytesLoc) ||
3422 parseAbsoluteExpression(MaxBytesToFill))
3428 if (checkForValidSection())
3432 Warning(AlignmentLoc,
"p2align directive with no operand(s) is ignored");
3439 bool ReturnVal =
false;
3444 if (Alignment >= 32) {
3445 ReturnVal |=
Error(AlignmentLoc,
"invalid alignment value");
3449 Alignment = 1ULL << Alignment;
3457 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2");
3461 ReturnVal |=
Error(AlignmentLoc,
"alignment must be smaller than 2**32");
3462 Alignment = 1u << 31;
3468 if (MaxBytesToFill < 1) {
3469 ReturnVal |=
Error(MaxBytesLoc,
3470 "alignment directive can never be satisfied in this "
3471 "many bytes, ignoring maximum bytes expression");
3475 if (MaxBytesToFill >= Alignment) {
3476 Warning(MaxBytesLoc,
"maximum bytes expression exceeds alignment and "
3482 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
3483 assert(Section &&
"must have section to emit alignment");
3485 if (HasFillExpr && FillExpr != 0 &&
Section->isBssSection()) {
3487 Warning(FillExprLoc,
"ignoring non-zero fill value in BSS section '" +
3495 getStreamer().emitCodeAlignment(
Align(Alignment),
3496 getTargetParser().getSTI(), MaxBytesToFill);
3499 getStreamer().emitValueToAlignment(
Align(Alignment), FillExpr, ValueSize,
3506bool AsmParser::parseDirectivePrefAlign() {
3507 SMLoc AlignmentLoc = getLexer().getLoc();
3509 if (checkForValidSection() || parseAbsoluteExpression(Log2Alignment))
3512 if (Log2Alignment < 0 || Log2Alignment > 63)
3513 return Error(AlignmentLoc,
"log2 alignment must be in the range [0, 63]");
3516 SMLoc SymLoc = getLexer().getLoc();
3520 SymLoc = getLexer().getLoc();
3521 if (parseIdentifier(Name))
3522 return Error(SymLoc,
"expected symbol name");
3526 SMLoc FillLoc = getLexer().getLoc();
3530 bool EmitNops =
false;
3532 SMLoc FillLoc2 = getLexer().getLoc();
3534 getLexer().getTok().getIdentifier() ==
"nop") {
3539 if (parseAbsoluteExpression(FillVal))
3541 if (FillVal < 0 || FillVal > 255)
3542 return Error(FillLoc2,
"fill value must be in range [0, 255]");
3543 Fill =
static_cast<uint8_t
>(FillVal);
3548 if ((EmitNops || Fill != 0) &&
3549 getStreamer().getCurrentSectionOnly()->isBssSection())
3550 return Error(FillLoc,
"non-zero fill in BSS section '" +
3551 getStreamer().getCurrentSectionOnly()->
getName() +
3554 getStreamer().emitPrefAlign(
Align(1ULL << Log2Alignment), *End, EmitNops,
3555 Fill, getTargetParser().getSTI());
3562bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
3564 int64_t FileNumber = -1;
3566 FileNumber = getTok().getIntVal();
3570 return TokError(
"negative file number");
3577 if (parseEscapedString(Path))
3580 StringRef Directory;
3582 std::string FilenameData;
3584 if (check(FileNumber == -1,
3585 "explicit path specified, but no file number") ||
3586 parseEscapedString(FilenameData))
3594 uint64_t MD5Hi, MD5Lo;
3595 bool HasMD5 =
false;
3597 std::optional<StringRef>
Source;
3598 bool HasSource =
false;
3599 std::string SourceString;
3604 "unexpected token in '.file' directive") ||
3605 parseIdentifier(Keyword))
3607 if (Keyword ==
"md5") {
3609 if (check(FileNumber == -1,
3610 "MD5 checksum specified, but no file number") ||
3613 }
else if (Keyword ==
"source") {
3615 if (check(FileNumber == -1,
3616 "source specified, but no file number") ||
3618 "unexpected token in '.file' directive") ||
3619 parseEscapedString(SourceString))
3622 return TokError(
"unexpected token in '.file' directive");
3626 if (FileNumber == -1) {
3630 if (
getContext().getAsmInfo().hasSingleParameterDotFile())
3631 getStreamer().emitFileDirective(
Filename);
3641 std::optional<MD5::MD5Result> CKMem;
3644 for (
unsigned i = 0; i != 8; ++i) {
3645 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3646 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3651 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
3652 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3653 Source = StringRef(SourceBuf, SourceString.size());
3655 if (FileNumber == 0) {
3659 getStreamer().emitDwarfFile0Directive(Directory,
Filename, CKMem, Source);
3661 Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3662 FileNumber, Directory,
Filename, CKMem, Source);
3669 ReportedInconsistentMD5 =
true;
3670 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
3679bool AsmParser::parseDirectiveLine() {
3691bool AsmParser::parseDirectiveLoc() {
3692 int64_t FileNumber = 0, LineNumber = 0;
3693 SMLoc Loc = getTok().getLoc();
3694 if (parseIntToken(FileNumber) ||
3696 "file number less than one in '.loc' directive") ||
3697 check(!
getContext().isValidDwarfFileNumber(FileNumber), Loc,
3698 "unassigned file number in '.loc' directive"))
3703 LineNumber = getTok().getIntVal();
3705 return TokError(
"line number less than zero in '.loc' directive");
3709 int64_t ColumnPos = 0;
3711 ColumnPos = getTok().getIntVal();
3713 return TokError(
"column position less than zero in '.loc' directive");
3717 auto PrevFlags =
getContext().getCurrentDwarfLoc().getFlags();
3722 auto parseLocOp = [&]() ->
bool {
3724 SMLoc Loc = getTok().getLoc();
3725 if (parseIdentifier(Name))
3726 return TokError(
"unexpected token in '.loc' directive");
3728 if (Name ==
"basic_block")
3730 else if (Name ==
"prologue_end")
3732 else if (Name ==
"epilogue_begin")
3734 else if (Name ==
"is_stmt") {
3735 Loc = getTok().getLoc();
3736 const MCExpr *
Value;
3737 if (parseExpression(
Value))
3741 int Value = MCE->getValue();
3743 Flags &= ~DWARF2_FLAG_IS_STMT;
3744 else if (
Value == 1)
3747 return Error(Loc,
"is_stmt value not 0 or 1");
3749 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
3751 }
else if (Name ==
"isa") {
3752 Loc = getTok().getLoc();
3753 const MCExpr *
Value;
3754 if (parseExpression(
Value))
3758 int Value = MCE->getValue();
3760 return Error(Loc,
"isa number less than zero");
3763 return Error(Loc,
"isa number not a constant value");
3765 }
else if (Name ==
"discriminator") {
3766 if (parseAbsoluteExpression(Discriminator))
3769 return Error(Loc,
"unknown sub-directive in '.loc' directive");
3774 if (parseMany(parseLocOp,
false ))
3777 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3778 Isa, Discriminator, StringRef());
3785bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) {
3787 DirectiveLoc = Lexer.
getLoc();
3788 if (parseIdentifier(Name))
3789 return TokError(
"expected identifier");
3792 getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name);
3798bool AsmParser::parseDirectiveStabs() {
3799 return TokError(
"unsupported directive '.stabs'");
3804bool AsmParser::parseDirectiveCVFile() {
3805 SMLoc FileNumberLoc = getTok().getLoc();
3808 std::string Checksum;
3811 if (parseIntToken(FileNumber,
"expected file number") ||
3812 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
3814 "unexpected token in '.cv_file' directive") ||
3819 "unexpected token in '.cv_file' directive") ||
3820 parseEscapedString(Checksum) ||
3821 parseIntToken(ChecksumKind,
3822 "expected checksum kind in '.cv_file' directive") ||
3828 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
3829 memcpy(CKMem, Checksum.data(), Checksum.size());
3830 ArrayRef<uint8_t> ChecksumAsBytes(
reinterpret_cast<const uint8_t *
>(CKMem),
3833 if (!getStreamer().emitCVFileDirective(FileNumber,
Filename, ChecksumAsBytes,
3834 static_cast<uint8_t
>(ChecksumKind)))
3835 return Error(FileNumberLoc,
"file number already allocated");
3840bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
3841 StringRef DirectiveName) {
3843 return parseTokenLoc(Loc) ||
3844 parseIntToken(FunctionId,
"expected function id") ||
3845 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3846 "expected function id within range [0, UINT_MAX)");
3849bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3851 return parseTokenLoc(Loc) ||
3852 parseIntToken(FileNumber,
"expected file number") ||
3853 check(FileNumber < 1, Loc,
3854 "file number less than one in '" + DirectiveName +
3856 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3857 "unassigned file number in '" + DirectiveName +
"' directive");
3864bool AsmParser::parseDirectiveCVFuncId() {
3865 SMLoc FunctionIdLoc = getTok().getLoc();
3868 if (parseCVFunctionId(FunctionId,
".cv_func_id") || parseEOL())
3871 if (!getStreamer().emitCVFuncIdDirective(FunctionId))
3872 return Error(FunctionIdLoc,
"function id already allocated");
3885bool AsmParser::parseDirectiveCVInlineSiteId() {
3886 SMLoc FunctionIdLoc = getTok().getLoc();
3894 if (parseCVFunctionId(FunctionId,
".cv_inline_site_id"))
3899 getTok().getIdentifier() !=
"within"),
3900 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3905 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
3910 getTok().getIdentifier() !=
"inlined_at"),
3911 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3917 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
3918 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
3923 IACol = getTok().getIntVal();
3930 if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3931 IALine, IACol, FunctionIdLoc))
3932 return Error(FunctionIdLoc,
"function id already allocated");
3944bool AsmParser::parseDirectiveCVLoc() {
3945 SMLoc DirectiveLoc = getTok().getLoc();
3946 int64_t FunctionId, FileNumber;
3947 if (parseCVFunctionId(FunctionId,
".cv_loc") ||
3948 parseCVFileId(FileNumber,
".cv_loc"))
3951 int64_t LineNumber = 0;
3953 LineNumber = getTok().getIntVal();
3955 return TokError(
"line number less than zero in '.cv_loc' directive");
3959 int64_t ColumnPos = 0;
3961 ColumnPos = getTok().getIntVal();
3963 return TokError(
"column position less than zero in '.cv_loc' directive");
3967 bool PrologueEnd =
false;
3968 uint64_t IsStmt = 0;
3970 auto parseOp = [&]() ->
bool {
3972 SMLoc Loc = getTok().getLoc();
3973 if (parseIdentifier(Name))
3974 return TokError(
"unexpected token in '.cv_loc' directive");
3975 if (Name ==
"prologue_end")
3977 else if (Name ==
"is_stmt") {
3978 Loc = getTok().getLoc();
3979 const MCExpr *
Value;
3980 if (parseExpression(
Value))
3985 IsStmt = MCE->getValue();
3988 return Error(Loc,
"is_stmt value not 0 or 1");
3990 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
3995 if (parseMany(parseOp,
false ))
3998 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
3999 ColumnPos, PrologueEnd, IsStmt, StringRef(),
4006bool AsmParser::parseDirectiveCVLinetable() {
4009 SMLoc Loc = getTok().getLoc();
4010 if (parseCVFunctionId(FunctionId,
".cv_linetable") || parseComma() ||
4011 parseTokenLoc(Loc) ||
4012 check(
parseSymbol(FnStartSym), Loc,
"expected identifier in directive") ||
4013 parseComma() || parseTokenLoc(Loc) ||
4014 check(
parseSymbol(FnEndSym), Loc,
"expected identifier in directive"))
4017 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
4023bool AsmParser::parseDirectiveCVInlineLinetable() {
4024 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
4026 SMLoc Loc = getTok().getLoc();
4027 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
4028 parseTokenLoc(Loc) ||
4029 parseIntToken(SourceFileId,
"expected SourceField") ||
4030 check(SourceFileId <= 0, Loc,
"File id less than zero") ||
4031 parseTokenLoc(Loc) ||
4032 parseIntToken(SourceLineNum,
"expected SourceLineNum") ||
4033 check(SourceLineNum < 0, Loc,
"Line number less than zero") ||
4034 parseTokenLoc(Loc) ||
4035 check(
parseSymbol(FnStartSym), Loc,
"expected identifier") ||
4036 parseTokenLoc(Loc) ||
4037 check(
parseSymbol(FnEndSym), Loc,
"expected identifier"))
4043 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
4044 SourceLineNum, FnStartSym,
4049void AsmParser::initializeCVDefRangeTypeMap() {
4050 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
4051 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4052 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4053 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4054 CVDefRangeTypeMap[
"reg_rel_indir"] = CVDR_DEFRANGE_REGISTER_REL_INDIR;
4059bool AsmParser::parseDirectiveCVDefRange() {
4061 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
4063 Loc = getLexer().getLoc();
4066 return Error(Loc,
"expected identifier in directive");
4068 Loc = getLexer().getLoc();
4071 return Error(Loc,
"expected identifier in directive");
4073 Ranges.push_back({GapStartSym, GapEndSym});
4076 StringRef CVDefRangeTypeStr;
4079 "expected comma before def_range type in .cv_def_range directive") ||
4080 parseIdentifier(CVDefRangeTypeStr))
4081 return Error(Loc,
"expected def_range type in directive");
4084 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4085 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4087 : CVTypeIt->getValue();
4089 case CVDR_DEFRANGE_REGISTER: {
4091 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4092 ".cv_def_range directive") ||
4093 parseAbsoluteExpression(DRRegister))
4094 return Error(Loc,
"expected register number");
4096 codeview::DefRangeRegisterHeader DRHdr;
4099 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4102 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4105 "expected comma before offset in .cv_def_range directive") ||
4106 parseAbsoluteExpression(DROffset))
4107 return Error(Loc,
"expected offset value");
4109 codeview::DefRangeFramePointerRelHeader DRHdr;
4111 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4114 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4116 int64_t DROffsetInParent;
4117 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4118 ".cv_def_range directive") ||
4119 parseAbsoluteExpression(DRRegister))
4120 return Error(Loc,
"expected register number");
4122 "expected comma before offset in .cv_def_range directive") ||
4123 parseAbsoluteExpression(DROffsetInParent))
4124 return Error(Loc,
"expected offset value");
4126 codeview::DefRangeSubfieldRegisterHeader DRHdr;
4130 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4133 case CVDR_DEFRANGE_REGISTER_REL: {
4136 int64_t DRBasePointerOffset;
4137 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4138 ".cv_def_range directive") ||
4139 parseAbsoluteExpression(DRRegister))
4140 return Error(Loc,
"expected register value");
4143 "expected comma before flag value in .cv_def_range directive") ||
4144 parseAbsoluteExpression(DRFlags))
4145 return Error(Loc,
"expected flag value");
4146 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
4147 "in .cv_def_range directive") ||
4148 parseAbsoluteExpression(DRBasePointerOffset))
4149 return Error(Loc,
"expected base pointer offset value");
4151 codeview::DefRangeRegisterRelHeader DRHdr;
4153 DRHdr.
Flags = DRFlags;
4155 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4158 case CVDR_DEFRANGE_REGISTER_REL_INDIR: {
4161 int64_t DRBasePointerOffset;
4162 int64_t DROffsetInUdt;
4163 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4164 ".cv_def_range directive") ||
4165 parseAbsoluteExpression(DRRegister))
4166 return Error(Loc,
"expected register value");
4169 "expected comma before flag value in .cv_def_range directive") ||
4170 parseAbsoluteExpression(DRFlags))
4171 return Error(Loc,
"expected flag value");
4172 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
4173 "in .cv_def_range directive") ||
4174 parseAbsoluteExpression(DRBasePointerOffset))
4175 return Error(Loc,
"expected base pointer offset value");
4176 if (parseToken(
AsmToken::Comma,
"expected comma before offset in UDT "
4177 "in .cv_def_range directive") ||
4178 parseAbsoluteExpression(DROffsetInUdt))
4179 return Error(Loc,
"expected offset in UDT value");
4181 codeview::DefRangeRegisterRelIndirHeader DRHdr;
4183 DRHdr.
Flags = DRFlags;
4186 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4190 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
4197bool AsmParser::parseDirectiveCVString() {
4199 if (checkForValidSection() || parseEscapedString(
Data))
4203 std::pair<StringRef, unsigned> Insertion =
4204 getCVContext().addToStringTable(
Data);
4205 getStreamer().emitInt32(Insertion.second);
4211bool AsmParser::parseDirectiveCVStringTable() {
4212 getStreamer().emitCVStringTableDirective();
4218bool AsmParser::parseDirectiveCVFileChecksums() {
4219 getStreamer().emitCVFileChecksumsDirective();
4225bool AsmParser::parseDirectiveCVFileChecksumOffset() {
4227 if (parseIntToken(FileNo))
4231 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4237bool AsmParser::parseDirectiveCVFPOData() {
4238 SMLoc DirLoc = getLexer().getLoc();
4241 return TokError(
"expected symbol name");
4244 getStreamer().emitCVFPOData(ProcSym, DirLoc);
4250bool AsmParser::parseDirectiveCFISections() {
4254 bool SFrame =
false;
4258 if (parseIdentifier(Name))
4259 return TokError(
"expected .eh_frame, .debug_frame, or .sframe");
4260 if (Name ==
".eh_frame")
4262 else if (Name ==
".debug_frame")
4264 else if (Name ==
".sframe")
4272 getStreamer().emitCFISections(EH,
Debug, SFrame);
4278bool AsmParser::parseDirectiveCFIStartProc() {
4279 CFIStartProcLoc = StartTokLoc;
4283 if (check(parseIdentifier(
Simple) ||
Simple !=
"simple",
4284 "unexpected token") ||
4294 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
4300bool AsmParser::parseDirectiveCFIEndProc() {
4301 CFIStartProcLoc = std::nullopt;
4306 getStreamer().emitCFIEndProc();
4311bool AsmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
4312 SMLoc DirectiveLoc) {
4316 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4320 return parseAbsoluteExpression(
Register);
4327bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
4329 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4330 parseAbsoluteExpression(
Offset) || parseEOL())
4339bool AsmParser::parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc) {
4341 if (parseAbsoluteExpression(
Offset) || parseEOL())
4344 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
4350bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
4351 int64_t Register1 = 0, Register2 = 0;
4352 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
4353 parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
4356 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
4362bool AsmParser::parseDirectiveCFIWindowSave(SMLoc DirectiveLoc) {
4365 getStreamer().emitCFIWindowSave(DirectiveLoc);
4371bool AsmParser::parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc) {
4372 int64_t Adjustment = 0;
4373 if (parseAbsoluteExpression(Adjustment) || parseEOL())
4376 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
4382bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
4384 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4387 getStreamer().emitCFIDefCfaRegister(
Register, DirectiveLoc);
4393bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc) {
4395 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4396 parseAbsoluteExpression(
Offset) || parseComma() ||
4407bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
4411 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4412 parseAbsoluteExpression(
Offset) || parseEOL())
4421bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
4424 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4425 parseAbsoluteExpression(
Offset) || parseEOL())
4433 if (Encoding & ~0xff)
4439 const unsigned Format = Encoding & 0xf;
4446 const unsigned Application = Encoding & 0x70;
4458bool AsmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
4459 int64_t Encoding = 0;
4460 if (parseAbsoluteExpression(Encoding))
4468 check(
parseSymbol(Sym),
"expected identifier in directive") || parseEOL())
4472 getStreamer().emitCFIPersonality(Sym, Encoding);
4474 getStreamer().emitCFILsda(Sym, Encoding);
4480bool AsmParser::parseDirectiveCFIRememberState(SMLoc DirectiveLoc) {
4483 getStreamer().emitCFIRememberState(DirectiveLoc);
4489bool AsmParser::parseDirectiveCFIRestoreState(SMLoc DirectiveLoc) {
4492 getStreamer().emitCFIRestoreState(DirectiveLoc);
4498bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
4501 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4504 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
4510bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
4512 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4515 getStreamer().emitCFIRestore(
Register, DirectiveLoc);
4521bool AsmParser::parseDirectiveCFIEscape(SMLoc DirectiveLoc) {
4524 if (parseAbsoluteExpression(CurrValue))
4527 Values.push_back((uint8_t)CurrValue);
4532 if (parseAbsoluteExpression(CurrValue))
4535 Values.push_back((uint8_t)CurrValue);
4538 getStreamer().emitCFIEscape(
Values, DirectiveLoc);
4544bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4546 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4548 getStreamer().emitCFIReturnColumn(
Register);
4554bool AsmParser::parseDirectiveCFISignalFrame(SMLoc DirectiveLoc) {
4558 getStreamer().emitCFISignalFrame();
4564bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4567 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4570 getStreamer().emitCFIUndefined(
Register, DirectiveLoc);
4576bool AsmParser::parseDirectiveCFILLVMRegisterPair(SMLoc DirectiveLoc) {
4578 int64_t R1 = 0,
R2 = 0;
4579 int64_t R1Size = 0, R2Size = 0;
4581 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4582 parseRegisterOrRegisterNumber(R1, DirectiveLoc) || parseComma() ||
4583 parseAbsoluteExpression(R1Size) || parseComma() ||
4584 parseRegisterOrRegisterNumber(
R2, DirectiveLoc) || parseComma() ||
4585 parseAbsoluteExpression(R2Size) || parseEOL())
4588 getStreamer().emitCFILLVMRegisterPair(
Register, R1, R1Size,
R2, R2Size,
4595bool AsmParser::parseDirectiveCFILLVMVectorRegisters(SMLoc DirectiveLoc) {
4597 std::vector<MCCFIInstruction::VectorRegisterWithLane> VRs;
4599 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma())
4603 int64_t VectorRegister = 0;
4606 if (parseRegisterOrRegisterNumber(VectorRegister, DirectiveLoc) ||
4607 parseComma() || parseIntToken(Lane,
"expected a lane number") ||
4608 parseComma() || parseAbsoluteExpression(
Size))
4610 VRs.push_back({unsigned(VectorRegister), unsigned(Lane), unsigned(
Size)});
4616 getStreamer().emitCFILLVMVectorRegisters(
Register, std::move(VRs),
4623bool AsmParser::parseDirectiveCFILLVMVectorOffset(SMLoc DirectiveLoc) {
4624 int64_t
Register = 0, MaskRegister = 0;
4625 int64_t RegisterSize = 0, MaskRegisterSize = 0;
4628 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4629 parseAbsoluteExpression(RegisterSize) || parseComma() ||
4630 parseRegisterOrRegisterNumber(MaskRegister, DirectiveLoc) ||
4631 parseComma() || parseAbsoluteExpression(MaskRegisterSize) ||
4632 parseComma() || parseAbsoluteExpression(
Offset) || parseEOL())
4635 getStreamer().emitCFILLVMVectorOffset(
Register, RegisterSize, MaskRegister,
4636 MaskRegisterSize,
Offset, DirectiveLoc);
4643bool AsmParser::parseDirectiveCFILLVMVectorRegisterMask(SMLoc DirectiveLoc) {
4644 int64_t
Register = 0, SpillReg = 0, MaskReg = 0;
4645 int64_t SpillRegLaneSize = 0, MaskRegSize = 0;
4647 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4648 parseRegisterOrRegisterNumber(SpillReg, DirectiveLoc) || parseComma() ||
4649 parseAbsoluteExpression(SpillRegLaneSize) || parseComma() ||
4650 parseRegisterOrRegisterNumber(MaskReg, DirectiveLoc) || parseComma() ||
4651 parseAbsoluteExpression(MaskRegSize) || parseEOL())
4654 getStreamer().emitCFILLVMVectorRegisterMask(
4655 Register, SpillReg, SpillRegLaneSize, MaskReg, MaskRegSize, DirectiveLoc);
4661bool AsmParser::parseDirectiveCFILabel(SMLoc Loc) {
4664 if (parseIdentifier(Name))
4665 return TokError(
"expected identifier");
4668 getStreamer().emitCFILabelDirective(Loc, Name);
4674bool AsmParser::parseDirectiveCFIValOffset(SMLoc DirectiveLoc) {
4678 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4679 parseAbsoluteExpression(
Offset) || parseEOL())
4689bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
4692 AltMacroMode = (Directive ==
".altmacro");
4699bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
4702 setMacrosEnabled(Directive ==
".macros_on");
4708bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4710 if (parseIdentifier(Name))
4711 return TokError(
"expected identifier in '.macro' directive");
4720 return Error(Lexer.
getLoc(),
"vararg parameter '" +
4722 "' should be the last parameter");
4726 return TokError(
"expected identifier in '.macro' directive");
4729 for (
const MCAsmMacroParameter& CurrParam : Parameters)
4731 return TokError(
"macro '" + Name +
"' has multiple parameters"
4740 QualLoc = Lexer.
getLoc();
4741 if (parseIdentifier(Qualifier))
4742 return Error(QualLoc,
"missing parameter qualifier for "
4743 "'" +
Parameter.Name +
"' in macro '" + Name +
"'");
4745 if (Qualifier ==
"req")
4747 else if (Qualifier ==
"vararg")
4750 return Error(QualLoc, Qualifier +
" is not a valid parameter qualifier "
4751 "for '" +
Parameter.Name +
"' in macro '" + Name +
"'");
4759 ParamLoc = Lexer.
getLoc();
4760 if (parseMacroArgument(
Parameter.Value,
false ))
4764 Warning(ParamLoc,
"pointless default value for required parameter "
4765 "'" +
Parameter.Name +
"' in macro '" + Name +
"'");
4778 AsmToken EndToken, StartToken = getTok();
4779 unsigned MacroDepth = 0;
4789 return Error(DirectiveLoc,
"no matching '.endmacro' in definition");
4794 if (getTok().getIdentifier() ==
".endm" ||
4795 getTok().getIdentifier() ==
".endmacro") {
4796 if (MacroDepth == 0) {
4797 EndToken = getTok();
4800 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
4807 }
else if (getTok().getIdentifier() ==
".macro") {
4813 (void)parseCppHashLineFilenameComment(getLexer().getLoc());
4817 eatToEndOfStatement();
4821 return Error(DirectiveLoc,
"macro '" + Name +
"' is already defined");
4826 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
4827 checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4828 MCAsmMacro
Macro(Name, Body, std::move(Parameters));
4849void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
4855 if (NParameters == 0)
4858 bool NamedParametersFound =
false;
4859 bool PositionalParametersFound =
false;
4864 while (!Body.
empty()) {
4866 std::size_t End = Body.
size(), Pos = 0;
4867 for (; Pos != End; ++Pos) {
4870 if (Body[Pos] ==
'\\' && Pos + 1 != End)
4874 if (Body[Pos] !=
'$' || Pos + 1 == End)
4876 char Next = Body[Pos + 1];
4878 isdigit(
static_cast<unsigned char>(
Next)))
4886 if (Body[Pos] ==
'$') {
4887 switch (Body[Pos + 1]) {
4894 PositionalParametersFound =
true;
4899 PositionalParametersFound =
true;
4905 unsigned I = Pos + 1;
4909 const char *Begin = Body.
data() + Pos + 1;
4910 StringRef
Argument(Begin,
I - (Pos + 1));
4913 if (Parameters[Index].Name == Argument)
4916 if (Index == NParameters) {
4917 if (Body[Pos + 1] ==
'(' && Body[Pos + 2] ==
')')
4923 NamedParametersFound =
true;
4931 if (!NamedParametersFound && PositionalParametersFound)
4932 Warning(DirectiveLoc,
"macro defined with named parameters which are not "
4933 "used in macro body, possible positional parameter "
4934 "found in body which will have no effect");
4939bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
4943 if (!isInsideMacroInstantiation())
4944 return TokError(
"unexpected '" + Directive +
"' in file, "
4945 "no current macro definition");
4948 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4949 TheCondState = TheCondStack.back();
4950 TheCondStack.pop_back();
4960bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
4962 return TokError(
"unexpected token in '" + Directive +
"' directive");
4966 if (isInsideMacroInstantiation()) {
4973 return TokError(
"unexpected '" + Directive +
"' in file, "
4974 "no current macro definition");
4979bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4982 if (parseTokenLoc(Loc) ||
4983 check(parseIdentifier(Name), Loc,
4984 "expected identifier in '.purgem' directive") ||
4989 return Error(DirectiveLoc,
"macro '" + Name +
"' is not defined");
4993 <<
"Un-defining macro: " << Name <<
"\n");
4999bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
5000 SMLoc NumBytesLoc = Lexer.
getLoc();
5001 const MCExpr *NumBytes;
5002 if (checkForValidSection() || parseExpression(NumBytes))
5005 int64_t FillExpr = 0;
5007 if (parseAbsoluteExpression(FillExpr))
5013 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
5020bool AsmParser::parseDirectiveDCB(StringRef IDVal,
unsigned Size) {
5021 SMLoc NumValuesLoc = Lexer.
getLoc();
5023 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
5026 if (NumValues < 0) {
5027 Warning(NumValuesLoc,
"'" + Twine(IDVal) +
"' directive with negative repeat count has no effect");
5034 const MCExpr *
Value;
5035 SMLoc ExprLoc = getLexer().getLoc();
5036 if (parseExpression(
Value))
5042 uint64_t IntValue = MCE->getValue();
5044 return Error(ExprLoc,
"literal value out of range for directive");
5045 for (uint64_t i = 0, e = NumValues; i !=
e; ++i)
5046 getStreamer().emitIntValue(IntValue,
Size);
5048 for (uint64_t i = 0, e = NumValues; i !=
e; ++i)
5049 getStreamer().emitValue(
Value,
Size, ExprLoc);
5057bool AsmParser::parseDirectiveRealDCB(StringRef IDVal,
const fltSemantics &Semantics) {
5058 SMLoc NumValuesLoc = Lexer.
getLoc();
5060 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
5063 if (NumValues < 0) {
5064 Warning(NumValuesLoc,
"'" + Twine(IDVal) +
"' directive with negative repeat count has no effect");
5072 if (parseRealValue(Semantics, AsInt) || parseEOL())
5075 for (uint64_t i = 0, e = NumValues; i !=
e; ++i)
5084bool AsmParser::parseDirectiveDS(StringRef IDVal,
unsigned Size) {
5085 SMLoc NumValuesLoc = Lexer.
getLoc();
5087 if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
5091 if (NumValues < 0) {
5092 Warning(NumValuesLoc,
"'" + Twine(IDVal) +
"' directive with negative repeat count has no effect");
5096 for (uint64_t i = 0, e = NumValues; i !=
e; ++i)
5097 getStreamer().emitFill(
Size, 0);
5104bool AsmParser::parseDirectiveLEB128(
bool Signed) {
5105 if (checkForValidSection())
5108 auto parseOp = [&]() ->
bool {
5109 const MCExpr *
Value;
5110 if (parseExpression(
Value))
5113 getStreamer().emitSLEB128Value(
Value);
5115 getStreamer().emitULEB128Value(
Value);
5119 return parseMany(parseOp);
5124bool AsmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
5125 auto parseOp = [&]() ->
bool {
5127 SMLoc Loc = getTok().getLoc();
5128 if (parseIdentifier(Name))
5129 return Error(Loc,
"expected identifier");
5131 if (discardLTOSymbol(Name))
5139 return Error(Loc,
"non-local symbol required");
5141 if (!getStreamer().emitSymbolAttribute(Sym, Attr))
5142 return Error(Loc,
"unable to emit symbol attribute");
5146 return parseMany(parseOp);
5151bool AsmParser::parseDirectiveComm(
bool IsLocal) {
5152 if (checkForValidSection())
5155 SMLoc IDLoc = getLexer().getLoc();
5158 return TokError(
"expected identifier in directive");
5164 SMLoc SizeLoc = getLexer().getLoc();
5165 if (parseAbsoluteExpression(
Size))
5168 int64_t Pow2Alignment = 0;
5169 SMLoc Pow2AlignmentLoc;
5172 Pow2AlignmentLoc = getLexer().getLoc();
5173 if (parseAbsoluteExpression(Pow2Alignment))
5178 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
5184 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
5185 Pow2Alignment =
Log2_64(Pow2Alignment);
5195 return Error(SizeLoc,
"size must be non-negative");
5199 return Error(IDLoc,
"invalid symbol redefinition");
5203 getStreamer().emitLocalCommonSymbol(Sym,
Size,
5204 Align(1ULL << Pow2Alignment));
5208 getStreamer().emitCommonSymbol(Sym,
Size,
Align(1ULL << Pow2Alignment));
5214bool AsmParser::parseDirectiveAbort(SMLoc DirectiveLoc) {
5215 StringRef Str = parseStringToEndOfStatement();
5220 return Error(DirectiveLoc,
".abort detected. Assembly stopping");
5223 return Error(DirectiveLoc,
5224 ".abort '" + Str +
"' detected. Assembly stopping");
5229bool AsmParser::parseDirectiveInclude() {
5232 SMLoc IncludeLoc = getTok().getLoc();
5235 "expected string in '.include' directive") ||
5238 "unexpected token in '.include' directive") ||
5241 check(enterIncludeFile(
Filename), IncludeLoc,
5242 "Could not find include file '" +
Filename +
"'"))
5250bool AsmParser::parseDirectiveIncbin() {
5253 SMLoc IncbinLoc = getTok().getLoc();
5255 "expected string in '.incbin' directive") ||
5260 const MCExpr *
Count =
nullptr;
5261 SMLoc SkipLoc, CountLoc;
5266 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
5270 CountLoc = getTok().getLoc();
5271 if (parseExpression(
Count))
5279 if (check(Skip < 0, SkipLoc,
"skip is negative"))
5284 return Error(IncbinLoc,
"Could not find incbin file '" +
Filename +
"'");
5290bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
5291 TheCondStack.push_back(TheCondState);
5293 if (TheCondState.
Ignore) {
5294 eatToEndOfStatement();
5297 if (parseAbsoluteExpression(ExprValue) || parseEOL())
5307 ExprValue = ExprValue == 0;
5310 ExprValue = ExprValue >= 0;
5313 ExprValue = ExprValue > 0;
5316 ExprValue = ExprValue <= 0;
5319 ExprValue = ExprValue < 0;
5323 TheCondState.
CondMet = ExprValue;
5332bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc,
bool ExpectBlank) {
5333 TheCondStack.push_back(TheCondState);
5336 if (TheCondState.
Ignore) {
5337 eatToEndOfStatement();
5339 StringRef Str = parseStringToEndOfStatement();
5344 TheCondState.
CondMet = ExpectBlank == Str.empty();
5354bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc,
bool ExpectEqual) {
5355 TheCondStack.push_back(TheCondState);
5358 if (TheCondState.
Ignore) {
5359 eatToEndOfStatement();
5361 StringRef Str1 = parseStringToComma();
5366 StringRef Str2 = parseStringToEndOfStatement();
5380bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc,
bool ExpectEqual) {
5381 TheCondStack.push_back(TheCondState);
5384 if (TheCondState.
Ignore) {
5385 eatToEndOfStatement();
5389 return TokError(
"expected string parameter for '.ifeqs' directive");
5390 return TokError(
"expected string parameter for '.ifnes' directive");
5393 StringRef String1 = getTok().getStringContents();
5399 "expected comma after first string for '.ifeqs' directive");
5401 "expected comma after first string for '.ifnes' directive");
5408 return TokError(
"expected string parameter for '.ifeqs' directive");
5409 return TokError(
"expected string parameter for '.ifnes' directive");
5412 StringRef String2 = getTok().getStringContents();
5415 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
5424bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc,
bool expect_defined) {
5426 TheCondStack.push_back(TheCondState);
5429 if (TheCondState.
Ignore) {
5430 eatToEndOfStatement();
5432 if (check(parseIdentifier(Name),
"expected identifier after '.ifdef'") ||
5450bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
5453 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
5454 " .if or an .elseif");
5457 bool LastIgnoreState =
false;
5458 if (!TheCondStack.empty())
5459 LastIgnoreState = TheCondStack.back().Ignore;
5460 if (LastIgnoreState || TheCondState.
CondMet) {
5461 TheCondState.
Ignore =
true;
5462 eatToEndOfStatement();
5465 if (parseAbsoluteExpression(ExprValue))
5471 TheCondState.
CondMet = ExprValue;
5480bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5486 return Error(DirectiveLoc,
"Encountered a .else that doesn't follow "
5487 " an .if or an .elseif");
5489 bool LastIgnoreState =
false;
5490 if (!TheCondStack.empty())
5491 LastIgnoreState = TheCondStack.back().Ignore;
5492 if (LastIgnoreState || TheCondState.
CondMet)
5493 TheCondState.
Ignore =
true;
5495 TheCondState.
Ignore =
false;
5502bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5515bool AsmParser::parseDirectiveError(SMLoc L,
bool WithMessage) {
5516 if (!TheCondStack.empty()) {
5517 if (TheCondStack.back().Ignore) {
5518 eatToEndOfStatement();
5524 return Error(L,
".err encountered");
5526 StringRef Message =
".error directive invoked in source file";
5529 return TokError(
".error argument must be a string");
5531 Message = getTok().getStringContents();
5535 return Error(L, Message);
5540bool AsmParser::parseDirectiveWarning(SMLoc L) {
5541 if (!TheCondStack.empty()) {
5542 if (TheCondStack.back().Ignore) {
5543 eatToEndOfStatement();
5548 StringRef Message =
".warning directive invoked in source file";
5552 return TokError(
".warning argument must be a string");
5554 Message = getTok().getStringContents();
5565bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5570 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
5572 if (!TheCondStack.empty()) {
5573 TheCondState = TheCondStack.back();
5574 TheCondStack.pop_back();
5580void AsmParser::initializeDirectiveKindMap() {
5587 DirectiveKindMap[
".set"] = DK_SET;
5588 DirectiveKindMap[
".equ"] = DK_EQU;
5589 DirectiveKindMap[
".equiv"] = DK_EQUIV;
5590 DirectiveKindMap[
".ascii"] = DK_ASCII;
5591 DirectiveKindMap[
".asciz"] = DK_ASCIZ;
5592 DirectiveKindMap[
".string"] = DK_STRING;
5593 DirectiveKindMap[
".byte"] = DK_BYTE;
5594 DirectiveKindMap[
".base64"] = DK_BASE64;
5595 DirectiveKindMap[
".short"] = DK_SHORT;
5596 DirectiveKindMap[
".value"] = DK_VALUE;
5597 DirectiveKindMap[
".2byte"] = DK_2BYTE;
5598 DirectiveKindMap[
".long"] = DK_LONG;
5599 DirectiveKindMap[
".int"] = DK_INT;
5600 DirectiveKindMap[
".4byte"] = DK_4BYTE;
5601 DirectiveKindMap[
".quad"] = DK_QUAD;
5602 DirectiveKindMap[
".8byte"] = DK_8BYTE;
5603 DirectiveKindMap[
".octa"] = DK_OCTA;
5604 DirectiveKindMap[
".single"] = DK_SINGLE;
5605 DirectiveKindMap[
".float"] = DK_FLOAT;
5606 DirectiveKindMap[
".double"] = DK_DOUBLE;
5607 DirectiveKindMap[
".align"] = DK_ALIGN;
5608 DirectiveKindMap[
".align32"] = DK_ALIGN32;
5609 DirectiveKindMap[
".balign"] = DK_BALIGN;
5610 DirectiveKindMap[
".balignw"] = DK_BALIGNW;
5611 DirectiveKindMap[
".balignl"] = DK_BALIGNL;
5612 DirectiveKindMap[
".p2align"] = DK_P2ALIGN;
5613 DirectiveKindMap[
".p2alignw"] = DK_P2ALIGNW;
5614 DirectiveKindMap[
".p2alignl"] = DK_P2ALIGNL;
5615 DirectiveKindMap[
".prefalign"] = DK_PREFALIGN;
5616 DirectiveKindMap[
".org"] = DK_ORG;
5617 DirectiveKindMap[
".fill"] = DK_FILL;
5618 DirectiveKindMap[
".zero"] = DK_ZERO;
5619 DirectiveKindMap[
".extern"] = DK_EXTERN;
5620 DirectiveKindMap[
".globl"] = DK_GLOBL;
5621 DirectiveKindMap[
".global"] = DK_GLOBAL;
5622 DirectiveKindMap[
".lazy_reference"] = DK_LAZY_REFERENCE;
5623 DirectiveKindMap[
".no_dead_strip"] = DK_NO_DEAD_STRIP;
5624 DirectiveKindMap[
".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5625 DirectiveKindMap[
".private_extern"] = DK_PRIVATE_EXTERN;
5626 DirectiveKindMap[
".reference"] = DK_REFERENCE;
5627 DirectiveKindMap[
".weak_definition"] = DK_WEAK_DEFINITION;
5628 DirectiveKindMap[
".weak_reference"] = DK_WEAK_REFERENCE;
5629 DirectiveKindMap[
".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5630 DirectiveKindMap[
".cold"] = DK_COLD;
5631 DirectiveKindMap[
".comm"] = DK_COMM;
5632 DirectiveKindMap[
".common"] = DK_COMMON;
5633 DirectiveKindMap[
".lcomm"] = DK_LCOMM;
5634 DirectiveKindMap[
".abort"] = DK_ABORT;
5635 DirectiveKindMap[
".include"] = DK_INCLUDE;
5636 DirectiveKindMap[
".incbin"] = DK_INCBIN;
5637 DirectiveKindMap[
".code16"] = DK_CODE16;
5638 DirectiveKindMap[
".code16gcc"] = DK_CODE16GCC;
5639 DirectiveKindMap[
".rept"] = DK_REPT;
5640 DirectiveKindMap[
".rep"] = DK_REPT;
5641 DirectiveKindMap[
".irp"] = DK_IRP;
5642 DirectiveKindMap[
".irpc"] = DK_IRPC;
5643 DirectiveKindMap[
".endr"] = DK_ENDR;
5644 DirectiveKindMap[
".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5645 DirectiveKindMap[
".bundle_lock"] = DK_BUNDLE_LOCK;
5646 DirectiveKindMap[
".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5647 DirectiveKindMap[
".if"] = DK_IF;
5648 DirectiveKindMap[
".ifeq"] = DK_IFEQ;
5649 DirectiveKindMap[
".ifge"] = DK_IFGE;
5650 DirectiveKindMap[
".ifgt"] = DK_IFGT;
5651 DirectiveKindMap[
".ifle"] = DK_IFLE;
5652 DirectiveKindMap[
".iflt"] = DK_IFLT;
5653 DirectiveKindMap[
".ifne"] = DK_IFNE;
5654 DirectiveKindMap[
".ifb"] = DK_IFB;
5655 DirectiveKindMap[
".ifnb"] = DK_IFNB;
5656 DirectiveKindMap[
".ifc"] = DK_IFC;
5657 DirectiveKindMap[
".ifeqs"] = DK_IFEQS;
5658 DirectiveKindMap[
".ifnc"] = DK_IFNC;
5659 DirectiveKindMap[
".ifnes"] = DK_IFNES;
5660 DirectiveKindMap[
".ifdef"] = DK_IFDEF;
5661 DirectiveKindMap[
".ifndef"] = DK_IFNDEF;
5662 DirectiveKindMap[
".ifnotdef"] = DK_IFNOTDEF;
5663 DirectiveKindMap[
".elseif"] = DK_ELSEIF;
5664 DirectiveKindMap[
".else"] = DK_ELSE;
5665 DirectiveKindMap[
".end"] = DK_END;
5666 DirectiveKindMap[
".endif"] = DK_ENDIF;
5667 DirectiveKindMap[
".skip"] = DK_SKIP;
5668 DirectiveKindMap[
".space"] = DK_SPACE;
5669 DirectiveKindMap[
".file"] = DK_FILE;
5670 DirectiveKindMap[
".line"] = DK_LINE;
5671 DirectiveKindMap[
".loc"] = DK_LOC;
5672 DirectiveKindMap[
".loc_label"] = DK_LOC_LABEL;
5673 DirectiveKindMap[
".stabs"] = DK_STABS;
5674 DirectiveKindMap[
".cv_file"] = DK_CV_FILE;
5675 DirectiveKindMap[
".cv_func_id"] = DK_CV_FUNC_ID;
5676 DirectiveKindMap[
".cv_loc"] = DK_CV_LOC;
5677 DirectiveKindMap[
".cv_linetable"] = DK_CV_LINETABLE;
5678 DirectiveKindMap[
".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5679 DirectiveKindMap[
".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5680 DirectiveKindMap[
".cv_def_range"] = DK_CV_DEF_RANGE;
5681 DirectiveKindMap[
".cv_string"] = DK_CV_STRING;
5682 DirectiveKindMap[
".cv_stringtable"] = DK_CV_STRINGTABLE;
5683 DirectiveKindMap[
".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5684 DirectiveKindMap[
".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5685 DirectiveKindMap[
".cv_fpo_data"] = DK_CV_FPO_DATA;
5686 DirectiveKindMap[
".sleb128"] = DK_SLEB128;
5687 DirectiveKindMap[
".uleb128"] = DK_ULEB128;
5688 DirectiveKindMap[
".cfi_sections"] = DK_CFI_SECTIONS;
5689 DirectiveKindMap[
".cfi_startproc"] = DK_CFI_STARTPROC;
5690 DirectiveKindMap[
".cfi_endproc"] = DK_CFI_ENDPROC;
5691 DirectiveKindMap[
".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5692 DirectiveKindMap[
".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5693 DirectiveKindMap[
".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5694 DirectiveKindMap[
".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5695 DirectiveKindMap[
".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
5696 DirectiveKindMap[
".cfi_offset"] = DK_CFI_OFFSET;
5697 DirectiveKindMap[
".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5698 DirectiveKindMap[
".cfi_llvm_register_pair"] = DK_CFI_LLVM_REGISTER_PAIR;
5699 DirectiveKindMap[
".cfi_llvm_vector_registers"] = DK_CFI_LLVM_VECTOR_REGISTERS;
5700 DirectiveKindMap[
".cfi_llvm_vector_offset"] = DK_CFI_LLVM_VECTOR_OFFSET;
5701 DirectiveKindMap[
".cfi_llvm_vector_register_mask"] =
5702 DK_CFI_LLVM_VECTOR_REGISTER_MASK;
5703 DirectiveKindMap[
".cfi_personality"] = DK_CFI_PERSONALITY;
5704 DirectiveKindMap[
".cfi_lsda"] = DK_CFI_LSDA;
5705 DirectiveKindMap[
".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5706 DirectiveKindMap[
".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5707 DirectiveKindMap[
".cfi_same_value"] = DK_CFI_SAME_VALUE;
5708 DirectiveKindMap[
".cfi_restore"] = DK_CFI_RESTORE;
5709 DirectiveKindMap[
".cfi_escape"] = DK_CFI_ESCAPE;
5710 DirectiveKindMap[
".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5711 DirectiveKindMap[
".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5712 DirectiveKindMap[
".cfi_undefined"] = DK_CFI_UNDEFINED;
5713 DirectiveKindMap[
".cfi_register"] = DK_CFI_REGISTER;
5714 DirectiveKindMap[
".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5715 DirectiveKindMap[
".cfi_label"] = DK_CFI_LABEL;
5716 DirectiveKindMap[
".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5717 DirectiveKindMap[
".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
5718 DirectiveKindMap[
".cfi_val_offset"] = DK_CFI_VAL_OFFSET;
5719 DirectiveKindMap[
".macros_on"] = DK_MACROS_ON;
5720 DirectiveKindMap[
".macros_off"] = DK_MACROS_OFF;
5721 DirectiveKindMap[
".macro"] = DK_MACRO;
5722 DirectiveKindMap[
".exitm"] = DK_EXITM;
5723 DirectiveKindMap[
".endm"] = DK_ENDM;
5724 DirectiveKindMap[
".endmacro"] = DK_ENDMACRO;
5725 DirectiveKindMap[
".purgem"] = DK_PURGEM;
5726 DirectiveKindMap[
".err"] = DK_ERR;
5727 DirectiveKindMap[
".error"] = DK_ERROR;
5728 DirectiveKindMap[
".warning"] = DK_WARNING;
5729 DirectiveKindMap[
".altmacro"] = DK_ALTMACRO;
5730 DirectiveKindMap[
".noaltmacro"] = DK_NOALTMACRO;
5731 DirectiveKindMap[
".reloc"] = DK_RELOC;
5732 DirectiveKindMap[
".dc"] = DK_DC;
5733 DirectiveKindMap[
".dc.a"] = DK_DC_A;
5734 DirectiveKindMap[
".dc.b"] = DK_DC_B;
5735 DirectiveKindMap[
".dc.d"] = DK_DC_D;
5736 DirectiveKindMap[
".dc.l"] = DK_DC_L;
5737 DirectiveKindMap[
".dc.s"] = DK_DC_S;
5738 DirectiveKindMap[
".dc.w"] = DK_DC_W;
5739 DirectiveKindMap[
".dc.x"] = DK_DC_X;
5740 DirectiveKindMap[
".dcb"] = DK_DCB;
5741 DirectiveKindMap[
".dcb.b"] = DK_DCB_B;
5742 DirectiveKindMap[
".dcb.d"] = DK_DCB_D;
5743 DirectiveKindMap[
".dcb.l"] = DK_DCB_L;
5744 DirectiveKindMap[
".dcb.s"] = DK_DCB_S;
5745 DirectiveKindMap[
".dcb.w"] = DK_DCB_W;
5746 DirectiveKindMap[
".dcb.x"] = DK_DCB_X;
5747 DirectiveKindMap[
".ds"] = DK_DS;
5748 DirectiveKindMap[
".ds.b"] = DK_DS_B;
5749 DirectiveKindMap[
".ds.d"] = DK_DS_D;
5750 DirectiveKindMap[
".ds.l"] = DK_DS_L;
5751 DirectiveKindMap[
".ds.p"] = DK_DS_P;
5752 DirectiveKindMap[
".ds.s"] = DK_DS_S;
5753 DirectiveKindMap[
".ds.w"] = DK_DS_W;
5754 DirectiveKindMap[
".ds.x"] = DK_DS_X;
5755 DirectiveKindMap[
".print"] = DK_PRINT;
5756 DirectiveKindMap[
".addrsig"] = DK_ADDRSIG;
5757 DirectiveKindMap[
".addrsig_sym"] = DK_ADDRSIG_SYM;
5758 DirectiveKindMap[
".pseudoprobe"] = DK_PSEUDO_PROBE;
5759 DirectiveKindMap[
".lto_discard"] = DK_LTO_DISCARD;
5760 DirectiveKindMap[
".lto_set_conditional"] = DK_LTO_SET_CONDITIONAL;
5761 DirectiveKindMap[
".memtag"] = DK_MEMTAG;
5764MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5765 AsmToken EndToken, StartToken = getTok();
5767 unsigned NestLevel = 0;
5771 printError(DirectiveLoc,
"no matching '.endr' in definition");
5776 StringRef Ident = getTok().getIdentifier();
5777 if (Ident ==
".rep" || Ident ==
".rept" || Ident ==
".irp" ||
5780 }
else if (Ident ==
".endr") {
5781 if (NestLevel == 0) {
5782 EndToken = getTok();
5786 printError(getTok().getLoc(),
"expected newline");
5794 eatToEndOfStatement();
5799 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5803 return &MacroLikeBodies.back();
5806void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5807 raw_svector_ostream &OS) {
5810 std::unique_ptr<MemoryBuffer> Instantiation =
5815 MacroInstantiation *
MI =
new MacroInstantiation{
5816 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5817 ActiveMacros.push_back(
MI);
5827bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5828 const MCExpr *CountExpr;
5829 SMLoc CountLoc = getTok().getLoc();
5830 if (parseExpression(CountExpr))
5834 if (!CountExpr->evaluateAsAbsolute(
Count, getStreamer().getAssemblerPtr())) {
5835 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
5838 if (check(
Count < 0, CountLoc,
"Count is negative") || parseEOL())
5842 MCAsmMacro *
M = parseMacroLikeBody(DirectiveLoc);
5848 SmallString<256> Buf;
5849 raw_svector_ostream OS(Buf);
5852 if (expandMacro(OS, *M, {}, {},
false))
5855 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5862bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5864 MCAsmMacroArguments
A;
5865 if (check(parseIdentifier(
Parameter.Name),
5866 "expected identifier in '.irp' directive") ||
5867 parseComma() || parseMacroArguments(
nullptr,
A) || parseEOL())
5871 MCAsmMacro *
M = parseMacroLikeBody(DirectiveLoc);
5877 SmallString<256> Buf;
5878 raw_svector_ostream OS(Buf);
5880 for (
const MCAsmMacroArgument &Arg :
A) {
5883 if (expandMacro(OS, *M, Parameter, Arg,
true))
5887 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5894bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5896 MCAsmMacroArguments
A;
5898 if (check(parseIdentifier(
Parameter.Name),
5899 "expected identifier in '.irpc' directive") ||
5900 parseComma() || parseMacroArguments(
nullptr,
A))
5903 if (
A.size() != 1 ||
A.front().size() != 1)
5904 return TokError(
"unexpected token in '.irpc' directive");
5909 MCAsmMacro *
M = parseMacroLikeBody(DirectiveLoc);
5915 SmallString<256> Buf;
5916 raw_svector_ostream OS(Buf);
5919 :
A[0][0].getString();
5920 for (std::size_t
I = 0, End =
Values.size();
I != End; ++
I) {
5921 MCAsmMacroArgument Arg;
5926 if (expandMacro(OS, *M, Parameter, Arg,
true))
5930 instantiateMacroLikeBody(M, DirectiveLoc, OS);
5935bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5936 if (ActiveMacros.empty())
5937 return TokError(
"unmatched '.endr' directive");
5947bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5949 const MCExpr *
Value;
5950 SMLoc ExprLoc = getLexer().getLoc();
5951 if (parseExpression(
Value))
5955 return Error(ExprLoc,
"unexpected expression in _emit");
5956 uint64_t IntValue = MCE->
getValue();
5958 return Error(ExprLoc,
"literal value out of range for directive");
5964bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5965 const MCExpr *
Value;
5966 SMLoc ExprLoc = getLexer().getLoc();
5967 if (parseExpression(
Value))
5971 return Error(ExprLoc,
"unexpected expression in align");
5972 uint64_t IntValue = MCE->
getValue();
5974 return Error(ExprLoc,
"literal value not a power of two greater then zero");
5980bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
5981 const AsmToken StrTok = getTok();
5984 return Error(DirectiveLoc,
"expected double quoted string after .print");
5991bool AsmParser::parseDirectiveAddrsig() {
5994 getStreamer().emitAddrsig();
5998bool AsmParser::parseDirectiveAddrsigSym() {
6000 if (check(
parseSymbol(Sym),
"expected identifier") || parseEOL())
6002 getStreamer().emitAddrsigSym(Sym);
6008bool AsmParser::parseDirectiveBundleAlignMode() {
6012 SMLoc ExprLoc = getLexer().getLoc();
6013 int64_t AlignSizePow2;
6014 if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
6016 check(AlignSizePow2 < 1 || AlignSizePow2 > 30, ExprLoc,
6017 "invalid bundle alignment size (expected between 1 and 30)"))
6020 getStreamer().emitBundleAlignMode(
Align(1ULL << AlignSizePow2));
6026bool AsmParser::parseDirectiveBundleLock() {
6027 if (checkForValidSection())
6029 bool AlignToEnd =
false;
6032 SMLoc Loc = getTok().getLoc();
6033 const char *InvalidOptionError =
"invalid option for `.bundle_lock`";
6036 if (check(parseIdentifier(Option), Loc, InvalidOptionError) ||
6037 check(Option !=
"align_to_end", Loc, InvalidOptionError) || parseEOL())
6042 getStreamer().emitBundleLock(AlignToEnd, getTargetParser().getSTI());
6048bool AsmParser::parseDirectiveBundleUnlock() {
6049 if (checkForValidSection() || parseEOL())
6052 getStreamer().emitBundleUnlock(getTargetParser().getSTI());
6056bool AsmParser::parseDirectivePseudoProbe() {
6062 if (parseIntToken(
Guid))
6064 if (parseIntToken(Index))
6066 if (parseIntToken(
Type))
6068 if (parseIntToken(Attr))
6080 int64_t CallerGuid = 0;
6082 CallerGuid = getTok().getIntVal();
6090 int64_t CallerProbeId = 0;
6092 CallerProbeId = getTok().getIntVal();
6102 if (parseIdentifier(FnName))
6103 return Error(getLexer().getLoc(),
"expected identifier");
6109 getStreamer().emitPseudoProbe(
Guid, Index,
Type, Attr, Discriminator,
6110 InlineStack, FnSym);
6119bool AsmParser::parseDirectiveLTODiscard() {
6120 auto ParseOp = [&]() ->
bool {
6122 SMLoc Loc = getTok().getLoc();
6123 if (parseIdentifier(Name))
6124 return Error(Loc,
"expected identifier");
6125 LTODiscardSymbols.
insert(Name);
6129 LTODiscardSymbols.
clear();
6130 return parseMany(ParseOp);
6156bool AsmParser::parseMSInlineAsm(
6157 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
6158 SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
6159 SmallVectorImpl<std::string> &Constraints,
6160 SmallVectorImpl<std::string> &Clobbers,
const MCInstrInfo *MII,
6161 MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
6162 SmallVector<void *, 4> InputDecls;
6163 SmallVector<void *, 4> OutputDecls;
6164 SmallVector<bool, 4> InputDeclsAddressOf;
6165 SmallVector<bool, 4> OutputDeclsAddressOf;
6166 SmallVector<std::string, 4> InputConstraints;
6167 SmallVector<std::string, 4> OutputConstraints;
6176 unsigned InputIdx = 0;
6177 unsigned OutputIdx = 0;
6180 if (parseCurlyBlockScope(AsmStrRewrites))
6183 ParseStatementInfo
Info(&AsmStrRewrites);
6184 bool StatementErr = parseStatement(Info, &SI);
6186 if (StatementErr ||
Info.ParseError) {
6188 printPendingErrors();
6193 assert(!hasPendingError() &&
"unexpected error from parseStatement");
6195 if (
Info.Opcode == ~0U)
6201 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
6202 MCParsedAsmOperand &Operand = *
Info.ParsedOperands[i];
6206 !getTargetParser().omitRegisterFromClobberLists(Operand.
getReg())) {
6207 unsigned NumDefs =
Desc.getNumDefs();
6216 if (SymName.
empty())
6224 if (Operand.
isImm()) {
6232 bool isOutput = (i == 1) &&
Desc.mayStore();
6239 OutputConstraints.
push_back((
"=" + Constraint).str());
6246 if (
Desc.operands()[i - 1].isBranchTarget())
6260 NumOutputs = OutputDecls.
size();
6261 NumInputs = InputDecls.
size();
6266 Clobbers.
assign(ClobberRegs.
size(), std::string());
6267 for (
unsigned I = 0,
E = ClobberRegs.
size();
I !=
E; ++
I) {
6268 raw_string_ostream OS(Clobbers[
I]);
6273 if (NumOutputs || NumInputs) {
6274 unsigned NumExprs = NumOutputs + NumInputs;
6275 OpDecls.resize(NumExprs);
6276 Constraints.
resize(NumExprs);
6277 for (
unsigned i = 0; i < NumOutputs; ++i) {
6278 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6279 Constraints[i] = OutputConstraints[i];
6281 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
6282 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6283 Constraints[
j] = InputConstraints[i];
6288 std::string AsmStringIR;
6289 raw_string_ostream OS(AsmStringIR);
6290 StringRef ASMString =
6292 const char *AsmStart = ASMString.
begin();
6293 const char *AsmEnd = ASMString.
end();
6295 for (
auto I = AsmStrRewrites.
begin(),
E = AsmStrRewrites.
end();
I !=
E; ++
I) {
6296 const AsmRewrite &AR = *
I;
6303 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
6306 if (
unsigned Len = Loc - AsmStart)
6307 OS << StringRef(AsmStart, Len);
6311 AsmStart = Loc + AR.
Len;
6315 unsigned AdditionalSkip = 0;
6337 size_t OffsetLen = OffsetName.
size();
6338 auto rewrite_it = std::find_if(
6339 I, AsmStrRewrites.
end(), [&](
const AsmRewrite &FusingAR) {
6340 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6341 (FusingAR.Kind == AOK_Input ||
6342 FusingAR.Kind == AOK_CallInput);
6344 if (rewrite_it == AsmStrRewrites.
end()) {
6345 OS <<
"offset " << OffsetName;
6347 OS <<
"${" << InputIdx++ <<
":P}";
6348 rewrite_it->Done =
true;
6350 OS <<
'$' << InputIdx++;
6351 rewrite_it->Done =
true;
6364 OS <<
"${" << InputIdx++ <<
":P}";
6366 OS <<
'$' << InputIdx++;
6369 OS <<
"${" << InputIdx++ <<
":P}";
6373 OS <<
"${" << OutputIdx++ <<
":P}";
6375 OS <<
'$' << OutputIdx++;
6380 case 8: OS <<
"byte ptr ";
break;
6381 case 16: OS <<
"word ptr ";
break;
6382 case 32: OS <<
"dword ptr ";
break;
6383 case 64: OS <<
"qword ptr ";
break;
6384 case 80: OS <<
"xword ptr ";
break;
6385 case 128: OS <<
"xmmword ptr ";
break;
6386 case 256: OS <<
"ymmword ptr ";
break;
6396 if (
getContext().getAsmInfo().getAlignmentIsInBytes())
6401 unsigned Val = AR.
Val;
6403 assert(Val < 10 &&
"Expected alignment less then 2^10.");
6404 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6416 AsmStart = Loc + AR.
Len + AdditionalSkip;
6420 if (AsmStart != AsmEnd)
6421 OS << StringRef(AsmStart, AsmEnd - AsmStart);
6423 AsmString = std::move(AsmStringIR);
6427bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
6428 MCAsmParserSemaCallback *SI) {
6429 AsmToken LabelTok = getTok();
6430 SMLoc LabelLoc = LabelTok.
getLoc();
6433 if (parseIdentifier(LabelVal))
6434 return Error(LabelLoc,
"The HLASM Label has to be an Identifier");
6439 if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
6448 return Error(LabelLoc,
6449 "Cannot have just a label for an HLASM inline asm statement");
6459 if (enabledGenDwarfForAssembly())
6466bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
6467 MCAsmParserSemaCallback *SI) {
6468 AsmToken OperationEntryTok = Lexer.
getTok();
6469 SMLoc OperationEntryLoc = OperationEntryTok.
getLoc();
6470 StringRef OperationEntryVal;
6473 if (parseIdentifier(OperationEntryVal))
6474 return Error(OperationEntryLoc,
"unexpected token at start of statement");
6480 return parseAndMatchAndEmitTargetInstruction(
6481 Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
6484bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
6485 MCAsmParserSemaCallback *SI) {
6486 assert(!hasPendingError() &&
"parseStatement started with pending error");
6489 bool ShouldParseAsHLASMLabel =
false;
6498 ShouldParseAsHLASMLabel =
true;
6504 if (getTok().getString().
empty() || getTok().getString().
front() ==
'\r' ||
6505 getTok().getString().
front() ==
'\n')
6520 if (getTok().getString().
front() ==
'\n' ||
6521 getTok().getString().
front() ==
'\r') {
6530 if (ShouldParseAsHLASMLabel) {
6533 if (parseAsHLASMLabel(Info, SI)) {
6536 eatToEndOfStatement();
6541 return parseAsMachineInstruction(Info, SI);
6553 return Parser.
TokError(
"missing expression");
6559 return Parser.
Error(
6560 EqualLoc,
"relocation specifier not permitted in symbol equating");
6568 return Parser.
Error(EqualLoc,
"redefinition of '" + Name +
"'");
6574 }
else if (Name ==
".") {
6589 if (
C.getTargetTriple().isSystemZ() &&
C.getTargetTriple().isOSzOS())
6590 return new HLASMAsmParser(
SM,
C, Out, MAI, CB);
6592 return new AsmParser(
SM,
C, Out, MAI, CB);
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)
static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc)
This function checks if the next token is <string> type or arithmetic.
static unsigned getDarwinBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)
static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI, AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)
static std::string angleBracketString(StringRef AltMacroStr)
creating a string without the escape characters '!'.
static int rewritesSort(const AsmRewrite *AsmRewriteA, const AsmRewrite *AsmRewriteB)
static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo)
static bool isOperator(AsmToken::TokenKind kind)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
static constexpr unsigned SM(unsigned Version)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr StringLiteral Filename
static StringRef getName(Value *V)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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
std::optional< uint32_t > getSpecifierForName(StringRef Name) const
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
bool shouldUseLogicalShr() const
StringRef getCommentString() const
StringRef getInternalSymbolPrefix() 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)
const AsmToken & getTok() const
Get the current AsmToken from the stream.
const MCExpr * applySpecifier(const MCExpr *E, uint32_t Variant)
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
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.
const MCAsmInfo & getAsmInfo() const
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.
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 initSections(const MCSubtargetInfo &STI)
Create the default sections and set the initial one.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
MCLFIRewriter * getLFIRewriter()
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.
LLVM_ABI void printIncludeStackForDiagnostic(SMLoc Loc, raw_ostream &OS) const
Prints the include stack of a buffer unless it is a macro instantiation buffer.
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 unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
LLVM_ABI ErrorOr< std::unique_ptr< MemoryBuffer > > OpenIncludeFile(const std::string &Filename, std::string &IncludedFile, bool RequiresNullTerminator=true)
Search for a file with the specified name in the current directory or in one of the IncludeDirs,...
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
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
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
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
Get the string size.
char front() const
Get the first character in the string.
constexpr const char * data() const
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.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
LLVM_ABI 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.
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.
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.
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.
RelativeUniformCounterPtr Values
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<X> - 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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI SourceMgr SrcMgr
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.
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<X> - 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.
@ Sub
Subtraction of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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<X> - 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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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.