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;
112 ParseStatementInfo() =
delete;
114 : AsmRewrites(rewrites) {}
126 void *SavedDiagContext;
127 std::unique_ptr<MCAsmParserExtension> PlatformParser;
129 std::optional<SMLoc> CFIStartProcLoc;
136 std::vector<AsmCond> TheCondStack;
144 std::vector<MacroInstantiation*> ActiveMacros;
147 std::deque<MCAsmMacro> MacroLikeBodies;
150 unsigned MacrosEnabledFlag : 1;
153 unsigned NumOfMacroInstantiations;
156 struct CppHashInfoTy {
161 CppHashInfoTy() : LineNumber(0), Buf(0) {}
163 CppHashInfoTy CppHashInfo;
174 unsigned AssemblerDialect = ~0
U;
177 bool IsDarwin =
false;
180 bool ParsingMSInlineAsm =
false;
183 bool ReportedInconsistentMD5 =
false;
186 bool AltMacroMode =
false;
189 virtual bool parseStatement(ParseStatementInfo &Info,
195 bool parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
202 bool enabledGenDwarfForAssembly();
207 AsmParser(
const AsmParser &) =
delete;
208 AsmParser &
operator=(
const AsmParser &) =
delete;
209 ~AsmParser()
override;
211 bool Run(
bool NoInitialTextSection,
bool NoFinalize =
false)
override;
214 ExtensionDirectiveHandler Handler)
override {
215 ExtensionDirectiveMap[
Directive] = Handler;
219 DirectiveKindMap[
Directive.lower()] = DirectiveKindMap[Alias.
lower()];
233 if (AssemblerDialect == ~0U)
236 return AssemblerDialect;
239 AssemblerDialect = i;
251 ParsingMSInlineAsm =
V;
276 SMLoc &EndLoc)
override;
294 bool parseCppHashLineFilenameComment(
SMLoc L,
bool SaveLocInfo =
true);
303 bool areMacrosEnabled() {
return MacrosEnabledFlag;}
306 void setMacrosEnabled(
bool Flag) {MacrosEnabledFlag =
Flag;}
309 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
318 void handleMacroExit();
321 bool parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg);
324 bool parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A);
326 void printMacroInstantiations();
335 bool enterIncludeFile(
const std::string &Filename);
339 bool processIncbinFile(
const std::string &Filename, int64_t Skip = 0,
348 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0);
359 enum class AssignmentKind {
371 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
372 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
373 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
375 bool parseRegisterOrRegisterNumber(int64_t &
Register,
SMLoc DirectiveLoc);
378 bool parseCVFileId(int64_t &FileId,
StringRef DirectiveName);
437 DK_BUNDLE_ALIGN_MODE,
451 DK_WEAK_DEF_CAN_BE_HIDDEN,
491 DK_CV_INLINE_SITE_ID,
494 DK_CV_INLINE_LINETABLE,
499 DK_CV_FILECHECKSUM_OFFSET,
505 DK_CFI_DEF_CFA_OFFSET,
506 DK_CFI_ADJUST_CFA_OFFSET,
507 DK_CFI_DEF_CFA_REGISTER,
508 DK_CFI_LLVM_DEF_ASPACE_CFA,
513 DK_CFI_REMEMBER_STATE,
514 DK_CFI_RESTORE_STATE,
518 DK_CFI_RETURN_COLUMN,
543 DK_LTO_SET_CONDITIONAL,
544 DK_CFI_MTE_TAGGED_FRAME,
554 enum CVDefRangeType {
556 CVDR_DEFRANGE_REGISTER,
557 CVDR_DEFRANGE_FRAMEPOINTER_REL,
558 CVDR_DEFRANGE_SUBFIELD_REGISTER,
559 CVDR_DEFRANGE_REGISTER_REL
567 bool parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated);
568 bool parseDirectiveReloc(
SMLoc DirectiveLoc);
569 bool parseDirectiveValue(
StringRef IDVal,
571 bool parseDirectiveOctaValue(
StringRef IDVal);
572 bool parseDirectiveRealValue(
StringRef IDVal,
574 bool parseDirectiveFill();
575 bool parseDirectiveZero();
577 bool parseDirectiveSet(
StringRef IDVal, AssignmentKind Kind);
578 bool parseDirectiveOrg();
580 bool parseDirectiveAlign(
bool IsPow2,
unsigned ValueSize);
583 bool parseDirectiveFile(
SMLoc DirectiveLoc);
584 bool parseDirectiveLine();
585 bool parseDirectiveLoc();
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);
627 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
630 bool parseDirectiveMacro(
SMLoc DirectiveLoc);
635 bool parseDirectiveBundleAlignMode();
637 bool parseDirectiveBundleLock();
639 bool parseDirectiveBundleUnlock();
642 bool parseDirectiveSpace(
StringRef IDVal);
651 bool parseDirectiveLEB128(
bool Signed);
657 bool parseDirectiveComm(
bool IsLocal);
659 bool parseDirectiveAbort();
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);
687 bool parseDirectiveIrp(
SMLoc DirectiveLoc);
688 bool parseDirectiveIrpc(
SMLoc DirectiveLoc);
689 bool parseDirectiveEndr(
SMLoc DirectiveLoc);
692 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
696 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
699 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
702 bool parseDirectiveError(
SMLoc DirectiveLoc,
bool WithMessage);
705 bool parseDirectiveWarning(
SMLoc DirectiveLoc);
708 bool parseDirectivePrint(
SMLoc DirectiveLoc);
711 bool parseDirectivePseudoProbe();
714 bool parseDirectiveLTODiscard();
717 bool parseDirectiveAddrsig();
718 bool parseDirectiveAddrsigSym();
720 void initializeDirectiveKindMap();
721 void initializeCVDefRangeTypeMap();
724class HLASMAsmParser final :
public AsmParser {
729 void lexLeadingSpaces() {
735 bool parseAsMachineInstruction(ParseStatementInfo &Info,
741 : AsmParser(SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
750 bool parseStatement(ParseStatementInfo &Info,
773 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI),
SrcMgr(SM),
774 CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(
true) {
802 "Need to implement createSPIRVAsmParser for SPIRV format.");
815 PlatformParser->Initialize(*
this);
816 initializeDirectiveKindMap();
817 initializeCVDefRangeTypeMap();
819 NumOfMacroInstantiations = 0;
822AsmParser::~AsmParser() {
823 assert((HadError || ActiveMacros.empty()) &&
824 "Unexpected active macro instantiation!");
833void AsmParser::printMacroInstantiations() {
835 for (MacroInstantiation *M :
reverse(ActiveMacros))
837 "while in macro instantiation");
841 printPendingErrors();
843 printMacroInstantiations();
847 if(getTargetParser().getTargetOptions().MCNoWarn)
849 if (getTargetParser().getTargetOptions().MCFatalWarnings)
852 printMacroInstantiations();
859 printMacroInstantiations();
863bool AsmParser::enterIncludeFile(
const std::string &Filename) {
864 std::string IncludedFile;
878bool AsmParser::processIncbinFile(
const std::string &Filename, int64_t Skip,
880 std::string IncludedFile;
891 if (!Count->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
892 return Error(Loc,
"expected absolute expression");
894 return Warning(Loc,
"negative count has no effect");
897 getStreamer().emitBytes(Bytes);
901void AsmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer) {
914 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
932 if (ParentIncludeLoc !=
SMLoc()) {
933 jumpToLoc(ParentIncludeLoc);
941bool AsmParser::enabledGenDwarfForAssembly() {
943 if (!getContext().getGenDwarfForAssembly())
948 if (getContext().getGenDwarfFileNumber() == 0) {
951 if (!FirstCppHashFilename.
empty())
952 getContext().setMCLineTableRootFile(
953 0, getContext().getCompilationDir(), FirstCppHashFilename,
954 std::nullopt, std::nullopt);
956 getContext().getMCDwarfLineTable(0).getRootFile();
957 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
958 0, getContext().getCompilationDir(), RootFile.
Name,
964bool AsmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
965 LTODiscardSymbols.
clear();
968 if (!NoInitialTextSection)
975 AsmCond StartingCondState = TheCondState;
982 if (getContext().getGenDwarfForAssembly()) {
983 MCSection *Sec = getStreamer().getCurrentSectionOnly();
985 MCSymbol *SectionStartSym = getContext().createTempSymbol();
986 getStreamer().emitLabel(SectionStartSym);
989 bool InsertResult = getContext().addGenDwarfSection(Sec);
990 assert(InsertResult &&
".text section should not have debug info yet");
994 getTargetParser().onBeginOfFile();
998 ParseStatementInfo
Info(&AsmStrRewrites);
999 bool Parsed = parseStatement(Info,
nullptr);
1009 printPendingErrors();
1012 if (Parsed && !getLexer().isAtStartOfStatement())
1013 eatToEndOfStatement();
1016 getTargetParser().onEndOfFile();
1017 printPendingErrors();
1020 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1022 getTargetParser().flushPendingInstructions(getStreamer());
1026 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1028 const auto &LineTables = getContext().getMCDwarfLineTables();
1029 if (!LineTables.empty()) {
1031 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1033 printError(getTok().getLoc(),
"unassigned file number: " +
1035 " for .file directives");
1051 if (
Sym &&
Sym->isTemporary() && !
Sym->isVariable() &&
1056 printError(getTok().getLoc(),
"assembler local symbol '" +
1057 Sym->getName() +
"' not defined");
1063 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1064 if (std::get<2>(LocSym)->isUndefined()) {
1067 CppHashInfo = std::get<1>(LocSym);
1068 printError(std::get<0>(LocSym),
"directional label undefined");
1074 if (!HadError && !NoFinalize) {
1076 TS->emitConstantPools();
1081 return HadError || getContext().hadError();
1084bool AsmParser::checkForValidSection() {
1085 if (!ParsingMSInlineAsm && !getStreamer().getCurrentFragment()) {
1087 return Error(getTok().getLoc(),
1088 "expected section directive before assembly directive");
1094void AsmParser::eatToEndOfStatement() {
1103StringRef AsmParser::parseStringToEndOfStatement() {
1104 const char *Start = getTok().getLoc().getPointer();
1109 const char *
End = getTok().getLoc().getPointer();
1113StringRef AsmParser::parseStringToComma() {
1114 const char *Start = getTok().getLoc().getPointer();
1120 const char *
End = getTok().getLoc().getPointer();
1129bool AsmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1130 if (parseExpression(Res))
1133 return parseRParen();
1141bool AsmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1142 if (parseExpression(Res))
1144 EndLoc = getTok().getEndLoc();
1145 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1156bool AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1158 SMLoc FirstTokenLoc = getLexer().getLoc();
1160 switch (FirstTokenKind) {
1162 return TokError(
"unknown token in expression");
1168 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1178 if (parseIdentifier(Identifier)) {
1182 bool ShouldGenerateTempSymbol =
false;
1185 ShouldGenerateTempSymbol =
true;
1187 if (!ShouldGenerateTempSymbol)
1188 return Error(FirstTokenLoc,
"invalid token in expression");
1198 EndLoc = FirstTokenLoc;
1203 std::pair<StringRef, StringRef>
Split;
1208 SMLoc AtLoc = getLexer().getLoc();
1210 if (parseIdentifier(VName))
1211 return Error(AtLoc,
"expected symbol variant after '@'");
1213 Split = std::make_pair(Identifier, VName);
1221 parseIdentifier(VName);
1224 Split = std::make_pair(Identifier, VName);
1232 return Error(getLexer().getLoc(),
"expected a symbol reference");
1237 if (!
Split.second.empty()) {
1238 Variant = getTargetParser().getVariantKindForName(
Split.second);
1245 "invalid variant '" +
Split.second +
"'");
1249 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1251 Sym = getContext().getOrCreateSymbol(
1256 if (
Sym->isVariable()) {
1257 auto V =
Sym->getVariableValue(
false);
1258 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1259 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1260 DoInline = TV->inlineAssignedExpr();
1263 return Error(EndLoc,
"unexpected modifier on variable reference");
1264 Res =
Sym->getVariableValue(
false);
1274 return TokError(
"literal value out of range for directive");
1276 SMLoc Loc = getTok().getLoc();
1277 int64_t
IntVal = getTok().getIntVal();
1285 std::pair<StringRef, StringRef>
Split = IDVal.
split(
'@');
1287 if (
Split.first.size() != IDVal.
size()) {
1290 return TokError(
"invalid variant '" +
Split.second +
"'");
1291 IDVal =
Split.first;
1293 if (IDVal ==
"f" || IDVal ==
"b") {
1297 if (IDVal ==
"b" &&
Sym->isUndefined())
1298 return Error(Loc,
"directional label undefined");
1299 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo,
Sym));
1307 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1316 return TokError(
"cannot use . as current PC");
1329 return parseParenExpr(Res, EndLoc);
1331 if (!PlatformParser->HasBracketExpressions())
1332 return TokError(
"brackets expression not supported on this target");
1334 return parseBracketExpr(Res, EndLoc);
1337 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1343 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1349 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1381 return TokError(
"expected '(' after operator");
1383 if (parseExpression(Res, EndLoc))
1387 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1392bool AsmParser::parseExpression(
const MCExpr *&Res) {
1394 return parseExpression(Res, EndLoc);
1398AsmParser::applyModifierToExpr(
const MCExpr *E,
1401 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
1415 TokError(
"invalid variant on expression '" + getTok().getIdentifier() +
1416 "' (already modified)");
1464 "Argument to the function cannot be a NULL value");
1466 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1467 (*CharPtr !=
'\0')) {
1468 if (*CharPtr ==
'!')
1472 if (*CharPtr ==
'>') {
1482 for (
size_t Pos = 0; Pos < AltMacroStr.
size(); Pos++) {
1483 if (AltMacroStr[Pos] ==
'!')
1485 Res += AltMacroStr[Pos];
1500bool AsmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1503 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1504 parseBinOpRHS(1, Res, EndLoc))
1512 return TokError(
"unexpected symbol modifier following '@'");
1517 return TokError(
"invalid variant '" + getTok().getIdentifier() +
"'");
1519 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
1521 return TokError(
"invalid modifier '" + getTok().getIdentifier() +
1522 "' (no symbols present)");
1532 if (Res->evaluateAsAbsolute(
Value))
1538bool AsmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1540 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1543bool AsmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1545 if (parseParenExpr(Res, EndLoc))
1548 for (; ParenDepth > 0; --ParenDepth) {
1549 if (parseBinOpRHS(1, Res, EndLoc))
1554 if (ParenDepth - 1 > 0) {
1555 EndLoc = getTok().getEndLoc();
1563bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1567 if (parseExpression(Expr))
1570 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1571 return Error(StartLoc,
"expected absolute expression");
1578 bool ShouldUseLogicalShr) {
1655 bool ShouldUseLogicalShr) {
1744bool AsmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
1749 unsigned TokPrec = getBinOpPrecedence(Lexer.
getKind(), Kind);
1753 if (TokPrec < Precedence)
1760 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1766 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
1767 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1779bool AsmParser::parseStatement(ParseStatementInfo &Info,
1781 assert(!hasPendingError() &&
"parseStatement started with pending error");
1787 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
1788 getTok().getString().front() ==
'\n')
1797 int64_t LocalLabelVal = -1;
1798 StartTokLoc =
ID.getLoc();
1800 return parseCppHashLineFilenameComment(IDLoc,
1801 !isInsideMacroInstantiation());
1805 LocalLabelVal = getTok().getIntVal();
1806 if (LocalLabelVal < 0) {
1807 if (!TheCondState.
Ignore) {
1809 return Error(IDLoc,
"unexpected token at start of statement");
1813 IDVal = getTok().getString();
1816 if (!TheCondState.
Ignore) {
1818 return Error(IDLoc,
"unexpected token at start of statement");
1836 getTargetParser().starIsStartOfStatement()) {
1840 }
else if (parseIdentifier(IDVal)) {
1841 if (!TheCondState.
Ignore) {
1843 return Error(IDLoc,
"unexpected token at start of statement");
1852 DirectiveKindMap.find(IDVal.
lower());
1853 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1855 : DirKindIt->getValue();
1866 return parseDirectiveIf(IDLoc, DirKind);
1868 return parseDirectiveIfb(IDLoc,
true);
1870 return parseDirectiveIfb(IDLoc,
false);
1872 return parseDirectiveIfc(IDLoc,
true);
1874 return parseDirectiveIfeqs(IDLoc,
true);
1876 return parseDirectiveIfc(IDLoc,
false);
1878 return parseDirectiveIfeqs(IDLoc,
false);
1880 return parseDirectiveIfdef(IDLoc,
true);
1883 return parseDirectiveIfdef(IDLoc,
false);
1885 return parseDirectiveElseIf(IDLoc);
1887 return parseDirectiveElse(IDLoc);
1889 return parseDirectiveEndIf(IDLoc);
1894 if (TheCondState.
Ignore) {
1895 eatToEndOfStatement();
1905 if (checkForValidSection())
1912 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
1920 if (LocalLabelVal == -1) {
1921 if (ParsingMSInlineAsm && SI) {
1923 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
1925 "We should have an internal name here.");
1928 IDVal = RewrittenLabel;
1930 Sym = getContext().getOrCreateSymbol(IDVal);
1938 StringRef CommentStr = parseStringToEndOfStatement();
1950 Sym->isExternal() && !cast<MCSymbolMachO>(
Sym)->isAltEntry())
1951 return Error(StartTokLoc,
"non-private labels cannot appear between "
1952 ".cfi_startproc / .cfi_endproc pairs") &&
1953 Error(*CFIStartProcLoc,
"previous .cfi_startproc was here");
1955 if (discardLTOSymbol(IDVal))
1958 getTargetParser().doBeforeLabelEmit(
Sym, IDLoc);
1961 if (!getTargetParser().isParsingMSInlineAsm())
1966 if (enabledGenDwarfForAssembly())
1970 getTargetParser().onLabelParsed(
Sym);
1979 return parseAssignment(IDVal, AssignmentKind::Equal);
1983 if (areMacrosEnabled())
1984 if (
MCAsmMacro *M = getContext().lookupMacro(IDVal))
1985 return handleMacroEntry(M, IDLoc);
2002 getTargetParser().flushPendingInstructions(getStreamer());
2004 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2006 "Should only return Failure iff there was an error");
2014 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2015 ExtensionDirectiveMap.
lookup(IDVal);
2017 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2026 return parseDirectiveSet(IDVal, AssignmentKind::Set);
2028 return parseDirectiveSet(IDVal, AssignmentKind::Equiv);
2029 case DK_LTO_SET_CONDITIONAL:
2030 return parseDirectiveSet(IDVal, AssignmentKind::LTOSetConditional);
2032 return parseDirectiveAscii(IDVal,
false);
2035 return parseDirectiveAscii(IDVal,
true);
2038 return parseDirectiveValue(IDVal, 1);
2044 return parseDirectiveValue(IDVal, 2);
2049 return parseDirectiveValue(IDVal, 4);
2052 return parseDirectiveValue(IDVal, 8);
2054 return parseDirectiveValue(
2055 IDVal, getContext().getAsmInfo()->getCodePointerSize());
2057 return parseDirectiveOctaValue(IDVal);
2061 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
2064 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
2066 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2067 return parseDirectiveAlign(IsPow2, 1);
2070 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2071 return parseDirectiveAlign(IsPow2, 4);
2074 return parseDirectiveAlign(
false, 1);
2076 return parseDirectiveAlign(
false, 2);
2078 return parseDirectiveAlign(
false, 4);
2080 return parseDirectiveAlign(
true, 1);
2082 return parseDirectiveAlign(
true, 2);
2084 return parseDirectiveAlign(
true, 4);
2086 return parseDirectiveOrg();
2088 return parseDirectiveFill();
2090 return parseDirectiveZero();
2092 eatToEndOfStatement();
2096 return parseDirectiveSymbolAttribute(
MCSA_Global);
2097 case DK_LAZY_REFERENCE:
2099 case DK_NO_DEAD_STRIP:
2101 case DK_SYMBOL_RESOLVER:
2103 case DK_PRIVATE_EXTERN:
2107 case DK_WEAK_DEFINITION:
2109 case DK_WEAK_REFERENCE:
2111 case DK_WEAK_DEF_CAN_BE_HIDDEN:
2114 return parseDirectiveSymbolAttribute(
MCSA_Cold);
2117 return parseDirectiveComm(
false);
2119 return parseDirectiveComm(
true);
2121 return parseDirectiveAbort();
2123 return parseDirectiveInclude();
2125 return parseDirectiveIncbin();
2128 return TokError(
Twine(IDVal) +
2129 " not currently supported for this target");
2131 return parseDirectiveRept(IDLoc, IDVal);
2133 return parseDirectiveIrp(IDLoc);
2135 return parseDirectiveIrpc(IDLoc);
2137 return parseDirectiveEndr(IDLoc);
2138 case DK_BUNDLE_ALIGN_MODE:
2139 return parseDirectiveBundleAlignMode();
2140 case DK_BUNDLE_LOCK:
2141 return parseDirectiveBundleLock();
2142 case DK_BUNDLE_UNLOCK:
2143 return parseDirectiveBundleUnlock();
2145 return parseDirectiveLEB128(
true);
2147 return parseDirectiveLEB128(
false);
2150 return parseDirectiveSpace(IDVal);
2152 return parseDirectiveFile(IDLoc);
2154 return parseDirectiveLine();
2156 return parseDirectiveLoc();
2158 return parseDirectiveStabs();
2160 return parseDirectiveCVFile();
2162 return parseDirectiveCVFuncId();
2163 case DK_CV_INLINE_SITE_ID:
2164 return parseDirectiveCVInlineSiteId();
2166 return parseDirectiveCVLoc();
2167 case DK_CV_LINETABLE:
2168 return parseDirectiveCVLinetable();
2169 case DK_CV_INLINE_LINETABLE:
2170 return parseDirectiveCVInlineLinetable();
2171 case DK_CV_DEF_RANGE:
2172 return parseDirectiveCVDefRange();
2174 return parseDirectiveCVString();
2175 case DK_CV_STRINGTABLE:
2176 return parseDirectiveCVStringTable();
2177 case DK_CV_FILECHECKSUMS:
2178 return parseDirectiveCVFileChecksums();
2179 case DK_CV_FILECHECKSUM_OFFSET:
2180 return parseDirectiveCVFileChecksumOffset();
2181 case DK_CV_FPO_DATA:
2182 return parseDirectiveCVFPOData();
2183 case DK_CFI_SECTIONS:
2184 return parseDirectiveCFISections();
2185 case DK_CFI_STARTPROC:
2186 return parseDirectiveCFIStartProc();
2187 case DK_CFI_ENDPROC:
2188 return parseDirectiveCFIEndProc();
2189 case DK_CFI_DEF_CFA:
2190 return parseDirectiveCFIDefCfa(IDLoc);
2191 case DK_CFI_DEF_CFA_OFFSET:
2192 return parseDirectiveCFIDefCfaOffset(IDLoc);
2193 case DK_CFI_ADJUST_CFA_OFFSET:
2194 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2195 case DK_CFI_DEF_CFA_REGISTER:
2196 return parseDirectiveCFIDefCfaRegister(IDLoc);
2197 case DK_CFI_LLVM_DEF_ASPACE_CFA:
2198 return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
2200 return parseDirectiveCFIOffset(IDLoc);
2201 case DK_CFI_REL_OFFSET:
2202 return parseDirectiveCFIRelOffset(IDLoc);
2203 case DK_CFI_PERSONALITY:
2204 return parseDirectiveCFIPersonalityOrLsda(
true);
2206 return parseDirectiveCFIPersonalityOrLsda(
false);
2207 case DK_CFI_REMEMBER_STATE:
2208 return parseDirectiveCFIRememberState(IDLoc);
2209 case DK_CFI_RESTORE_STATE:
2210 return parseDirectiveCFIRestoreState(IDLoc);
2211 case DK_CFI_SAME_VALUE:
2212 return parseDirectiveCFISameValue(IDLoc);
2213 case DK_CFI_RESTORE:
2214 return parseDirectiveCFIRestore(IDLoc);
2216 return parseDirectiveCFIEscape(IDLoc);
2217 case DK_CFI_RETURN_COLUMN:
2218 return parseDirectiveCFIReturnColumn(IDLoc);
2219 case DK_CFI_SIGNAL_FRAME:
2220 return parseDirectiveCFISignalFrame(IDLoc);
2221 case DK_CFI_UNDEFINED:
2222 return parseDirectiveCFIUndefined(IDLoc);
2223 case DK_CFI_REGISTER:
2224 return parseDirectiveCFIRegister(IDLoc);
2225 case DK_CFI_WINDOW_SAVE:
2226 return parseDirectiveCFIWindowSave(IDLoc);
2229 return parseDirectiveMacrosOnOff(IDVal);
2231 return parseDirectiveMacro(IDLoc);
2234 return parseDirectiveAltmacro(IDVal);
2236 return parseDirectiveExitMacro(IDVal);
2239 return parseDirectiveEndMacro(IDVal);
2241 return parseDirectivePurgeMacro(IDLoc);
2243 return parseDirectiveEnd(IDLoc);
2245 return parseDirectiveError(IDLoc,
false);
2247 return parseDirectiveError(IDLoc,
true);
2249 return parseDirectiveWarning(IDLoc);
2251 return parseDirectiveReloc(IDLoc);
2254 return parseDirectiveDCB(IDVal, 2);
2256 return parseDirectiveDCB(IDVal, 1);
2258 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2260 return parseDirectiveDCB(IDVal, 4);
2262 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2265 return TokError(
Twine(IDVal) +
2266 " not currently supported for this target");
2269 return parseDirectiveDS(IDVal, 2);
2271 return parseDirectiveDS(IDVal, 1);
2273 return parseDirectiveDS(IDVal, 8);
2276 return parseDirectiveDS(IDVal, 4);
2279 return parseDirectiveDS(IDVal, 12);
2281 return parseDirectivePrint(IDLoc);
2283 return parseDirectiveAddrsig();
2284 case DK_ADDRSIG_SYM:
2285 return parseDirectiveAddrsigSym();
2286 case DK_PSEUDO_PROBE:
2287 return parseDirectivePseudoProbe();
2288 case DK_LTO_DISCARD:
2289 return parseDirectiveLTODiscard();
2291 return parseDirectiveSymbolAttribute(
MCSA_Memtag);
2294 return Error(IDLoc,
"unknown directive");
2298 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2299 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2300 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2303 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2304 return parseDirectiveMSAlign(IDLoc, Info);
2306 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2308 if (checkForValidSection())
2311 return parseAndMatchAndEmitTargetInstruction(Info, IDVal,
ID, IDLoc);
2314bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
2319 std::string OpcodeStr = IDVal.
lower();
2321 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
ID,
2322 Info.ParsedOperands);
2323 Info.ParseError = ParseHadError;
2326 if (getShowParsedOperands()) {
2329 OS <<
"parsed instruction: [";
2330 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2333 Info.ParsedOperands[i]->print(
OS);
2341 if (hasPendingError() || ParseHadError)
2346 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2347 getContext().getGenDwarfSectionSyms().
count(
2348 getStreamer().getCurrentSectionOnly())) {
2350 if (ActiveMacros.empty())
2354 ActiveMacros.front()->ExitBuffer);
2359 if (!CppHashInfo.Filename.empty()) {
2360 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2362 getContext().setGenDwarfFileNumber(FileNumber);
2364 unsigned CppHashLocLineNo =
2366 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2369 getStreamer().emitDwarfLocDirective(
2370 getContext().getGenDwarfFileNumber(), Line, 0,
2376 if (!ParseHadError) {
2378 if (getTargetParser().MatchAndEmitInstruction(
2380 getTargetParser().isParsingMSInlineAsm()))
2406bool AsmParser::parseCppHashLineFilenameComment(
SMLoc L,
bool SaveLocInfo) {
2411 "Lexing Cpp line comment: Expected Integer");
2412 int64_t LineNumber = getTok().getIntVal();
2415 "Lexing Cpp line comment: Expected String");
2427 CppHashInfo.Loc =
L;
2429 CppHashInfo.LineNumber = LineNumber;
2430 CppHashInfo.Buf = CurBuffer;
2431 if (FirstCppHashFilename.
empty())
2438void AsmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2439 auto *Parser =
static_cast<AsmParser *
>(Context);
2445 unsigned CppHashBuf =
2446 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2451 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2460 if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
2461 if (Parser->SavedDiagHandler)
2462 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2464 Parser->getContext().diagnose(Diag);
2471 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2474 int CppHashLocLineNo =
2475 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2477 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2483 if (Parser->SavedDiagHandler)
2484 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2486 Parser->getContext().diagnose(NewDiag);
2494 return isalnum(
static_cast<unsigned char>(c)) || c ==
'_' || c ==
'$' ||
2501 bool EnableAtPseudoVariable) {
2503 bool HasVararg = NParameters ?
Parameters.back().Vararg :
false;
2508 while (!Body.
empty()) {
2510 std::size_t
End = Body.
size(), Pos = 0;
2511 for (; Pos !=
End; ++Pos) {
2513 if (IsDarwin && !NParameters) {
2515 if (Body[Pos] !=
'$' || Pos + 1 ==
End)
2518 char Next = Body[Pos + 1];
2519 if (Next ==
'$' || Next ==
'n' ||
2520 isdigit(
static_cast<unsigned char>(Next)))
2524 if (Body[Pos] ==
'\\' && Pos + 1 !=
End)
2536 if (IsDarwin && !NParameters) {
2537 switch (Body[Pos + 1]) {
2551 unsigned Index = Body[Pos + 1] -
'0';
2557 OS << Token.getString();
2564 unsigned I = Pos + 1;
2566 if (EnableAtPseudoVariable && Body[
I] ==
'@') {
2568 }
else if (Body[
I] ==
'+') {
2576 const char *Begin = Body.
data() + Pos + 1;
2581 OS << NumOfMacroInstantiations;
2591 if (
Index == NParameters) {
2592 if (Body[Pos + 1] ==
'(' && Body[Pos + 2] ==
')')
2599 bool VarargParameter = HasVararg &&
Index == (NParameters - 1);
2608 if (AltMacroMode && Token.getString().front() ==
'%' &&
2611 OS << Token.getIntVal();
2614 else if (AltMacroMode && Token.getString().front() ==
'<' &&
2621 OS << Token.getString();
2623 OS << Token.getStringContents();
2669class AsmLexerSkipSpaceRAII {
2671 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2675 ~AsmLexerSkipSpaceRAII() {
2685bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg) {
2689 StringRef Str = parseStringToEndOfStatement();
2695 unsigned ParenLevel = 0;
2698 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2705 return TokError(
"unexpected token in macro instantiation");
2707 if (ParenLevel == 0) {
2720 MA.push_back(getTok());
2744 MA.push_back(getTok());
2748 if (ParenLevel != 0)
2749 return TokError(
"unbalanced parentheses in macro argument");
2754bool AsmParser::parseMacroArguments(
const MCAsmMacro *M,
2755 MCAsmMacroArguments &
A) {
2756 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
2757 bool NamedParametersFound =
false;
2760 A.resize(NParameters);
2761 FALocs.
resize(NParameters);
2766 bool HasVararg = NParameters ?
M->Parameters.back().Vararg :
false;
2767 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2773 if (parseIdentifier(FA.
Name))
2774 return Error(IDLoc,
"invalid argument identifier for formal argument");
2777 return TokError(
"expected '=' after formal parameter identifier");
2781 NamedParametersFound =
true;
2783 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2785 if (NamedParametersFound && FA.
Name.
empty())
2786 return Error(IDLoc,
"cannot mix positional and keyword arguments");
2791 const MCExpr *AbsoluteExp;
2795 if (parseExpression(AbsoluteExp, EndLoc))
2797 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
2798 getStreamer().getAssemblerPtr()))
2799 return Error(StrLoc,
"expected absolute expression");
2804 FA.
Value.push_back(newToken);
2809 jumpToLoc(EndLoc, CurBuffer);
2814 FA.
Value.push_back(newToken);
2815 }
else if(parseMacroArgument(FA.
Value, Vararg))
2818 unsigned PI = Parameter;
2821 for (FAI = 0; FAI < NParameters; ++FAI)
2822 if (
M->Parameters[FAI].Name == FA.
Name)
2825 if (FAI >= NParameters) {
2826 assert(M &&
"expected macro to be defined");
2827 return Error(IDLoc,
"parameter named '" + FA.
Name +
2828 "' does not exist for macro '" +
M->Name +
"'");
2833 if (!FA.
Value.empty()) {
2838 if (FALocs.
size() <= PI)
2841 FALocs[PI] = Lexer.
getLoc();
2849 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
2850 if (
A[FAI].empty()) {
2851 if (
M->Parameters[FAI].Required) {
2853 "missing value for required parameter "
2854 "'" +
M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
2858 if (!
M->Parameters[FAI].Value.empty())
2859 A[FAI] =
M->Parameters[FAI].Value;
2868 return TokError(
"too many positional arguments");
2875 if (ActiveMacros.size() == MaxNestingDepth) {
2876 std::ostringstream MaxNestingDepthError;
2877 MaxNestingDepthError <<
"macros cannot be nested more than "
2878 << MaxNestingDepth <<
" levels deep."
2879 <<
" Use -asm-macro-max-nesting-depth to increase "
2881 return TokError(MaxNestingDepthError.str());
2884 MCAsmMacroArguments
A;
2885 if (parseMacroArguments(M,
A))
2893 if ((!IsDarwin ||
M->Parameters.size()) &&
M->Parameters.size() !=
A.size())
2894 return Error(getTok().getLoc(),
"Wrong number of arguments");
2895 if (expandMacro(
OS, *M,
M->Parameters,
A,
true))
2900 OS <<
".endmacro\n";
2902 std::unique_ptr<MemoryBuffer> Instantiation =
2907 MacroInstantiation *
MI =
new MacroInstantiation{
2908 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2909 ActiveMacros.push_back(
MI);
2911 ++NumOfMacroInstantiations;
2921void AsmParser::handleMacroExit() {
2923 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2931 delete ActiveMacros.back();
2932 ActiveMacros.pop_back();
2935bool AsmParser::parseAssignment(
StringRef Name, AssignmentKind Kind) {
2938 SMLoc ExprLoc = getTok().getLoc();
2940 Kind == AssignmentKind::Set ||
Kind == AssignmentKind::Equal;
2952 if (discardLTOSymbol(
Name))
2957 case AssignmentKind::Equal:
2960 case AssignmentKind::Set:
2961 case AssignmentKind::Equiv:
2965 case AssignmentKind::LTOSetConditional:
2967 return Error(ExprLoc,
"expected identifier");
2979bool AsmParser::parseIdentifier(
StringRef &Res) {
2986 SMLoc PrefixLoc = getLexer().getLoc();
2998 if (PrefixLoc.
getPointer() + 1 != Buf[0].getLoc().getPointer())
3012 Res = getTok().getIdentifier();
3024bool AsmParser::parseDirectiveSet(
StringRef IDVal, AssignmentKind Kind) {
3026 if (
check(parseIdentifier(
Name),
"expected identifier") || parseComma() ||
3027 parseAssignment(
Name, Kind))
3032bool AsmParser::parseEscapedString(std::string &Data) {
3037 StringRef Str = getTok().getStringContents();
3038 for (
unsigned i = 0, e = Str.size(); i != e; ++i) {
3039 if (Str[i] !=
'\\') {
3048 return TokError(
"unexpected backslash at end of string");
3051 if (Str[i] ==
'x' || Str[i] ==
'X') {
3052 size_t length = Str.size();
3053 if (i + 1 >= length || !
isHexDigit(Str[i + 1]))
3054 return TokError(
"invalid hexadecimal escape sequence");
3059 while (i + 1 < length &&
isHexDigit(Str[i + 1]))
3060 Value =
Value * 16 + hexDigitValue(Str[++i]);
3067 if ((
unsigned)(Str[i] -
'0') <= 7) {
3069 unsigned Value = Str[i] -
'0';
3071 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3075 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3082 return TokError(
"invalid octal escape sequence (out of range)");
3092 return TokError(
"invalid escape sequence (unrecognized character)");
3094 case 'b': Data +=
'\b';
break;
3095 case 'f': Data +=
'\f';
break;
3096 case 'n': Data +=
'\n';
break;
3097 case 'r': Data +=
'\r';
break;
3098 case 't': Data +=
'\t';
break;
3099 case '"': Data +=
'"';
break;
3100 case '\\': Data +=
'\\';
break;
3108bool AsmParser::parseAngleBracketString(std::string &Data) {
3109 SMLoc EndLoc, StartLoc = getTok().getLoc();
3111 const char *StartChar = StartLoc.
getPointer() + 1;
3112 const char *EndChar = EndLoc.
getPointer() - 1;
3113 jumpToLoc(EndLoc, CurBuffer);
3126bool AsmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3127 auto parseOp = [&]() ->
bool {
3129 if (checkForValidSection())
3134 if (parseEscapedString(Data))
3136 getStreamer().emitBytes(Data);
3139 getStreamer().emitBytes(
StringRef(
"\0", 1));
3143 return parseMany(parseOp);
3148bool AsmParser::parseDirectiveReloc(
SMLoc DirectiveLoc) {
3150 const MCExpr *Expr =
nullptr;
3153 if (parseExpression(
Offset))
3166 if (parseExpression(Expr))
3171 return Error(ExprLoc,
"expression must be relocatable");
3179 if (std::optional<std::pair<bool, std::string>> Err =
3180 getStreamer().emitRelocDirective(*
Offset,
Name, Expr, DirectiveLoc,
3182 return Error(Err->first ? NameLoc : OffsetLoc, Err->second);
3189bool AsmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3190 auto parseOp = [&]() ->
bool {
3192 SMLoc ExprLoc = getLexer().getLoc();
3193 if (checkForValidSection() || parseExpression(
Value))
3198 uint64_t IntValue = MCE->getValue();
3200 return Error(ExprLoc,
"out of range literal value");
3201 getStreamer().emitIntValue(IntValue,
Size);
3203 getStreamer().emitValue(
Value,
Size, ExprLoc);
3207 return parseMany(parseOp);
3213 return Asm.TokError(
"unknown token in expression");
3214 SMLoc ExprLoc = Asm.getTok().getLoc();
3215 APInt IntValue = Asm.getTok().getAPIntVal();
3217 if (!IntValue.
isIntN(128))
3218 return Asm.Error(ExprLoc,
"out of range literal value");
3219 if (!IntValue.
isIntN(64)) {
3232bool AsmParser::parseDirectiveOctaValue(
StringRef IDVal) {
3233 auto parseOp = [&]() ->
bool {
3234 if (checkForValidSection())
3240 getStreamer().emitInt64(lo);
3241 getStreamer().emitInt64(hi);
3243 getStreamer().emitInt64(hi);
3244 getStreamer().emitInt64(lo);
3249 return parseMany(parseOp);
3263 return TokError(Lexer.
getErr());
3266 return TokError(
"unexpected token in directive");
3278 return TokError(
"invalid floating point literal");
3280 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3282 return TokError(
"invalid floating point literal");
3289 Res =
Value.bitcastToAPInt();
3296bool AsmParser::parseDirectiveRealValue(
StringRef IDVal,
3298 auto parseOp = [&]() ->
bool {
3300 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3307 return parseMany(parseOp);
3312bool AsmParser::parseDirectiveZero() {
3315 if (checkForValidSection() || parseExpression(NumBytes))
3321 if (parseAbsoluteExpression(Val))
3327 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3334bool AsmParser::parseDirectiveFill() {
3337 if (checkForValidSection() || parseExpression(NumValues))
3340 int64_t FillSize = 1;
3341 int64_t FillExpr = 0;
3343 SMLoc SizeLoc, ExprLoc;
3346 SizeLoc = getTok().getLoc();
3347 if (parseAbsoluteExpression(FillSize))
3350 ExprLoc = getTok().getLoc();
3351 if (parseAbsoluteExpression(FillExpr))
3359 Warning(SizeLoc,
"'.fill' directive with negative size has no effect");
3363 Warning(SizeLoc,
"'.fill' directive with size greater than 8 has been truncated to 8");
3367 if (!isUInt<32>(FillExpr) && FillSize > 4)
3368 Warning(ExprLoc,
"'.fill' directive pattern has been truncated to 32-bits");
3370 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3377bool AsmParser::parseDirectiveOrg() {
3380 if (checkForValidSection() || parseExpression(
Offset))
3384 int64_t FillExpr = 0;
3386 if (parseAbsoluteExpression(FillExpr))
3391 getStreamer().emitValueToOffset(
Offset, FillExpr, OffsetLoc);
3397bool AsmParser::parseDirectiveAlign(
bool IsPow2,
unsigned ValueSize) {
3398 SMLoc AlignmentLoc = getLexer().getLoc();
3401 bool HasFillExpr =
false;
3402 int64_t FillExpr = 0;
3403 int64_t MaxBytesToFill = 0;
3406 auto parseAlign = [&]() ->
bool {
3407 if (parseAbsoluteExpression(Alignment))
3415 if (parseTokenLoc(FillExprLoc) || parseAbsoluteExpression(FillExpr))
3419 if (parseTokenLoc(MaxBytesLoc) ||
3420 parseAbsoluteExpression(MaxBytesToFill))
3426 if (checkForValidSection())
3430 Warning(AlignmentLoc,
"p2align directive with no operand(s) is ignored");
3437 bool ReturnVal =
false;
3442 if (Alignment >= 32) {
3443 ReturnVal |=
Error(AlignmentLoc,
"invalid alignment value");
3447 Alignment = 1ULL << Alignment;
3455 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2");
3456 Alignment = llvm::bit_floor<uint64_t>(Alignment);
3458 if (!isUInt<32>(Alignment)) {
3459 ReturnVal |=
Error(AlignmentLoc,
"alignment must be smaller than 2**32");
3460 Alignment = 1u << 31;
3464 if (HasFillExpr && FillExpr != 0) {
3465 MCSection *Sec = getStreamer().getCurrentSectionOnly();
3468 Warning(FillExprLoc,
"ignoring non-zero fill value in " +
3477 if (MaxBytesToFill < 1) {
3478 ReturnVal |=
Error(MaxBytesLoc,
3479 "alignment directive can never be satisfied in this "
3480 "many bytes, ignoring maximum bytes expression");
3484 if (MaxBytesToFill >= Alignment) {
3485 Warning(MaxBytesLoc,
"maximum bytes expression exceeds alignment and "
3494 assert(Section &&
"must have section to emit alignment");
3495 bool useCodeAlign =
Section->useCodeAlign();
3496 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
3497 ValueSize == 1 && useCodeAlign) {
3498 getStreamer().emitCodeAlignment(
3499 Align(Alignment), &getTargetParser().getSTI(), MaxBytesToFill);
3502 getStreamer().emitValueToAlignment(
Align(Alignment), FillExpr, ValueSize,
3512bool AsmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
3514 int64_t FileNumber = -1;
3516 FileNumber = getTok().getIntVal();
3520 return TokError(
"negative file number");
3527 if (parseEscapedString(Path))
3532 std::string FilenameData;
3534 if (
check(FileNumber == -1,
3535 "explicit path specified, but no file number") ||
3536 parseEscapedString(FilenameData))
3545 bool HasMD5 =
false;
3547 std::optional<StringRef>
Source;
3548 bool HasSource =
false;
3549 std::string SourceString;
3554 "unexpected token in '.file' directive") ||
3555 parseIdentifier(Keyword))
3557 if (Keyword ==
"md5") {
3559 if (
check(FileNumber == -1,
3560 "MD5 checksum specified, but no file number") ||
3563 }
else if (Keyword ==
"source") {
3565 if (
check(FileNumber == -1,
3566 "source specified, but no file number") ||
3568 "unexpected token in '.file' directive") ||
3569 parseEscapedString(SourceString))
3572 return TokError(
"unexpected token in '.file' directive");
3576 if (FileNumber == -1) {
3580 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
3581 getStreamer().emitFileDirective(Filename);
3591 std::optional<MD5::MD5Result> CKMem;
3594 for (
unsigned i = 0; i != 8; ++i) {
3595 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3596 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3601 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
3602 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3605 if (FileNumber == 0) {
3609 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3612 FileNumber, Directory, Filename, CKMem, Source);
3619 ReportedInconsistentMD5 =
true;
3620 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
3629bool AsmParser::parseDirectiveLine() {
3632 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
3647bool AsmParser::parseDirectiveLoc() {
3648 int64_t FileNumber = 0, LineNumber = 0;
3649 SMLoc Loc = getTok().getLoc();
3650 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
3652 "file number less than one in '.loc' directive") ||
3653 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3654 "unassigned file number in '.loc' directive"))
3659 LineNumber = getTok().getIntVal();
3661 return TokError(
"line number less than zero in '.loc' directive");
3665 int64_t ColumnPos = 0;
3667 ColumnPos = getTok().getIntVal();
3669 return TokError(
"column position less than zero in '.loc' directive");
3673 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
3678 auto parseLocOp = [&]() ->
bool {
3680 SMLoc Loc = getTok().getLoc();
3681 if (parseIdentifier(
Name))
3682 return TokError(
"unexpected token in '.loc' directive");
3684 if (
Name ==
"basic_block")
3686 else if (
Name ==
"prologue_end")
3688 else if (
Name ==
"epilogue_begin")
3690 else if (
Name ==
"is_stmt") {
3691 Loc = getTok().getLoc();
3693 if (parseExpression(
Value))
3697 int Value = MCE->getValue();
3699 Flags &= ~DWARF2_FLAG_IS_STMT;
3700 else if (
Value == 1)
3703 return Error(Loc,
"is_stmt value not 0 or 1");
3705 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
3707 }
else if (
Name ==
"isa") {
3708 Loc = getTok().getLoc();
3710 if (parseExpression(
Value))
3714 int Value = MCE->getValue();
3716 return Error(Loc,
"isa number less than zero");
3719 return Error(Loc,
"isa number not a constant value");
3721 }
else if (
Name ==
"discriminator") {
3722 if (parseAbsoluteExpression(Discriminator))
3725 return Error(Loc,
"unknown sub-directive in '.loc' directive");
3730 if (parseMany(parseLocOp,
false ))
3733 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3741bool AsmParser::parseDirectiveStabs() {
3742 return TokError(
"unsupported directive '.stabs'");
3747bool AsmParser::parseDirectiveCVFile() {
3748 SMLoc FileNumberLoc = getTok().getLoc();
3751 std::string Checksum;
3754 if (parseIntToken(FileNumber,
3755 "expected file number in '.cv_file' directive") ||
3756 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
3758 "unexpected token in '.cv_file' directive") ||
3759 parseEscapedString(Filename))
3763 "unexpected token in '.cv_file' directive") ||
3764 parseEscapedString(Checksum) ||
3765 parseIntToken(ChecksumKind,
3766 "expected checksum kind in '.cv_file' directive") ||
3771 Checksum = fromHex(Checksum);
3772 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
3773 memcpy(CKMem, Checksum.data(), Checksum.size());
3777 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3778 static_cast<uint8_t
>(ChecksumKind)))
3779 return Error(FileNumberLoc,
"file number already allocated");
3784bool AsmParser::parseCVFunctionId(int64_t &
FunctionId,
3787 return parseTokenLoc(Loc) ||
3788 parseIntToken(
FunctionId,
"expected function id in '" + DirectiveName +
3790 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3791 "expected function id within range [0, UINT_MAX)");
3794bool AsmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
3796 return parseTokenLoc(Loc) ||
3797 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
3799 check(FileNumber < 1, Loc,
"file number less than one in '" +
3800 DirectiveName +
"' directive") ||
3801 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3802 "unassigned file number in '" + DirectiveName +
"' directive");
3809bool AsmParser::parseDirectiveCVFuncId() {
3810 SMLoc FunctionIdLoc = getTok().getLoc();
3813 if (parseCVFunctionId(
FunctionId,
".cv_func_id") || parseEOL())
3816 if (!getStreamer().emitCVFuncIdDirective(
FunctionId))
3817 return Error(FunctionIdLoc,
"function id already allocated");
3830bool AsmParser::parseDirectiveCVInlineSiteId() {
3831 SMLoc FunctionIdLoc = getTok().getLoc();
3839 if (parseCVFunctionId(
FunctionId,
".cv_inline_site_id"))
3844 getTok().getIdentifier() !=
"within"),
3845 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3850 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
3855 getTok().getIdentifier() !=
"inlined_at"),
3856 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3862 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
3863 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
3868 IACol = getTok().getIntVal();
3875 if (!getStreamer().emitCVInlineSiteIdDirective(
FunctionId, IAFunc, IAFile,
3876 IALine, IACol, FunctionIdLoc))
3877 return Error(FunctionIdLoc,
"function id already allocated");
3889bool AsmParser::parseDirectiveCVLoc() {
3890 SMLoc DirectiveLoc = getTok().getLoc();
3892 if (parseCVFunctionId(
FunctionId,
".cv_loc") ||
3893 parseCVFileId(FileNumber,
".cv_loc"))
3896 int64_t LineNumber = 0;
3898 LineNumber = getTok().getIntVal();
3900 return TokError(
"line number less than zero in '.cv_loc' directive");
3904 int64_t ColumnPos = 0;
3906 ColumnPos = getTok().getIntVal();
3908 return TokError(
"column position less than zero in '.cv_loc' directive");
3912 bool PrologueEnd =
false;
3915 auto parseOp = [&]() ->
bool {
3917 SMLoc Loc = getTok().getLoc();
3918 if (parseIdentifier(
Name))
3919 return TokError(
"unexpected token in '.cv_loc' directive");
3920 if (
Name ==
"prologue_end")
3922 else if (
Name ==
"is_stmt") {
3923 Loc = getTok().getLoc();
3925 if (parseExpression(
Value))
3929 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
3930 IsStmt = MCE->getValue();
3933 return Error(Loc,
"is_stmt value not 0 or 1");
3935 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
3940 if (parseMany(parseOp,
false ))
3943 getStreamer().emitCVLocDirective(
FunctionId, FileNumber, LineNumber,
3944 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
3951bool AsmParser::parseDirectiveCVLinetable() {
3954 SMLoc Loc = getTok().getLoc();
3955 if (parseCVFunctionId(
FunctionId,
".cv_linetable") || parseComma() ||
3956 parseTokenLoc(Loc) ||
3957 check(parseIdentifier(FnStartName), Loc,
3958 "expected identifier in directive") ||
3959 parseComma() || parseTokenLoc(Loc) ||
3960 check(parseIdentifier(FnEndName), Loc,
3961 "expected identifier in directive"))
3964 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3965 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3967 getStreamer().emitCVLinetableDirective(
FunctionId, FnStartSym, FnEndSym);
3973bool AsmParser::parseDirectiveCVInlineLinetable() {
3974 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3976 SMLoc Loc = getTok().getLoc();
3977 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
3978 parseTokenLoc(Loc) ||
3981 "expected SourceField in '.cv_inline_linetable' directive") ||
3982 check(SourceFileId <= 0, Loc,
3983 "File id less than zero in '.cv_inline_linetable' directive") ||
3984 parseTokenLoc(Loc) ||
3987 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3988 check(SourceLineNum < 0, Loc,
3989 "Line number less than zero in '.cv_inline_linetable' directive") ||
3990 parseTokenLoc(Loc) ||
check(parseIdentifier(FnStartName), Loc,
3991 "expected identifier in directive") ||
3992 parseTokenLoc(Loc) ||
check(parseIdentifier(FnEndName), Loc,
3993 "expected identifier in directive"))
3999 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4000 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4001 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
4002 SourceLineNum, FnStartSym,
4007void AsmParser::initializeCVDefRangeTypeMap() {
4008 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
4009 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4010 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4011 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4016bool AsmParser::parseDirectiveCVDefRange() {
4018 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
4020 Loc = getLexer().getLoc();
4022 if (parseIdentifier(GapStartName))
4023 return Error(Loc,
"expected identifier in directive");
4024 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
4026 Loc = getLexer().getLoc();
4028 if (parseIdentifier(GapEndName))
4029 return Error(Loc,
"expected identifier in directive");
4030 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
4032 Ranges.push_back({GapStartSym, GapEndSym});
4038 "expected comma before def_range type in .cv_def_range directive") ||
4039 parseIdentifier(CVDefRangeTypeStr))
4040 return Error(Loc,
"expected def_range type in directive");
4043 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4044 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4046 : CVTypeIt->getValue();
4048 case CVDR_DEFRANGE_REGISTER: {
4050 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4051 ".cv_def_range directive") ||
4052 parseAbsoluteExpression(DRRegister))
4053 return Error(Loc,
"expected register number");
4058 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4061 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4064 "expected comma before offset in .cv_def_range directive") ||
4065 parseAbsoluteExpression(DROffset))
4066 return Error(Loc,
"expected offset value");
4070 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4073 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4075 int64_t DROffsetInParent;
4076 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4077 ".cv_def_range directive") ||
4078 parseAbsoluteExpression(DRRegister))
4079 return Error(Loc,
"expected register number");
4081 "expected comma before offset in .cv_def_range directive") ||
4082 parseAbsoluteExpression(DROffsetInParent))
4083 return Error(Loc,
"expected offset value");
4089 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4092 case CVDR_DEFRANGE_REGISTER_REL: {
4095 int64_t DRBasePointerOffset;
4096 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4097 ".cv_def_range directive") ||
4098 parseAbsoluteExpression(DRRegister))
4099 return Error(Loc,
"expected register value");
4102 "expected comma before flag value in .cv_def_range directive") ||
4103 parseAbsoluteExpression(DRFlags))
4104 return Error(Loc,
"expected flag value");
4105 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
4106 "in .cv_def_range directive") ||
4107 parseAbsoluteExpression(DRBasePointerOffset))
4108 return Error(Loc,
"expected base pointer offset value");
4112 DRHdr.
Flags = DRFlags;
4114 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4118 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
4125bool AsmParser::parseDirectiveCVString() {
4127 if (checkForValidSection() || parseEscapedString(Data))
4131 std::pair<StringRef, unsigned> Insertion =
4132 getCVContext().addToStringTable(Data);
4133 getStreamer().emitInt32(Insertion.second);
4139bool AsmParser::parseDirectiveCVStringTable() {
4140 getStreamer().emitCVStringTableDirective();
4146bool AsmParser::parseDirectiveCVFileChecksums() {
4147 getStreamer().emitCVFileChecksumsDirective();
4153bool AsmParser::parseDirectiveCVFileChecksumOffset() {
4155 if (parseIntToken(FileNo,
"expected identifier in directive"))
4159 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4165bool AsmParser::parseDirectiveCVFPOData() {
4166 SMLoc DirLoc = getLexer().getLoc();
4168 if (parseIdentifier(ProcName))
4169 return TokError(
"expected symbol name");
4172 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4173 getStreamer().emitCVFPOData(ProcSym, DirLoc);
4179bool AsmParser::parseDirectiveCFISections() {
4186 if (parseIdentifier(
Name))
4187 return TokError(
"expected .eh_frame or .debug_frame");
4188 if (
Name ==
".eh_frame")
4190 else if (
Name ==
".debug_frame")
4198 getStreamer().emitCFISections(EH,
Debug);
4204bool AsmParser::parseDirectiveCFIStartProc() {
4205 CFIStartProcLoc = StartTokLoc;
4210 "unexpected token") ||
4220 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
4226bool AsmParser::parseDirectiveCFIEndProc() {
4227 CFIStartProcLoc = std::nullopt;
4232 getStreamer().emitCFIEndProc();
4237bool AsmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
4238 SMLoc DirectiveLoc) {
4242 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4244 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo,
true);
4246 return parseAbsoluteExpression(
Register);
4253bool AsmParser::parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc) {
4255 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4256 parseAbsoluteExpression(
Offset) || parseEOL())
4265bool AsmParser::parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc) {
4267 if (parseAbsoluteExpression(
Offset) || parseEOL())
4270 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
4276bool AsmParser::parseDirectiveCFIRegister(
SMLoc DirectiveLoc) {
4277 int64_t Register1 = 0, Register2 = 0;
4278 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
4279 parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
4282 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
4288bool AsmParser::parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc) {
4291 getStreamer().emitCFIWindowSave(DirectiveLoc);
4297bool AsmParser::parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc) {
4298 int64_t Adjustment = 0;
4299 if (parseAbsoluteExpression(Adjustment) || parseEOL())
4302 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
4308bool AsmParser::parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc) {
4310 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4313 getStreamer().emitCFIDefCfaRegister(
Register, DirectiveLoc);
4319bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(
SMLoc DirectiveLoc) {
4321 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4322 parseAbsoluteExpression(
Offset) || parseComma() ||
4333bool AsmParser::parseDirectiveCFIOffset(
SMLoc DirectiveLoc) {
4337 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4338 parseAbsoluteExpression(
Offset) || parseEOL())
4347bool AsmParser::parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc) {
4350 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4351 parseAbsoluteExpression(
Offset) || parseEOL())
4359 if (Encoding & ~0xff)
4365 const unsigned Format = Encoding & 0xf;
4372 const unsigned Application = Encoding & 0x70;
4384bool AsmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
4385 int64_t Encoding = 0;
4386 if (parseAbsoluteExpression(Encoding))
4394 check(parseIdentifier(
Name),
"expected identifier in directive") ||
4401 getStreamer().emitCFIPersonality(
Sym, Encoding);
4403 getStreamer().emitCFILsda(
Sym, Encoding);
4409bool AsmParser::parseDirectiveCFIRememberState(
SMLoc DirectiveLoc) {
4412 getStreamer().emitCFIRememberState(DirectiveLoc);
4418bool AsmParser::parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc) {
4421 getStreamer().emitCFIRestoreState(DirectiveLoc);
4427bool AsmParser::parseDirectiveCFISameValue(
SMLoc DirectiveLoc) {
4430 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4433 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
4439bool AsmParser::parseDirectiveCFIRestore(
SMLoc DirectiveLoc) {
4441 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4444 getStreamer().emitCFIRestore(
Register, DirectiveLoc);
4450bool AsmParser::parseDirectiveCFIEscape(
SMLoc DirectiveLoc) {
4453 if (parseAbsoluteExpression(CurrValue))
4456 Values.push_back((uint8_t)CurrValue);
4461 if (parseAbsoluteExpression(CurrValue))
4464 Values.push_back((uint8_t)CurrValue);
4467 getStreamer().emitCFIEscape(Values, DirectiveLoc);
4473bool AsmParser::parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc) {
4475 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4477 getStreamer().emitCFIReturnColumn(
Register);
4483bool AsmParser::parseDirectiveCFISignalFrame(
SMLoc DirectiveLoc) {
4487 getStreamer().emitCFISignalFrame();
4493bool AsmParser::parseDirectiveCFIUndefined(
SMLoc DirectiveLoc) {
4496 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4499 getStreamer().emitCFIUndefined(
Register, DirectiveLoc);
4509 AltMacroMode = (
Directive ==
".altmacro");
4519 setMacrosEnabled(
Directive ==
".macros_on");
4525bool AsmParser::parseDirectiveMacro(
SMLoc DirectiveLoc) {
4527 if (parseIdentifier(
Name))
4528 return TokError(
"expected identifier in '.macro' directive");
4537 return Error(Lexer.
getLoc(),
"vararg parameter '" +
4539 "' should be the last parameter");
4542 if (parseIdentifier(Parameter.
Name))
4543 return TokError(
"expected identifier in '.macro' directive");
4547 if (CurrParam.Name == Parameter.
Name)
4548 return TokError(
"macro '" +
Name +
"' has multiple parameters"
4549 " named '" + Parameter.
Name +
"'");
4557 QualLoc = Lexer.
getLoc();
4558 if (parseIdentifier(Qualifier))
4559 return Error(QualLoc,
"missing parameter qualifier for "
4560 "'" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4562 if (Qualifier ==
"req")
4564 else if (Qualifier ==
"vararg")
4567 return Error(QualLoc, Qualifier +
" is not a valid parameter qualifier "
4568 "for '" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4576 ParamLoc = Lexer.
getLoc();
4577 if (parseMacroArgument(Parameter.
Value,
false ))
4581 Warning(ParamLoc,
"pointless default value for required parameter "
4582 "'" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4595 AsmToken EndToken, StartToken = getTok();
4596 unsigned MacroDepth = 0;
4606 return Error(DirectiveLoc,
"no matching '.endmacro' in definition");
4611 if (getTok().getIdentifier() ==
".endm" ||
4612 getTok().getIdentifier() ==
".endmacro") {
4613 if (MacroDepth == 0) {
4614 EndToken = getTok();
4617 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
4624 }
else if (getTok().getIdentifier() ==
".macro") {
4630 (void)parseCppHashLineFilenameComment(getLexer().getLoc());
4634 eatToEndOfStatement();
4637 if (getContext().lookupMacro(
Name)) {
4638 return Error(DirectiveLoc,
"macro '" +
Name +
"' is already defined");
4644 checkForBadMacro(DirectiveLoc,
Name, Body, Parameters);
4648 getContext().defineMacro(
Name, std::move(
Macro));
4672 if (NParameters == 0)
4675 bool NamedParametersFound =
false;
4676 bool PositionalParametersFound =
false;
4681 while (!Body.
empty()) {
4683 std::size_t
End = Body.
size(), Pos = 0;
4684 for (; Pos !=
End; ++Pos) {
4687 if (Body[Pos] ==
'\\' && Pos + 1 !=
End)
4691 if (Body[Pos] !=
'$' || Pos + 1 ==
End)
4693 char Next = Body[Pos + 1];
4694 if (Next ==
'$' || Next ==
'n' ||
4695 isdigit(
static_cast<unsigned char>(Next)))
4703 if (Body[Pos] ==
'$') {
4704 switch (Body[Pos + 1]) {
4711 PositionalParametersFound =
true;
4716 PositionalParametersFound =
true;
4722 unsigned I = Pos + 1;
4726 const char *Begin = Body.
data() + Pos + 1;
4733 if (
Index == NParameters) {
4734 if (Body[Pos + 1] ==
'(' && Body[Pos + 2] ==
')')
4740 NamedParametersFound =
true;
4748 if (!NamedParametersFound && PositionalParametersFound)
4749 Warning(DirectiveLoc,
"macro defined with named parameters which are not "
4750 "used in macro body, possible positional parameter "
4751 "found in body which will have no effect");
4760 if (!isInsideMacroInstantiation())
4761 return TokError(
"unexpected '" +
Directive +
"' in file, "
4762 "no current macro definition");
4765 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4766 TheCondState = TheCondStack.back();
4767 TheCondStack.pop_back();
4779 return TokError(
"unexpected token in '" +
Directive +
"' directive");
4783 if (isInsideMacroInstantiation()) {
4790 return TokError(
"unexpected '" +
Directive +
"' in file, "
4791 "no current macro definition");
4796bool AsmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
4799 if (parseTokenLoc(Loc) ||
4801 "expected identifier in '.purgem' directive") ||
4805 if (!getContext().lookupMacro(
Name))
4806 return Error(DirectiveLoc,
"macro '" +
Name +
"' is not defined");
4808 getContext().undefineMacro(
Name);
4810 <<
"Un-defining macro: " <<
Name <<
"\n");
4816bool AsmParser::parseDirectiveBundleAlignMode() {
4819 SMLoc ExprLoc = getLexer().getLoc();
4820 int64_t AlignSizePow2;
4821 if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4823 check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4824 "invalid bundle alignment size (expected between 0 and 30)"))
4827 getStreamer().emitBundleAlignMode(
Align(1ULL << AlignSizePow2));
4833bool AsmParser::parseDirectiveBundleLock() {
4834 if (checkForValidSection())
4836 bool AlignToEnd =
false;
4839 SMLoc Loc = getTok().getLoc();
4840 const char *kInvalidOptionError =
4841 "invalid option for '.bundle_lock' directive";
4844 if (
check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4845 check(Option !=
"align_to_end", Loc, kInvalidOptionError) || parseEOL())
4850 getStreamer().emitBundleLock(AlignToEnd);
4856bool AsmParser::parseDirectiveBundleUnlock() {
4857 if (checkForValidSection() || parseEOL())
4860 getStreamer().emitBundleUnlock();
4866bool AsmParser::parseDirectiveSpace(
StringRef IDVal) {
4869 if (checkForValidSection() || parseExpression(NumBytes))
4872 int64_t FillExpr = 0;
4874 if (parseAbsoluteExpression(FillExpr))
4880 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4887bool AsmParser::parseDirectiveDCB(
StringRef IDVal,
unsigned Size) {
4890 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4893 if (NumValues < 0) {
4894 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4902 SMLoc ExprLoc = getLexer().getLoc();
4903 if (parseExpression(
Value))
4909 uint64_t IntValue = MCE->getValue();
4911 return Error(ExprLoc,
"literal value out of range for directive");
4912 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4913 getStreamer().emitIntValue(IntValue,
Size);
4915 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4916 getStreamer().emitValue(
Value,
Size, ExprLoc);
4927 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4930 if (NumValues < 0) {
4931 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4939 if (parseRealValue(Semantics, AsInt) || parseEOL())
4942 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4951bool AsmParser::parseDirectiveDS(
StringRef IDVal,
unsigned Size) {
4954 if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
4958 if (NumValues < 0) {
4959 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4963 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4964 getStreamer().emitFill(
Size, 0);
4971bool AsmParser::parseDirectiveLEB128(
bool Signed) {
4972 if (checkForValidSection())
4975 auto parseOp = [&]() ->
bool {
4977 if (parseExpression(
Value))
4980 getStreamer().emitSLEB128Value(
Value);
4982 getStreamer().emitULEB128Value(
Value);
4986 return parseMany(parseOp);
4991bool AsmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
4992 auto parseOp = [&]() ->
bool {
4994 SMLoc Loc = getTok().getLoc();
4995 if (parseIdentifier(
Name))
4996 return Error(Loc,
"expected identifier");
4998 if (discardLTOSymbol(
Name))
5006 return Error(Loc,
"non-local symbol required");
5008 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
5009 return Error(Loc,
"unable to emit symbol attribute");
5013 return parseMany(parseOp);
5018bool AsmParser::parseDirectiveComm(
bool IsLocal) {
5019 if (checkForValidSection())
5022 SMLoc IDLoc = getLexer().getLoc();
5024 if (parseIdentifier(
Name))
5025 return TokError(
"expected identifier in directive");
5034 SMLoc SizeLoc = getLexer().getLoc();
5035 if (parseAbsoluteExpression(
Size))
5038 int64_t Pow2Alignment = 0;
5039 SMLoc Pow2AlignmentLoc;
5042 Pow2AlignmentLoc = getLexer().getLoc();
5043 if (parseAbsoluteExpression(Pow2Alignment))
5048 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
5051 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5054 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
5055 Pow2Alignment =
Log2_64(Pow2Alignment);
5065 return Error(SizeLoc,
"size must be non-negative");
5067 Sym->redefineIfPossible();
5068 if (!
Sym->isUndefined())
5069 return Error(IDLoc,
"invalid symbol redefinition");
5073 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
5074 Align(1ULL << Pow2Alignment));
5078 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
5084bool AsmParser::parseDirectiveAbort() {
5086 SMLoc Loc = getLexer().getLoc();
5088 StringRef Str = parseStringToEndOfStatement();
5093 return Error(Loc,
".abort detected. Assembly stopping.");
5095 return Error(Loc,
".abort '" + Str +
"' detected. Assembly stopping.");
5103bool AsmParser::parseDirectiveInclude() {
5106 SMLoc IncludeLoc = getTok().getLoc();
5109 "expected string in '.include' directive") ||
5110 parseEscapedString(Filename) ||
5112 "unexpected token in '.include' directive") ||
5115 check(enterIncludeFile(Filename), IncludeLoc,
5116 "Could not find include file '" + Filename +
"'"))
5124bool AsmParser::parseDirectiveIncbin() {
5127 SMLoc IncbinLoc = getTok().getLoc();
5129 "expected string in '.incbin' directive") ||
5130 parseEscapedString(Filename))
5134 const MCExpr *Count =
nullptr;
5135 SMLoc SkipLoc, CountLoc;
5140 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
5144 CountLoc = getTok().getLoc();
5145 if (parseExpression(Count))
5153 if (
check(Skip < 0, SkipLoc,
"skip is negative"))
5157 if (processIncbinFile(Filename, Skip, Count, CountLoc))
5158 return Error(IncbinLoc,
"Could not find incbin file '" + Filename +
"'");
5164bool AsmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
5165 TheCondStack.push_back(TheCondState);
5167 if (TheCondState.
Ignore) {
5168 eatToEndOfStatement();
5171 if (parseAbsoluteExpression(ExprValue) || parseEOL())
5181 ExprValue = ExprValue == 0;
5184 ExprValue = ExprValue >= 0;
5187 ExprValue = ExprValue > 0;
5190 ExprValue = ExprValue <= 0;
5193 ExprValue = ExprValue < 0;
5197 TheCondState.
CondMet = ExprValue;
5206bool AsmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
5207 TheCondStack.push_back(TheCondState);
5210 if (TheCondState.
Ignore) {
5211 eatToEndOfStatement();
5213 StringRef Str = parseStringToEndOfStatement();
5218 TheCondState.
CondMet = ExpectBlank == Str.empty();
5228bool AsmParser::parseDirectiveIfc(
SMLoc DirectiveLoc,
bool ExpectEqual) {
5229 TheCondStack.push_back(TheCondState);
5232 if (TheCondState.
Ignore) {
5233 eatToEndOfStatement();
5240 StringRef Str2 = parseStringToEndOfStatement();
5254bool AsmParser::parseDirectiveIfeqs(
SMLoc DirectiveLoc,
bool ExpectEqual) {
5257 return TokError(
"expected string parameter for '.ifeqs' directive");
5258 return TokError(
"expected string parameter for '.ifnes' directive");
5261 StringRef String1 = getTok().getStringContents();
5267 "expected comma after first string for '.ifeqs' directive");
5268 return TokError(
"expected comma after first string for '.ifnes' directive");
5275 return TokError(
"expected string parameter for '.ifeqs' directive");
5276 return TokError(
"expected string parameter for '.ifnes' directive");
5279 StringRef String2 = getTok().getStringContents();
5282 TheCondStack.push_back(TheCondState);
5284 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
5292bool AsmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
5294 TheCondStack.push_back(TheCondState);
5297 if (TheCondState.
Ignore) {
5298 eatToEndOfStatement();
5300 if (
check(parseIdentifier(
Name),
"expected identifier after '.ifdef'") ||
5318bool AsmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc) {
5321 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
5322 " .if or an .elseif");
5325 bool LastIgnoreState =
false;
5326 if (!TheCondStack.empty())
5327 LastIgnoreState = TheCondStack.back().Ignore;
5328 if (LastIgnoreState || TheCondState.
CondMet) {
5329 TheCondState.
Ignore =
true;
5330 eatToEndOfStatement();
5333 if (parseAbsoluteExpression(ExprValue))
5339 TheCondState.
CondMet = ExprValue;
5348bool AsmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
5354 return Error(DirectiveLoc,
"Encountered a .else that doesn't follow "
5355 " an .if or an .elseif");
5357 bool LastIgnoreState =
false;
5358 if (!TheCondStack.empty())
5359 LastIgnoreState = TheCondStack.back().Ignore;
5360 if (LastIgnoreState || TheCondState.
CondMet)
5361 TheCondState.
Ignore =
true;
5363 TheCondState.
Ignore =
false;
5370bool AsmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
5383bool AsmParser::parseDirectiveError(
SMLoc L,
bool WithMessage) {
5384 if (!TheCondStack.empty()) {
5385 if (TheCondStack.back().Ignore) {
5386 eatToEndOfStatement();
5392 return Error(L,
".err encountered");
5394 StringRef Message =
".error directive invoked in source file";
5397 return TokError(
".error argument must be a string");
5399 Message = getTok().getStringContents();
5403 return Error(L, Message);
5408bool AsmParser::parseDirectiveWarning(
SMLoc L) {
5409 if (!TheCondStack.empty()) {
5410 if (TheCondStack.back().Ignore) {
5411 eatToEndOfStatement();
5416 StringRef Message =
".warning directive invoked in source file";
5420 return TokError(
".warning argument must be a string");
5422 Message = getTok().getStringContents();
5433bool AsmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
5438 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
5440 if (!TheCondStack.empty()) {
5441 TheCondState = TheCondStack.back();
5442 TheCondStack.pop_back();
5448void AsmParser::initializeDirectiveKindMap() {
5455 DirectiveKindMap[
".set"] = DK_SET;
5456 DirectiveKindMap[
".equ"] = DK_EQU;
5457 DirectiveKindMap[
".equiv"] = DK_EQUIV;
5458 DirectiveKindMap[
".ascii"] = DK_ASCII;
5459 DirectiveKindMap[
".asciz"] = DK_ASCIZ;
5460 DirectiveKindMap[
".string"] = DK_STRING;
5461 DirectiveKindMap[
".byte"] = DK_BYTE;
5462 DirectiveKindMap[
".short"] = DK_SHORT;
5463 DirectiveKindMap[
".value"] = DK_VALUE;
5464 DirectiveKindMap[
".2byte"] = DK_2BYTE;
5465 DirectiveKindMap[
".long"] = DK_LONG;
5466 DirectiveKindMap[
".int"] = DK_INT;
5467 DirectiveKindMap[
".4byte"] = DK_4BYTE;
5468 DirectiveKindMap[
".quad"] = DK_QUAD;
5469 DirectiveKindMap[
".8byte"] = DK_8BYTE;
5470 DirectiveKindMap[
".octa"] = DK_OCTA;
5471 DirectiveKindMap[
".single"] = DK_SINGLE;
5472 DirectiveKindMap[
".float"] = DK_FLOAT;
5473 DirectiveKindMap[
".double"] = DK_DOUBLE;
5474 DirectiveKindMap[
".align"] = DK_ALIGN;
5475 DirectiveKindMap[
".align32"] = DK_ALIGN32;
5476 DirectiveKindMap[
".balign"] = DK_BALIGN;
5477 DirectiveKindMap[
".balignw"] = DK_BALIGNW;
5478 DirectiveKindMap[
".balignl"] = DK_BALIGNL;
5479 DirectiveKindMap[
".p2align"] = DK_P2ALIGN;
5480 DirectiveKindMap[
".p2alignw"] = DK_P2ALIGNW;
5481 DirectiveKindMap[
".p2alignl"] = DK_P2ALIGNL;
5482 DirectiveKindMap[
".org"] = DK_ORG;
5483 DirectiveKindMap[
".fill"] = DK_FILL;
5484 DirectiveKindMap[
".zero"] = DK_ZERO;
5485 DirectiveKindMap[
".extern"] = DK_EXTERN;
5486 DirectiveKindMap[
".globl"] = DK_GLOBL;
5487 DirectiveKindMap[
".global"] = DK_GLOBAL;
5488 DirectiveKindMap[
".lazy_reference"] = DK_LAZY_REFERENCE;
5489 DirectiveKindMap[
".no_dead_strip"] = DK_NO_DEAD_STRIP;
5490 DirectiveKindMap[
".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5491 DirectiveKindMap[
".private_extern"] = DK_PRIVATE_EXTERN;
5492 DirectiveKindMap[
".reference"] = DK_REFERENCE;
5493 DirectiveKindMap[
".weak_definition"] = DK_WEAK_DEFINITION;
5494 DirectiveKindMap[
".weak_reference"] = DK_WEAK_REFERENCE;
5495 DirectiveKindMap[
".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5496 DirectiveKindMap[
".cold"] = DK_COLD;
5497 DirectiveKindMap[
".comm"] = DK_COMM;
5498 DirectiveKindMap[
".common"] = DK_COMMON;
5499 DirectiveKindMap[
".lcomm"] = DK_LCOMM;
5500 DirectiveKindMap[
".abort"] = DK_ABORT;
5501 DirectiveKindMap[
".include"] = DK_INCLUDE;
5502 DirectiveKindMap[
".incbin"] = DK_INCBIN;
5503 DirectiveKindMap[
".code16"] = DK_CODE16;
5504 DirectiveKindMap[
".code16gcc"] = DK_CODE16GCC;
5505 DirectiveKindMap[
".rept"] = DK_REPT;
5506 DirectiveKindMap[
".rep"] = DK_REPT;
5507 DirectiveKindMap[
".irp"] = DK_IRP;
5508 DirectiveKindMap[
".irpc"] = DK_IRPC;
5509 DirectiveKindMap[
".endr"] = DK_ENDR;
5510 DirectiveKindMap[
".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5511 DirectiveKindMap[
".bundle_lock"] = DK_BUNDLE_LOCK;
5512 DirectiveKindMap[
".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5513 DirectiveKindMap[
".if"] = DK_IF;
5514 DirectiveKindMap[
".ifeq"] = DK_IFEQ;
5515 DirectiveKindMap[
".ifge"] = DK_IFGE;
5516 DirectiveKindMap[
".ifgt"] = DK_IFGT;
5517 DirectiveKindMap[
".ifle"] = DK_IFLE;
5518 DirectiveKindMap[
".iflt"] = DK_IFLT;
5519 DirectiveKindMap[
".ifne"] = DK_IFNE;
5520 DirectiveKindMap[
".ifb"] = DK_IFB;
5521 DirectiveKindMap[
".ifnb"] = DK_IFNB;
5522 DirectiveKindMap[
".ifc"] = DK_IFC;
5523 DirectiveKindMap[
".ifeqs"] = DK_IFEQS;
5524 DirectiveKindMap[
".ifnc"] = DK_IFNC;
5525 DirectiveKindMap[
".ifnes"] = DK_IFNES;
5526 DirectiveKindMap[
".ifdef"] = DK_IFDEF;
5527 DirectiveKindMap[
".ifndef"] = DK_IFNDEF;
5528 DirectiveKindMap[
".ifnotdef"] = DK_IFNOTDEF;
5529 DirectiveKindMap[
".elseif"] = DK_ELSEIF;
5530 DirectiveKindMap[
".else"] = DK_ELSE;
5531 DirectiveKindMap[
".end"] = DK_END;
5532 DirectiveKindMap[
".endif"] = DK_ENDIF;
5533 DirectiveKindMap[
".skip"] = DK_SKIP;
5534 DirectiveKindMap[
".space"] = DK_SPACE;
5535 DirectiveKindMap[
".file"] = DK_FILE;
5536 DirectiveKindMap[
".line"] = DK_LINE;
5537 DirectiveKindMap[
".loc"] = DK_LOC;
5538 DirectiveKindMap[
".stabs"] = DK_STABS;
5539 DirectiveKindMap[
".cv_file"] = DK_CV_FILE;
5540 DirectiveKindMap[
".cv_func_id"] = DK_CV_FUNC_ID;
5541 DirectiveKindMap[
".cv_loc"] = DK_CV_LOC;
5542 DirectiveKindMap[
".cv_linetable"] = DK_CV_LINETABLE;
5543 DirectiveKindMap[
".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5544 DirectiveKindMap[
".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5545 DirectiveKindMap[
".cv_def_range"] = DK_CV_DEF_RANGE;
5546 DirectiveKindMap[
".cv_string"] = DK_CV_STRING;
5547 DirectiveKindMap[
".cv_stringtable"] = DK_CV_STRINGTABLE;
5548 DirectiveKindMap[
".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5549 DirectiveKindMap[
".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5550 DirectiveKindMap[
".cv_fpo_data"] = DK_CV_FPO_DATA;
5551 DirectiveKindMap[
".sleb128"] = DK_SLEB128;
5552 DirectiveKindMap[
".uleb128"] = DK_ULEB128;
5553 DirectiveKindMap[
".cfi_sections"] = DK_CFI_SECTIONS;
5554 DirectiveKindMap[
".cfi_startproc"] = DK_CFI_STARTPROC;
5555 DirectiveKindMap[
".cfi_endproc"] = DK_CFI_ENDPROC;
5556 DirectiveKindMap[
".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5557 DirectiveKindMap[
".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5558 DirectiveKindMap[
".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5559 DirectiveKindMap[
".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5560 DirectiveKindMap[
".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
5561 DirectiveKindMap[
".cfi_offset"] = DK_CFI_OFFSET;
5562 DirectiveKindMap[
".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5563 DirectiveKindMap[
".cfi_personality"] = DK_CFI_PERSONALITY;
5564 DirectiveKindMap[
".cfi_lsda"] = DK_CFI_LSDA;
5565 DirectiveKindMap[
".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5566 DirectiveKindMap[
".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5567 DirectiveKindMap[
".cfi_same_value"] = DK_CFI_SAME_VALUE;
5568 DirectiveKindMap[
".cfi_restore"] = DK_CFI_RESTORE;
5569 DirectiveKindMap[
".cfi_escape"] = DK_CFI_ESCAPE;
5570 DirectiveKindMap[
".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5571 DirectiveKindMap[
".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5572 DirectiveKindMap[
".cfi_undefined"] = DK_CFI_UNDEFINED;
5573 DirectiveKindMap[
".cfi_register"] = DK_CFI_REGISTER;
5574 DirectiveKindMap[
".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5575 DirectiveKindMap[
".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5576 DirectiveKindMap[
".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
5577 DirectiveKindMap[
".macros_on"] = DK_MACROS_ON;
5578 DirectiveKindMap[
".macros_off"] = DK_MACROS_OFF;
5579 DirectiveKindMap[
".macro"] = DK_MACRO;
5580 DirectiveKindMap[
".exitm"] = DK_EXITM;
5581 DirectiveKindMap[
".endm"] = DK_ENDM;
5582 DirectiveKindMap[
".endmacro"] = DK_ENDMACRO;
5583 DirectiveKindMap[
".purgem"] = DK_PURGEM;
5584 DirectiveKindMap[
".err"] = DK_ERR;
5585 DirectiveKindMap[
".error"] = DK_ERROR;
5586 DirectiveKindMap[
".warning"] = DK_WARNING;
5587 DirectiveKindMap[
".altmacro"] = DK_ALTMACRO;
5588 DirectiveKindMap[
".noaltmacro"] = DK_NOALTMACRO;
5589 DirectiveKindMap[
".reloc"] = DK_RELOC;
5590 DirectiveKindMap[
".dc"] = DK_DC;
5591 DirectiveKindMap[
".dc.a"] = DK_DC_A;
5592 DirectiveKindMap[
".dc.b"] = DK_DC_B;
5593 DirectiveKindMap[
".dc.d"] = DK_DC_D;
5594 DirectiveKindMap[
".dc.l"] = DK_DC_L;
5595 DirectiveKindMap[
".dc.s"] = DK_DC_S;
5596 DirectiveKindMap[
".dc.w"] = DK_DC_W;
5597 DirectiveKindMap[
".dc.x"] = DK_DC_X;
5598 DirectiveKindMap[
".dcb"] = DK_DCB;
5599 DirectiveKindMap[
".dcb.b"] = DK_DCB_B;
5600 DirectiveKindMap[
".dcb.d"] = DK_DCB_D;
5601 DirectiveKindMap[
".dcb.l"] = DK_DCB_L;
5602 DirectiveKindMap[
".dcb.s"] = DK_DCB_S;
5603 DirectiveKindMap[
".dcb.w"] = DK_DCB_W;
5604 DirectiveKindMap[
".dcb.x"] = DK_DCB_X;
5605 DirectiveKindMap[
".ds"] = DK_DS;
5606 DirectiveKindMap[
".ds.b"] = DK_DS_B;
5607 DirectiveKindMap[
".ds.d"] = DK_DS_D;
5608 DirectiveKindMap[
".ds.l"] = DK_DS_L;
5609 DirectiveKindMap[
".ds.p"] = DK_DS_P;
5610 DirectiveKindMap[
".ds.s"] = DK_DS_S;
5611 DirectiveKindMap[
".ds.w"] = DK_DS_W;
5612 DirectiveKindMap[
".ds.x"] = DK_DS_X;
5613 DirectiveKindMap[
".print"] = DK_PRINT;
5614 DirectiveKindMap[
".addrsig"] = DK_ADDRSIG;
5615 DirectiveKindMap[
".addrsig_sym"] = DK_ADDRSIG_SYM;
5616 DirectiveKindMap[
".pseudoprobe"] = DK_PSEUDO_PROBE;
5617 DirectiveKindMap[
".lto_discard"] = DK_LTO_DISCARD;
5618 DirectiveKindMap[
".lto_set_conditional"] = DK_LTO_SET_CONDITIONAL;
5619 DirectiveKindMap[
".memtag"] = DK_MEMTAG;
5623 AsmToken EndToken, StartToken = getTok();
5625 unsigned NestLevel = 0;
5629 printError(DirectiveLoc,
"no matching '.endr' in definition");
5634 StringRef Ident = getTok().getIdentifier();
5635 if (Ident ==
".rep" || Ident ==
".rept" || Ident ==
".irp" ||
5638 }
else if (Ident ==
".endr") {
5639 if (NestLevel == 0) {
5640 EndToken = getTok();
5644 printError(getTok().getLoc(),
"expected newline");
5652 eatToEndOfStatement();
5661 return &MacroLikeBodies.back();
5664void AsmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
5668 std::unique_ptr<MemoryBuffer> Instantiation =
5673 MacroInstantiation *
MI =
new MacroInstantiation{
5674 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5675 ActiveMacros.push_back(
MI);
5685bool AsmParser::parseDirectiveRept(
SMLoc DirectiveLoc,
StringRef Dir) {
5687 SMLoc CountLoc = getTok().getLoc();
5688 if (parseExpression(CountExpr))
5692 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5693 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
5696 if (
check(Count < 0, CountLoc,
"Count is negative") || parseEOL())
5710 if (expandMacro(
OS, *M, std::nullopt, std::nullopt,
false))
5713 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5720bool AsmParser::parseDirectiveIrp(
SMLoc DirectiveLoc) {
5722 MCAsmMacroArguments
A;
5723 if (
check(parseIdentifier(Parameter.
Name),
5724 "expected identifier in '.irp' directive") ||
5725 parseComma() || parseMacroArguments(
nullptr,
A) || parseEOL())
5738 for (
const MCAsmMacroArgument &Arg :
A) {
5741 if (expandMacro(
OS, *M, Parameter, Arg,
true))
5745 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5752bool AsmParser::parseDirectiveIrpc(
SMLoc DirectiveLoc) {
5754 MCAsmMacroArguments
A;
5756 if (
check(parseIdentifier(Parameter.
Name),
5757 "expected identifier in '.irpc' directive") ||
5758 parseComma() || parseMacroArguments(
nullptr,
A))
5761 if (
A.size() != 1 ||
A.front().size() != 1)
5762 return TokError(
"unexpected token in '.irpc' directive");
5776 StringRef Values =
A.front().front().getString();
5777 for (std::size_t
I = 0,
End = Values.
size();
I !=
End; ++
I) {
5778 MCAsmMacroArgument Arg;
5783 if (expandMacro(
OS, *M, Parameter, Arg,
true))
5787 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5792bool AsmParser::parseDirectiveEndr(
SMLoc DirectiveLoc) {
5793 if (ActiveMacros.empty())
5794 return TokError(
"unmatched '.endr' directive");
5804bool AsmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
5807 SMLoc ExprLoc = getLexer().getLoc();
5808 if (parseExpression(
Value))
5812 return Error(ExprLoc,
"unexpected expression in _emit");
5814 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5815 return Error(ExprLoc,
"literal value out of range for directive");
5821bool AsmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
5823 SMLoc ExprLoc = getLexer().getLoc();
5824 if (parseExpression(
Value))
5828 return Error(ExprLoc,
"unexpected expression in align");
5831 return Error(ExprLoc,
"literal value not a power of two greater then zero");
5837bool AsmParser::parseDirectivePrint(
SMLoc DirectiveLoc) {
5841 return Error(DirectiveLoc,
"expected double quoted string after .print");
5848bool AsmParser::parseDirectiveAddrsig() {
5851 getStreamer().emitAddrsig();
5855bool AsmParser::parseDirectiveAddrsigSym() {
5857 if (
check(parseIdentifier(
Name),
"expected identifier") || parseEOL())
5860 getStreamer().emitAddrsigSym(
Sym);
5864bool AsmParser::parseDirectivePseudoProbe() {
5871 if (parseIntToken(
Guid,
"unexpected token in '.pseudoprobe' directive"))
5874 if (parseIntToken(
Index,
"unexpected token in '.pseudoprobe' directive"))
5877 if (parseIntToken(
Type,
"unexpected token in '.pseudoprobe' directive"))
5880 if (parseIntToken(Attr,
"unexpected token in '.pseudoprobe' directive"))
5884 if (parseIntToken(Discriminator,
5885 "unexpected token in '.pseudoprobe' directive"))
5896 int64_t CallerGuid = 0;
5898 if (parseIntToken(CallerGuid,
5899 "unexpected token in '.pseudoprobe' directive"))
5907 int64_t CallerProbeId = 0;
5909 if (parseIntToken(CallerProbeId,
5910 "unexpected token in '.pseudoprobe' directive"))
5920 if (parseIdentifier(FnName))
5921 return Error(getLexer().getLoc(),
"unexpected token in '.pseudoprobe' directive");
5922 MCSymbol *FnSym = getContext().lookupSymbol(FnName);
5927 getStreamer().emitPseudoProbe(
Guid,
Index,
Type, Attr, Discriminator,
5928 InlineStack, FnSym);
5937bool AsmParser::parseDirectiveLTODiscard() {
5938 auto ParseOp = [&]() ->
bool {
5940 SMLoc Loc = getTok().getLoc();
5941 if (parseIdentifier(
Name))
5942 return Error(Loc,
"expected identifier");
5947 LTODiscardSymbols.
clear();
5948 return parseMany(ParseOp);
5974bool AsmParser::parseMSInlineAsm(
5975 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
5994 unsigned InputIdx = 0;
5995 unsigned OutputIdx = 0;
5998 if (parseCurlyBlockScope(AsmStrRewrites))
6001 ParseStatementInfo
Info(&AsmStrRewrites);
6002 bool StatementErr = parseStatement(Info, &SI);
6004 if (StatementErr ||
Info.ParseError) {
6006 printPendingErrors();
6011 assert(!hasPendingError() &&
"unexpected error from parseStatement");
6013 if (
Info.Opcode == ~0U)
6019 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
6024 !getTargetParser().OmitRegisterFromClobberLists(Operand.
getReg())) {
6025 unsigned NumDefs =
Desc.getNumDefs();
6034 if (SymName.
empty())
6042 if (Operand.
isImm()) {
6050 bool isOutput = (i == 1) &&
Desc.mayStore();
6057 OutputConstraints.
push_back((
"=" + Constraint).str());
6064 if (
Desc.operands()[i - 1].isBranchTarget())
6078 NumOutputs = OutputDecls.
size();
6079 NumInputs = InputDecls.
size();
6084 Clobbers.
assign(ClobberRegs.
size(), std::string());
6085 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
6091 if (NumOutputs || NumInputs) {
6092 unsigned NumExprs = NumOutputs + NumInputs;
6093 OpDecls.resize(NumExprs);
6094 Constraints.
resize(NumExprs);
6095 for (
unsigned i = 0; i < NumOutputs; ++i) {
6096 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6097 Constraints[i] = OutputConstraints[i];
6099 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
6100 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6101 Constraints[
j] = InputConstraints[i];
6106 std::string AsmStringIR;
6110 const char *AsmStart = ASMString.
begin();
6111 const char *AsmEnd = ASMString.
end();
6113 for (
auto it = AsmStrRewrites.
begin(); it != AsmStrRewrites.
end(); ++it) {
6121 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
6124 if (
unsigned Len = Loc - AsmStart)
6129 AsmStart = Loc + AR.
Len;
6133 unsigned AdditionalSkip = 0;
6155 size_t OffsetLen = OffsetName.
size();
6156 auto rewrite_it = std::find_if(
6158 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6159 (FusingAR.Kind == AOK_Input ||
6160 FusingAR.Kind == AOK_CallInput);
6162 if (rewrite_it == AsmStrRewrites.
end()) {
6163 OS <<
"offset " << OffsetName;
6165 OS <<
"${" << InputIdx++ <<
":P}";
6166 rewrite_it->Done =
true;
6168 OS <<
'$' << InputIdx++;
6169 rewrite_it->Done =
true;
6182 OS <<
"${" << InputIdx++ <<
":P}";
6184 OS <<
'$' << InputIdx++;
6187 OS <<
"${" << InputIdx++ <<
":P}";
6191 OS <<
"${" << OutputIdx++ <<
":P}";
6193 OS <<
'$' << OutputIdx++;
6198 case 8:
OS <<
"byte ptr ";
break;
6199 case 16:
OS <<
"word ptr ";
break;
6200 case 32:
OS <<
"dword ptr ";
break;
6201 case 64:
OS <<
"qword ptr ";
break;
6202 case 80:
OS <<
"xword ptr ";
break;
6203 case 128:
OS <<
"xmmword ptr ";
break;
6204 case 256:
OS <<
"ymmword ptr ";
break;
6214 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6219 unsigned Val = AR.
Val;
6221 assert(Val < 10 &&
"Expected alignment less then 2^10.");
6222 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6234 AsmStart = Loc + AR.
Len + AdditionalSkip;
6238 if (AsmStart != AsmEnd)
6241 AsmString =
OS.str();
6245bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
6251 if (parseIdentifier(LabelVal))
6252 return Error(LabelLoc,
"The HLASM Label has to be an Identifier");
6257 if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
6266 return Error(LabelLoc,
6267 "Cannot have just a label for an HLASM inline asm statement");
6270 getContext().getAsmInfo()->shouldEmitLabelsInUpperCase()
6274 getTargetParser().doBeforeLabelEmit(
Sym, LabelLoc);
6281 if (enabledGenDwarfForAssembly())
6285 getTargetParser().onLabelParsed(
Sym);
6290bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
6293 SMLoc OperationEntryLoc = OperationEntryTok.
getLoc();
6297 if (parseIdentifier(OperationEntryVal))
6298 return Error(OperationEntryLoc,
"unexpected token at start of statement");
6304 return parseAndMatchAndEmitTargetInstruction(
6305 Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
6308bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
6310 assert(!hasPendingError() &&
"parseStatement started with pending error");
6313 bool ShouldParseAsHLASMLabel =
false;
6322 ShouldParseAsHLASMLabel =
true;
6328 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
6329 getTok().getString().front() ==
'\n')
6344 if (getTok().getString().front() ==
'\n' ||
6345 getTok().getString().front() ==
'\r') {
6354 if (ShouldParseAsHLASMLabel) {
6357 if (parseAsHLASMLabel(Info, SI)) {
6360 eatToEndOfStatement();
6365 return parseAsMachineInstruction(Info, SI);
6369namespace MCParserUtils {
6374 switch (
Value->getKind()) {
6405 return Parser.
TokError(
"missing expression");
6423 return Parser.
Error(EqualLoc,
"Recursive use of '" +
Name +
"'");
6424 else if (
Sym->isUndefined(
false) && !
Sym->isUsed() &&
6427 else if (
Sym->isVariable() && !
Sym->isUsed() && allow_redef)
6429 else if (!
Sym->isUndefined() && (!
Sym->isVariable() || !allow_redef))
6430 return Parser.
Error(EqualLoc,
"redefinition of '" +
Name +
"'");
6431 else if (!
Sym->isVariable())
6432 return Parser.
Error(EqualLoc,
"invalid assignment to '" +
Name +
"'");
6433 else if (!isa<MCConstantExpr>(
Sym->getVariableValue()))
6434 return Parser.
Error(EqualLoc,
6435 "invalid reassignment of non-absolute variable '" +
6437 }
else if (
Name ==
".") {
6443 Sym->setRedefinable(allow_redef);
6455 if (
C.getTargetTriple().isSystemZ() &&
C.getTargetTriple().isOSzOS())
6456 return new HLASMAsmParser(SM,
C, Out, MAI, CB);
6458 return new AsmParser(SM,
C, Out, MAI, CB);
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 bool isIdentifierChar(char c)
static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI, AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr)
static std::string angleBracketString(StringRef AltMacroStr)
creating a string without the escape characters '!'.
static int rewritesSort(const AsmRewrite *AsmRewriteA, const AsmRewrite *AsmRewriteB)
static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo)
static bool isOperator(AsmToken::TokenKind kind)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This file contains constants used for implementing Dwarf debug support.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static bool isHexDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)
Factory for NaN values.
Class for arbitrary precision integers.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
APInt getHiBits(unsigned numBits) const
Compute an APInt containing numBits highbits from this APInt.
unsigned getBitWidth() const
Return the number of bits in the APInt.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
AsmCond - Class to support conditional assembly.
ConditionalAssemblyType TheCond
AsmLexer - Lexer class for assembly files.
Target independent representation for an assembler token.
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Holds state from .cv_file and .cv_loc directives for later emission.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool useParensForSymbolVariant() const
bool preserveAsmComments() const
Return true if assembly (inline or otherwise) should be parsed.
bool isLittleEndian() const
True if the target is little endian.
unsigned getAssemblerDialect() const
bool doesAllowAtInName() const
StringRef getPrivateLabelPrefix() const
bool shouldEmitLabelsInUpperCase() const
bool shouldUseLogicalShr() const
StringRef getCommentString() const
bool hasSubsectionsViaSymbols() const
bool getDollarIsPC() const
Generic assembler lexer interface, for use by target specific assembly lexers.
void UnLex(AsmToken const &Token)
void setAllowHashInIdentifier(bool V)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void setLexHLASMIntegers(bool V)
Set whether to lex HLASM-flavour integers. For now this is only [0-9]*.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
SMLoc getLoc() const
Get the current source location.
SMLoc getErrLoc()
Get the current error location.
void setLexMasmIntegers(bool V)
Set whether to lex masm-style binary (e.g., 0b1101) and radix-specified literals (e....
const AsmToken & getTok() const
Get the current (last) lexed token.
AsmToken::TokenKind getKind() const
Get the kind of current token.
void setLexHLASMStrings(bool V)
Set whether to "lex" HLASM-flavour character and string literals.
void setSkipSpace(bool val)
Set whether spaces should be ignored by the lexer.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
const std::string & getErr()
Get the current error string.
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
Generic Sema callback for assembly parser.
virtual ~MCAsmParserSemaCallback()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)=0
Emit an error at the location L, with the message Msg.
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual StringRef parseStringToEndOfStatement()=0
Parse up to the end of statement and return the contents from the current token until the end of the ...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual SourceMgr & getSourceManager()=0
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo)=0
Parse a primary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool checkForValidSection()=0
Ensure that we have a valid section set in the streamer.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual bool discardLTOSymbol(StringRef) const
MCAsmParser & operator=(const MCAsmParser &)=delete
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
virtual bool isParsingMSInlineAsm()=0
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression of a specified parenthesis depth, assuming that the initial '(' charact...
virtual unsigned getAssemblerDialect()
virtual MCAsmLexer & getLexer()=0
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAngleBracketString(std::string &Data)=0
Parse an angle-bracket delimited string at the current position if one is present,...
bool TokError(const Twine &Msg, SMRange Range=std::nullopt)
Report an error at the current lexer location.
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl< std::pair< void *, bool > > &OpDecls, SmallVectorImpl< std::string > &Constraints, SmallVectorImpl< std::string > &Clobbers, const MCInstrInfo *MII, const MCInstPrinter *IP, MCAsmParserSemaCallback &SI)=0
Parse MS-style inline assembly.
virtual void setAssemblerDialect(unsigned i)
virtual MCContext & getContext()=0
virtual void setParsingMSInlineAsm(bool V)=0
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
bool Error(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)
Return an error at the location L, with the message Msg.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ AShr
Arithmetic shift right.
@ LShr
Logical shift right.
@ GTE
Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).
@ GT
Signed greater than comparison (result is either 0 or some target-specific non-zero value)
@ Xor
Bitwise exclusive or.
@ LT
Signed less than comparison (result is either 0 or some target-specific non-zero value).
@ LTE
Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).
@ NE
Inequality comparison.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
void * allocate(unsigned Size, unsigned Align=8)
Environment getObjectFileType() const
bool isDwarfMD5UsageConsistent(unsigned CUID) const
Reports whether MD5 checksum usage is consistent (all-or-none).
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
bool getGenDwarfForAssembly()
void setGenDwarfForAssembly(bool Value)
void setDwarfVersion(uint16_t v)
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
MCSymbol * lookupSymbol(const Twine &Name) const
Get the symbol for Name, or null.
CodeViewContext & getCVContext()
MCSymbol * createDirectionalLocalSymbol(unsigned LocalLabelVal)
Create the definition of a directional local symbol for numbered label (used for "1:" definitions).
uint16_t getDwarfVersion() const
const MCAsmInfo * getAsmInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
MCSymbol * getDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before)
Create and return a directional local symbol for numbered label (used for "1b" or 1f" references).
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printRegName(raw_ostream &OS, MCRegister Reg) const
Print the assembler register name.
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isMemUseUpRegs() const
isMemUseUpRegs - Is memory operand use up regs, for example, intel MS inline asm may use ARR[baseReg ...
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool needAddressOf() const
needAddressOf - Do we need to emit code to get the address of the variable/label? Only valid when par...
virtual MCRegister getReg() const =0
virtual bool isOffsetOfLocal() const
isOffsetOfLocal - Do we need to emit code to get the offset of the local variable,...
virtual StringRef getSymName()
virtual bool isImm() const =0
isImm - Is this an immediate operand?
unsigned getMCOperandNum()
StringRef getConstraint()
virtual void * getOpDecl()
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
virtual StringRef getVirtualSectionKind() const
void setBeginSymbol(MCSymbol *Sym)
bool isVirtualSection() const
Check whether this section is "virtual", that is has no actual object file contents.
StringRef getName() const
MCSymbol * getBeginSymbol()
Streaming machine code generation interface.
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI)
Create the default sections and set the initial one.
void setStartTokLocPtr(const SMLoc *Loc)
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static VariantKind getVariantKindForName(StringRef Name)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool isWeakExternal() const
bool isVariable() const
isVariable - Check if this is a variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSubtargetInfo & getSTI() const
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
static const MCUnaryExpr * createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
This represents an "assembler immediate".
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
StringRef getBuffer() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
constexpr bool isSuccess() const
Wrapper class representing virtual and physical registers.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
SourceMgr::DiagKind getKind() const
StringRef getLineContents() const
StringRef getMessage() const
ArrayRef< std::pair< unsigned, unsigned > > getRanges() const
const SourceMgr * getSourceMgr() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
void * getDiagContext() const
unsigned getMainFileID() const
DiagHandlerTy getDiagHandler() const
const MemoryBuffer * getMemoryBuffer(unsigned i) const
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
SMLoc getParentIncludeLoc(unsigned i) const
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
std::string upper() const
Convert the given ASCII string to uppercase.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
std::string lower() const
int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
This class represents a function that is read from a sample profile.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
@ C
The default llvm calling convention, compatible with C.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value)
Returns whether the given symbol is used anywhere in the given expression, or subexpressions.
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
MCAsmParserExtension * createCOFFAsmParser()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::tuple< uint64_t, uint32_t > InlineSite
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
std::vector< MCAsmMacroParameter > MCAsmMacroParameters
auto unique(Range &&R, Predicate P)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MCAsmParserExtension * createXCOFFAsmParser()
MCAsmParserExtension * createGOFFAsmParser()
auto reverse(ContainerTy &&C)
cl::opt< unsigned > AsmMacroMaxNestingDepth
const char AsmRewritePrecedence[]
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
static bool hasDiscriminator(uint32_t Flags)
MCAsmParserExtension * createWasmAsmParser()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance for parsing assembly similar to gas syntax.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
MCAsmParserExtension * createELFAsmParser()
MCAsmParserExtension * createDarwinAsmParser()
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
@ MCSA_Memtag
.memtag (ELF)
@ MCSA_PrivateExtern
.private_extern (MachO)
@ MCSA_WeakReference
.weak_reference (MachO)
@ MCSA_LazyReference
.lazy_reference (MachO)
@ MCSA_Reference
.reference (MachO)
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
@ MCSA_WeakDefinition
.weak_definition (MachO)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
ArrayRef< int > hi(ArrayRef< int > Vuu)
ArrayRef< int > lo(ArrayRef< int > Vuu)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
std::vector< AsmToken > Value
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
std::optional< StringRef > Source
The source code of the file.