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;
244 SMRange Range = std::nullopt)
override;
246 SMRange Range = std::nullopt)
override;
251 ParsingMSInlineAsm =
V;
276 SMLoc &EndLoc)
override;
294 bool parseCppHashLineFilenameComment(
SMLoc L,
bool SaveLocInfo =
true);
304 bool areMacrosEnabled() {
return MacrosEnabledFlag;}
307 void setMacrosEnabled(
bool Flag) {MacrosEnabledFlag =
Flag;}
310 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
319 void handleMacroExit();
322 bool parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg);
325 bool parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A);
327 void printMacroInstantiations();
329 SMRange Range = std::nullopt)
const {
336 bool enterIncludeFile(
const std::string &Filename);
340 bool processIncbinFile(
const std::string &Filename, int64_t Skip = 0,
349 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0);
360 enum class AssignmentKind {
372 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
373 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
374 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
376 bool parseRegisterOrRegisterNumber(int64_t &
Register,
SMLoc DirectiveLoc);
379 bool parseCVFileId(int64_t &FileId,
StringRef DirectiveName);
438 DK_BUNDLE_ALIGN_MODE,
452 DK_WEAK_DEF_CAN_BE_HIDDEN,
492 DK_CV_INLINE_SITE_ID,
495 DK_CV_INLINE_LINETABLE,
500 DK_CV_FILECHECKSUM_OFFSET,
506 DK_CFI_DEF_CFA_OFFSET,
507 DK_CFI_ADJUST_CFA_OFFSET,
508 DK_CFI_DEF_CFA_REGISTER,
509 DK_CFI_LLVM_DEF_ASPACE_CFA,
514 DK_CFI_REMEMBER_STATE,
515 DK_CFI_RESTORE_STATE,
519 DK_CFI_RETURN_COLUMN,
544 DK_LTO_SET_CONDITIONAL,
545 DK_CFI_MTE_TAGGED_FRAME,
555 enum CVDefRangeType {
557 CVDR_DEFRANGE_REGISTER,
558 CVDR_DEFRANGE_FRAMEPOINTER_REL,
559 CVDR_DEFRANGE_SUBFIELD_REGISTER,
560 CVDR_DEFRANGE_REGISTER_REL
568 bool parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated);
569 bool parseDirectiveReloc(
SMLoc DirectiveLoc);
570 bool parseDirectiveValue(
StringRef IDVal,
572 bool parseDirectiveOctaValue(
StringRef IDVal);
573 bool parseDirectiveRealValue(
StringRef IDVal,
575 bool parseDirectiveFill();
576 bool parseDirectiveZero();
578 bool parseDirectiveSet(
StringRef IDVal, AssignmentKind Kind);
579 bool parseDirectiveOrg();
581 bool parseDirectiveAlign(
bool IsPow2,
unsigned ValueSize);
584 bool parseDirectiveFile(
SMLoc DirectiveLoc);
585 bool parseDirectiveLine();
586 bool parseDirectiveLoc();
587 bool parseDirectiveStabs();
591 bool parseDirectiveCVFile();
592 bool parseDirectiveCVFuncId();
593 bool parseDirectiveCVInlineSiteId();
594 bool parseDirectiveCVLoc();
595 bool parseDirectiveCVLinetable();
596 bool parseDirectiveCVInlineLinetable();
597 bool parseDirectiveCVDefRange();
598 bool parseDirectiveCVString();
599 bool parseDirectiveCVStringTable();
600 bool parseDirectiveCVFileChecksums();
601 bool parseDirectiveCVFileChecksumOffset();
602 bool parseDirectiveCVFPOData();
605 bool parseDirectiveCFIRegister(
SMLoc DirectiveLoc);
606 bool parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc);
607 bool parseDirectiveCFISections();
608 bool parseDirectiveCFIStartProc();
609 bool parseDirectiveCFIEndProc();
610 bool parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc);
611 bool parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc);
612 bool parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc);
613 bool parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc);
614 bool parseDirectiveCFILLVMDefAspaceCfa(
SMLoc DirectiveLoc);
615 bool parseDirectiveCFIOffset(
SMLoc DirectiveLoc);
616 bool parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc);
617 bool parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality);
618 bool parseDirectiveCFIRememberState(
SMLoc DirectiveLoc);
619 bool parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc);
620 bool parseDirectiveCFISameValue(
SMLoc DirectiveLoc);
621 bool parseDirectiveCFIRestore(
SMLoc DirectiveLoc);
622 bool parseDirectiveCFIEscape(
SMLoc DirectiveLoc);
623 bool parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc);
624 bool parseDirectiveCFISignalFrame(
SMLoc DirectiveLoc);
625 bool parseDirectiveCFIUndefined(
SMLoc DirectiveLoc);
628 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
631 bool parseDirectiveMacro(
SMLoc DirectiveLoc);
636 bool parseDirectiveBundleAlignMode();
638 bool parseDirectiveBundleLock();
640 bool parseDirectiveBundleUnlock();
643 bool parseDirectiveSpace(
StringRef IDVal);
652 bool parseDirectiveLEB128(
bool Signed);
658 bool parseDirectiveComm(
bool IsLocal);
660 bool parseDirectiveAbort();
661 bool parseDirectiveInclude();
662 bool parseDirectiveIncbin();
665 bool parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
667 bool parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
669 bool parseDirectiveIfc(
SMLoc DirectiveLoc,
bool ExpectEqual);
671 bool parseDirectiveIfeqs(
SMLoc DirectiveLoc,
bool ExpectEqual);
673 bool parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
674 bool parseDirectiveElseIf(
SMLoc DirectiveLoc);
675 bool parseDirectiveElse(
SMLoc DirectiveLoc);
676 bool parseDirectiveEndIf(
SMLoc DirectiveLoc);
688 bool parseDirectiveIrp(
SMLoc DirectiveLoc);
689 bool parseDirectiveIrpc(
SMLoc DirectiveLoc);
690 bool parseDirectiveEndr(
SMLoc DirectiveLoc);
693 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
697 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
700 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
703 bool parseDirectiveError(
SMLoc DirectiveLoc,
bool WithMessage);
706 bool parseDirectiveWarning(
SMLoc DirectiveLoc);
709 bool parseDirectivePrint(
SMLoc DirectiveLoc);
712 bool parseDirectivePseudoProbe();
715 bool parseDirectiveLTODiscard();
718 bool parseDirectiveAddrsig();
719 bool parseDirectiveAddrsigSym();
721 void initializeDirectiveKindMap();
722 void initializeCVDefRangeTypeMap();
725class HLASMAsmParser final :
public AsmParser {
730 void lexLeadingSpaces() {
736 bool parseAsMachineInstruction(ParseStatementInfo &Info,
742 : AsmParser(SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
751 bool parseStatement(ParseStatementInfo &Info,
774 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI),
SrcMgr(SM),
775 CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(
true) {
803 "Need to implement createSPIRVAsmParser for SPIRV format.");
816 PlatformParser->Initialize(*
this);
817 initializeDirectiveKindMap();
818 initializeCVDefRangeTypeMap();
820 NumOfMacroInstantiations = 0;
823AsmParser::~AsmParser() {
824 assert((HadError || ActiveMacros.empty()) &&
825 "Unexpected active macro instantiation!");
834void AsmParser::printMacroInstantiations() {
836 for (std::vector<MacroInstantiation *>::const_reverse_iterator
837 it = ActiveMacros.rbegin(),
838 ie = ActiveMacros.rend();
841 "while in macro instantiation");
845 printPendingErrors();
847 printMacroInstantiations();
851 if(getTargetParser().getTargetOptions().MCNoWarn)
853 if (getTargetParser().getTargetOptions().MCFatalWarnings)
854 return Error(L, Msg, Range);
856 printMacroInstantiations();
863 printMacroInstantiations();
867bool AsmParser::enterIncludeFile(
const std::string &Filename) {
868 std::string IncludedFile;
882bool AsmParser::processIncbinFile(
const std::string &Filename, int64_t Skip,
884 std::string IncludedFile;
895 if (!Count->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
896 return Error(Loc,
"expected absolute expression");
898 return Warning(Loc,
"negative count has no effect");
901 getStreamer().emitBytes(Bytes);
905void AsmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer) {
918 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
936 if (ParentIncludeLoc !=
SMLoc()) {
937 jumpToLoc(ParentIncludeLoc);
945bool AsmParser::enabledGenDwarfForAssembly() {
947 if (!getContext().getGenDwarfForAssembly())
952 if (getContext().getGenDwarfFileNumber() == 0) {
955 if (!FirstCppHashFilename.
empty())
956 getContext().setMCLineTableRootFile(
957 0, getContext().getCompilationDir(), FirstCppHashFilename,
958 std::nullopt, std::nullopt);
960 getContext().getMCDwarfLineTable(0).getRootFile();
961 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
962 0, getContext().getCompilationDir(), RootFile.
Name,
968bool AsmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
969 LTODiscardSymbols.
clear();
972 if (!NoInitialTextSection)
979 AsmCond StartingCondState = TheCondState;
986 if (getContext().getGenDwarfForAssembly()) {
987 MCSection *Sec = getStreamer().getCurrentSectionOnly();
989 MCSymbol *SectionStartSym = getContext().createTempSymbol();
990 getStreamer().emitLabel(SectionStartSym);
993 bool InsertResult = getContext().addGenDwarfSection(Sec);
994 assert(InsertResult &&
".text section should not have debug info yet");
998 getTargetParser().onBeginOfFile();
1002 ParseStatementInfo
Info(&AsmStrRewrites);
1003 bool Parsed = parseStatement(Info,
nullptr);
1013 printPendingErrors();
1016 if (Parsed && !getLexer().isAtStartOfStatement())
1017 eatToEndOfStatement();
1020 getTargetParser().onEndOfFile();
1021 printPendingErrors();
1024 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1026 getTargetParser().flushPendingInstructions(getStreamer());
1030 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1032 const auto &LineTables = getContext().getMCDwarfLineTables();
1033 if (!LineTables.empty()) {
1035 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1037 printError(getTok().getLoc(),
"unassigned file number: " +
1039 " for .file directives");
1055 if (
Sym->isTemporary() && !
Sym->isVariable() && !
Sym->isDefined())
1059 printError(getTok().getLoc(),
"assembler local symbol '" +
1060 Sym->getName() +
"' not defined");
1066 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1067 if (std::get<2>(LocSym)->isUndefined()) {
1070 CppHashInfo = std::get<1>(LocSym);
1071 printError(std::get<0>(LocSym),
"directional label undefined");
1077 if (!HadError && !NoFinalize) {
1079 TS->emitConstantPools();
1084 return HadError || getContext().hadError();
1087bool AsmParser::checkForValidSection() {
1088 if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1090 return Error(getTok().getLoc(),
1091 "expected section directive before assembly directive");
1097void AsmParser::eatToEndOfStatement() {
1106StringRef AsmParser::parseStringToEndOfStatement() {
1107 const char *Start = getTok().getLoc().getPointer();
1112 const char *
End = getTok().getLoc().getPointer();
1116StringRef AsmParser::parseStringToComma() {
1117 const char *Start = getTok().getLoc().getPointer();
1123 const char *
End = getTok().getLoc().getPointer();
1132bool AsmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1133 if (parseExpression(Res))
1136 return parseRParen();
1144bool AsmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1145 if (parseExpression(Res))
1147 EndLoc = getTok().getEndLoc();
1148 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1159bool AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1161 SMLoc FirstTokenLoc = getLexer().getLoc();
1163 switch (FirstTokenKind) {
1165 return TokError(
"unknown token in expression");
1171 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1181 if (parseIdentifier(Identifier)) {
1185 bool ShouldGenerateTempSymbol =
false;
1188 ShouldGenerateTempSymbol =
true;
1190 if (!ShouldGenerateTempSymbol)
1191 return Error(FirstTokenLoc,
"invalid token in expression");
1201 EndLoc = FirstTokenLoc;
1206 std::pair<StringRef, StringRef>
Split;
1211 SMLoc AtLoc = getLexer().getLoc();
1213 if (parseIdentifier(VName))
1214 return Error(AtLoc,
"expected symbol variant after '@'");
1216 Split = std::make_pair(Identifier, VName);
1224 parseIdentifier(VName);
1227 Split = std::make_pair(Identifier, VName);
1235 return Error(getLexer().getLoc(),
"expected a symbol reference");
1240 if (!
Split.second.empty()) {
1241 Variant = getTargetParser().getVariantKindForName(
Split.second);
1248 "invalid variant '" +
Split.second +
"'");
1252 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1254 Sym = getContext().getOrCreateSymbol(
1259 if (
Sym->isVariable()) {
1260 auto V =
Sym->getVariableValue(
false);
1261 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1262 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1263 DoInline = TV->inlineAssignedExpr();
1266 return Error(EndLoc,
"unexpected modifier on variable reference");
1267 Res =
Sym->getVariableValue(
false);
1277 return TokError(
"literal value out of range for directive");
1279 SMLoc Loc = getTok().getLoc();
1280 int64_t
IntVal = getTok().getIntVal();
1288 std::pair<StringRef, StringRef>
Split = IDVal.
split(
'@');
1290 if (
Split.first.size() != IDVal.
size()) {
1293 return TokError(
"invalid variant '" +
Split.second +
"'");
1294 IDVal =
Split.first;
1296 if (IDVal ==
"f" || IDVal ==
"b") {
1300 if (IDVal ==
"b" &&
Sym->isUndefined())
1301 return Error(Loc,
"directional label undefined");
1302 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo,
Sym));
1310 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1319 return TokError(
"cannot use . as current PC");
1332 return parseParenExpr(Res, EndLoc);
1334 if (!PlatformParser->HasBracketExpressions())
1335 return TokError(
"brackets expression not supported on this target");
1337 return parseBracketExpr(Res, EndLoc);
1340 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1346 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1352 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1384 return TokError(
"expected '(' after operator");
1386 if (parseExpression(Res, EndLoc))
1390 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1395bool AsmParser::parseExpression(
const MCExpr *&Res) {
1397 return parseExpression(Res, EndLoc);
1401AsmParser::applyModifierToExpr(
const MCExpr *E,
1404 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
1418 TokError(
"invalid variant on expression '" + getTok().getIdentifier() +
1419 "' (already modified)");
1467 "Argument to the function cannot be a NULL value");
1469 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1470 (*CharPtr !=
'\0')) {
1471 if (*CharPtr ==
'!')
1475 if (*CharPtr ==
'>') {
1485 for (
size_t Pos = 0; Pos < AltMacroStr.
size(); Pos++) {
1486 if (AltMacroStr[Pos] ==
'!')
1488 Res += AltMacroStr[Pos];
1503bool AsmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1506 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1507 parseBinOpRHS(1, Res, EndLoc))
1517 return TokError(
"unexpected symbol modifier following '@'");
1522 return TokError(
"invalid variant '" + getTok().getIdentifier() +
"'");
1524 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
1526 return TokError(
"invalid modifier '" + getTok().getIdentifier() +
1527 "' (no symbols present)");
1537 if (Res->evaluateAsAbsolute(
Value))
1543bool AsmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1545 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1548bool AsmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1550 if (parseParenExpr(Res, EndLoc))
1553 for (; ParenDepth > 0; --ParenDepth) {
1554 if (parseBinOpRHS(1, Res, EndLoc))
1559 if (ParenDepth - 1 > 0) {
1560 EndLoc = getTok().getEndLoc();
1568bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1572 if (parseExpression(Expr))
1575 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1576 return Error(StartLoc,
"expected absolute expression");
1583 bool ShouldUseLogicalShr) {
1660 bool ShouldUseLogicalShr) {
1749bool AsmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
1754 unsigned TokPrec = getBinOpPrecedence(Lexer.
getKind(), Kind);
1758 if (TokPrec < Precedence)
1765 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1771 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
1772 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1784bool AsmParser::parseStatement(ParseStatementInfo &Info,
1786 assert(!hasPendingError() &&
"parseStatement started with pending error");
1792 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
1793 getTok().getString().front() ==
'\n')
1802 int64_t LocalLabelVal = -1;
1803 StartTokLoc =
ID.getLoc();
1805 return parseCppHashLineFilenameComment(IDLoc,
1806 !isInsideMacroInstantiation());
1810 LocalLabelVal = getTok().getIntVal();
1811 if (LocalLabelVal < 0) {
1812 if (!TheCondState.
Ignore) {
1814 return Error(IDLoc,
"unexpected token at start of statement");
1818 IDVal = getTok().getString();
1821 if (!TheCondState.
Ignore) {
1823 return Error(IDLoc,
"unexpected token at start of statement");
1841 getTargetParser().starIsStartOfStatement()) {
1845 }
else if (parseIdentifier(IDVal)) {
1846 if (!TheCondState.
Ignore) {
1848 return Error(IDLoc,
"unexpected token at start of statement");
1857 DirectiveKindMap.find(IDVal.
lower());
1858 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1860 : DirKindIt->getValue();
1871 return parseDirectiveIf(IDLoc, DirKind);
1873 return parseDirectiveIfb(IDLoc,
true);
1875 return parseDirectiveIfb(IDLoc,
false);
1877 return parseDirectiveIfc(IDLoc,
true);
1879 return parseDirectiveIfeqs(IDLoc,
true);
1881 return parseDirectiveIfc(IDLoc,
false);
1883 return parseDirectiveIfeqs(IDLoc,
false);
1885 return parseDirectiveIfdef(IDLoc,
true);
1888 return parseDirectiveIfdef(IDLoc,
false);
1890 return parseDirectiveElseIf(IDLoc);
1892 return parseDirectiveElse(IDLoc);
1894 return parseDirectiveEndIf(IDLoc);
1899 if (TheCondState.
Ignore) {
1900 eatToEndOfStatement();
1910 if (checkForValidSection())
1917 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
1925 if (LocalLabelVal == -1) {
1926 if (ParsingMSInlineAsm && SI) {
1928 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
1930 "We should have an internal name here.");
1933 IDVal = RewrittenLabel;
1935 Sym = getContext().getOrCreateSymbol(IDVal);
1943 StringRef CommentStr = parseStringToEndOfStatement();
1955 Sym->isExternal() && !cast<MCSymbolMachO>(
Sym)->isAltEntry())
1956 return Error(StartTokLoc,
"non-private labels cannot appear between "
1957 ".cfi_startproc / .cfi_endproc pairs") &&
1958 Error(*CFIStartProcLoc,
"previous .cfi_startproc was here");
1960 if (discardLTOSymbol(IDVal))
1963 getTargetParser().doBeforeLabelEmit(
Sym, IDLoc);
1966 if (!getTargetParser().isParsingMSInlineAsm())
1971 if (enabledGenDwarfForAssembly())
1975 getTargetParser().onLabelParsed(
Sym);
1984 return parseAssignment(IDVal, AssignmentKind::Equal);
1988 if (areMacrosEnabled())
1989 if (
const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
1990 return handleMacroEntry(M, IDLoc);
2008 getTargetParser().flushPendingInstructions(getStreamer());
2010 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2012 "Should only return Failure iff there was an error");
2020 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2021 ExtensionDirectiveMap.
lookup(IDVal);
2023 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2032 return parseDirectiveSet(IDVal, AssignmentKind::Set);
2034 return parseDirectiveSet(IDVal, AssignmentKind::Equiv);
2035 case DK_LTO_SET_CONDITIONAL:
2036 return parseDirectiveSet(IDVal, AssignmentKind::LTOSetConditional);
2038 return parseDirectiveAscii(IDVal,
false);
2041 return parseDirectiveAscii(IDVal,
true);
2044 return parseDirectiveValue(IDVal, 1);
2050 return parseDirectiveValue(IDVal, 2);
2055 return parseDirectiveValue(IDVal, 4);
2058 return parseDirectiveValue(IDVal, 8);
2060 return parseDirectiveValue(
2061 IDVal, getContext().getAsmInfo()->getCodePointerSize());
2063 return parseDirectiveOctaValue(IDVal);
2067 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
2070 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
2072 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2073 return parseDirectiveAlign(IsPow2, 1);
2076 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2077 return parseDirectiveAlign(IsPow2, 4);
2080 return parseDirectiveAlign(
false, 1);
2082 return parseDirectiveAlign(
false, 2);
2084 return parseDirectiveAlign(
false, 4);
2086 return parseDirectiveAlign(
true, 1);
2088 return parseDirectiveAlign(
true, 2);
2090 return parseDirectiveAlign(
true, 4);
2092 return parseDirectiveOrg();
2094 return parseDirectiveFill();
2096 return parseDirectiveZero();
2098 eatToEndOfStatement();
2102 return parseDirectiveSymbolAttribute(
MCSA_Global);
2103 case DK_LAZY_REFERENCE:
2105 case DK_NO_DEAD_STRIP:
2107 case DK_SYMBOL_RESOLVER:
2109 case DK_PRIVATE_EXTERN:
2113 case DK_WEAK_DEFINITION:
2115 case DK_WEAK_REFERENCE:
2117 case DK_WEAK_DEF_CAN_BE_HIDDEN:
2120 return parseDirectiveSymbolAttribute(
MCSA_Cold);
2123 return parseDirectiveComm(
false);
2125 return parseDirectiveComm(
true);
2127 return parseDirectiveAbort();
2129 return parseDirectiveInclude();
2131 return parseDirectiveIncbin();
2134 return TokError(
Twine(IDVal) +
2135 " not currently supported for this target");
2137 return parseDirectiveRept(IDLoc, IDVal);
2139 return parseDirectiveIrp(IDLoc);
2141 return parseDirectiveIrpc(IDLoc);
2143 return parseDirectiveEndr(IDLoc);
2144 case DK_BUNDLE_ALIGN_MODE:
2145 return parseDirectiveBundleAlignMode();
2146 case DK_BUNDLE_LOCK:
2147 return parseDirectiveBundleLock();
2148 case DK_BUNDLE_UNLOCK:
2149 return parseDirectiveBundleUnlock();
2151 return parseDirectiveLEB128(
true);
2153 return parseDirectiveLEB128(
false);
2156 return parseDirectiveSpace(IDVal);
2158 return parseDirectiveFile(IDLoc);
2160 return parseDirectiveLine();
2162 return parseDirectiveLoc();
2164 return parseDirectiveStabs();
2166 return parseDirectiveCVFile();
2168 return parseDirectiveCVFuncId();
2169 case DK_CV_INLINE_SITE_ID:
2170 return parseDirectiveCVInlineSiteId();
2172 return parseDirectiveCVLoc();
2173 case DK_CV_LINETABLE:
2174 return parseDirectiveCVLinetable();
2175 case DK_CV_INLINE_LINETABLE:
2176 return parseDirectiveCVInlineLinetable();
2177 case DK_CV_DEF_RANGE:
2178 return parseDirectiveCVDefRange();
2180 return parseDirectiveCVString();
2181 case DK_CV_STRINGTABLE:
2182 return parseDirectiveCVStringTable();
2183 case DK_CV_FILECHECKSUMS:
2184 return parseDirectiveCVFileChecksums();
2185 case DK_CV_FILECHECKSUM_OFFSET:
2186 return parseDirectiveCVFileChecksumOffset();
2187 case DK_CV_FPO_DATA:
2188 return parseDirectiveCVFPOData();
2189 case DK_CFI_SECTIONS:
2190 return parseDirectiveCFISections();
2191 case DK_CFI_STARTPROC:
2192 return parseDirectiveCFIStartProc();
2193 case DK_CFI_ENDPROC:
2194 return parseDirectiveCFIEndProc();
2195 case DK_CFI_DEF_CFA:
2196 return parseDirectiveCFIDefCfa(IDLoc);
2197 case DK_CFI_DEF_CFA_OFFSET:
2198 return parseDirectiveCFIDefCfaOffset(IDLoc);
2199 case DK_CFI_ADJUST_CFA_OFFSET:
2200 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2201 case DK_CFI_DEF_CFA_REGISTER:
2202 return parseDirectiveCFIDefCfaRegister(IDLoc);
2203 case DK_CFI_LLVM_DEF_ASPACE_CFA:
2204 return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
2206 return parseDirectiveCFIOffset(IDLoc);
2207 case DK_CFI_REL_OFFSET:
2208 return parseDirectiveCFIRelOffset(IDLoc);
2209 case DK_CFI_PERSONALITY:
2210 return parseDirectiveCFIPersonalityOrLsda(
true);
2212 return parseDirectiveCFIPersonalityOrLsda(
false);
2213 case DK_CFI_REMEMBER_STATE:
2214 return parseDirectiveCFIRememberState(IDLoc);
2215 case DK_CFI_RESTORE_STATE:
2216 return parseDirectiveCFIRestoreState(IDLoc);
2217 case DK_CFI_SAME_VALUE:
2218 return parseDirectiveCFISameValue(IDLoc);
2219 case DK_CFI_RESTORE:
2220 return parseDirectiveCFIRestore(IDLoc);
2222 return parseDirectiveCFIEscape(IDLoc);
2223 case DK_CFI_RETURN_COLUMN:
2224 return parseDirectiveCFIReturnColumn(IDLoc);
2225 case DK_CFI_SIGNAL_FRAME:
2226 return parseDirectiveCFISignalFrame(IDLoc);
2227 case DK_CFI_UNDEFINED:
2228 return parseDirectiveCFIUndefined(IDLoc);
2229 case DK_CFI_REGISTER:
2230 return parseDirectiveCFIRegister(IDLoc);
2231 case DK_CFI_WINDOW_SAVE:
2232 return parseDirectiveCFIWindowSave(IDLoc);
2235 return parseDirectiveMacrosOnOff(IDVal);
2237 return parseDirectiveMacro(IDLoc);
2240 return parseDirectiveAltmacro(IDVal);
2242 return parseDirectiveExitMacro(IDVal);
2245 return parseDirectiveEndMacro(IDVal);
2247 return parseDirectivePurgeMacro(IDLoc);
2249 return parseDirectiveEnd(IDLoc);
2251 return parseDirectiveError(IDLoc,
false);
2253 return parseDirectiveError(IDLoc,
true);
2255 return parseDirectiveWarning(IDLoc);
2257 return parseDirectiveReloc(IDLoc);
2260 return parseDirectiveDCB(IDVal, 2);
2262 return parseDirectiveDCB(IDVal, 1);
2264 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2266 return parseDirectiveDCB(IDVal, 4);
2268 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2271 return TokError(
Twine(IDVal) +
2272 " not currently supported for this target");
2275 return parseDirectiveDS(IDVal, 2);
2277 return parseDirectiveDS(IDVal, 1);
2279 return parseDirectiveDS(IDVal, 8);
2282 return parseDirectiveDS(IDVal, 4);
2285 return parseDirectiveDS(IDVal, 12);
2287 return parseDirectivePrint(IDLoc);
2289 return parseDirectiveAddrsig();
2290 case DK_ADDRSIG_SYM:
2291 return parseDirectiveAddrsigSym();
2292 case DK_PSEUDO_PROBE:
2293 return parseDirectivePseudoProbe();
2294 case DK_LTO_DISCARD:
2295 return parseDirectiveLTODiscard();
2297 return parseDirectiveSymbolAttribute(
MCSA_Memtag);
2300 return Error(IDLoc,
"unknown directive");
2304 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2305 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2306 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2309 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2310 return parseDirectiveMSAlign(IDLoc, Info);
2312 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2314 if (checkForValidSection())
2317 return parseAndMatchAndEmitTargetInstruction(Info, IDVal,
ID, IDLoc);
2320bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
2325 std::string OpcodeStr = IDVal.
lower();
2327 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
ID,
2328 Info.ParsedOperands);
2329 Info.ParseError = ParseHadError;
2332 if (getShowParsedOperands()) {
2335 OS <<
"parsed instruction: [";
2336 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2339 Info.ParsedOperands[i]->print(
OS);
2347 if (hasPendingError() || ParseHadError)
2352 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2353 getContext().getGenDwarfSectionSyms().
count(
2354 getStreamer().getCurrentSectionOnly())) {
2356 if (ActiveMacros.empty())
2360 ActiveMacros.front()->ExitBuffer);
2365 if (!CppHashInfo.Filename.empty()) {
2366 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2368 getContext().setGenDwarfFileNumber(FileNumber);
2370 unsigned CppHashLocLineNo =
2372 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2375 getStreamer().emitDwarfLocDirective(
2376 getContext().getGenDwarfFileNumber(), Line, 0,
2382 if (!ParseHadError) {
2384 if (getTargetParser().MatchAndEmitInstruction(
2386 getTargetParser().isParsingMSInlineAsm()))
2412bool AsmParser::parseCppHashLineFilenameComment(
SMLoc L,
bool SaveLocInfo) {
2417 "Lexing Cpp line comment: Expected Integer");
2418 int64_t LineNumber = getTok().getIntVal();
2421 "Lexing Cpp line comment: Expected String");
2433 CppHashInfo.Loc =
L;
2435 CppHashInfo.LineNumber = LineNumber;
2436 CppHashInfo.Buf = CurBuffer;
2437 if (FirstCppHashFilename.
empty())
2444void AsmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2445 auto *Parser =
static_cast<AsmParser *
>(
Context);
2451 unsigned CppHashBuf =
2452 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2457 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2466 if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
2467 if (Parser->SavedDiagHandler)
2468 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2470 Parser->getContext().diagnose(Diag);
2477 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2480 int CppHashLocLineNo =
2481 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2483 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2489 if (Parser->SavedDiagHandler)
2490 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2492 Parser->getContext().diagnose(NewDiag);
2500 return isalnum(
static_cast<unsigned char>(c)) || c ==
'_' || c ==
'$' ||
2507 bool EnableAtPseudoVariable,
SMLoc L) {
2509 bool HasVararg = NParameters ?
Parameters.back().Vararg :
false;
2510 if ((!IsDarwin || NParameters != 0) && NParameters !=
A.size())
2511 return Error(L,
"Wrong number of arguments");
2515 while (!Body.
empty()) {
2517 std::size_t
End = Body.
size(), Pos = 0;
2518 for (; Pos !=
End; ++Pos) {
2520 if (IsDarwin && !NParameters) {
2522 if (Body[Pos] !=
'$' || Pos + 1 ==
End)
2525 char Next = Body[Pos + 1];
2526 if (Next ==
'$' || Next ==
'n' ||
2527 isdigit(
static_cast<unsigned char>(Next)))
2531 if (Body[Pos] ==
'\\' && Pos + 1 !=
End)
2543 if (IsDarwin && !NParameters) {
2544 switch (Body[Pos + 1]) {
2558 unsigned Index = Body[Pos + 1] -
'0';
2564 OS << Token.getString();
2570 unsigned I = Pos + 1;
2573 if (EnableAtPseudoVariable && Body[
I] ==
'@' &&
I + 1 !=
End)
2579 const char *Begin = Body.
data() + Pos + 1;
2584 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();
2668class AsmLexerSkipSpaceRAII {
2670 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2674 ~AsmLexerSkipSpaceRAII() {
2684bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg) {
2688 StringRef Str = parseStringToEndOfStatement();
2694 unsigned ParenLevel = 0;
2697 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2704 return TokError(
"unexpected token in macro instantiation");
2706 if (ParenLevel == 0) {
2721 MA.push_back(getTok());
2747 MA.push_back(getTok());
2751 if (ParenLevel != 0)
2752 return TokError(
"unbalanced parentheses in macro argument");
2757bool AsmParser::parseMacroArguments(
const MCAsmMacro *M,
2758 MCAsmMacroArguments &
A) {
2759 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
2760 bool NamedParametersFound =
false;
2763 A.resize(NParameters);
2764 FALocs.
resize(NParameters);
2769 bool HasVararg = NParameters ?
M->Parameters.back().Vararg :
false;
2770 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2776 if (parseIdentifier(FA.
Name))
2777 return Error(IDLoc,
"invalid argument identifier for formal argument");
2780 return TokError(
"expected '=' after formal parameter identifier");
2784 NamedParametersFound =
true;
2786 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2788 if (NamedParametersFound && FA.
Name.
empty())
2789 return Error(IDLoc,
"cannot mix positional and keyword arguments");
2794 const MCExpr *AbsoluteExp;
2798 if (parseExpression(AbsoluteExp, EndLoc))
2800 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
2801 getStreamer().getAssemblerPtr()))
2802 return Error(StrLoc,
"expected absolute expression");
2807 FA.
Value.push_back(newToken);
2812 jumpToLoc(EndLoc, CurBuffer);
2817 FA.
Value.push_back(newToken);
2818 }
else if(parseMacroArgument(FA.
Value, Vararg))
2821 unsigned PI = Parameter;
2824 for (FAI = 0; FAI < NParameters; ++FAI)
2825 if (
M->Parameters[FAI].Name == FA.
Name)
2828 if (FAI >= NParameters) {
2829 assert(M &&
"expected macro to be defined");
2830 return Error(IDLoc,
"parameter named '" + FA.
Name +
2831 "' does not exist for macro '" +
M->Name +
"'");
2836 if (!FA.
Value.empty()) {
2841 if (FALocs.
size() <= PI)
2844 FALocs[PI] = Lexer.
getLoc();
2852 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
2853 if (
A[FAI].empty()) {
2854 if (
M->Parameters[FAI].Required) {
2856 "missing value for required parameter "
2857 "'" +
M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
2861 if (!
M->Parameters[FAI].Value.empty())
2862 A[FAI] =
M->Parameters[FAI].Value;
2872 return TokError(
"too many positional arguments");
2879 if (ActiveMacros.size() == MaxNestingDepth) {
2880 std::ostringstream MaxNestingDepthError;
2881 MaxNestingDepthError <<
"macros cannot be nested more than "
2882 << MaxNestingDepth <<
" levels deep."
2883 <<
" Use -asm-macro-max-nesting-depth to increase "
2885 return TokError(MaxNestingDepthError.str());
2888 MCAsmMacroArguments
A;
2889 if (parseMacroArguments(M,
A))
2898 if (expandMacro(
OS, Body,
M->Parameters,
A,
true, getTok().getLoc()))
2903 OS <<
".endmacro\n";
2905 std::unique_ptr<MemoryBuffer> Instantiation =
2910 MacroInstantiation *
MI =
new MacroInstantiation{
2911 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2912 ActiveMacros.push_back(
MI);
2914 ++NumOfMacroInstantiations;
2924void AsmParser::handleMacroExit() {
2926 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2930 delete ActiveMacros.back();
2931 ActiveMacros.pop_back();
2934bool AsmParser::parseAssignment(
StringRef Name, AssignmentKind Kind) {
2937 SMLoc ExprLoc = getTok().getLoc();
2939 Kind == AssignmentKind::Set ||
Kind == AssignmentKind::Equal;
2951 if (discardLTOSymbol(
Name))
2956 case AssignmentKind::Equal:
2959 case AssignmentKind::Set:
2960 case AssignmentKind::Equiv:
2964 case AssignmentKind::LTOSetConditional:
2966 return Error(ExprLoc,
"expected identifier");
2978bool AsmParser::parseIdentifier(
StringRef &Res) {
2985 SMLoc PrefixLoc = getLexer().getLoc();
2997 if (PrefixLoc.
getPointer() + 1 != Buf[0].getLoc().getPointer())
3011 Res = getTok().getIdentifier();
3023bool AsmParser::parseDirectiveSet(
StringRef IDVal, AssignmentKind Kind) {
3025 if (
check(parseIdentifier(
Name),
"expected identifier") || parseComma() ||
3026 parseAssignment(
Name, Kind))
3031bool AsmParser::parseEscapedString(std::string &Data) {
3036 StringRef Str = getTok().getStringContents();
3037 for (
unsigned i = 0, e = Str.size(); i != e; ++i) {
3038 if (Str[i] !=
'\\') {
3047 return TokError(
"unexpected backslash at end of string");
3050 if (Str[i] ==
'x' || Str[i] ==
'X') {
3051 size_t length = Str.size();
3052 if (i + 1 >= length || !
isHexDigit(Str[i + 1]))
3053 return TokError(
"invalid hexadecimal escape sequence");
3058 while (i + 1 < length &&
isHexDigit(Str[i + 1]))
3059 Value =
Value * 16 + hexDigitValue(Str[++i]);
3066 if ((
unsigned)(Str[i] -
'0') <= 7) {
3068 unsigned Value = Str[i] -
'0';
3070 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3074 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3081 return TokError(
"invalid octal escape sequence (out of range)");
3091 return TokError(
"invalid escape sequence (unrecognized character)");
3093 case 'b': Data +=
'\b';
break;
3094 case 'f': Data +=
'\f';
break;
3095 case 'n': Data +=
'\n';
break;
3096 case 'r': Data +=
'\r';
break;
3097 case 't': Data +=
'\t';
break;
3098 case '"': Data +=
'"';
break;
3099 case '\\': Data +=
'\\';
break;
3107bool AsmParser::parseAngleBracketString(std::string &Data) {
3108 SMLoc EndLoc, StartLoc = getTok().getLoc();
3110 const char *StartChar = StartLoc.
getPointer() + 1;
3111 const char *EndChar = EndLoc.
getPointer() - 1;
3112 jumpToLoc(EndLoc, CurBuffer);
3125bool AsmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3126 auto parseOp = [&]() ->
bool {
3128 if (checkForValidSection())
3133 if (parseEscapedString(Data))
3135 getStreamer().emitBytes(Data);
3138 getStreamer().emitBytes(
StringRef(
"\0", 1));
3142 return parseMany(parseOp);
3147bool AsmParser::parseDirectiveReloc(
SMLoc DirectiveLoc) {
3149 const MCExpr *Expr =
nullptr;
3152 if (parseExpression(
Offset))
3165 if (parseExpression(Expr))
3170 return Error(ExprLoc,
"expression must be relocatable");
3178 if (std::optional<std::pair<bool, std::string>> Err =
3179 getStreamer().emitRelocDirective(*
Offset,
Name, Expr, DirectiveLoc,
3181 return Error(Err->first ? NameLoc : OffsetLoc, Err->second);
3188bool AsmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3189 auto parseOp = [&]() ->
bool {
3191 SMLoc ExprLoc = getLexer().getLoc();
3192 if (checkForValidSection() || parseExpression(
Value))
3197 uint64_t IntValue = MCE->getValue();
3199 return Error(ExprLoc,
"out of range literal value");
3200 getStreamer().emitIntValue(IntValue,
Size);
3202 getStreamer().emitValue(
Value,
Size, ExprLoc);
3206 return parseMany(parseOp);
3212 return Asm.TokError(
"unknown token in expression");
3213 SMLoc ExprLoc = Asm.getTok().getLoc();
3214 APInt IntValue = Asm.getTok().getAPIntVal();
3216 if (!IntValue.
isIntN(128))
3217 return Asm.Error(ExprLoc,
"out of range literal value");
3218 if (!IntValue.
isIntN(64)) {
3231bool AsmParser::parseDirectiveOctaValue(
StringRef IDVal) {
3232 auto parseOp = [&]() ->
bool {
3233 if (checkForValidSection())
3239 getStreamer().emitInt64(lo);
3240 getStreamer().emitInt64(hi);
3242 getStreamer().emitInt64(hi);
3243 getStreamer().emitInt64(lo);
3248 return parseMany(parseOp);
3262 return TokError(Lexer.
getErr());
3265 return TokError(
"unexpected token in directive");
3277 return TokError(
"invalid floating point literal");
3279 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3281 return TokError(
"invalid floating point literal");
3288 Res =
Value.bitcastToAPInt();
3295bool AsmParser::parseDirectiveRealValue(
StringRef IDVal,
3297 auto parseOp = [&]() ->
bool {
3299 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3306 return parseMany(parseOp);
3311bool AsmParser::parseDirectiveZero() {
3314 if (checkForValidSection() || parseExpression(NumBytes))
3320 if (parseAbsoluteExpression(Val))
3326 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3333bool AsmParser::parseDirectiveFill() {
3336 if (checkForValidSection() || parseExpression(NumValues))
3339 int64_t FillSize = 1;
3340 int64_t FillExpr = 0;
3342 SMLoc SizeLoc, ExprLoc;
3345 SizeLoc = getTok().getLoc();
3346 if (parseAbsoluteExpression(FillSize))
3349 ExprLoc = getTok().getLoc();
3350 if (parseAbsoluteExpression(FillExpr))
3358 Warning(SizeLoc,
"'.fill' directive with negative size has no effect");
3362 Warning(SizeLoc,
"'.fill' directive with size greater than 8 has been truncated to 8");
3366 if (!isUInt<32>(FillExpr) && FillSize > 4)
3367 Warning(ExprLoc,
"'.fill' directive pattern has been truncated to 32-bits");
3369 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3376bool AsmParser::parseDirectiveOrg() {
3379 if (checkForValidSection() || parseExpression(
Offset))
3383 int64_t FillExpr = 0;
3385 if (parseAbsoluteExpression(FillExpr))
3390 getStreamer().emitValueToOffset(
Offset, FillExpr, OffsetLoc);
3396bool AsmParser::parseDirectiveAlign(
bool IsPow2,
unsigned ValueSize) {
3397 SMLoc AlignmentLoc = getLexer().getLoc();
3400 bool HasFillExpr =
false;
3401 int64_t FillExpr = 0;
3402 int64_t MaxBytesToFill = 0;
3405 auto parseAlign = [&]() ->
bool {
3406 if (parseAbsoluteExpression(Alignment))
3414 if (parseTokenLoc(FillExprLoc) || parseAbsoluteExpression(FillExpr))
3418 if (parseTokenLoc(MaxBytesLoc) ||
3419 parseAbsoluteExpression(MaxBytesToFill))
3425 if (checkForValidSection())
3429 Warning(AlignmentLoc,
"p2align directive with no operand(s) is ignored");
3436 bool ReturnVal =
false;
3441 if (Alignment >= 32) {
3442 ReturnVal |=
Error(AlignmentLoc,
"invalid alignment value");
3446 Alignment = 1ULL << Alignment;
3454 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2");
3455 Alignment = llvm::bit_floor<uint64_t>(Alignment);
3457 if (!isUInt<32>(Alignment)) {
3458 ReturnVal |=
Error(AlignmentLoc,
"alignment must be smaller than 2**32");
3459 Alignment = 1u << 31;
3463 if (HasFillExpr && FillExpr != 0) {
3464 MCSection *Sec = getStreamer().getCurrentSectionOnly();
3467 Warning(FillExprLoc,
"ignoring non-zero fill value in " +
3476 if (MaxBytesToFill < 1) {
3477 ReturnVal |=
Error(MaxBytesLoc,
3478 "alignment directive can never be satisfied in this "
3479 "many bytes, ignoring maximum bytes expression");
3483 if (MaxBytesToFill >= Alignment) {
3484 Warning(MaxBytesLoc,
"maximum bytes expression exceeds alignment and "
3493 assert(Section &&
"must have section to emit alignment");
3494 bool useCodeAlign =
Section->useCodeAlign();
3495 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
3496 ValueSize == 1 && useCodeAlign) {
3497 getStreamer().emitCodeAlignment(
3498 Align(Alignment), &getTargetParser().getSTI(), MaxBytesToFill);
3501 getStreamer().emitValueToAlignment(
Align(Alignment), FillExpr, ValueSize,
3511bool AsmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
3513 int64_t FileNumber = -1;
3515 FileNumber = getTok().getIntVal();
3519 return TokError(
"negative file number");
3526 if (parseEscapedString(Path))
3531 std::string FilenameData;
3533 if (
check(FileNumber == -1,
3534 "explicit path specified, but no file number") ||
3535 parseEscapedString(FilenameData))
3544 bool HasMD5 =
false;
3546 std::optional<StringRef>
Source;
3547 bool HasSource =
false;
3548 std::string SourceString;
3553 "unexpected token in '.file' directive") ||
3554 parseIdentifier(Keyword))
3556 if (Keyword ==
"md5") {
3558 if (
check(FileNumber == -1,
3559 "MD5 checksum specified, but no file number") ||
3562 }
else if (Keyword ==
"source") {
3564 if (
check(FileNumber == -1,
3565 "source specified, but no file number") ||
3567 "unexpected token in '.file' directive") ||
3568 parseEscapedString(SourceString))
3571 return TokError(
"unexpected token in '.file' directive");
3575 if (FileNumber == -1) {
3579 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
3580 getStreamer().emitFileDirective(Filename);
3590 std::optional<MD5::MD5Result> CKMem;
3593 for (
unsigned i = 0; i != 8; ++i) {
3594 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3595 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3600 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
3601 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3604 if (FileNumber == 0) {
3608 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3611 FileNumber, Directory, Filename, CKMem, Source);
3618 ReportedInconsistentMD5 =
true;
3619 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
3628bool AsmParser::parseDirectiveLine() {
3631 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
3646bool AsmParser::parseDirectiveLoc() {
3647 int64_t FileNumber = 0, LineNumber = 0;
3648 SMLoc Loc = getTok().getLoc();
3649 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
3651 "file number less than one in '.loc' directive") ||
3652 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3653 "unassigned file number in '.loc' directive"))
3658 LineNumber = getTok().getIntVal();
3660 return TokError(
"line number less than zero in '.loc' directive");
3664 int64_t ColumnPos = 0;
3666 ColumnPos = getTok().getIntVal();
3668 return TokError(
"column position less than zero in '.loc' directive");
3672 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
3677 auto parseLocOp = [&]() ->
bool {
3679 SMLoc Loc = getTok().getLoc();
3680 if (parseIdentifier(
Name))
3681 return TokError(
"unexpected token in '.loc' directive");
3683 if (
Name ==
"basic_block")
3685 else if (
Name ==
"prologue_end")
3687 else if (
Name ==
"epilogue_begin")
3689 else if (
Name ==
"is_stmt") {
3690 Loc = getTok().getLoc();
3692 if (parseExpression(
Value))
3696 int Value = MCE->getValue();
3698 Flags &= ~DWARF2_FLAG_IS_STMT;
3699 else if (
Value == 1)
3702 return Error(Loc,
"is_stmt value not 0 or 1");
3704 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
3706 }
else if (
Name ==
"isa") {
3707 Loc = getTok().getLoc();
3709 if (parseExpression(
Value))
3713 int Value = MCE->getValue();
3715 return Error(Loc,
"isa number less than zero");
3718 return Error(Loc,
"isa number not a constant value");
3720 }
else if (
Name ==
"discriminator") {
3721 if (parseAbsoluteExpression(Discriminator))
3724 return Error(Loc,
"unknown sub-directive in '.loc' directive");
3729 if (parseMany(parseLocOp,
false ))
3732 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3740bool AsmParser::parseDirectiveStabs() {
3741 return TokError(
"unsupported directive '.stabs'");
3746bool AsmParser::parseDirectiveCVFile() {
3747 SMLoc FileNumberLoc = getTok().getLoc();
3750 std::string Checksum;
3753 if (parseIntToken(FileNumber,
3754 "expected file number in '.cv_file' directive") ||
3755 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
3757 "unexpected token in '.cv_file' directive") ||
3758 parseEscapedString(Filename))
3762 "unexpected token in '.cv_file' directive") ||
3763 parseEscapedString(Checksum) ||
3764 parseIntToken(ChecksumKind,
3765 "expected checksum kind in '.cv_file' directive") ||
3770 Checksum = fromHex(Checksum);
3771 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
3772 memcpy(CKMem, Checksum.data(), Checksum.size());
3776 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3777 static_cast<uint8_t
>(ChecksumKind)))
3778 return Error(FileNumberLoc,
"file number already allocated");
3783bool AsmParser::parseCVFunctionId(int64_t &
FunctionId,
3786 return parseTokenLoc(Loc) ||
3787 parseIntToken(
FunctionId,
"expected function id in '" + DirectiveName +
3789 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3790 "expected function id within range [0, UINT_MAX)");
3793bool AsmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
3795 return parseTokenLoc(Loc) ||
3796 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
3798 check(FileNumber < 1, Loc,
"file number less than one in '" +
3799 DirectiveName +
"' directive") ||
3800 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3801 "unassigned file number in '" + DirectiveName +
"' directive");
3808bool AsmParser::parseDirectiveCVFuncId() {
3809 SMLoc FunctionIdLoc = getTok().getLoc();
3812 if (parseCVFunctionId(
FunctionId,
".cv_func_id") || parseEOL())
3815 if (!getStreamer().emitCVFuncIdDirective(
FunctionId))
3816 return Error(FunctionIdLoc,
"function id already allocated");
3829bool AsmParser::parseDirectiveCVInlineSiteId() {
3830 SMLoc FunctionIdLoc = getTok().getLoc();
3838 if (parseCVFunctionId(
FunctionId,
".cv_inline_site_id"))
3843 getTok().getIdentifier() !=
"within"),
3844 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3849 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
3854 getTok().getIdentifier() !=
"inlined_at"),
3855 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3861 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
3862 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
3867 IACol = getTok().getIntVal();
3874 if (!getStreamer().emitCVInlineSiteIdDirective(
FunctionId, IAFunc, IAFile,
3875 IALine, IACol, FunctionIdLoc))
3876 return Error(FunctionIdLoc,
"function id already allocated");
3888bool AsmParser::parseDirectiveCVLoc() {
3889 SMLoc DirectiveLoc = getTok().getLoc();
3891 if (parseCVFunctionId(
FunctionId,
".cv_loc") ||
3892 parseCVFileId(FileNumber,
".cv_loc"))
3895 int64_t LineNumber = 0;
3897 LineNumber = getTok().getIntVal();
3899 return TokError(
"line number less than zero in '.cv_loc' directive");
3903 int64_t ColumnPos = 0;
3905 ColumnPos = getTok().getIntVal();
3907 return TokError(
"column position less than zero in '.cv_loc' directive");
3911 bool PrologueEnd =
false;
3914 auto parseOp = [&]() ->
bool {
3916 SMLoc Loc = getTok().getLoc();
3917 if (parseIdentifier(
Name))
3918 return TokError(
"unexpected token in '.cv_loc' directive");
3919 if (
Name ==
"prologue_end")
3921 else if (
Name ==
"is_stmt") {
3922 Loc = getTok().getLoc();
3924 if (parseExpression(
Value))
3928 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
3929 IsStmt = MCE->getValue();
3932 return Error(Loc,
"is_stmt value not 0 or 1");
3934 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
3939 if (parseMany(parseOp,
false ))
3942 getStreamer().emitCVLocDirective(
FunctionId, FileNumber, LineNumber,
3943 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
3950bool AsmParser::parseDirectiveCVLinetable() {
3953 SMLoc Loc = getTok().getLoc();
3954 if (parseCVFunctionId(
FunctionId,
".cv_linetable") || parseComma() ||
3955 parseTokenLoc(Loc) ||
3956 check(parseIdentifier(FnStartName), Loc,
3957 "expected identifier in directive") ||
3958 parseComma() || parseTokenLoc(Loc) ||
3959 check(parseIdentifier(FnEndName), Loc,
3960 "expected identifier in directive"))
3963 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3964 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3966 getStreamer().emitCVLinetableDirective(
FunctionId, FnStartSym, FnEndSym);
3972bool AsmParser::parseDirectiveCVInlineLinetable() {
3973 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3975 SMLoc Loc = getTok().getLoc();
3976 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
3977 parseTokenLoc(Loc) ||
3980 "expected SourceField in '.cv_inline_linetable' directive") ||
3981 check(SourceFileId <= 0, Loc,
3982 "File id less than zero in '.cv_inline_linetable' directive") ||
3983 parseTokenLoc(Loc) ||
3986 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3987 check(SourceLineNum < 0, Loc,
3988 "Line number less than zero in '.cv_inline_linetable' directive") ||
3989 parseTokenLoc(Loc) ||
check(parseIdentifier(FnStartName), Loc,
3990 "expected identifier in directive") ||
3991 parseTokenLoc(Loc) ||
check(parseIdentifier(FnEndName), Loc,
3992 "expected identifier in directive"))
3998 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3999 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4000 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
4001 SourceLineNum, FnStartSym,
4006void AsmParser::initializeCVDefRangeTypeMap() {
4007 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
4008 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4009 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4010 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4015bool AsmParser::parseDirectiveCVDefRange() {
4017 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
4019 Loc = getLexer().getLoc();
4021 if (parseIdentifier(GapStartName))
4022 return Error(Loc,
"expected identifier in directive");
4023 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
4025 Loc = getLexer().getLoc();
4027 if (parseIdentifier(GapEndName))
4028 return Error(Loc,
"expected identifier in directive");
4029 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
4031 Ranges.push_back({GapStartSym, GapEndSym});
4037 "expected comma before def_range type in .cv_def_range directive") ||
4038 parseIdentifier(CVDefRangeTypeStr))
4039 return Error(Loc,
"expected def_range type in directive");
4042 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4043 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4045 : CVTypeIt->getValue();
4047 case CVDR_DEFRANGE_REGISTER: {
4049 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4050 ".cv_def_range directive") ||
4051 parseAbsoluteExpression(DRRegister))
4052 return Error(Loc,
"expected register number");
4057 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4060 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4063 "expected comma before offset in .cv_def_range directive") ||
4064 parseAbsoluteExpression(DROffset))
4065 return Error(Loc,
"expected offset value");
4069 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4072 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4074 int64_t DROffsetInParent;
4075 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4076 ".cv_def_range directive") ||
4077 parseAbsoluteExpression(DRRegister))
4078 return Error(Loc,
"expected register number");
4080 "expected comma before offset in .cv_def_range directive") ||
4081 parseAbsoluteExpression(DROffsetInParent))
4082 return Error(Loc,
"expected offset value");
4088 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4091 case CVDR_DEFRANGE_REGISTER_REL: {
4094 int64_t DRBasePointerOffset;
4095 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4096 ".cv_def_range directive") ||
4097 parseAbsoluteExpression(DRRegister))
4098 return Error(Loc,
"expected register value");
4101 "expected comma before flag value in .cv_def_range directive") ||
4102 parseAbsoluteExpression(DRFlags))
4103 return Error(Loc,
"expected flag value");
4104 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
4105 "in .cv_def_range directive") ||
4106 parseAbsoluteExpression(DRBasePointerOffset))
4107 return Error(Loc,
"expected base pointer offset value");
4111 DRHdr.
Flags = DRFlags;
4113 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4117 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
4124bool AsmParser::parseDirectiveCVString() {
4126 if (checkForValidSection() || parseEscapedString(Data))
4130 std::pair<StringRef, unsigned> Insertion =
4131 getCVContext().addToStringTable(Data);
4132 getStreamer().emitInt32(Insertion.second);
4138bool AsmParser::parseDirectiveCVStringTable() {
4139 getStreamer().emitCVStringTableDirective();
4145bool AsmParser::parseDirectiveCVFileChecksums() {
4146 getStreamer().emitCVFileChecksumsDirective();
4152bool AsmParser::parseDirectiveCVFileChecksumOffset() {
4154 if (parseIntToken(FileNo,
"expected identifier in directive"))
4158 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4164bool AsmParser::parseDirectiveCVFPOData() {
4165 SMLoc DirLoc = getLexer().getLoc();
4167 if (parseIdentifier(ProcName))
4168 return TokError(
"expected symbol name");
4171 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4172 getStreamer().emitCVFPOData(ProcSym, DirLoc);
4178bool AsmParser::parseDirectiveCFISections() {
4185 if (parseIdentifier(
Name))
4186 return TokError(
"expected .eh_frame or .debug_frame");
4187 if (
Name ==
".eh_frame")
4189 else if (
Name ==
".debug_frame")
4197 getStreamer().emitCFISections(EH,
Debug);
4203bool AsmParser::parseDirectiveCFIStartProc() {
4204 CFIStartProcLoc = StartTokLoc;
4209 "unexpected token") ||
4219 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
4225bool AsmParser::parseDirectiveCFIEndProc() {
4226 CFIStartProcLoc = std::nullopt;
4231 getStreamer().emitCFIEndProc();
4236bool AsmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
4237 SMLoc DirectiveLoc) {
4241 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4243 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo,
true);
4245 return parseAbsoluteExpression(
Register);
4252bool AsmParser::parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc) {
4254 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4255 parseAbsoluteExpression(
Offset) || parseEOL())
4264bool AsmParser::parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc) {
4266 if (parseAbsoluteExpression(
Offset) || parseEOL())
4269 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
4275bool AsmParser::parseDirectiveCFIRegister(
SMLoc DirectiveLoc) {
4276 int64_t Register1 = 0, Register2 = 0;
4277 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
4278 parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
4281 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
4287bool AsmParser::parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc) {
4290 getStreamer().emitCFIWindowSave(DirectiveLoc);
4296bool AsmParser::parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc) {
4297 int64_t Adjustment = 0;
4298 if (parseAbsoluteExpression(Adjustment) || parseEOL())
4301 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
4307bool AsmParser::parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc) {
4309 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4312 getStreamer().emitCFIDefCfaRegister(
Register, DirectiveLoc);
4318bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(
SMLoc DirectiveLoc) {
4320 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4321 parseAbsoluteExpression(
Offset) || parseComma() ||
4332bool AsmParser::parseDirectiveCFIOffset(
SMLoc DirectiveLoc) {
4336 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4337 parseAbsoluteExpression(
Offset) || parseEOL())
4346bool AsmParser::parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc) {
4349 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4350 parseAbsoluteExpression(
Offset) || parseEOL())
4358 if (Encoding & ~0xff)
4364 const unsigned Format = Encoding & 0xf;
4371 const unsigned Application = Encoding & 0x70;
4383bool AsmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
4384 int64_t Encoding = 0;
4385 if (parseAbsoluteExpression(Encoding))
4393 check(parseIdentifier(
Name),
"expected identifier in directive") ||
4400 getStreamer().emitCFIPersonality(
Sym, Encoding);
4402 getStreamer().emitCFILsda(
Sym, Encoding);
4408bool AsmParser::parseDirectiveCFIRememberState(
SMLoc DirectiveLoc) {
4411 getStreamer().emitCFIRememberState(DirectiveLoc);
4417bool AsmParser::parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc) {
4420 getStreamer().emitCFIRestoreState(DirectiveLoc);
4426bool AsmParser::parseDirectiveCFISameValue(
SMLoc DirectiveLoc) {
4429 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4432 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
4438bool AsmParser::parseDirectiveCFIRestore(
SMLoc DirectiveLoc) {
4440 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4443 getStreamer().emitCFIRestore(
Register, DirectiveLoc);
4449bool AsmParser::parseDirectiveCFIEscape(
SMLoc DirectiveLoc) {
4452 if (parseAbsoluteExpression(CurrValue))
4455 Values.push_back((uint8_t)CurrValue);
4460 if (parseAbsoluteExpression(CurrValue))
4463 Values.push_back((uint8_t)CurrValue);
4466 getStreamer().emitCFIEscape(Values, DirectiveLoc);
4472bool AsmParser::parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc) {
4474 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4476 getStreamer().emitCFIReturnColumn(
Register);
4482bool AsmParser::parseDirectiveCFISignalFrame(
SMLoc DirectiveLoc) {
4486 getStreamer().emitCFISignalFrame();
4492bool AsmParser::parseDirectiveCFIUndefined(
SMLoc DirectiveLoc) {
4495 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4498 getStreamer().emitCFIUndefined(
Register, DirectiveLoc);
4508 AltMacroMode = (
Directive ==
".altmacro");
4518 setMacrosEnabled(
Directive ==
".macros_on");
4524bool AsmParser::parseDirectiveMacro(
SMLoc DirectiveLoc) {
4526 if (parseIdentifier(
Name))
4527 return TokError(
"expected identifier in '.macro' directive");
4536 return Error(Lexer.
getLoc(),
"vararg parameter '" +
4538 "' should be the last parameter");
4541 if (parseIdentifier(Parameter.
Name))
4542 return TokError(
"expected identifier in '.macro' directive");
4546 if (CurrParam.Name.equals(Parameter.
Name))
4547 return TokError(
"macro '" +
Name +
"' has multiple parameters"
4548 " named '" + Parameter.
Name +
"'");
4556 QualLoc = Lexer.
getLoc();
4557 if (parseIdentifier(Qualifier))
4558 return Error(QualLoc,
"missing parameter qualifier for "
4559 "'" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4561 if (Qualifier ==
"req")
4563 else if (Qualifier ==
"vararg")
4566 return Error(QualLoc, Qualifier +
" is not a valid parameter qualifier "
4567 "for '" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4575 ParamLoc = Lexer.
getLoc();
4576 if (parseMacroArgument(Parameter.
Value,
false ))
4580 Warning(ParamLoc,
"pointless default value for required parameter "
4581 "'" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4594 AsmToken EndToken, StartToken = getTok();
4595 unsigned MacroDepth = 0;
4605 return Error(DirectiveLoc,
"no matching '.endmacro' in definition");
4610 if (getTok().getIdentifier() ==
".endm" ||
4611 getTok().getIdentifier() ==
".endmacro") {
4612 if (MacroDepth == 0) {
4613 EndToken = getTok();
4616 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
4623 }
else if (getTok().getIdentifier() ==
".macro") {
4629 (void)parseCppHashLineFilenameComment(getLexer().getLoc());
4633 eatToEndOfStatement();
4636 if (getContext().lookupMacro(
Name)) {
4637 return Error(DirectiveLoc,
"macro '" +
Name +
"' is already defined");
4643 checkForBadMacro(DirectiveLoc,
Name, Body, Parameters);
4647 getContext().defineMacro(
Name, std::move(
Macro));
4671 if (NParameters == 0)
4674 bool NamedParametersFound =
false;
4675 bool PositionalParametersFound =
false;
4680 while (!Body.
empty()) {
4682 std::size_t
End = Body.
size(), Pos = 0;
4683 for (; Pos !=
End; ++Pos) {
4686 if (Body[Pos] ==
'\\' && Pos + 1 !=
End)
4690 if (Body[Pos] !=
'$' || Pos + 1 ==
End)
4692 char Next = Body[Pos + 1];
4693 if (Next ==
'$' || Next ==
'n' ||
4694 isdigit(
static_cast<unsigned char>(Next)))
4702 if (Body[Pos] ==
'$') {
4703 switch (Body[Pos + 1]) {
4710 PositionalParametersFound =
true;
4715 PositionalParametersFound =
true;
4721 unsigned I = Pos + 1;
4725 const char *Begin = Body.
data() + Pos + 1;
4732 if (
Index == NParameters) {
4733 if (Body[Pos + 1] ==
'(' && Body[Pos + 2] ==
')')
4739 NamedParametersFound =
true;
4747 if (!NamedParametersFound && PositionalParametersFound)
4748 Warning(DirectiveLoc,
"macro defined with named parameters which are not "
4749 "used in macro body, possible positional parameter "
4750 "found in body which will have no effect");
4759 if (!isInsideMacroInstantiation())
4760 return TokError(
"unexpected '" +
Directive +
"' in file, "
4761 "no current macro definition");
4764 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4765 TheCondState = TheCondStack.back();
4766 TheCondStack.pop_back();
4778 return TokError(
"unexpected token in '" +
Directive +
"' directive");
4782 if (isInsideMacroInstantiation()) {
4789 return TokError(
"unexpected '" +
Directive +
"' in file, "
4790 "no current macro definition");
4795bool AsmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
4798 if (parseTokenLoc(Loc) ||
4800 "expected identifier in '.purgem' directive") ||
4804 if (!getContext().lookupMacro(
Name))
4805 return Error(DirectiveLoc,
"macro '" +
Name +
"' is not defined");
4807 getContext().undefineMacro(
Name);
4809 <<
"Un-defining macro: " <<
Name <<
"\n");
4815bool AsmParser::parseDirectiveBundleAlignMode() {
4818 SMLoc ExprLoc = getLexer().getLoc();
4819 int64_t AlignSizePow2;
4820 if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4822 check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4823 "invalid bundle alignment size (expected between 0 and 30)"))
4826 getStreamer().emitBundleAlignMode(
Align(1ULL << AlignSizePow2));
4832bool AsmParser::parseDirectiveBundleLock() {
4833 if (checkForValidSection())
4835 bool AlignToEnd =
false;
4838 SMLoc Loc = getTok().getLoc();
4839 const char *kInvalidOptionError =
4840 "invalid option for '.bundle_lock' directive";
4843 if (
check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4844 check(Option !=
"align_to_end", Loc, kInvalidOptionError) || parseEOL())
4849 getStreamer().emitBundleLock(AlignToEnd);
4855bool AsmParser::parseDirectiveBundleUnlock() {
4856 if (checkForValidSection() || parseEOL())
4859 getStreamer().emitBundleUnlock();
4865bool AsmParser::parseDirectiveSpace(
StringRef IDVal) {
4868 if (checkForValidSection() || parseExpression(NumBytes))
4871 int64_t FillExpr = 0;
4873 if (parseAbsoluteExpression(FillExpr))
4879 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4886bool AsmParser::parseDirectiveDCB(
StringRef IDVal,
unsigned Size) {
4889 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4892 if (NumValues < 0) {
4893 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4901 SMLoc ExprLoc = getLexer().getLoc();
4902 if (parseExpression(
Value))
4908 uint64_t IntValue = MCE->getValue();
4910 return Error(ExprLoc,
"literal value out of range for directive");
4911 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4912 getStreamer().emitIntValue(IntValue,
Size);
4914 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4915 getStreamer().emitValue(
Value,
Size, ExprLoc);
4926 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4929 if (NumValues < 0) {
4930 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4938 if (parseRealValue(Semantics, AsInt) || parseEOL())
4941 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4950bool AsmParser::parseDirectiveDS(
StringRef IDVal,
unsigned Size) {
4953 if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
4957 if (NumValues < 0) {
4958 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4962 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4963 getStreamer().emitFill(
Size, 0);
4970bool AsmParser::parseDirectiveLEB128(
bool Signed) {
4971 if (checkForValidSection())
4974 auto parseOp = [&]() ->
bool {
4976 if (parseExpression(
Value))
4979 getStreamer().emitSLEB128Value(
Value);
4981 getStreamer().emitULEB128Value(
Value);
4985 return parseMany(parseOp);
4990bool AsmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
4991 auto parseOp = [&]() ->
bool {
4993 SMLoc Loc = getTok().getLoc();
4994 if (parseIdentifier(
Name))
4995 return Error(Loc,
"expected identifier");
4997 if (discardLTOSymbol(
Name))
5005 return Error(Loc,
"non-local symbol required");
5007 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
5008 return Error(Loc,
"unable to emit symbol attribute");
5012 return parseMany(parseOp);
5017bool AsmParser::parseDirectiveComm(
bool IsLocal) {
5018 if (checkForValidSection())
5021 SMLoc IDLoc = getLexer().getLoc();
5023 if (parseIdentifier(
Name))
5024 return TokError(
"expected identifier in directive");
5033 SMLoc SizeLoc = getLexer().getLoc();
5034 if (parseAbsoluteExpression(
Size))
5037 int64_t Pow2Alignment = 0;
5038 SMLoc Pow2AlignmentLoc;
5041 Pow2AlignmentLoc = getLexer().getLoc();
5042 if (parseAbsoluteExpression(Pow2Alignment))
5047 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
5050 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5053 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
5054 Pow2Alignment =
Log2_64(Pow2Alignment);
5064 return Error(SizeLoc,
"size must be non-negative");
5066 Sym->redefineIfPossible();
5067 if (!
Sym->isUndefined())
5068 return Error(IDLoc,
"invalid symbol redefinition");
5072 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
5073 Align(1ULL << Pow2Alignment));
5077 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
5083bool AsmParser::parseDirectiveAbort() {
5085 SMLoc Loc = getLexer().getLoc();
5087 StringRef Str = parseStringToEndOfStatement();
5092 return Error(Loc,
".abort detected. Assembly stopping.");
5094 return Error(Loc,
".abort '" + Str +
"' detected. Assembly stopping.");
5102bool AsmParser::parseDirectiveInclude() {
5105 SMLoc IncludeLoc = getTok().getLoc();
5108 "expected string in '.include' directive") ||
5109 parseEscapedString(Filename) ||
5111 "unexpected token in '.include' directive") ||
5114 check(enterIncludeFile(Filename), IncludeLoc,
5115 "Could not find include file '" + Filename +
"'"))
5123bool AsmParser::parseDirectiveIncbin() {
5126 SMLoc IncbinLoc = getTok().getLoc();
5128 "expected string in '.incbin' directive") ||
5129 parseEscapedString(Filename))
5133 const MCExpr *Count =
nullptr;
5134 SMLoc SkipLoc, CountLoc;
5139 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
5143 CountLoc = getTok().getLoc();
5144 if (parseExpression(Count))
5152 if (
check(Skip < 0, SkipLoc,
"skip is negative"))
5156 if (processIncbinFile(Filename, Skip, Count, CountLoc))
5157 return Error(IncbinLoc,
"Could not find incbin file '" + Filename +
"'");
5163bool AsmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
5164 TheCondStack.push_back(TheCondState);
5166 if (TheCondState.
Ignore) {
5167 eatToEndOfStatement();
5170 if (parseAbsoluteExpression(ExprValue) || parseEOL())
5180 ExprValue = ExprValue == 0;
5183 ExprValue = ExprValue >= 0;
5186 ExprValue = ExprValue > 0;
5189 ExprValue = ExprValue <= 0;
5192 ExprValue = ExprValue < 0;
5196 TheCondState.
CondMet = ExprValue;
5205bool AsmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
5206 TheCondStack.push_back(TheCondState);
5209 if (TheCondState.
Ignore) {
5210 eatToEndOfStatement();
5212 StringRef Str = parseStringToEndOfStatement();
5217 TheCondState.
CondMet = ExpectBlank == Str.empty();
5227bool AsmParser::parseDirectiveIfc(
SMLoc DirectiveLoc,
bool ExpectEqual) {
5228 TheCondStack.push_back(TheCondState);
5231 if (TheCondState.
Ignore) {
5232 eatToEndOfStatement();
5239 StringRef Str2 = parseStringToEndOfStatement();
5253bool AsmParser::parseDirectiveIfeqs(
SMLoc DirectiveLoc,
bool ExpectEqual) {
5256 return TokError(
"expected string parameter for '.ifeqs' directive");
5257 return TokError(
"expected string parameter for '.ifnes' directive");
5260 StringRef String1 = getTok().getStringContents();
5266 "expected comma after first string for '.ifeqs' directive");
5267 return TokError(
"expected comma after first string for '.ifnes' directive");
5274 return TokError(
"expected string parameter for '.ifeqs' directive");
5275 return TokError(
"expected string parameter for '.ifnes' directive");
5278 StringRef String2 = getTok().getStringContents();
5281 TheCondStack.push_back(TheCondState);
5283 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
5291bool AsmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
5293 TheCondStack.push_back(TheCondState);
5296 if (TheCondState.
Ignore) {
5297 eatToEndOfStatement();
5299 if (
check(parseIdentifier(
Name),
"expected identifier after '.ifdef'") ||
5317bool AsmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc) {
5320 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
5321 " .if or an .elseif");
5324 bool LastIgnoreState =
false;
5325 if (!TheCondStack.empty())
5326 LastIgnoreState = TheCondStack.back().Ignore;
5327 if (LastIgnoreState || TheCondState.
CondMet) {
5328 TheCondState.
Ignore =
true;
5329 eatToEndOfStatement();
5332 if (parseAbsoluteExpression(ExprValue))
5338 TheCondState.
CondMet = ExprValue;
5347bool AsmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
5353 return Error(DirectiveLoc,
"Encountered a .else that doesn't follow "
5354 " an .if or an .elseif");
5356 bool LastIgnoreState =
false;
5357 if (!TheCondStack.empty())
5358 LastIgnoreState = TheCondStack.back().Ignore;
5359 if (LastIgnoreState || TheCondState.
CondMet)
5360 TheCondState.
Ignore =
true;
5362 TheCondState.
Ignore =
false;
5369bool AsmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
5382bool AsmParser::parseDirectiveError(
SMLoc L,
bool WithMessage) {
5383 if (!TheCondStack.empty()) {
5384 if (TheCondStack.back().Ignore) {
5385 eatToEndOfStatement();
5391 return Error(L,
".err encountered");
5393 StringRef Message =
".error directive invoked in source file";
5396 return TokError(
".error argument must be a string");
5398 Message = getTok().getStringContents();
5402 return Error(L, Message);
5407bool AsmParser::parseDirectiveWarning(
SMLoc L) {
5408 if (!TheCondStack.empty()) {
5409 if (TheCondStack.back().Ignore) {
5410 eatToEndOfStatement();
5415 StringRef Message =
".warning directive invoked in source file";
5419 return TokError(
".warning argument must be a string");
5421 Message = getTok().getStringContents();
5432bool AsmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
5437 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
5439 if (!TheCondStack.empty()) {
5440 TheCondState = TheCondStack.back();
5441 TheCondStack.pop_back();
5447void AsmParser::initializeDirectiveKindMap() {
5454 DirectiveKindMap[
".set"] = DK_SET;
5455 DirectiveKindMap[
".equ"] = DK_EQU;
5456 DirectiveKindMap[
".equiv"] = DK_EQUIV;
5457 DirectiveKindMap[
".ascii"] = DK_ASCII;
5458 DirectiveKindMap[
".asciz"] = DK_ASCIZ;
5459 DirectiveKindMap[
".string"] = DK_STRING;
5460 DirectiveKindMap[
".byte"] = DK_BYTE;
5461 DirectiveKindMap[
".short"] = DK_SHORT;
5462 DirectiveKindMap[
".value"] = DK_VALUE;
5463 DirectiveKindMap[
".2byte"] = DK_2BYTE;
5464 DirectiveKindMap[
".long"] = DK_LONG;
5465 DirectiveKindMap[
".int"] = DK_INT;
5466 DirectiveKindMap[
".4byte"] = DK_4BYTE;
5467 DirectiveKindMap[
".quad"] = DK_QUAD;
5468 DirectiveKindMap[
".8byte"] = DK_8BYTE;
5469 DirectiveKindMap[
".octa"] = DK_OCTA;
5470 DirectiveKindMap[
".single"] = DK_SINGLE;
5471 DirectiveKindMap[
".float"] = DK_FLOAT;
5472 DirectiveKindMap[
".double"] = DK_DOUBLE;
5473 DirectiveKindMap[
".align"] = DK_ALIGN;
5474 DirectiveKindMap[
".align32"] = DK_ALIGN32;
5475 DirectiveKindMap[
".balign"] = DK_BALIGN;
5476 DirectiveKindMap[
".balignw"] = DK_BALIGNW;
5477 DirectiveKindMap[
".balignl"] = DK_BALIGNL;
5478 DirectiveKindMap[
".p2align"] = DK_P2ALIGN;
5479 DirectiveKindMap[
".p2alignw"] = DK_P2ALIGNW;
5480 DirectiveKindMap[
".p2alignl"] = DK_P2ALIGNL;
5481 DirectiveKindMap[
".org"] = DK_ORG;
5482 DirectiveKindMap[
".fill"] = DK_FILL;
5483 DirectiveKindMap[
".zero"] = DK_ZERO;
5484 DirectiveKindMap[
".extern"] = DK_EXTERN;
5485 DirectiveKindMap[
".globl"] = DK_GLOBL;
5486 DirectiveKindMap[
".global"] = DK_GLOBAL;
5487 DirectiveKindMap[
".lazy_reference"] = DK_LAZY_REFERENCE;
5488 DirectiveKindMap[
".no_dead_strip"] = DK_NO_DEAD_STRIP;
5489 DirectiveKindMap[
".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5490 DirectiveKindMap[
".private_extern"] = DK_PRIVATE_EXTERN;
5491 DirectiveKindMap[
".reference"] = DK_REFERENCE;
5492 DirectiveKindMap[
".weak_definition"] = DK_WEAK_DEFINITION;
5493 DirectiveKindMap[
".weak_reference"] = DK_WEAK_REFERENCE;
5494 DirectiveKindMap[
".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5495 DirectiveKindMap[
".cold"] = DK_COLD;
5496 DirectiveKindMap[
".comm"] = DK_COMM;
5497 DirectiveKindMap[
".common"] = DK_COMMON;
5498 DirectiveKindMap[
".lcomm"] = DK_LCOMM;
5499 DirectiveKindMap[
".abort"] = DK_ABORT;
5500 DirectiveKindMap[
".include"] = DK_INCLUDE;
5501 DirectiveKindMap[
".incbin"] = DK_INCBIN;
5502 DirectiveKindMap[
".code16"] = DK_CODE16;
5503 DirectiveKindMap[
".code16gcc"] = DK_CODE16GCC;
5504 DirectiveKindMap[
".rept"] = DK_REPT;
5505 DirectiveKindMap[
".rep"] = DK_REPT;
5506 DirectiveKindMap[
".irp"] = DK_IRP;
5507 DirectiveKindMap[
".irpc"] = DK_IRPC;
5508 DirectiveKindMap[
".endr"] = DK_ENDR;
5509 DirectiveKindMap[
".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5510 DirectiveKindMap[
".bundle_lock"] = DK_BUNDLE_LOCK;
5511 DirectiveKindMap[
".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5512 DirectiveKindMap[
".if"] = DK_IF;
5513 DirectiveKindMap[
".ifeq"] = DK_IFEQ;
5514 DirectiveKindMap[
".ifge"] = DK_IFGE;
5515 DirectiveKindMap[
".ifgt"] = DK_IFGT;
5516 DirectiveKindMap[
".ifle"] = DK_IFLE;
5517 DirectiveKindMap[
".iflt"] = DK_IFLT;
5518 DirectiveKindMap[
".ifne"] = DK_IFNE;
5519 DirectiveKindMap[
".ifb"] = DK_IFB;
5520 DirectiveKindMap[
".ifnb"] = DK_IFNB;
5521 DirectiveKindMap[
".ifc"] = DK_IFC;
5522 DirectiveKindMap[
".ifeqs"] = DK_IFEQS;
5523 DirectiveKindMap[
".ifnc"] = DK_IFNC;
5524 DirectiveKindMap[
".ifnes"] = DK_IFNES;
5525 DirectiveKindMap[
".ifdef"] = DK_IFDEF;
5526 DirectiveKindMap[
".ifndef"] = DK_IFNDEF;
5527 DirectiveKindMap[
".ifnotdef"] = DK_IFNOTDEF;
5528 DirectiveKindMap[
".elseif"] = DK_ELSEIF;
5529 DirectiveKindMap[
".else"] = DK_ELSE;
5530 DirectiveKindMap[
".end"] = DK_END;
5531 DirectiveKindMap[
".endif"] = DK_ENDIF;
5532 DirectiveKindMap[
".skip"] = DK_SKIP;
5533 DirectiveKindMap[
".space"] = DK_SPACE;
5534 DirectiveKindMap[
".file"] = DK_FILE;
5535 DirectiveKindMap[
".line"] = DK_LINE;
5536 DirectiveKindMap[
".loc"] = DK_LOC;
5537 DirectiveKindMap[
".stabs"] = DK_STABS;
5538 DirectiveKindMap[
".cv_file"] = DK_CV_FILE;
5539 DirectiveKindMap[
".cv_func_id"] = DK_CV_FUNC_ID;
5540 DirectiveKindMap[
".cv_loc"] = DK_CV_LOC;
5541 DirectiveKindMap[
".cv_linetable"] = DK_CV_LINETABLE;
5542 DirectiveKindMap[
".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5543 DirectiveKindMap[
".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5544 DirectiveKindMap[
".cv_def_range"] = DK_CV_DEF_RANGE;
5545 DirectiveKindMap[
".cv_string"] = DK_CV_STRING;
5546 DirectiveKindMap[
".cv_stringtable"] = DK_CV_STRINGTABLE;
5547 DirectiveKindMap[
".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5548 DirectiveKindMap[
".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5549 DirectiveKindMap[
".cv_fpo_data"] = DK_CV_FPO_DATA;
5550 DirectiveKindMap[
".sleb128"] = DK_SLEB128;
5551 DirectiveKindMap[
".uleb128"] = DK_ULEB128;
5552 DirectiveKindMap[
".cfi_sections"] = DK_CFI_SECTIONS;
5553 DirectiveKindMap[
".cfi_startproc"] = DK_CFI_STARTPROC;
5554 DirectiveKindMap[
".cfi_endproc"] = DK_CFI_ENDPROC;
5555 DirectiveKindMap[
".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5556 DirectiveKindMap[
".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5557 DirectiveKindMap[
".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5558 DirectiveKindMap[
".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5559 DirectiveKindMap[
".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
5560 DirectiveKindMap[
".cfi_offset"] = DK_CFI_OFFSET;
5561 DirectiveKindMap[
".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5562 DirectiveKindMap[
".cfi_personality"] = DK_CFI_PERSONALITY;
5563 DirectiveKindMap[
".cfi_lsda"] = DK_CFI_LSDA;
5564 DirectiveKindMap[
".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5565 DirectiveKindMap[
".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5566 DirectiveKindMap[
".cfi_same_value"] = DK_CFI_SAME_VALUE;
5567 DirectiveKindMap[
".cfi_restore"] = DK_CFI_RESTORE;
5568 DirectiveKindMap[
".cfi_escape"] = DK_CFI_ESCAPE;
5569 DirectiveKindMap[
".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5570 DirectiveKindMap[
".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5571 DirectiveKindMap[
".cfi_undefined"] = DK_CFI_UNDEFINED;
5572 DirectiveKindMap[
".cfi_register"] = DK_CFI_REGISTER;
5573 DirectiveKindMap[
".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5574 DirectiveKindMap[
".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5575 DirectiveKindMap[
".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
5576 DirectiveKindMap[
".macros_on"] = DK_MACROS_ON;
5577 DirectiveKindMap[
".macros_off"] = DK_MACROS_OFF;
5578 DirectiveKindMap[
".macro"] = DK_MACRO;
5579 DirectiveKindMap[
".exitm"] = DK_EXITM;
5580 DirectiveKindMap[
".endm"] = DK_ENDM;
5581 DirectiveKindMap[
".endmacro"] = DK_ENDMACRO;
5582 DirectiveKindMap[
".purgem"] = DK_PURGEM;
5583 DirectiveKindMap[
".err"] = DK_ERR;
5584 DirectiveKindMap[
".error"] = DK_ERROR;
5585 DirectiveKindMap[
".warning"] = DK_WARNING;
5586 DirectiveKindMap[
".altmacro"] = DK_ALTMACRO;
5587 DirectiveKindMap[
".noaltmacro"] = DK_NOALTMACRO;
5588 DirectiveKindMap[
".reloc"] = DK_RELOC;
5589 DirectiveKindMap[
".dc"] = DK_DC;
5590 DirectiveKindMap[
".dc.a"] = DK_DC_A;
5591 DirectiveKindMap[
".dc.b"] = DK_DC_B;
5592 DirectiveKindMap[
".dc.d"] = DK_DC_D;
5593 DirectiveKindMap[
".dc.l"] = DK_DC_L;
5594 DirectiveKindMap[
".dc.s"] = DK_DC_S;
5595 DirectiveKindMap[
".dc.w"] = DK_DC_W;
5596 DirectiveKindMap[
".dc.x"] = DK_DC_X;
5597 DirectiveKindMap[
".dcb"] = DK_DCB;
5598 DirectiveKindMap[
".dcb.b"] = DK_DCB_B;
5599 DirectiveKindMap[
".dcb.d"] = DK_DCB_D;
5600 DirectiveKindMap[
".dcb.l"] = DK_DCB_L;
5601 DirectiveKindMap[
".dcb.s"] = DK_DCB_S;
5602 DirectiveKindMap[
".dcb.w"] = DK_DCB_W;
5603 DirectiveKindMap[
".dcb.x"] = DK_DCB_X;
5604 DirectiveKindMap[
".ds"] = DK_DS;
5605 DirectiveKindMap[
".ds.b"] = DK_DS_B;
5606 DirectiveKindMap[
".ds.d"] = DK_DS_D;
5607 DirectiveKindMap[
".ds.l"] = DK_DS_L;
5608 DirectiveKindMap[
".ds.p"] = DK_DS_P;
5609 DirectiveKindMap[
".ds.s"] = DK_DS_S;
5610 DirectiveKindMap[
".ds.w"] = DK_DS_W;
5611 DirectiveKindMap[
".ds.x"] = DK_DS_X;
5612 DirectiveKindMap[
".print"] = DK_PRINT;
5613 DirectiveKindMap[
".addrsig"] = DK_ADDRSIG;
5614 DirectiveKindMap[
".addrsig_sym"] = DK_ADDRSIG_SYM;
5615 DirectiveKindMap[
".pseudoprobe"] = DK_PSEUDO_PROBE;
5616 DirectiveKindMap[
".lto_discard"] = DK_LTO_DISCARD;
5617 DirectiveKindMap[
".lto_set_conditional"] = DK_LTO_SET_CONDITIONAL;
5618 DirectiveKindMap[
".memtag"] = DK_MEMTAG;
5622 AsmToken EndToken, StartToken = getTok();
5624 unsigned NestLevel = 0;
5628 printError(DirectiveLoc,
"no matching '.endr' in definition");
5633 (getTok().getIdentifier() ==
".rep" ||
5634 getTok().getIdentifier() ==
".rept" ||
5635 getTok().getIdentifier() ==
".irp" ||
5636 getTok().getIdentifier() ==
".irpc")) {
5642 if (NestLevel == 0) {
5643 EndToken = getTok();
5646 printError(getTok().getLoc(),
5647 "unexpected token in '.endr' directive");
5656 eatToEndOfStatement();
5665 return &MacroLikeBodies.back();
5668void AsmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
5672 std::unique_ptr<MemoryBuffer> Instantiation =
5677 MacroInstantiation *
MI =
new MacroInstantiation{
5678 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5679 ActiveMacros.push_back(
MI);
5689bool AsmParser::parseDirectiveRept(
SMLoc DirectiveLoc,
StringRef Dir) {
5691 SMLoc CountLoc = getTok().getLoc();
5692 if (parseExpression(CountExpr))
5696 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5697 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
5700 if (
check(Count < 0, CountLoc,
"Count is negative") || parseEOL())
5714 if (expandMacro(
OS,
M->Body, std::nullopt, std::nullopt,
false,
5718 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5725bool AsmParser::parseDirectiveIrp(
SMLoc DirectiveLoc) {
5727 MCAsmMacroArguments
A;
5728 if (
check(parseIdentifier(Parameter.
Name),
5729 "expected identifier in '.irp' directive") ||
5730 parseComma() || parseMacroArguments(
nullptr,
A) || parseEOL())
5743 for (
const MCAsmMacroArgument &Arg :
A) {
5746 if (expandMacro(
OS,
M->Body, Parameter, Arg,
true, getTok().getLoc()))
5750 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5757bool AsmParser::parseDirectiveIrpc(
SMLoc DirectiveLoc) {
5759 MCAsmMacroArguments
A;
5761 if (
check(parseIdentifier(Parameter.
Name),
5762 "expected identifier in '.irpc' directive") ||
5763 parseComma() || parseMacroArguments(
nullptr,
A))
5766 if (
A.size() != 1 ||
A.front().size() != 1)
5767 return TokError(
"unexpected token in '.irpc' directive");
5781 StringRef Values =
A.front().front().getString();
5782 for (std::size_t
I = 0,
End = Values.
size();
I !=
End; ++
I) {
5783 MCAsmMacroArgument Arg;
5788 if (expandMacro(
OS,
M->Body, Parameter, Arg,
true, getTok().getLoc()))
5792 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5797bool AsmParser::parseDirectiveEndr(
SMLoc DirectiveLoc) {
5798 if (ActiveMacros.empty())
5799 return TokError(
"unmatched '.endr' directive");
5809bool AsmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
5812 SMLoc ExprLoc = getLexer().getLoc();
5813 if (parseExpression(
Value))
5817 return Error(ExprLoc,
"unexpected expression in _emit");
5819 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5820 return Error(ExprLoc,
"literal value out of range for directive");
5826bool AsmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
5828 SMLoc ExprLoc = getLexer().getLoc();
5829 if (parseExpression(
Value))
5833 return Error(ExprLoc,
"unexpected expression in align");
5836 return Error(ExprLoc,
"literal value not a power of two greater then zero");
5842bool AsmParser::parseDirectivePrint(
SMLoc DirectiveLoc) {
5846 return Error(DirectiveLoc,
"expected double quoted string after .print");
5853bool AsmParser::parseDirectiveAddrsig() {
5856 getStreamer().emitAddrsig();
5860bool AsmParser::parseDirectiveAddrsigSym() {
5862 if (
check(parseIdentifier(
Name),
"expected identifier") || parseEOL())
5865 getStreamer().emitAddrsigSym(
Sym);
5869bool AsmParser::parseDirectivePseudoProbe() {
5876 if (parseIntToken(Guid,
"unexpected token in '.pseudoprobe' directive"))
5879 if (parseIntToken(
Index,
"unexpected token in '.pseudoprobe' directive"))
5882 if (parseIntToken(
Type,
"unexpected token in '.pseudoprobe' directive"))
5885 if (parseIntToken(Attr,
"unexpected token in '.pseudoprobe' directive"))
5889 if (parseIntToken(Discriminator,
5890 "unexpected token in '.pseudoprobe' directive"))
5901 int64_t CallerGuid = 0;
5903 if (parseIntToken(CallerGuid,
5904 "unexpected token in '.pseudoprobe' directive"))
5912 int64_t CallerProbeId = 0;
5914 if (parseIntToken(CallerProbeId,
5915 "unexpected token in '.pseudoprobe' directive"))
5925 if (parseIdentifier(FnName))
5926 return Error(getLexer().getLoc(),
"unexpected token in '.pseudoprobe' directive");
5927 MCSymbol *FnSym = getContext().lookupSymbol(FnName);
5932 getStreamer().emitPseudoProbe(Guid,
Index,
Type, Attr, Discriminator,
5933 InlineStack, FnSym);
5942bool AsmParser::parseDirectiveLTODiscard() {
5943 auto ParseOp = [&]() ->
bool {
5945 SMLoc Loc = getTok().getLoc();
5946 if (parseIdentifier(
Name))
5947 return Error(Loc,
"expected identifier");
5952 LTODiscardSymbols.
clear();
5953 return parseMany(ParseOp);
5979bool AsmParser::parseMSInlineAsm(
5980 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
5999 unsigned InputIdx = 0;
6000 unsigned OutputIdx = 0;
6003 if (parseCurlyBlockScope(AsmStrRewrites))
6006 ParseStatementInfo
Info(&AsmStrRewrites);
6007 bool StatementErr = parseStatement(Info, &SI);
6009 if (StatementErr ||
Info.ParseError) {
6011 printPendingErrors();
6016 assert(!hasPendingError() &&
"unexpected error from parseStatement");
6018 if (
Info.Opcode == ~0U)
6024 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
6029 !getTargetParser().OmitRegisterFromClobberLists(Operand.
getReg())) {
6030 unsigned NumDefs =
Desc.getNumDefs();
6039 if (SymName.
empty())
6047 if (Operand.
isImm()) {
6055 bool isOutput = (i == 1) &&
Desc.mayStore();
6062 OutputConstraints.
push_back((
"=" + Constraint).str());
6069 if (
Desc.operands()[i - 1].isBranchTarget())
6083 NumOutputs = OutputDecls.
size();
6084 NumInputs = InputDecls.
size();
6088 ClobberRegs.
erase(std::unique(ClobberRegs.
begin(), ClobberRegs.
end()),
6090 Clobbers.
assign(ClobberRegs.
size(), std::string());
6091 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
6097 if (NumOutputs || NumInputs) {
6098 unsigned NumExprs = NumOutputs + NumInputs;
6099 OpDecls.resize(NumExprs);
6100 Constraints.
resize(NumExprs);
6101 for (
unsigned i = 0; i < NumOutputs; ++i) {
6102 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6103 Constraints[i] = OutputConstraints[i];
6105 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
6106 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6107 Constraints[
j] = InputConstraints[i];
6112 std::string AsmStringIR;
6116 const char *AsmStart = ASMString.
begin();
6117 const char *AsmEnd = ASMString.
end();
6119 for (
auto it = AsmStrRewrites.
begin(); it != AsmStrRewrites.
end(); ++it) {
6127 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
6130 if (
unsigned Len = Loc - AsmStart)
6135 AsmStart = Loc + AR.
Len;
6139 unsigned AdditionalSkip = 0;
6161 size_t OffsetLen = OffsetName.
size();
6162 auto rewrite_it = std::find_if(
6164 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6165 (FusingAR.Kind == AOK_Input ||
6166 FusingAR.Kind == AOK_CallInput);
6168 if (rewrite_it == AsmStrRewrites.
end()) {
6169 OS <<
"offset " << OffsetName;
6171 OS <<
"${" << InputIdx++ <<
":P}";
6172 rewrite_it->Done =
true;
6174 OS <<
'$' << InputIdx++;
6175 rewrite_it->Done =
true;
6188 OS <<
"${" << InputIdx++ <<
":P}";
6190 OS <<
'$' << InputIdx++;
6193 OS <<
"${" << InputIdx++ <<
":P}";
6197 OS <<
"${" << OutputIdx++ <<
":P}";
6199 OS <<
'$' << OutputIdx++;
6204 case 8:
OS <<
"byte ptr ";
break;
6205 case 16:
OS <<
"word ptr ";
break;
6206 case 32:
OS <<
"dword ptr ";
break;
6207 case 64:
OS <<
"qword ptr ";
break;
6208 case 80:
OS <<
"xword ptr ";
break;
6209 case 128:
OS <<
"xmmword ptr ";
break;
6210 case 256:
OS <<
"ymmword ptr ";
break;
6220 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6225 unsigned Val = AR.
Val;
6227 assert(Val < 10 &&
"Expected alignment less then 2^10.");
6228 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6240 AsmStart = Loc + AR.
Len + AdditionalSkip;
6244 if (AsmStart != AsmEnd)
6247 AsmString =
OS.str();
6251bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
6257 if (parseIdentifier(LabelVal))
6258 return Error(LabelLoc,
"The HLASM Label has to be an Identifier");
6263 if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
6272 return Error(LabelLoc,
6273 "Cannot have just a label for an HLASM inline asm statement");
6276 getContext().getAsmInfo()->shouldEmitLabelsInUpperCase()
6280 getTargetParser().doBeforeLabelEmit(
Sym, LabelLoc);
6287 if (enabledGenDwarfForAssembly())
6291 getTargetParser().onLabelParsed(
Sym);
6296bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
6299 SMLoc OperationEntryLoc = OperationEntryTok.
getLoc();
6303 if (parseIdentifier(OperationEntryVal))
6304 return Error(OperationEntryLoc,
"unexpected token at start of statement");
6310 return parseAndMatchAndEmitTargetInstruction(
6311 Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
6314bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
6316 assert(!hasPendingError() &&
"parseStatement started with pending error");
6319 bool ShouldParseAsHLASMLabel =
false;
6328 ShouldParseAsHLASMLabel =
true;
6334 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
6335 getTok().getString().front() ==
'\n')
6350 if (getTok().getString().front() ==
'\n' ||
6351 getTok().getString().front() ==
'\r') {
6360 if (ShouldParseAsHLASMLabel) {
6363 if (parseAsHLASMLabel(Info, SI)) {
6366 eatToEndOfStatement();
6371 return parseAsMachineInstruction(Info, SI);
6375namespace MCParserUtils {
6380 switch (
Value->getKind()) {
6411 return Parser.
TokError(
"missing expression");
6429 return Parser.
Error(EqualLoc,
"Recursive use of '" +
Name +
"'");
6430 else if (
Sym->isUndefined(
false) && !
Sym->isUsed() &&
6433 else if (
Sym->isVariable() && !
Sym->isUsed() && allow_redef)
6435 else if (!
Sym->isUndefined() && (!
Sym->isVariable() || !allow_redef))
6436 return Parser.
Error(EqualLoc,
"redefinition of '" +
Name +
"'");
6437 else if (!
Sym->isVariable())
6438 return Parser.
Error(EqualLoc,
"invalid assignment to '" +
Name +
"'");
6439 else if (!isa<MCConstantExpr>(
Sym->getVariableValue()))
6440 return Parser.
Error(EqualLoc,
6441 "invalid reassignment of non-absolute variable '" +
6443 }
else if (
Name ==
".") {
6449 Sym->setRedefinable(allow_redef);
6461 if (
C.getTargetTriple().isSystemZ() &&
C.getTargetTriple().isOSzOS())
6462 return new HLASMAsmParser(SM,
C, Out, MAI, CB);
6464 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
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)
virtual bool isVirtualSection() const =0
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
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()
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.