81typedef std::vector<AsmToken> MCAsmMacroArgument;
82typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
86struct MacroInstantiation {
88 SMLoc InstantiationLoc;
97 size_t CondStackDepth;
100struct ParseStatementInfo {
105 unsigned Opcode = ~0
U;
108 bool ParseError =
false;
112 ParseStatementInfo() =
delete;
114 : AsmRewrites(rewrites) {}
126 void *SavedDiagContext;
127 std::unique_ptr<MCAsmParserExtension> PlatformParser;
129 std::optional<SMLoc> CFIStartProcLoc;
136 std::vector<AsmCond> TheCondStack;
144 std::vector<MacroInstantiation*> ActiveMacros;
147 std::deque<MCAsmMacro> MacroLikeBodies;
150 unsigned MacrosEnabledFlag : 1;
153 unsigned NumOfMacroInstantiations;
156 struct CppHashInfoTy {
161 CppHashInfoTy() : LineNumber(0), Buf(0) {}
163 CppHashInfoTy CppHashInfo;
174 unsigned AssemblerDialect = ~0
U;
177 bool IsDarwin =
false;
180 bool ParsingMSInlineAsm =
false;
183 bool ReportedInconsistentMD5 =
false;
186 bool AltMacroMode =
false;
189 virtual bool parseStatement(ParseStatementInfo &Info,
195 bool parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
202 bool enabledGenDwarfForAssembly();
207 AsmParser(
const AsmParser &) =
delete;
208 AsmParser &
operator=(
const AsmParser &) =
delete;
209 ~AsmParser()
override;
211 bool Run(
bool NoInitialTextSection,
bool NoFinalize =
false)
override;
214 ExtensionDirectiveHandler Handler)
override {
215 ExtensionDirectiveMap[
Directive] = Handler;
219 DirectiveKindMap[
Directive.lower()] = DirectiveKindMap[Alias.
lower()];
233 if (AssemblerDialect == ~0U)
236 return AssemblerDialect;
239 AssemblerDialect = i;
251 ParsingMSInlineAsm =
V;
276 SMLoc &EndLoc)
override;
294 bool parseCppHashLineFilenameComment(
SMLoc L,
bool SaveLocInfo =
true);
303 bool areMacrosEnabled() {
return MacrosEnabledFlag;}
306 void setMacrosEnabled(
bool Flag) {MacrosEnabledFlag =
Flag;}
309 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
318 void handleMacroExit();
321 bool parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg);
324 bool parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A);
326 void printMacroInstantiations();
335 bool enterIncludeFile(
const std::string &Filename);
339 bool processIncbinFile(
const std::string &Filename, int64_t Skip = 0,
348 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0);
359 enum class AssignmentKind {
371 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
372 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
373 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
375 bool parseRegisterOrRegisterNumber(int64_t &
Register,
SMLoc DirectiveLoc);
378 bool parseCVFileId(int64_t &FileId,
StringRef DirectiveName);
437 DK_BUNDLE_ALIGN_MODE,
451 DK_WEAK_DEF_CAN_BE_HIDDEN,
491 DK_CV_INLINE_SITE_ID,
494 DK_CV_INLINE_LINETABLE,
499 DK_CV_FILECHECKSUM_OFFSET,
505 DK_CFI_DEF_CFA_OFFSET,
506 DK_CFI_ADJUST_CFA_OFFSET,
507 DK_CFI_DEF_CFA_REGISTER,
508 DK_CFI_LLVM_DEF_ASPACE_CFA,
513 DK_CFI_REMEMBER_STATE,
514 DK_CFI_RESTORE_STATE,
518 DK_CFI_RETURN_COLUMN,
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);
626 bool parseDirectiveCFILabel(
SMLoc DirectiveLoc);
629 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
632 bool parseDirectiveMacro(
SMLoc DirectiveLoc);
637 bool parseDirectiveBundleAlignMode();
639 bool parseDirectiveBundleLock();
641 bool parseDirectiveBundleUnlock();
644 bool parseDirectiveSpace(
StringRef IDVal);
653 bool parseDirectiveLEB128(
bool Signed);
659 bool parseDirectiveComm(
bool IsLocal);
661 bool parseDirectiveAbort(
SMLoc DirectiveLoc);
662 bool parseDirectiveInclude();
663 bool parseDirectiveIncbin();
666 bool parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
668 bool parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
670 bool parseDirectiveIfc(
SMLoc DirectiveLoc,
bool ExpectEqual);
672 bool parseDirectiveIfeqs(
SMLoc DirectiveLoc,
bool ExpectEqual);
674 bool parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
675 bool parseDirectiveElseIf(
SMLoc DirectiveLoc);
676 bool parseDirectiveElse(
SMLoc DirectiveLoc);
677 bool parseDirectiveEndIf(
SMLoc DirectiveLoc);
689 bool parseDirectiveIrp(
SMLoc DirectiveLoc);
690 bool parseDirectiveIrpc(
SMLoc DirectiveLoc);
691 bool parseDirectiveEndr(
SMLoc DirectiveLoc);
694 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
698 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
701 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
704 bool parseDirectiveError(
SMLoc DirectiveLoc,
bool WithMessage);
707 bool parseDirectiveWarning(
SMLoc DirectiveLoc);
710 bool parseDirectivePrint(
SMLoc DirectiveLoc);
713 bool parseDirectivePseudoProbe();
716 bool parseDirectiveLTODiscard();
719 bool parseDirectiveAddrsig();
720 bool parseDirectiveAddrsigSym();
722 void initializeDirectiveKindMap();
723 void initializeCVDefRangeTypeMap();
726class HLASMAsmParser final :
public AsmParser {
731 void lexLeadingSpaces() {
737 bool parseAsMachineInstruction(ParseStatementInfo &Info,
743 : AsmParser(SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
752 bool parseStatement(ParseStatementInfo &Info,
775 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI),
SrcMgr(SM),
776 CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(
true) {
804 "Need to implement createSPIRVAsmParser for SPIRV format.");
817 PlatformParser->Initialize(*
this);
818 initializeDirectiveKindMap();
819 initializeCVDefRangeTypeMap();
821 NumOfMacroInstantiations = 0;
824AsmParser::~AsmParser() {
825 assert((HadError || ActiveMacros.empty()) &&
826 "Unexpected active macro instantiation!");
835void AsmParser::printMacroInstantiations() {
837 for (MacroInstantiation *M :
reverse(ActiveMacros))
839 "while in macro instantiation");
843 printPendingErrors();
845 printMacroInstantiations();
849 if(getTargetParser().getTargetOptions().MCNoWarn)
851 if (getTargetParser().getTargetOptions().MCFatalWarnings)
854 printMacroInstantiations();
861 printMacroInstantiations();
865bool AsmParser::enterIncludeFile(
const std::string &Filename) {
866 std::string IncludedFile;
880bool AsmParser::processIncbinFile(
const std::string &Filename, int64_t Skip,
882 std::string IncludedFile;
893 if (!Count->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
894 return Error(Loc,
"expected absolute expression");
896 return Warning(Loc,
"negative count has no effect");
899 getStreamer().emitBytes(Bytes);
903void AsmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer) {
916 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
934 if (ParentIncludeLoc !=
SMLoc()) {
935 jumpToLoc(ParentIncludeLoc);
943bool AsmParser::enabledGenDwarfForAssembly() {
945 if (!getContext().getGenDwarfForAssembly())
950 if (getContext().getGenDwarfFileNumber() == 0) {
953 if (!FirstCppHashFilename.
empty())
954 getContext().setMCLineTableRootFile(
955 0, getContext().getCompilationDir(), FirstCppHashFilename,
956 std::nullopt, std::nullopt);
958 getContext().getMCDwarfLineTable(0).getRootFile();
959 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
960 0, getContext().getCompilationDir(), RootFile.
Name,
966bool AsmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
967 LTODiscardSymbols.
clear();
970 if (!NoInitialTextSection)
977 AsmCond StartingCondState = TheCondState;
984 if (getContext().getGenDwarfForAssembly()) {
985 MCSection *Sec = getStreamer().getCurrentSectionOnly();
987 MCSymbol *SectionStartSym = getContext().createTempSymbol();
988 getStreamer().emitLabel(SectionStartSym);
991 bool InsertResult = getContext().addGenDwarfSection(Sec);
992 assert(InsertResult &&
".text section should not have debug info yet");
996 getTargetParser().onBeginOfFile();
1000 ParseStatementInfo
Info(&AsmStrRewrites);
1001 bool Parsed = parseStatement(Info,
nullptr);
1011 printPendingErrors();
1014 if (Parsed && !getLexer().isAtStartOfStatement())
1015 eatToEndOfStatement();
1018 getTargetParser().onEndOfFile();
1019 printPendingErrors();
1022 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1024 getTargetParser().flushPendingInstructions(getStreamer());
1028 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1030 const auto &LineTables = getContext().getMCDwarfLineTables();
1031 if (!LineTables.empty()) {
1033 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1035 printError(getTok().getLoc(),
"unassigned file number: " +
1037 " for .file directives");
1053 if (
Sym &&
Sym->isTemporary() && !
Sym->isVariable() &&
1058 printError(getTok().getLoc(),
"assembler local symbol '" +
1059 Sym->getName() +
"' not defined");
1065 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1066 if (std::get<2>(LocSym)->isUndefined()) {
1069 CppHashInfo = std::get<1>(LocSym);
1070 printError(std::get<0>(LocSym),
"directional label undefined");
1076 if (!HadError && !NoFinalize) {
1078 TS->emitConstantPools();
1083 return HadError || getContext().hadError();
1086bool AsmParser::checkForValidSection() {
1087 if (!ParsingMSInlineAsm && !getStreamer().getCurrentFragment()) {
1089 return Error(getTok().getLoc(),
1090 "expected section directive before assembly directive");
1096void AsmParser::eatToEndOfStatement() {
1105StringRef AsmParser::parseStringToEndOfStatement() {
1106 const char *Start = getTok().getLoc().getPointer();
1111 const char *
End = getTok().getLoc().getPointer();
1115StringRef AsmParser::parseStringToComma() {
1116 const char *Start = getTok().getLoc().getPointer();
1122 const char *
End = getTok().getLoc().getPointer();
1131bool AsmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1132 if (parseExpression(Res))
1135 return parseRParen();
1143bool AsmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1144 if (parseExpression(Res))
1146 EndLoc = getTok().getEndLoc();
1147 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1158bool AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1160 SMLoc FirstTokenLoc = getLexer().getLoc();
1162 switch (FirstTokenKind) {
1164 return TokError(
"unknown token in expression");
1170 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1180 if (parseIdentifier(Identifier)) {
1184 bool ShouldGenerateTempSymbol =
false;
1187 ShouldGenerateTempSymbol =
true;
1189 if (!ShouldGenerateTempSymbol)
1190 return Error(FirstTokenLoc,
"invalid token in expression");
1200 EndLoc = FirstTokenLoc;
1205 std::pair<StringRef, StringRef>
Split;
1210 SMLoc AtLoc = getLexer().getLoc();
1212 if (parseIdentifier(VName))
1213 return Error(AtLoc,
"expected symbol variant after '@'");
1215 Split = std::make_pair(Identifier, VName);
1223 parseIdentifier(VName);
1226 Split = std::make_pair(Identifier, VName);
1234 return Error(getLexer().getLoc(),
"expected a symbol reference");
1239 if (!
Split.second.empty()) {
1240 Variant = getTargetParser().getVariantKindForName(
Split.second);
1247 "invalid variant '" +
Split.second +
"'");
1251 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1253 Sym = getContext().getOrCreateSymbol(
1258 if (
Sym->isVariable()) {
1259 auto V =
Sym->getVariableValue(
false);
1260 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1261 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1262 DoInline = TV->inlineAssignedExpr();
1265 return Error(EndLoc,
"unexpected modifier on variable reference");
1266 Res =
Sym->getVariableValue(
false);
1276 return TokError(
"literal value out of range for directive");
1278 SMLoc Loc = getTok().getLoc();
1279 int64_t
IntVal = getTok().getIntVal();
1287 std::pair<StringRef, StringRef>
Split = IDVal.
split(
'@');
1289 if (
Split.first.size() != IDVal.
size()) {
1292 return TokError(
"invalid variant '" +
Split.second +
"'");
1293 IDVal =
Split.first;
1295 if (IDVal ==
"f" || IDVal ==
"b") {
1299 if (IDVal ==
"b" &&
Sym->isUndefined())
1300 return Error(Loc,
"directional label undefined");
1301 DirLabels.push_back(std::make_tuple(Loc, CppHashInfo,
Sym));
1309 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1318 return TokError(
"cannot use . as current PC");
1331 return parseParenExpr(Res, EndLoc);
1333 if (!PlatformParser->HasBracketExpressions())
1334 return TokError(
"brackets expression not supported on this target");
1336 return parseBracketExpr(Res, EndLoc);
1339 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1345 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1351 if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
1383 return TokError(
"expected '(' after operator");
1385 if (parseExpression(Res, EndLoc))
1389 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1394bool AsmParser::parseExpression(
const MCExpr *&Res) {
1396 return parseExpression(Res, EndLoc);
1400AsmParser::applyModifierToExpr(
const MCExpr *E,
1403 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
1417 TokError(
"invalid variant on expression '" + getTok().getIdentifier() +
1418 "' (already modified)");
1466 "Argument to the function cannot be a NULL value");
1468 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1469 (*CharPtr !=
'\0')) {
1470 if (*CharPtr ==
'!')
1474 if (*CharPtr ==
'>') {
1484 for (
size_t Pos = 0; Pos < AltMacroStr.
size(); Pos++) {
1485 if (AltMacroStr[Pos] ==
'!')
1487 Res += AltMacroStr[Pos];
1502bool AsmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1505 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1506 parseBinOpRHS(1, Res, EndLoc))
1514 return TokError(
"unexpected symbol modifier following '@'");
1519 return TokError(
"invalid variant '" + getTok().getIdentifier() +
"'");
1521 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
1523 return TokError(
"invalid modifier '" + getTok().getIdentifier() +
1524 "' (no symbols present)");
1534 if (Res->evaluateAsAbsolute(
Value))
1540bool AsmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1542 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1545bool AsmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1547 if (parseParenExpr(Res, EndLoc))
1550 for (; ParenDepth > 0; --ParenDepth) {
1551 if (parseBinOpRHS(1, Res, EndLoc))
1556 if (ParenDepth - 1 > 0) {
1557 EndLoc = getTok().getEndLoc();
1565bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1569 if (parseExpression(Expr))
1572 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1573 return Error(StartLoc,
"expected absolute expression");
1580 bool ShouldUseLogicalShr) {
1657 bool ShouldUseLogicalShr) {
1746bool AsmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
1751 unsigned TokPrec = getBinOpPrecedence(Lexer.
getKind(), Kind);
1755 if (TokPrec < Precedence)
1762 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1768 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
1769 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1781bool AsmParser::parseStatement(ParseStatementInfo &Info,
1783 assert(!hasPendingError() &&
"parseStatement started with pending error");
1789 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
1790 getTok().getString().front() ==
'\n')
1799 int64_t LocalLabelVal = -1;
1800 StartTokLoc =
ID.getLoc();
1802 return parseCppHashLineFilenameComment(IDLoc,
1803 !isInsideMacroInstantiation());
1807 LocalLabelVal = getTok().getIntVal();
1808 if (LocalLabelVal < 0) {
1809 if (!TheCondState.
Ignore) {
1811 return Error(IDLoc,
"unexpected token at start of statement");
1815 IDVal = getTok().getString();
1818 if (!TheCondState.
Ignore) {
1820 return Error(IDLoc,
"unexpected token at start of statement");
1838 getTargetParser().starIsStartOfStatement()) {
1842 }
else if (parseIdentifier(IDVal)) {
1843 if (!TheCondState.
Ignore) {
1845 return Error(IDLoc,
"unexpected token at start of statement");
1854 DirectiveKindMap.find(IDVal.
lower());
1855 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1857 : DirKindIt->getValue();
1868 return parseDirectiveIf(IDLoc, DirKind);
1870 return parseDirectiveIfb(IDLoc,
true);
1872 return parseDirectiveIfb(IDLoc,
false);
1874 return parseDirectiveIfc(IDLoc,
true);
1876 return parseDirectiveIfeqs(IDLoc,
true);
1878 return parseDirectiveIfc(IDLoc,
false);
1880 return parseDirectiveIfeqs(IDLoc,
false);
1882 return parseDirectiveIfdef(IDLoc,
true);
1885 return parseDirectiveIfdef(IDLoc,
false);
1887 return parseDirectiveElseIf(IDLoc);
1889 return parseDirectiveElse(IDLoc);
1891 return parseDirectiveEndIf(IDLoc);
1896 if (TheCondState.
Ignore) {
1897 eatToEndOfStatement();
1907 if (checkForValidSection())
1914 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
1922 if (LocalLabelVal == -1) {
1923 if (ParsingMSInlineAsm && SI) {
1925 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
1927 "We should have an internal name here.");
1930 IDVal = RewrittenLabel;
1932 Sym = getContext().getOrCreateSymbol(IDVal);
1940 StringRef CommentStr = parseStringToEndOfStatement();
1952 Sym->isExternal() && !cast<MCSymbolMachO>(
Sym)->isAltEntry())
1953 return Error(StartTokLoc,
"non-private labels cannot appear between "
1954 ".cfi_startproc / .cfi_endproc pairs") &&
1955 Error(*CFIStartProcLoc,
"previous .cfi_startproc was here");
1957 if (discardLTOSymbol(IDVal))
1960 getTargetParser().doBeforeLabelEmit(
Sym, IDLoc);
1963 if (!getTargetParser().isParsingMSInlineAsm())
1968 if (enabledGenDwarfForAssembly())
1972 getTargetParser().onLabelParsed(
Sym);
1981 return parseAssignment(IDVal, AssignmentKind::Equal);
1985 if (areMacrosEnabled())
1986 if (
MCAsmMacro *M = getContext().lookupMacro(IDVal))
1987 return handleMacroEntry(M, IDLoc);
2004 getTargetParser().flushPendingInstructions(getStreamer());
2006 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2008 "Should only return Failure iff there was an error");
2016 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2017 ExtensionDirectiveMap.
lookup(IDVal);
2019 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2028 return parseDirectiveSet(IDVal, AssignmentKind::Set);
2030 return parseDirectiveSet(IDVal, AssignmentKind::Equiv);
2031 case DK_LTO_SET_CONDITIONAL:
2032 return parseDirectiveSet(IDVal, AssignmentKind::LTOSetConditional);
2034 return parseDirectiveAscii(IDVal,
false);
2037 return parseDirectiveAscii(IDVal,
true);
2040 return parseDirectiveValue(IDVal, 1);
2046 return parseDirectiveValue(IDVal, 2);
2051 return parseDirectiveValue(IDVal, 4);
2054 return parseDirectiveValue(IDVal, 8);
2056 return parseDirectiveValue(
2057 IDVal, getContext().getAsmInfo()->getCodePointerSize());
2059 return parseDirectiveOctaValue(IDVal);
2063 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
2066 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
2068 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2069 return parseDirectiveAlign(IsPow2, 1);
2072 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
2073 return parseDirectiveAlign(IsPow2, 4);
2076 return parseDirectiveAlign(
false, 1);
2078 return parseDirectiveAlign(
false, 2);
2080 return parseDirectiveAlign(
false, 4);
2082 return parseDirectiveAlign(
true, 1);
2084 return parseDirectiveAlign(
true, 2);
2086 return parseDirectiveAlign(
true, 4);
2088 return parseDirectiveOrg();
2090 return parseDirectiveFill();
2092 return parseDirectiveZero();
2094 eatToEndOfStatement();
2098 return parseDirectiveSymbolAttribute(
MCSA_Global);
2099 case DK_LAZY_REFERENCE:
2101 case DK_NO_DEAD_STRIP:
2103 case DK_SYMBOL_RESOLVER:
2105 case DK_PRIVATE_EXTERN:
2109 case DK_WEAK_DEFINITION:
2111 case DK_WEAK_REFERENCE:
2113 case DK_WEAK_DEF_CAN_BE_HIDDEN:
2116 return parseDirectiveSymbolAttribute(
MCSA_Cold);
2119 return parseDirectiveComm(
false);
2121 return parseDirectiveComm(
true);
2123 return parseDirectiveAbort(IDLoc);
2125 return parseDirectiveInclude();
2127 return parseDirectiveIncbin();
2130 return TokError(
Twine(IDVal) +
2131 " not currently supported for this target");
2133 return parseDirectiveRept(IDLoc, IDVal);
2135 return parseDirectiveIrp(IDLoc);
2137 return parseDirectiveIrpc(IDLoc);
2139 return parseDirectiveEndr(IDLoc);
2140 case DK_BUNDLE_ALIGN_MODE:
2141 return parseDirectiveBundleAlignMode();
2142 case DK_BUNDLE_LOCK:
2143 return parseDirectiveBundleLock();
2144 case DK_BUNDLE_UNLOCK:
2145 return parseDirectiveBundleUnlock();
2147 return parseDirectiveLEB128(
true);
2149 return parseDirectiveLEB128(
false);
2152 return parseDirectiveSpace(IDVal);
2154 return parseDirectiveFile(IDLoc);
2156 return parseDirectiveLine();
2158 return parseDirectiveLoc();
2160 return parseDirectiveStabs();
2162 return parseDirectiveCVFile();
2164 return parseDirectiveCVFuncId();
2165 case DK_CV_INLINE_SITE_ID:
2166 return parseDirectiveCVInlineSiteId();
2168 return parseDirectiveCVLoc();
2169 case DK_CV_LINETABLE:
2170 return parseDirectiveCVLinetable();
2171 case DK_CV_INLINE_LINETABLE:
2172 return parseDirectiveCVInlineLinetable();
2173 case DK_CV_DEF_RANGE:
2174 return parseDirectiveCVDefRange();
2176 return parseDirectiveCVString();
2177 case DK_CV_STRINGTABLE:
2178 return parseDirectiveCVStringTable();
2179 case DK_CV_FILECHECKSUMS:
2180 return parseDirectiveCVFileChecksums();
2181 case DK_CV_FILECHECKSUM_OFFSET:
2182 return parseDirectiveCVFileChecksumOffset();
2183 case DK_CV_FPO_DATA:
2184 return parseDirectiveCVFPOData();
2185 case DK_CFI_SECTIONS:
2186 return parseDirectiveCFISections();
2187 case DK_CFI_STARTPROC:
2188 return parseDirectiveCFIStartProc();
2189 case DK_CFI_ENDPROC:
2190 return parseDirectiveCFIEndProc();
2191 case DK_CFI_DEF_CFA:
2192 return parseDirectiveCFIDefCfa(IDLoc);
2193 case DK_CFI_DEF_CFA_OFFSET:
2194 return parseDirectiveCFIDefCfaOffset(IDLoc);
2195 case DK_CFI_ADJUST_CFA_OFFSET:
2196 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2197 case DK_CFI_DEF_CFA_REGISTER:
2198 return parseDirectiveCFIDefCfaRegister(IDLoc);
2199 case DK_CFI_LLVM_DEF_ASPACE_CFA:
2200 return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
2202 return parseDirectiveCFIOffset(IDLoc);
2203 case DK_CFI_REL_OFFSET:
2204 return parseDirectiveCFIRelOffset(IDLoc);
2205 case DK_CFI_PERSONALITY:
2206 return parseDirectiveCFIPersonalityOrLsda(
true);
2208 return parseDirectiveCFIPersonalityOrLsda(
false);
2209 case DK_CFI_REMEMBER_STATE:
2210 return parseDirectiveCFIRememberState(IDLoc);
2211 case DK_CFI_RESTORE_STATE:
2212 return parseDirectiveCFIRestoreState(IDLoc);
2213 case DK_CFI_SAME_VALUE:
2214 return parseDirectiveCFISameValue(IDLoc);
2215 case DK_CFI_RESTORE:
2216 return parseDirectiveCFIRestore(IDLoc);
2218 return parseDirectiveCFIEscape(IDLoc);
2219 case DK_CFI_RETURN_COLUMN:
2220 return parseDirectiveCFIReturnColumn(IDLoc);
2221 case DK_CFI_SIGNAL_FRAME:
2222 return parseDirectiveCFISignalFrame(IDLoc);
2223 case DK_CFI_UNDEFINED:
2224 return parseDirectiveCFIUndefined(IDLoc);
2225 case DK_CFI_REGISTER:
2226 return parseDirectiveCFIRegister(IDLoc);
2227 case DK_CFI_WINDOW_SAVE:
2228 return parseDirectiveCFIWindowSave(IDLoc);
2230 return parseDirectiveCFILabel(IDLoc);
2233 return parseDirectiveMacrosOnOff(IDVal);
2235 return parseDirectiveMacro(IDLoc);
2238 return parseDirectiveAltmacro(IDVal);
2240 return parseDirectiveExitMacro(IDVal);
2243 return parseDirectiveEndMacro(IDVal);
2245 return parseDirectivePurgeMacro(IDLoc);
2247 return parseDirectiveEnd(IDLoc);
2249 return parseDirectiveError(IDLoc,
false);
2251 return parseDirectiveError(IDLoc,
true);
2253 return parseDirectiveWarning(IDLoc);
2255 return parseDirectiveReloc(IDLoc);
2258 return parseDirectiveDCB(IDVal, 2);
2260 return parseDirectiveDCB(IDVal, 1);
2262 return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2264 return parseDirectiveDCB(IDVal, 4);
2266 return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2269 return TokError(
Twine(IDVal) +
2270 " not currently supported for this target");
2273 return parseDirectiveDS(IDVal, 2);
2275 return parseDirectiveDS(IDVal, 1);
2277 return parseDirectiveDS(IDVal, 8);
2280 return parseDirectiveDS(IDVal, 4);
2283 return parseDirectiveDS(IDVal, 12);
2285 return parseDirectivePrint(IDLoc);
2287 return parseDirectiveAddrsig();
2288 case DK_ADDRSIG_SYM:
2289 return parseDirectiveAddrsigSym();
2290 case DK_PSEUDO_PROBE:
2291 return parseDirectivePseudoProbe();
2292 case DK_LTO_DISCARD:
2293 return parseDirectiveLTODiscard();
2295 return parseDirectiveSymbolAttribute(
MCSA_Memtag);
2298 return Error(IDLoc,
"unknown directive");
2302 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2303 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2304 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2307 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2308 return parseDirectiveMSAlign(IDLoc, Info);
2310 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2312 if (checkForValidSection())
2315 return parseAndMatchAndEmitTargetInstruction(Info, IDVal,
ID, IDLoc);
2318bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
2323 std::string OpcodeStr = IDVal.
lower();
2325 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
ID,
2326 Info.ParsedOperands);
2327 Info.ParseError = ParseHadError;
2330 if (getShowParsedOperands()) {
2333 OS <<
"parsed instruction: [";
2334 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2337 Info.ParsedOperands[i]->print(
OS);
2345 if (hasPendingError() || ParseHadError)
2350 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2351 getContext().getGenDwarfSectionSyms().
count(
2352 getStreamer().getCurrentSectionOnly())) {
2354 if (ActiveMacros.empty())
2358 ActiveMacros.front()->ExitBuffer);
2363 if (!CppHashInfo.Filename.empty()) {
2364 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2366 getContext().setGenDwarfFileNumber(FileNumber);
2368 unsigned CppHashLocLineNo =
2370 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2373 getStreamer().emitDwarfLocDirective(
2374 getContext().getGenDwarfFileNumber(), Line, 0,
2380 if (!ParseHadError) {
2382 if (getTargetParser().MatchAndEmitInstruction(
2384 getTargetParser().isParsingMSInlineAsm()))
2410bool AsmParser::parseCppHashLineFilenameComment(
SMLoc L,
bool SaveLocInfo) {
2415 "Lexing Cpp line comment: Expected Integer");
2416 int64_t LineNumber = getTok().getIntVal();
2419 "Lexing Cpp line comment: Expected String");
2431 CppHashInfo.Loc =
L;
2433 CppHashInfo.LineNumber = LineNumber;
2434 CppHashInfo.Buf = CurBuffer;
2435 if (FirstCppHashFilename.
empty())
2442void AsmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2443 auto *Parser =
static_cast<AsmParser *
>(Context);
2449 unsigned CppHashBuf =
2450 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2455 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2464 if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
2465 if (Parser->SavedDiagHandler)
2466 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2468 Parser->getContext().diagnose(Diag);
2475 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2478 int CppHashLocLineNo =
2479 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2481 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2487 if (Parser->SavedDiagHandler)
2488 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2490 Parser->getContext().diagnose(NewDiag);
2498 return isalnum(
static_cast<unsigned char>(c)) || c ==
'_' || c ==
'$' ||
2505 bool EnableAtPseudoVariable) {
2507 auto expandArg = [&](
unsigned Index) {
2508 bool HasVararg = NParameters ?
Parameters.back().Vararg :
false;
2509 bool VarargParameter = HasVararg &&
Index == (NParameters - 1);
2518 if (AltMacroMode && Token.getString().front() ==
'%' &&
2521 OS << Token.getIntVal();
2524 else if (AltMacroMode && Token.getString().front() ==
'<' &&
2531 OS << Token.getString();
2533 OS << Token.getStringContents();
2541 if (Body[
I] ==
'\\' &&
I + 1 !=
End) {
2543 if (EnableAtPseudoVariable && Body[
I + 1] ==
'@') {
2544 OS << NumOfMacroInstantiations;
2548 if (Body[
I + 1] ==
'+') {
2553 if (Body[
I + 1] ==
'(' && Body[
I + 2] ==
')') {
2562 if (AltMacroMode &&
I !=
End && Body[
I] ==
'&')
2568 if (
Index == NParameters)
2577 if (Body[
I] ==
'$' &&
I + 1 !=
End && IsDarwin && !NParameters) {
2579 switch (Body[
I + 1]) {
2595 unsigned Index = Body[
I + 1] -
'0';
2598 OS << Token.getString();
2610 const size_t Start =
I;
2619 if (
Index != NParameters) {
2621 if (
I !=
End && Body[
I] ==
'&')
2665class AsmLexerSkipSpaceRAII {
2667 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2671 ~AsmLexerSkipSpaceRAII() {
2681bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
bool Vararg) {
2685 StringRef Str = parseStringToEndOfStatement();
2691 unsigned ParenLevel = 0;
2694 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2701 return TokError(
"unexpected token in macro instantiation");
2703 if (ParenLevel == 0) {
2716 MA.push_back(getTok());
2740 MA.push_back(getTok());
2744 if (ParenLevel != 0)
2745 return TokError(
"unbalanced parentheses in macro argument");
2750bool AsmParser::parseMacroArguments(
const MCAsmMacro *M,
2751 MCAsmMacroArguments &
A) {
2752 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
2753 bool NamedParametersFound =
false;
2756 A.resize(NParameters);
2757 FALocs.
resize(NParameters);
2762 bool HasVararg = NParameters ?
M->Parameters.back().Vararg :
false;
2763 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2769 if (parseIdentifier(FA.
Name))
2770 return Error(IDLoc,
"invalid argument identifier for formal argument");
2773 return TokError(
"expected '=' after formal parameter identifier");
2777 NamedParametersFound =
true;
2779 bool Vararg = HasVararg && Parameter == (NParameters - 1);
2781 if (NamedParametersFound && FA.
Name.
empty())
2782 return Error(IDLoc,
"cannot mix positional and keyword arguments");
2787 const MCExpr *AbsoluteExp;
2791 if (parseExpression(AbsoluteExp, EndLoc))
2793 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
2794 getStreamer().getAssemblerPtr()))
2795 return Error(StrLoc,
"expected absolute expression");
2800 FA.
Value.push_back(newToken);
2805 jumpToLoc(EndLoc, CurBuffer);
2810 FA.
Value.push_back(newToken);
2811 }
else if(parseMacroArgument(FA.
Value, Vararg))
2814 unsigned PI = Parameter;
2817 for (FAI = 0; FAI < NParameters; ++FAI)
2818 if (
M->Parameters[FAI].Name == FA.
Name)
2821 if (FAI >= NParameters) {
2822 assert(M &&
"expected macro to be defined");
2823 return Error(IDLoc,
"parameter named '" + FA.
Name +
2824 "' does not exist for macro '" +
M->Name +
"'");
2829 if (!FA.
Value.empty()) {
2834 if (FALocs.
size() <= PI)
2837 FALocs[PI] = Lexer.
getLoc();
2845 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
2846 if (
A[FAI].empty()) {
2847 if (
M->Parameters[FAI].Required) {
2849 "missing value for required parameter "
2850 "'" +
M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
2854 if (!
M->Parameters[FAI].Value.empty())
2855 A[FAI] =
M->Parameters[FAI].Value;
2864 return TokError(
"too many positional arguments");
2871 if (ActiveMacros.size() == MaxNestingDepth) {
2872 std::ostringstream MaxNestingDepthError;
2873 MaxNestingDepthError <<
"macros cannot be nested more than "
2874 << MaxNestingDepth <<
" levels deep."
2875 <<
" Use -asm-macro-max-nesting-depth to increase "
2877 return TokError(MaxNestingDepthError.str());
2880 MCAsmMacroArguments
A;
2881 if (parseMacroArguments(M,
A))
2889 if ((!IsDarwin ||
M->Parameters.size()) &&
M->Parameters.size() !=
A.size())
2890 return Error(getTok().getLoc(),
"Wrong number of arguments");
2891 if (expandMacro(
OS, *M,
M->Parameters,
A,
true))
2896 OS <<
".endmacro\n";
2898 std::unique_ptr<MemoryBuffer> Instantiation =
2903 MacroInstantiation *
MI =
new MacroInstantiation{
2904 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2905 ActiveMacros.push_back(
MI);
2907 ++NumOfMacroInstantiations;
2917void AsmParser::handleMacroExit() {
2919 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2927 delete ActiveMacros.back();
2928 ActiveMacros.pop_back();
2931bool AsmParser::parseAssignment(
StringRef Name, AssignmentKind Kind) {
2934 SMLoc ExprLoc = getTok().getLoc();
2936 Kind == AssignmentKind::Set ||
Kind == AssignmentKind::Equal;
2948 if (discardLTOSymbol(
Name))
2953 case AssignmentKind::Equal:
2956 case AssignmentKind::Set:
2957 case AssignmentKind::Equiv:
2961 case AssignmentKind::LTOSetConditional:
2963 return Error(ExprLoc,
"expected identifier");
2975bool AsmParser::parseIdentifier(
StringRef &Res) {
2982 SMLoc PrefixLoc = getLexer().getLoc();
2994 if (PrefixLoc.
getPointer() + 1 != Buf[0].getLoc().getPointer())
3008 Res = getTok().getIdentifier();
3020bool AsmParser::parseDirectiveSet(
StringRef IDVal, AssignmentKind Kind) {
3022 if (check(parseIdentifier(
Name),
"expected identifier") || parseComma() ||
3023 parseAssignment(
Name, Kind))
3028bool AsmParser::parseEscapedString(std::string &Data) {
3033 StringRef Str = getTok().getStringContents();
3034 for (
unsigned i = 0, e = Str.size(); i != e; ++i) {
3035 if (Str[i] !=
'\\') {
3036 if (Str[i] ==
'\n') {
3038 if (
Warning(NewlineLoc,
"unterminated string; newline inserted"))
3049 return TokError(
"unexpected backslash at end of string");
3052 if (Str[i] ==
'x' || Str[i] ==
'X') {
3053 size_t length = Str.size();
3054 if (i + 1 >= length || !
isHexDigit(Str[i + 1]))
3055 return TokError(
"invalid hexadecimal escape sequence");
3060 while (i + 1 < length &&
isHexDigit(Str[i + 1]))
3061 Value =
Value * 16 + hexDigitValue(Str[++i]);
3068 if ((
unsigned)(Str[i] -
'0') <= 7) {
3070 unsigned Value = Str[i] -
'0';
3072 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3076 if (i + 1 != e && ((
unsigned)(Str[i + 1] -
'0')) <= 7) {
3083 return TokError(
"invalid octal escape sequence (out of range)");
3093 return TokError(
"invalid escape sequence (unrecognized character)");
3095 case 'b': Data +=
'\b';
break;
3096 case 'f': Data +=
'\f';
break;
3097 case 'n': Data +=
'\n';
break;
3098 case 'r': Data +=
'\r';
break;
3099 case 't': Data +=
'\t';
break;
3100 case '"': Data +=
'"';
break;
3101 case '\\': Data +=
'\\';
break;
3109bool AsmParser::parseAngleBracketString(std::string &Data) {
3110 SMLoc EndLoc, StartLoc = getTok().getLoc();
3112 const char *StartChar = StartLoc.
getPointer() + 1;
3113 const char *EndChar = EndLoc.
getPointer() - 1;
3114 jumpToLoc(EndLoc, CurBuffer);
3127bool AsmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3128 auto parseOp = [&]() ->
bool {
3130 if (checkForValidSection())
3135 if (parseEscapedString(Data))
3137 getStreamer().emitBytes(Data);
3140 getStreamer().emitBytes(
StringRef(
"\0", 1));
3144 return parseMany(parseOp);
3149bool AsmParser::parseDirectiveReloc(
SMLoc DirectiveLoc) {
3151 const MCExpr *Expr =
nullptr;
3154 if (parseExpression(
Offset))
3167 if (parseExpression(Expr))
3172 return Error(ExprLoc,
"expression must be relocatable");
3180 if (std::optional<std::pair<bool, std::string>> Err =
3181 getStreamer().emitRelocDirective(*
Offset,
Name, Expr, DirectiveLoc,
3183 return Error(Err->first ? NameLoc : OffsetLoc, Err->second);
3190bool AsmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3191 auto parseOp = [&]() ->
bool {
3193 SMLoc ExprLoc = getLexer().getLoc();
3194 if (checkForValidSection() || parseExpression(
Value))
3199 uint64_t IntValue = MCE->getValue();
3201 return Error(ExprLoc,
"out of range literal value");
3202 getStreamer().emitIntValue(IntValue,
Size);
3204 getStreamer().emitValue(
Value,
Size, ExprLoc);
3208 return parseMany(parseOp);
3214 return Asm.TokError(
"unknown token in expression");
3215 SMLoc ExprLoc = Asm.getTok().getLoc();
3216 APInt IntValue = Asm.getTok().getAPIntVal();
3218 if (!IntValue.
isIntN(128))
3219 return Asm.Error(ExprLoc,
"out of range literal value");
3220 if (!IntValue.
isIntN(64)) {
3233bool AsmParser::parseDirectiveOctaValue(
StringRef IDVal) {
3234 auto parseOp = [&]() ->
bool {
3235 if (checkForValidSection())
3241 getStreamer().emitInt64(lo);
3242 getStreamer().emitInt64(hi);
3244 getStreamer().emitInt64(hi);
3245 getStreamer().emitInt64(lo);
3250 return parseMany(parseOp);
3264 return TokError(Lexer.
getErr());
3267 return TokError(
"unexpected token in directive");
3279 return TokError(
"invalid floating point literal");
3281 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3283 return TokError(
"invalid floating point literal");
3290 Res =
Value.bitcastToAPInt();
3297bool AsmParser::parseDirectiveRealValue(
StringRef IDVal,
3299 auto parseOp = [&]() ->
bool {
3301 if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3308 return parseMany(parseOp);
3313bool AsmParser::parseDirectiveZero() {
3316 if (checkForValidSection() || parseExpression(NumBytes))
3322 if (parseAbsoluteExpression(Val))
3328 getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3335bool AsmParser::parseDirectiveFill() {
3338 if (checkForValidSection() || parseExpression(NumValues))
3341 int64_t FillSize = 1;
3342 int64_t FillExpr = 0;
3344 SMLoc SizeLoc, ExprLoc;
3347 SizeLoc = getTok().getLoc();
3348 if (parseAbsoluteExpression(FillSize))
3351 ExprLoc = getTok().getLoc();
3352 if (parseAbsoluteExpression(FillExpr))
3360 Warning(SizeLoc,
"'.fill' directive with negative size has no effect");
3364 Warning(SizeLoc,
"'.fill' directive with size greater than 8 has been truncated to 8");
3368 if (!isUInt<32>(FillExpr) && FillSize > 4)
3369 Warning(ExprLoc,
"'.fill' directive pattern has been truncated to 32-bits");
3371 getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3378bool AsmParser::parseDirectiveOrg() {
3381 if (checkForValidSection() || parseExpression(
Offset))
3385 int64_t FillExpr = 0;
3387 if (parseAbsoluteExpression(FillExpr))
3392 getStreamer().emitValueToOffset(
Offset, FillExpr, OffsetLoc);
3398bool AsmParser::parseDirectiveAlign(
bool IsPow2,
unsigned ValueSize) {
3399 SMLoc AlignmentLoc = getLexer().getLoc();
3402 bool HasFillExpr =
false;
3403 int64_t FillExpr = 0;
3404 int64_t MaxBytesToFill = 0;
3407 auto parseAlign = [&]() ->
bool {
3408 if (parseAbsoluteExpression(Alignment))
3416 if (parseTokenLoc(FillExprLoc) || parseAbsoluteExpression(FillExpr))
3420 if (parseTokenLoc(MaxBytesLoc) ||
3421 parseAbsoluteExpression(MaxBytesToFill))
3427 if (checkForValidSection())
3431 Warning(AlignmentLoc,
"p2align directive with no operand(s) is ignored");
3438 bool ReturnVal =
false;
3443 if (Alignment >= 32) {
3444 ReturnVal |=
Error(AlignmentLoc,
"invalid alignment value");
3448 Alignment = 1ULL << Alignment;
3456 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2");
3457 Alignment = llvm::bit_floor<uint64_t>(Alignment);
3459 if (!isUInt<32>(Alignment)) {
3460 ReturnVal |=
Error(AlignmentLoc,
"alignment must be smaller than 2**32");
3461 Alignment = 1u << 31;
3467 if (MaxBytesToFill < 1) {
3468 ReturnVal |=
Error(MaxBytesLoc,
3469 "alignment directive can never be satisfied in this "
3470 "many bytes, ignoring maximum bytes expression");
3474 if (MaxBytesToFill >= Alignment) {
3475 Warning(MaxBytesLoc,
"maximum bytes expression exceeds alignment and "
3482 assert(Section &&
"must have section to emit alignment");
3484 if (HasFillExpr && FillExpr != 0 &&
Section->isVirtualSection()) {
3486 Warning(FillExprLoc,
"ignoring non-zero fill value in " +
3487 Section->getVirtualSectionKind() +
3488 " section '" +
Section->getName() +
"'");
3494 if (
Section->useCodeAlign() && !HasFillExpr) {
3495 getStreamer().emitCodeAlignment(
3496 Align(Alignment), &getTargetParser().getSTI(), MaxBytesToFill);
3499 getStreamer().emitValueToAlignment(
Align(Alignment), FillExpr, ValueSize,
3509bool AsmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
3511 int64_t FileNumber = -1;
3513 FileNumber = getTok().getIntVal();
3517 return TokError(
"negative file number");
3524 if (parseEscapedString(Path))
3529 std::string FilenameData;
3531 if (check(FileNumber == -1,
3532 "explicit path specified, but no file number") ||
3533 parseEscapedString(FilenameData))
3542 bool HasMD5 =
false;
3544 std::optional<StringRef>
Source;
3545 bool HasSource =
false;
3546 std::string SourceString;
3551 "unexpected token in '.file' directive") ||
3552 parseIdentifier(Keyword))
3554 if (Keyword ==
"md5") {
3556 if (check(FileNumber == -1,
3557 "MD5 checksum specified, but no file number") ||
3560 }
else if (Keyword ==
"source") {
3562 if (check(FileNumber == -1,
3563 "source specified, but no file number") ||
3565 "unexpected token in '.file' directive") ||
3566 parseEscapedString(SourceString))
3569 return TokError(
"unexpected token in '.file' directive");
3573 if (FileNumber == -1) {
3577 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
3578 getStreamer().emitFileDirective(Filename);
3588 std::optional<MD5::MD5Result> CKMem;
3591 for (
unsigned i = 0; i != 8; ++i) {
3592 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3593 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3598 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
3599 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3602 if (FileNumber == 0) {
3606 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3609 FileNumber, Directory, Filename, CKMem, Source);
3616 ReportedInconsistentMD5 =
true;
3617 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
3626bool AsmParser::parseDirectiveLine() {
3629 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
3644bool AsmParser::parseDirectiveLoc() {
3645 int64_t FileNumber = 0, LineNumber = 0;
3646 SMLoc Loc = getTok().getLoc();
3647 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
3649 "file number less than one in '.loc' directive") ||
3650 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3651 "unassigned file number in '.loc' directive"))
3656 LineNumber = getTok().getIntVal();
3658 return TokError(
"line number less than zero in '.loc' directive");
3662 int64_t ColumnPos = 0;
3664 ColumnPos = getTok().getIntVal();
3666 return TokError(
"column position less than zero in '.loc' directive");
3670 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
3675 auto parseLocOp = [&]() ->
bool {
3677 SMLoc Loc = getTok().getLoc();
3678 if (parseIdentifier(
Name))
3679 return TokError(
"unexpected token in '.loc' directive");
3681 if (
Name ==
"basic_block")
3683 else if (
Name ==
"prologue_end")
3685 else if (
Name ==
"epilogue_begin")
3687 else if (
Name ==
"is_stmt") {
3688 Loc = getTok().getLoc();
3690 if (parseExpression(
Value))
3694 int Value = MCE->getValue();
3696 Flags &= ~DWARF2_FLAG_IS_STMT;
3697 else if (
Value == 1)
3700 return Error(Loc,
"is_stmt value not 0 or 1");
3702 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
3704 }
else if (
Name ==
"isa") {
3705 Loc = getTok().getLoc();
3707 if (parseExpression(
Value))
3711 int Value = MCE->getValue();
3713 return Error(Loc,
"isa number less than zero");
3716 return Error(Loc,
"isa number not a constant value");
3718 }
else if (
Name ==
"discriminator") {
3719 if (parseAbsoluteExpression(Discriminator))
3722 return Error(Loc,
"unknown sub-directive in '.loc' directive");
3727 if (parseMany(parseLocOp,
false ))
3730 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3738bool AsmParser::parseDirectiveStabs() {
3739 return TokError(
"unsupported directive '.stabs'");
3744bool AsmParser::parseDirectiveCVFile() {
3745 SMLoc FileNumberLoc = getTok().getLoc();
3748 std::string Checksum;
3751 if (parseIntToken(FileNumber,
3752 "expected file number in '.cv_file' directive") ||
3753 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
3755 "unexpected token in '.cv_file' directive") ||
3756 parseEscapedString(Filename))
3760 "unexpected token in '.cv_file' directive") ||
3761 parseEscapedString(Checksum) ||
3762 parseIntToken(ChecksumKind,
3763 "expected checksum kind in '.cv_file' directive") ||
3768 Checksum = fromHex(Checksum);
3769 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
3770 memcpy(CKMem, Checksum.data(), Checksum.size());
3774 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3775 static_cast<uint8_t
>(ChecksumKind)))
3776 return Error(FileNumberLoc,
"file number already allocated");
3781bool AsmParser::parseCVFunctionId(int64_t &
FunctionId,
3784 return parseTokenLoc(Loc) ||
3785 parseIntToken(
FunctionId,
"expected function id in '" + DirectiveName +
3787 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3788 "expected function id within range [0, UINT_MAX)");
3791bool AsmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
3793 return parseTokenLoc(Loc) ||
3794 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
3796 check(FileNumber < 1, Loc,
"file number less than one in '" +
3797 DirectiveName +
"' directive") ||
3798 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3799 "unassigned file number in '" + DirectiveName +
"' directive");
3806bool AsmParser::parseDirectiveCVFuncId() {
3807 SMLoc FunctionIdLoc = getTok().getLoc();
3810 if (parseCVFunctionId(
FunctionId,
".cv_func_id") || parseEOL())
3813 if (!getStreamer().emitCVFuncIdDirective(
FunctionId))
3814 return Error(FunctionIdLoc,
"function id already allocated");
3827bool AsmParser::parseDirectiveCVInlineSiteId() {
3828 SMLoc FunctionIdLoc = getTok().getLoc();
3836 if (parseCVFunctionId(
FunctionId,
".cv_inline_site_id"))
3841 getTok().getIdentifier() !=
"within"),
3842 "expected 'within' identifier in '.cv_inline_site_id' directive"))
3847 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
3852 getTok().getIdentifier() !=
"inlined_at"),
3853 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3859 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
3860 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
3865 IACol = getTok().getIntVal();
3872 if (!getStreamer().emitCVInlineSiteIdDirective(
FunctionId, IAFunc, IAFile,
3873 IALine, IACol, FunctionIdLoc))
3874 return Error(FunctionIdLoc,
"function id already allocated");
3886bool AsmParser::parseDirectiveCVLoc() {
3887 SMLoc DirectiveLoc = getTok().getLoc();
3889 if (parseCVFunctionId(
FunctionId,
".cv_loc") ||
3890 parseCVFileId(FileNumber,
".cv_loc"))
3893 int64_t LineNumber = 0;
3895 LineNumber = getTok().getIntVal();
3897 return TokError(
"line number less than zero in '.cv_loc' directive");
3901 int64_t ColumnPos = 0;
3903 ColumnPos = getTok().getIntVal();
3905 return TokError(
"column position less than zero in '.cv_loc' directive");
3909 bool PrologueEnd =
false;
3912 auto parseOp = [&]() ->
bool {
3914 SMLoc Loc = getTok().getLoc();
3915 if (parseIdentifier(
Name))
3916 return TokError(
"unexpected token in '.cv_loc' directive");
3917 if (
Name ==
"prologue_end")
3919 else if (
Name ==
"is_stmt") {
3920 Loc = getTok().getLoc();
3922 if (parseExpression(
Value))
3926 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
3927 IsStmt = MCE->getValue();
3930 return Error(Loc,
"is_stmt value not 0 or 1");
3932 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
3937 if (parseMany(parseOp,
false ))
3940 getStreamer().emitCVLocDirective(
FunctionId, FileNumber, LineNumber,
3941 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
3948bool AsmParser::parseDirectiveCVLinetable() {
3951 SMLoc Loc = getTok().getLoc();
3952 if (parseCVFunctionId(
FunctionId,
".cv_linetable") || parseComma() ||
3953 parseTokenLoc(Loc) ||
3954 check(parseIdentifier(FnStartName), Loc,
3955 "expected identifier in directive") ||
3956 parseComma() || parseTokenLoc(Loc) ||
3957 check(parseIdentifier(FnEndName), Loc,
3958 "expected identifier in directive"))
3961 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3962 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3964 getStreamer().emitCVLinetableDirective(
FunctionId, FnStartSym, FnEndSym);
3970bool AsmParser::parseDirectiveCVInlineLinetable() {
3971 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3973 SMLoc Loc = getTok().getLoc();
3974 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
3975 parseTokenLoc(Loc) ||
3978 "expected SourceField in '.cv_inline_linetable' directive") ||
3979 check(SourceFileId <= 0, Loc,
3980 "File id less than zero in '.cv_inline_linetable' directive") ||
3981 parseTokenLoc(Loc) ||
3984 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3985 check(SourceLineNum < 0, Loc,
3986 "Line number less than zero in '.cv_inline_linetable' directive") ||
3987 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3988 "expected identifier in directive") ||
3989 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3990 "expected identifier in directive"))
3996 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3997 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3998 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
3999 SourceLineNum, FnStartSym,
4004void AsmParser::initializeCVDefRangeTypeMap() {
4005 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
4006 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4007 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4008 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4013bool AsmParser::parseDirectiveCVDefRange() {
4015 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
4017 Loc = getLexer().getLoc();
4019 if (parseIdentifier(GapStartName))
4020 return Error(Loc,
"expected identifier in directive");
4021 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
4023 Loc = getLexer().getLoc();
4025 if (parseIdentifier(GapEndName))
4026 return Error(Loc,
"expected identifier in directive");
4027 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
4029 Ranges.push_back({GapStartSym, GapEndSym});
4035 "expected comma before def_range type in .cv_def_range directive") ||
4036 parseIdentifier(CVDefRangeTypeStr))
4037 return Error(Loc,
"expected def_range type in directive");
4040 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4041 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4043 : CVTypeIt->getValue();
4045 case CVDR_DEFRANGE_REGISTER: {
4047 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4048 ".cv_def_range directive") ||
4049 parseAbsoluteExpression(DRRegister))
4050 return Error(Loc,
"expected register number");
4055 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4058 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4061 "expected comma before offset in .cv_def_range directive") ||
4062 parseAbsoluteExpression(DROffset))
4063 return Error(Loc,
"expected offset value");
4067 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4070 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4072 int64_t DROffsetInParent;
4073 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4074 ".cv_def_range directive") ||
4075 parseAbsoluteExpression(DRRegister))
4076 return Error(Loc,
"expected register number");
4078 "expected comma before offset in .cv_def_range directive") ||
4079 parseAbsoluteExpression(DROffsetInParent))
4080 return Error(Loc,
"expected offset value");
4086 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4089 case CVDR_DEFRANGE_REGISTER_REL: {
4092 int64_t DRBasePointerOffset;
4093 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
4094 ".cv_def_range directive") ||
4095 parseAbsoluteExpression(DRRegister))
4096 return Error(Loc,
"expected register value");
4099 "expected comma before flag value in .cv_def_range directive") ||
4100 parseAbsoluteExpression(DRFlags))
4101 return Error(Loc,
"expected flag value");
4102 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
4103 "in .cv_def_range directive") ||
4104 parseAbsoluteExpression(DRBasePointerOffset))
4105 return Error(Loc,
"expected base pointer offset value");
4109 DRHdr.
Flags = DRFlags;
4111 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4115 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
4122bool AsmParser::parseDirectiveCVString() {
4124 if (checkForValidSection() || parseEscapedString(Data))
4128 std::pair<StringRef, unsigned> Insertion =
4129 getCVContext().addToStringTable(Data);
4130 getStreamer().emitInt32(Insertion.second);
4136bool AsmParser::parseDirectiveCVStringTable() {
4137 getStreamer().emitCVStringTableDirective();
4143bool AsmParser::parseDirectiveCVFileChecksums() {
4144 getStreamer().emitCVFileChecksumsDirective();
4150bool AsmParser::parseDirectiveCVFileChecksumOffset() {
4152 if (parseIntToken(FileNo,
"expected identifier in directive"))
4156 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4162bool AsmParser::parseDirectiveCVFPOData() {
4163 SMLoc DirLoc = getLexer().getLoc();
4165 if (parseIdentifier(ProcName))
4166 return TokError(
"expected symbol name");
4169 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4170 getStreamer().emitCVFPOData(ProcSym, DirLoc);
4176bool AsmParser::parseDirectiveCFISections() {
4183 if (parseIdentifier(
Name))
4184 return TokError(
"expected .eh_frame or .debug_frame");
4185 if (
Name ==
".eh_frame")
4187 else if (
Name ==
".debug_frame")
4195 getStreamer().emitCFISections(EH,
Debug);
4201bool AsmParser::parseDirectiveCFIStartProc() {
4202 CFIStartProcLoc = StartTokLoc;
4206 if (check(parseIdentifier(
Simple) ||
Simple !=
"simple",
4207 "unexpected token") ||
4217 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
4223bool AsmParser::parseDirectiveCFIEndProc() {
4224 CFIStartProcLoc = std::nullopt;
4229 getStreamer().emitCFIEndProc();
4234bool AsmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
4235 SMLoc DirectiveLoc) {
4239 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
4241 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo,
true);
4243 return parseAbsoluteExpression(
Register);
4250bool AsmParser::parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc) {
4252 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4253 parseAbsoluteExpression(
Offset) || parseEOL())
4262bool AsmParser::parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc) {
4264 if (parseAbsoluteExpression(
Offset) || parseEOL())
4267 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
4273bool AsmParser::parseDirectiveCFIRegister(
SMLoc DirectiveLoc) {
4274 int64_t Register1 = 0, Register2 = 0;
4275 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
4276 parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
4279 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
4285bool AsmParser::parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc) {
4288 getStreamer().emitCFIWindowSave(DirectiveLoc);
4294bool AsmParser::parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc) {
4295 int64_t Adjustment = 0;
4296 if (parseAbsoluteExpression(Adjustment) || parseEOL())
4299 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
4305bool AsmParser::parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc) {
4307 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4310 getStreamer().emitCFIDefCfaRegister(
Register, DirectiveLoc);
4316bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(
SMLoc DirectiveLoc) {
4318 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4319 parseAbsoluteExpression(
Offset) || parseComma() ||
4330bool AsmParser::parseDirectiveCFIOffset(
SMLoc DirectiveLoc) {
4334 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4335 parseAbsoluteExpression(
Offset) || parseEOL())
4344bool AsmParser::parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc) {
4347 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseComma() ||
4348 parseAbsoluteExpression(
Offset) || parseEOL())
4356 if (Encoding & ~0xff)
4362 const unsigned Format = Encoding & 0xf;
4369 const unsigned Application = Encoding & 0x70;
4381bool AsmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
4382 int64_t Encoding = 0;
4383 if (parseAbsoluteExpression(Encoding))
4391 check(parseIdentifier(
Name),
"expected identifier in directive") ||
4398 getStreamer().emitCFIPersonality(
Sym, Encoding);
4400 getStreamer().emitCFILsda(
Sym, Encoding);
4406bool AsmParser::parseDirectiveCFIRememberState(
SMLoc DirectiveLoc) {
4409 getStreamer().emitCFIRememberState(DirectiveLoc);
4415bool AsmParser::parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc) {
4418 getStreamer().emitCFIRestoreState(DirectiveLoc);
4424bool AsmParser::parseDirectiveCFISameValue(
SMLoc DirectiveLoc) {
4427 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4430 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
4436bool AsmParser::parseDirectiveCFIRestore(
SMLoc DirectiveLoc) {
4438 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4441 getStreamer().emitCFIRestore(
Register, DirectiveLoc);
4447bool AsmParser::parseDirectiveCFIEscape(
SMLoc DirectiveLoc) {
4450 if (parseAbsoluteExpression(CurrValue))
4453 Values.push_back((uint8_t)CurrValue);
4458 if (parseAbsoluteExpression(CurrValue))
4461 Values.push_back((uint8_t)CurrValue);
4464 getStreamer().emitCFIEscape(Values, DirectiveLoc);
4470bool AsmParser::parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc) {
4472 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4474 getStreamer().emitCFIReturnColumn(
Register);
4480bool AsmParser::parseDirectiveCFISignalFrame(
SMLoc DirectiveLoc) {
4484 getStreamer().emitCFISignalFrame();
4490bool AsmParser::parseDirectiveCFIUndefined(
SMLoc DirectiveLoc) {
4493 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) || parseEOL())
4496 getStreamer().emitCFIUndefined(
Register, DirectiveLoc);
4502bool AsmParser::parseDirectiveCFILabel(
SMLoc Loc) {
4505 if (parseIdentifier(
Name))
4506 return TokError(
"expected identifier");
4509 getStreamer().emitCFILabelDirective(Loc,
Name);
4519 AltMacroMode = (
Directive ==
".altmacro");
4529 setMacrosEnabled(
Directive ==
".macros_on");
4535bool AsmParser::parseDirectiveMacro(
SMLoc DirectiveLoc) {
4537 if (parseIdentifier(
Name))
4538 return TokError(
"expected identifier in '.macro' directive");
4547 return Error(Lexer.
getLoc(),
"vararg parameter '" +
4549 "' should be the last parameter");
4552 if (parseIdentifier(Parameter.
Name))
4553 return TokError(
"expected identifier in '.macro' directive");
4557 if (CurrParam.Name == Parameter.
Name)
4558 return TokError(
"macro '" +
Name +
"' has multiple parameters"
4559 " named '" + Parameter.
Name +
"'");
4567 QualLoc = Lexer.
getLoc();
4568 if (parseIdentifier(Qualifier))
4569 return Error(QualLoc,
"missing parameter qualifier for "
4570 "'" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4572 if (Qualifier ==
"req")
4574 else if (Qualifier ==
"vararg")
4577 return Error(QualLoc, Qualifier +
" is not a valid parameter qualifier "
4578 "for '" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4586 ParamLoc = Lexer.
getLoc();
4587 if (parseMacroArgument(Parameter.
Value,
false ))
4591 Warning(ParamLoc,
"pointless default value for required parameter "
4592 "'" + Parameter.
Name +
"' in macro '" +
Name +
"'");
4605 AsmToken EndToken, StartToken = getTok();
4606 unsigned MacroDepth = 0;
4616 return Error(DirectiveLoc,
"no matching '.endmacro' in definition");
4621 if (getTok().getIdentifier() ==
".endm" ||
4622 getTok().getIdentifier() ==
".endmacro") {
4623 if (MacroDepth == 0) {
4624 EndToken = getTok();
4627 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
4634 }
else if (getTok().getIdentifier() ==
".macro") {
4640 (void)parseCppHashLineFilenameComment(getLexer().getLoc());
4644 eatToEndOfStatement();
4647 if (getContext().lookupMacro(
Name)) {
4648 return Error(DirectiveLoc,
"macro '" +
Name +
"' is already defined");
4654 checkForBadMacro(DirectiveLoc,
Name, Body, Parameters);
4658 getContext().defineMacro(
Name, std::move(
Macro));
4682 if (NParameters == 0)
4685 bool NamedParametersFound =
false;
4686 bool PositionalParametersFound =
false;
4691 while (!Body.
empty()) {
4693 std::size_t
End = Body.
size(), Pos = 0;
4694 for (; Pos !=
End; ++Pos) {
4697 if (Body[Pos] ==
'\\' && Pos + 1 !=
End)
4701 if (Body[Pos] !=
'$' || Pos + 1 ==
End)
4703 char Next = Body[Pos + 1];
4704 if (Next ==
'$' || Next ==
'n' ||
4705 isdigit(
static_cast<unsigned char>(Next)))
4713 if (Body[Pos] ==
'$') {
4714 switch (Body[Pos + 1]) {
4721 PositionalParametersFound =
true;
4726 PositionalParametersFound =
true;
4732 unsigned I = Pos + 1;
4736 const char *Begin = Body.
data() + Pos + 1;
4743 if (
Index == NParameters) {
4744 if (Body[Pos + 1] ==
'(' && Body[Pos + 2] ==
')')
4750 NamedParametersFound =
true;
4758 if (!NamedParametersFound && PositionalParametersFound)
4759 Warning(DirectiveLoc,
"macro defined with named parameters which are not "
4760 "used in macro body, possible positional parameter "
4761 "found in body which will have no effect");
4770 if (!isInsideMacroInstantiation())
4771 return TokError(
"unexpected '" +
Directive +
"' in file, "
4772 "no current macro definition");
4775 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4776 TheCondState = TheCondStack.back();
4777 TheCondStack.pop_back();
4789 return TokError(
"unexpected token in '" +
Directive +
"' directive");
4793 if (isInsideMacroInstantiation()) {
4800 return TokError(
"unexpected '" +
Directive +
"' in file, "
4801 "no current macro definition");
4806bool AsmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
4809 if (parseTokenLoc(Loc) ||
4810 check(parseIdentifier(
Name), Loc,
4811 "expected identifier in '.purgem' directive") ||
4815 if (!getContext().lookupMacro(
Name))
4816 return Error(DirectiveLoc,
"macro '" +
Name +
"' is not defined");
4818 getContext().undefineMacro(
Name);
4820 <<
"Un-defining macro: " <<
Name <<
"\n");
4826bool AsmParser::parseDirectiveBundleAlignMode() {
4829 SMLoc ExprLoc = getLexer().getLoc();
4830 int64_t AlignSizePow2;
4831 if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4833 check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4834 "invalid bundle alignment size (expected between 0 and 30)"))
4837 getStreamer().emitBundleAlignMode(
Align(1ULL << AlignSizePow2));
4843bool AsmParser::parseDirectiveBundleLock() {
4844 if (checkForValidSection())
4846 bool AlignToEnd =
false;
4849 SMLoc Loc = getTok().getLoc();
4850 const char *kInvalidOptionError =
4851 "invalid option for '.bundle_lock' directive";
4854 if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4855 check(Option !=
"align_to_end", Loc, kInvalidOptionError) || parseEOL())
4860 getStreamer().emitBundleLock(AlignToEnd);
4866bool AsmParser::parseDirectiveBundleUnlock() {
4867 if (checkForValidSection() || parseEOL())
4870 getStreamer().emitBundleUnlock();
4876bool AsmParser::parseDirectiveSpace(
StringRef IDVal) {
4879 if (checkForValidSection() || parseExpression(NumBytes))
4882 int64_t FillExpr = 0;
4884 if (parseAbsoluteExpression(FillExpr))
4890 getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4897bool AsmParser::parseDirectiveDCB(
StringRef IDVal,
unsigned Size) {
4900 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4903 if (NumValues < 0) {
4904 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4912 SMLoc ExprLoc = getLexer().getLoc();
4913 if (parseExpression(
Value))
4919 uint64_t IntValue = MCE->getValue();
4921 return Error(ExprLoc,
"literal value out of range for directive");
4922 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4923 getStreamer().emitIntValue(IntValue,
Size);
4925 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4926 getStreamer().emitValue(
Value,
Size, ExprLoc);
4937 if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4940 if (NumValues < 0) {
4941 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4949 if (parseRealValue(Semantics, AsInt) || parseEOL())
4952 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4961bool AsmParser::parseDirectiveDS(
StringRef IDVal,
unsigned Size) {
4964 if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
4968 if (NumValues < 0) {
4969 Warning(NumValuesLoc,
"'" +
Twine(IDVal) +
"' directive with negative repeat count has no effect");
4973 for (
uint64_t i = 0, e = NumValues; i !=
e; ++i)
4974 getStreamer().emitFill(
Size, 0);
4981bool AsmParser::parseDirectiveLEB128(
bool Signed) {
4982 if (checkForValidSection())
4985 auto parseOp = [&]() ->
bool {
4987 if (parseExpression(
Value))
4990 getStreamer().emitSLEB128Value(
Value);
4992 getStreamer().emitULEB128Value(
Value);
4996 return parseMany(parseOp);
5001bool AsmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
5002 auto parseOp = [&]() ->
bool {
5004 SMLoc Loc = getTok().getLoc();
5005 if (parseIdentifier(
Name))
5006 return Error(Loc,
"expected identifier");
5008 if (discardLTOSymbol(
Name))
5016 return Error(Loc,
"non-local symbol required");
5018 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
5019 return Error(Loc,
"unable to emit symbol attribute");
5023 return parseMany(parseOp);
5028bool AsmParser::parseDirectiveComm(
bool IsLocal) {
5029 if (checkForValidSection())
5032 SMLoc IDLoc = getLexer().getLoc();
5034 if (parseIdentifier(
Name))
5035 return TokError(
"expected identifier in directive");
5044 SMLoc SizeLoc = getLexer().getLoc();
5045 if (parseAbsoluteExpression(
Size))
5048 int64_t Pow2Alignment = 0;
5049 SMLoc Pow2AlignmentLoc;
5052 Pow2AlignmentLoc = getLexer().getLoc();
5053 if (parseAbsoluteExpression(Pow2Alignment))
5058 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
5061 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5064 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
5065 Pow2Alignment =
Log2_64(Pow2Alignment);
5075 return Error(SizeLoc,
"size must be non-negative");
5077 Sym->redefineIfPossible();
5078 if (!
Sym->isUndefined())
5079 return Error(IDLoc,
"invalid symbol redefinition");
5083 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
5084 Align(1ULL << Pow2Alignment));
5088 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
5094bool AsmParser::parseDirectiveAbort(
SMLoc DirectiveLoc) {
5095 StringRef Str = parseStringToEndOfStatement();
5100 return Error(DirectiveLoc,
".abort detected. Assembly stopping");
5103 return Error(DirectiveLoc,
5104 ".abort '" + Str +
"' detected. Assembly stopping");
5109bool AsmParser::parseDirectiveInclude() {
5112 SMLoc IncludeLoc = getTok().getLoc();
5115 "expected string in '.include' directive") ||
5116 parseEscapedString(Filename) ||
5118 "unexpected token in '.include' directive") ||
5121 check(enterIncludeFile(Filename), IncludeLoc,
5122 "Could not find include file '" + Filename +
"'"))
5130bool AsmParser::parseDirectiveIncbin() {
5133 SMLoc IncbinLoc = getTok().getLoc();
5135 "expected string in '.incbin' directive") ||
5136 parseEscapedString(Filename))
5140 const MCExpr *Count =
nullptr;
5141 SMLoc SkipLoc, CountLoc;
5146 if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
5150 CountLoc = getTok().getLoc();
5151 if (parseExpression(Count))
5159 if (check(Skip < 0, SkipLoc,
"skip is negative"))
5163 if (processIncbinFile(Filename, Skip, Count, CountLoc))
5164 return Error(IncbinLoc,
"Could not find incbin file '" + Filename +
"'");
5170bool AsmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
5171 TheCondStack.push_back(TheCondState);
5173 if (TheCondState.
Ignore) {
5174 eatToEndOfStatement();
5177 if (parseAbsoluteExpression(ExprValue) || parseEOL())
5187 ExprValue = ExprValue == 0;
5190 ExprValue = ExprValue >= 0;
5193 ExprValue = ExprValue > 0;
5196 ExprValue = ExprValue <= 0;
5199 ExprValue = ExprValue < 0;
5203 TheCondState.
CondMet = ExprValue;
5212bool AsmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
5213 TheCondStack.push_back(TheCondState);
5216 if (TheCondState.
Ignore) {
5217 eatToEndOfStatement();
5219 StringRef Str = parseStringToEndOfStatement();
5224 TheCondState.
CondMet = ExpectBlank == Str.empty();
5234bool AsmParser::parseDirectiveIfc(
SMLoc DirectiveLoc,
bool ExpectEqual) {
5235 TheCondStack.push_back(TheCondState);
5238 if (TheCondState.
Ignore) {
5239 eatToEndOfStatement();
5246 StringRef Str2 = parseStringToEndOfStatement();
5260bool AsmParser::parseDirectiveIfeqs(
SMLoc DirectiveLoc,
bool ExpectEqual) {
5263 return TokError(
"expected string parameter for '.ifeqs' directive");
5264 return TokError(
"expected string parameter for '.ifnes' directive");
5267 StringRef String1 = getTok().getStringContents();
5273 "expected comma after first string for '.ifeqs' directive");
5274 return TokError(
"expected comma after first string for '.ifnes' directive");
5281 return TokError(
"expected string parameter for '.ifeqs' directive");
5282 return TokError(
"expected string parameter for '.ifnes' directive");
5285 StringRef String2 = getTok().getStringContents();
5288 TheCondStack.push_back(TheCondState);
5290 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
5298bool AsmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
5300 TheCondStack.push_back(TheCondState);
5303 if (TheCondState.
Ignore) {
5304 eatToEndOfStatement();
5306 if (check(parseIdentifier(
Name),
"expected identifier after '.ifdef'") ||
5324bool AsmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc) {
5327 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
5328 " .if or an .elseif");
5331 bool LastIgnoreState =
false;
5332 if (!TheCondStack.empty())
5333 LastIgnoreState = TheCondStack.back().Ignore;
5334 if (LastIgnoreState || TheCondState.
CondMet) {
5335 TheCondState.
Ignore =
true;
5336 eatToEndOfStatement();
5339 if (parseAbsoluteExpression(ExprValue))
5345 TheCondState.
CondMet = ExprValue;
5354bool AsmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
5360 return Error(DirectiveLoc,
"Encountered a .else that doesn't follow "
5361 " an .if or an .elseif");
5363 bool LastIgnoreState =
false;
5364 if (!TheCondStack.empty())
5365 LastIgnoreState = TheCondStack.back().Ignore;
5366 if (LastIgnoreState || TheCondState.
CondMet)
5367 TheCondState.
Ignore =
true;
5369 TheCondState.
Ignore =
false;
5376bool AsmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
5389bool AsmParser::parseDirectiveError(
SMLoc L,
bool WithMessage) {
5390 if (!TheCondStack.empty()) {
5391 if (TheCondStack.back().Ignore) {
5392 eatToEndOfStatement();
5398 return Error(L,
".err encountered");
5400 StringRef Message =
".error directive invoked in source file";
5403 return TokError(
".error argument must be a string");
5405 Message = getTok().getStringContents();
5409 return Error(L, Message);
5414bool AsmParser::parseDirectiveWarning(
SMLoc L) {
5415 if (!TheCondStack.empty()) {
5416 if (TheCondStack.back().Ignore) {
5417 eatToEndOfStatement();
5422 StringRef Message =
".warning directive invoked in source file";
5426 return TokError(
".warning argument must be a string");
5428 Message = getTok().getStringContents();
5439bool AsmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
5444 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
5446 if (!TheCondStack.empty()) {
5447 TheCondState = TheCondStack.back();
5448 TheCondStack.pop_back();
5454void AsmParser::initializeDirectiveKindMap() {
5461 DirectiveKindMap[
".set"] = DK_SET;
5462 DirectiveKindMap[
".equ"] = DK_EQU;
5463 DirectiveKindMap[
".equiv"] = DK_EQUIV;
5464 DirectiveKindMap[
".ascii"] = DK_ASCII;
5465 DirectiveKindMap[
".asciz"] = DK_ASCIZ;
5466 DirectiveKindMap[
".string"] = DK_STRING;
5467 DirectiveKindMap[
".byte"] = DK_BYTE;
5468 DirectiveKindMap[
".short"] = DK_SHORT;
5469 DirectiveKindMap[
".value"] = DK_VALUE;
5470 DirectiveKindMap[
".2byte"] = DK_2BYTE;
5471 DirectiveKindMap[
".long"] = DK_LONG;
5472 DirectiveKindMap[
".int"] = DK_INT;
5473 DirectiveKindMap[
".4byte"] = DK_4BYTE;
5474 DirectiveKindMap[
".quad"] = DK_QUAD;
5475 DirectiveKindMap[
".8byte"] = DK_8BYTE;
5476 DirectiveKindMap[
".octa"] = DK_OCTA;
5477 DirectiveKindMap[
".single"] = DK_SINGLE;
5478 DirectiveKindMap[
".float"] = DK_FLOAT;
5479 DirectiveKindMap[
".double"] = DK_DOUBLE;
5480 DirectiveKindMap[
".align"] = DK_ALIGN;
5481 DirectiveKindMap[
".align32"] = DK_ALIGN32;
5482 DirectiveKindMap[
".balign"] = DK_BALIGN;
5483 DirectiveKindMap[
".balignw"] = DK_BALIGNW;
5484 DirectiveKindMap[
".balignl"] = DK_BALIGNL;
5485 DirectiveKindMap[
".p2align"] = DK_P2ALIGN;
5486 DirectiveKindMap[
".p2alignw"] = DK_P2ALIGNW;
5487 DirectiveKindMap[
".p2alignl"] = DK_P2ALIGNL;
5488 DirectiveKindMap[
".org"] = DK_ORG;
5489 DirectiveKindMap[
".fill"] = DK_FILL;
5490 DirectiveKindMap[
".zero"] = DK_ZERO;
5491 DirectiveKindMap[
".extern"] = DK_EXTERN;
5492 DirectiveKindMap[
".globl"] = DK_GLOBL;
5493 DirectiveKindMap[
".global"] = DK_GLOBAL;
5494 DirectiveKindMap[
".lazy_reference"] = DK_LAZY_REFERENCE;
5495 DirectiveKindMap[
".no_dead_strip"] = DK_NO_DEAD_STRIP;
5496 DirectiveKindMap[
".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5497 DirectiveKindMap[
".private_extern"] = DK_PRIVATE_EXTERN;
5498 DirectiveKindMap[
".reference"] = DK_REFERENCE;
5499 DirectiveKindMap[
".weak_definition"] = DK_WEAK_DEFINITION;
5500 DirectiveKindMap[
".weak_reference"] = DK_WEAK_REFERENCE;
5501 DirectiveKindMap[
".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5502 DirectiveKindMap[
".cold"] = DK_COLD;
5503 DirectiveKindMap[
".comm"] = DK_COMM;
5504 DirectiveKindMap[
".common"] = DK_COMMON;
5505 DirectiveKindMap[
".lcomm"] = DK_LCOMM;
5506 DirectiveKindMap[
".abort"] = DK_ABORT;
5507 DirectiveKindMap[
".include"] = DK_INCLUDE;
5508 DirectiveKindMap[
".incbin"] = DK_INCBIN;
5509 DirectiveKindMap[
".code16"] = DK_CODE16;
5510 DirectiveKindMap[
".code16gcc"] = DK_CODE16GCC;
5511 DirectiveKindMap[
".rept"] = DK_REPT;
5512 DirectiveKindMap[
".rep"] = DK_REPT;
5513 DirectiveKindMap[
".irp"] = DK_IRP;
5514 DirectiveKindMap[
".irpc"] = DK_IRPC;
5515 DirectiveKindMap[
".endr"] = DK_ENDR;
5516 DirectiveKindMap[
".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5517 DirectiveKindMap[
".bundle_lock"] = DK_BUNDLE_LOCK;
5518 DirectiveKindMap[
".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5519 DirectiveKindMap[
".if"] = DK_IF;
5520 DirectiveKindMap[
".ifeq"] = DK_IFEQ;
5521 DirectiveKindMap[
".ifge"] = DK_IFGE;
5522 DirectiveKindMap[
".ifgt"] = DK_IFGT;
5523 DirectiveKindMap[
".ifle"] = DK_IFLE;
5524 DirectiveKindMap[
".iflt"] = DK_IFLT;
5525 DirectiveKindMap[
".ifne"] = DK_IFNE;
5526 DirectiveKindMap[
".ifb"] = DK_IFB;
5527 DirectiveKindMap[
".ifnb"] = DK_IFNB;
5528 DirectiveKindMap[
".ifc"] = DK_IFC;
5529 DirectiveKindMap[
".ifeqs"] = DK_IFEQS;
5530 DirectiveKindMap[
".ifnc"] = DK_IFNC;
5531 DirectiveKindMap[
".ifnes"] = DK_IFNES;
5532 DirectiveKindMap[
".ifdef"] = DK_IFDEF;
5533 DirectiveKindMap[
".ifndef"] = DK_IFNDEF;
5534 DirectiveKindMap[
".ifnotdef"] = DK_IFNOTDEF;
5535 DirectiveKindMap[
".elseif"] = DK_ELSEIF;
5536 DirectiveKindMap[
".else"] = DK_ELSE;
5537 DirectiveKindMap[
".end"] = DK_END;
5538 DirectiveKindMap[
".endif"] = DK_ENDIF;
5539 DirectiveKindMap[
".skip"] = DK_SKIP;
5540 DirectiveKindMap[
".space"] = DK_SPACE;
5541 DirectiveKindMap[
".file"] = DK_FILE;
5542 DirectiveKindMap[
".line"] = DK_LINE;
5543 DirectiveKindMap[
".loc"] = DK_LOC;
5544 DirectiveKindMap[
".stabs"] = DK_STABS;
5545 DirectiveKindMap[
".cv_file"] = DK_CV_FILE;
5546 DirectiveKindMap[
".cv_func_id"] = DK_CV_FUNC_ID;
5547 DirectiveKindMap[
".cv_loc"] = DK_CV_LOC;
5548 DirectiveKindMap[
".cv_linetable"] = DK_CV_LINETABLE;
5549 DirectiveKindMap[
".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5550 DirectiveKindMap[
".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5551 DirectiveKindMap[
".cv_def_range"] = DK_CV_DEF_RANGE;
5552 DirectiveKindMap[
".cv_string"] = DK_CV_STRING;
5553 DirectiveKindMap[
".cv_stringtable"] = DK_CV_STRINGTABLE;
5554 DirectiveKindMap[
".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5555 DirectiveKindMap[
".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5556 DirectiveKindMap[
".cv_fpo_data"] = DK_CV_FPO_DATA;
5557 DirectiveKindMap[
".sleb128"] = DK_SLEB128;
5558 DirectiveKindMap[
".uleb128"] = DK_ULEB128;
5559 DirectiveKindMap[
".cfi_sections"] = DK_CFI_SECTIONS;
5560 DirectiveKindMap[
".cfi_startproc"] = DK_CFI_STARTPROC;
5561 DirectiveKindMap[
".cfi_endproc"] = DK_CFI_ENDPROC;
5562 DirectiveKindMap[
".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5563 DirectiveKindMap[
".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5564 DirectiveKindMap[
".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5565 DirectiveKindMap[
".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5566 DirectiveKindMap[
".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
5567 DirectiveKindMap[
".cfi_offset"] = DK_CFI_OFFSET;
5568 DirectiveKindMap[
".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5569 DirectiveKindMap[
".cfi_personality"] = DK_CFI_PERSONALITY;
5570 DirectiveKindMap[
".cfi_lsda"] = DK_CFI_LSDA;
5571 DirectiveKindMap[
".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5572 DirectiveKindMap[
".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5573 DirectiveKindMap[
".cfi_same_value"] = DK_CFI_SAME_VALUE;
5574 DirectiveKindMap[
".cfi_restore"] = DK_CFI_RESTORE;
5575 DirectiveKindMap[
".cfi_escape"] = DK_CFI_ESCAPE;
5576 DirectiveKindMap[
".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5577 DirectiveKindMap[
".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5578 DirectiveKindMap[
".cfi_undefined"] = DK_CFI_UNDEFINED;
5579 DirectiveKindMap[
".cfi_register"] = DK_CFI_REGISTER;
5580 DirectiveKindMap[
".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5581 DirectiveKindMap[
".cfi_label"] = DK_CFI_LABEL;
5582 DirectiveKindMap[
".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5583 DirectiveKindMap[
".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
5584 DirectiveKindMap[
".macros_on"] = DK_MACROS_ON;
5585 DirectiveKindMap[
".macros_off"] = DK_MACROS_OFF;
5586 DirectiveKindMap[
".macro"] = DK_MACRO;
5587 DirectiveKindMap[
".exitm"] = DK_EXITM;
5588 DirectiveKindMap[
".endm"] = DK_ENDM;
5589 DirectiveKindMap[
".endmacro"] = DK_ENDMACRO;
5590 DirectiveKindMap[
".purgem"] = DK_PURGEM;
5591 DirectiveKindMap[
".err"] = DK_ERR;
5592 DirectiveKindMap[
".error"] = DK_ERROR;
5593 DirectiveKindMap[
".warning"] = DK_WARNING;
5594 DirectiveKindMap[
".altmacro"] = DK_ALTMACRO;
5595 DirectiveKindMap[
".noaltmacro"] = DK_NOALTMACRO;
5596 DirectiveKindMap[
".reloc"] = DK_RELOC;
5597 DirectiveKindMap[
".dc"] = DK_DC;
5598 DirectiveKindMap[
".dc.a"] = DK_DC_A;
5599 DirectiveKindMap[
".dc.b"] = DK_DC_B;
5600 DirectiveKindMap[
".dc.d"] = DK_DC_D;
5601 DirectiveKindMap[
".dc.l"] = DK_DC_L;
5602 DirectiveKindMap[
".dc.s"] = DK_DC_S;
5603 DirectiveKindMap[
".dc.w"] = DK_DC_W;
5604 DirectiveKindMap[
".dc.x"] = DK_DC_X;
5605 DirectiveKindMap[
".dcb"] = DK_DCB;
5606 DirectiveKindMap[
".dcb.b"] = DK_DCB_B;
5607 DirectiveKindMap[
".dcb.d"] = DK_DCB_D;
5608 DirectiveKindMap[
".dcb.l"] = DK_DCB_L;
5609 DirectiveKindMap[
".dcb.s"] = DK_DCB_S;
5610 DirectiveKindMap[
".dcb.w"] = DK_DCB_W;
5611 DirectiveKindMap[
".dcb.x"] = DK_DCB_X;
5612 DirectiveKindMap[
".ds"] = DK_DS;
5613 DirectiveKindMap[
".ds.b"] = DK_DS_B;
5614 DirectiveKindMap[
".ds.d"] = DK_DS_D;
5615 DirectiveKindMap[
".ds.l"] = DK_DS_L;
5616 DirectiveKindMap[
".ds.p"] = DK_DS_P;
5617 DirectiveKindMap[
".ds.s"] = DK_DS_S;
5618 DirectiveKindMap[
".ds.w"] = DK_DS_W;
5619 DirectiveKindMap[
".ds.x"] = DK_DS_X;
5620 DirectiveKindMap[
".print"] = DK_PRINT;
5621 DirectiveKindMap[
".addrsig"] = DK_ADDRSIG;
5622 DirectiveKindMap[
".addrsig_sym"] = DK_ADDRSIG_SYM;
5623 DirectiveKindMap[
".pseudoprobe"] = DK_PSEUDO_PROBE;
5624 DirectiveKindMap[
".lto_discard"] = DK_LTO_DISCARD;
5625 DirectiveKindMap[
".lto_set_conditional"] = DK_LTO_SET_CONDITIONAL;
5626 DirectiveKindMap[
".memtag"] = DK_MEMTAG;
5630 AsmToken EndToken, StartToken = getTok();
5632 unsigned NestLevel = 0;
5636 printError(DirectiveLoc,
"no matching '.endr' in definition");
5641 StringRef Ident = getTok().getIdentifier();
5642 if (Ident ==
".rep" || Ident ==
".rept" || Ident ==
".irp" ||
5645 }
else if (Ident ==
".endr") {
5646 if (NestLevel == 0) {
5647 EndToken = getTok();
5651 printError(getTok().getLoc(),
"expected newline");
5659 eatToEndOfStatement();
5668 return &MacroLikeBodies.back();
5671void AsmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
5675 std::unique_ptr<MemoryBuffer> Instantiation =
5680 MacroInstantiation *
MI =
new MacroInstantiation{
5681 DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5682 ActiveMacros.push_back(
MI);
5692bool AsmParser::parseDirectiveRept(
SMLoc DirectiveLoc,
StringRef Dir) {
5694 SMLoc CountLoc = getTok().getLoc();
5695 if (parseExpression(CountExpr))
5699 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5700 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
5703 if (check(Count < 0, CountLoc,
"Count is negative") || parseEOL())
5717 if (expandMacro(
OS, *M, std::nullopt, std::nullopt,
false))
5720 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5727bool AsmParser::parseDirectiveIrp(
SMLoc DirectiveLoc) {
5729 MCAsmMacroArguments
A;
5730 if (check(parseIdentifier(Parameter.
Name),
5731 "expected identifier in '.irp' directive") ||
5732 parseComma() || parseMacroArguments(
nullptr,
A) || parseEOL())
5745 for (
const MCAsmMacroArgument &Arg :
A) {
5748 if (expandMacro(
OS, *M, Parameter, Arg,
true))
5752 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5759bool AsmParser::parseDirectiveIrpc(
SMLoc DirectiveLoc) {
5761 MCAsmMacroArguments
A;
5763 if (check(parseIdentifier(Parameter.
Name),
5764 "expected identifier in '.irpc' directive") ||
5765 parseComma() || parseMacroArguments(
nullptr,
A))
5768 if (
A.size() != 1 ||
A.front().size() != 1)
5769 return TokError(
"unexpected token in '.irpc' directive");
5784 :
A[0][0].getString();
5785 for (std::size_t
I = 0,
End = Values.
size();
I !=
End; ++
I) {
5786 MCAsmMacroArgument Arg;
5791 if (expandMacro(
OS, *M, Parameter, Arg,
true))
5795 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5800bool AsmParser::parseDirectiveEndr(
SMLoc DirectiveLoc) {
5801 if (ActiveMacros.empty())
5802 return TokError(
"unmatched '.endr' directive");
5812bool AsmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
5815 SMLoc ExprLoc = getLexer().getLoc();
5816 if (parseExpression(
Value))
5820 return Error(ExprLoc,
"unexpected expression in _emit");
5822 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5823 return Error(ExprLoc,
"literal value out of range for directive");
5829bool AsmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
5831 SMLoc ExprLoc = getLexer().getLoc();
5832 if (parseExpression(
Value))
5836 return Error(ExprLoc,
"unexpected expression in align");
5839 return Error(ExprLoc,
"literal value not a power of two greater then zero");
5845bool AsmParser::parseDirectivePrint(
SMLoc DirectiveLoc) {
5849 return Error(DirectiveLoc,
"expected double quoted string after .print");
5856bool AsmParser::parseDirectiveAddrsig() {
5859 getStreamer().emitAddrsig();
5863bool AsmParser::parseDirectiveAddrsigSym() {
5865 if (check(parseIdentifier(
Name),
"expected identifier") || parseEOL())
5868 getStreamer().emitAddrsigSym(
Sym);
5872bool AsmParser::parseDirectivePseudoProbe() {
5879 if (parseIntToken(
Guid,
"unexpected token in '.pseudoprobe' directive"))
5882 if (parseIntToken(
Index,
"unexpected token in '.pseudoprobe' directive"))
5885 if (parseIntToken(
Type,
"unexpected token in '.pseudoprobe' directive"))
5888 if (parseIntToken(Attr,
"unexpected token in '.pseudoprobe' directive"))
5892 if (parseIntToken(Discriminator,
5893 "unexpected token in '.pseudoprobe' directive"))
5904 int64_t CallerGuid = 0;
5906 if (parseIntToken(CallerGuid,
5907 "unexpected token in '.pseudoprobe' directive"))
5915 int64_t CallerProbeId = 0;
5917 if (parseIntToken(CallerProbeId,
5918 "unexpected token in '.pseudoprobe' directive"))
5928 if (parseIdentifier(FnName))
5929 return Error(getLexer().getLoc(),
"unexpected token in '.pseudoprobe' directive");
5930 MCSymbol *FnSym = getContext().lookupSymbol(FnName);
5935 getStreamer().emitPseudoProbe(
Guid,
Index,
Type, Attr, Discriminator,
5936 InlineStack, FnSym);
5945bool AsmParser::parseDirectiveLTODiscard() {
5946 auto ParseOp = [&]() ->
bool {
5948 SMLoc Loc = getTok().getLoc();
5949 if (parseIdentifier(
Name))
5950 return Error(Loc,
"expected identifier");
5955 LTODiscardSymbols.
clear();
5956 return parseMany(ParseOp);
5982bool AsmParser::parseMSInlineAsm(
5983 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
6002 unsigned InputIdx = 0;
6003 unsigned OutputIdx = 0;
6006 if (parseCurlyBlockScope(AsmStrRewrites))
6009 ParseStatementInfo
Info(&AsmStrRewrites);
6010 bool StatementErr = parseStatement(Info, &SI);
6012 if (StatementErr ||
Info.ParseError) {
6014 printPendingErrors();
6019 assert(!hasPendingError() &&
"unexpected error from parseStatement");
6021 if (
Info.Opcode == ~0U)
6027 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
6032 !getTargetParser().OmitRegisterFromClobberLists(Operand.
getReg())) {
6033 unsigned NumDefs =
Desc.getNumDefs();
6042 if (SymName.
empty())
6050 if (Operand.
isImm()) {
6058 bool isOutput = (i == 1) &&
Desc.mayStore();
6065 OutputConstraints.
push_back((
"=" + Constraint).str());
6072 if (
Desc.operands()[i - 1].isBranchTarget())
6086 NumOutputs = OutputDecls.
size();
6087 NumInputs = InputDecls.
size();
6092 Clobbers.
assign(ClobberRegs.
size(), std::string());
6093 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
6099 if (NumOutputs || NumInputs) {
6100 unsigned NumExprs = NumOutputs + NumInputs;
6101 OpDecls.resize(NumExprs);
6102 Constraints.
resize(NumExprs);
6103 for (
unsigned i = 0; i < NumOutputs; ++i) {
6104 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6105 Constraints[i] = OutputConstraints[i];
6107 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
6108 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6109 Constraints[
j] = InputConstraints[i];
6114 std::string AsmStringIR;
6118 const char *AsmStart = ASMString.
begin();
6119 const char *AsmEnd = ASMString.
end();
6121 for (
auto I = AsmStrRewrites.
begin(), E = AsmStrRewrites.
end();
I != E; ++
I) {
6129 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
6132 if (
unsigned Len = Loc - AsmStart)
6137 AsmStart = Loc + AR.
Len;
6141 unsigned AdditionalSkip = 0;
6163 size_t OffsetLen = OffsetName.
size();
6164 auto rewrite_it = std::find_if(
6166 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6167 (FusingAR.Kind == AOK_Input ||
6168 FusingAR.Kind == AOK_CallInput);
6170 if (rewrite_it == AsmStrRewrites.
end()) {
6171 OS <<
"offset " << OffsetName;
6173 OS <<
"${" << InputIdx++ <<
":P}";
6174 rewrite_it->Done =
true;
6176 OS <<
'$' << InputIdx++;
6177 rewrite_it->Done =
true;
6190 OS <<
"${" << InputIdx++ <<
":P}";
6192 OS <<
'$' << InputIdx++;
6195 OS <<
"${" << InputIdx++ <<
":P}";
6199 OS <<
"${" << OutputIdx++ <<
":P}";
6201 OS <<
'$' << OutputIdx++;
6206 case 8:
OS <<
"byte ptr ";
break;
6207 case 16:
OS <<
"word ptr ";
break;
6208 case 32:
OS <<
"dword ptr ";
break;
6209 case 64:
OS <<
"qword ptr ";
break;
6210 case 80:
OS <<
"xword ptr ";
break;
6211 case 128:
OS <<
"xmmword ptr ";
break;
6212 case 256:
OS <<
"ymmword ptr ";
break;
6222 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6227 unsigned Val = AR.
Val;
6229 assert(Val < 10 &&
"Expected alignment less then 2^10.");
6230 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6242 AsmStart = Loc + AR.
Len + AdditionalSkip;
6246 if (AsmStart != AsmEnd)
6249 AsmString = AsmStringIR;
6253bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
6259 if (parseIdentifier(LabelVal))
6260 return Error(LabelLoc,
"The HLASM Label has to be an Identifier");
6265 if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
6274 return Error(LabelLoc,
6275 "Cannot have just a label for an HLASM inline asm statement");
6278 getContext().getAsmInfo()->shouldEmitLabelsInUpperCase()
6282 getTargetParser().doBeforeLabelEmit(
Sym, LabelLoc);
6289 if (enabledGenDwarfForAssembly())
6293 getTargetParser().onLabelParsed(
Sym);
6298bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
6301 SMLoc OperationEntryLoc = OperationEntryTok.
getLoc();
6305 if (parseIdentifier(OperationEntryVal))
6306 return Error(OperationEntryLoc,
"unexpected token at start of statement");
6312 return parseAndMatchAndEmitTargetInstruction(
6313 Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
6316bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
6318 assert(!hasPendingError() &&
"parseStatement started with pending error");
6321 bool ShouldParseAsHLASMLabel =
false;
6330 ShouldParseAsHLASMLabel =
true;
6336 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
6337 getTok().getString().front() ==
'\n')
6352 if (getTok().getString().front() ==
'\n' ||
6353 getTok().getString().front() ==
'\r') {
6362 if (ShouldParseAsHLASMLabel) {
6365 if (parseAsHLASMLabel(Info, SI)) {
6368 eatToEndOfStatement();
6373 return parseAsMachineInstruction(Info, SI);
6377namespace MCParserUtils {
6382 switch (
Value->getKind()) {
6413 return Parser.
TokError(
"missing expression");
6431 return Parser.
Error(EqualLoc,
"Recursive use of '" +
Name +
"'");
6432 else if (
Sym->isUndefined(
false) && !
Sym->isUsed() &&
6435 else if (
Sym->isVariable() && !
Sym->isUsed() && allow_redef)
6437 else if (!
Sym->isUndefined() && (!
Sym->isVariable() || !allow_redef))
6438 return Parser.
Error(EqualLoc,
"redefinition of '" +
Name +
"'");
6439 else if (!
Sym->isVariable())
6440 return Parser.
Error(EqualLoc,
"invalid assignment to '" +
Name +
"'");
6441 else if (!isa<MCConstantExpr>(
Sym->getVariableValue()))
6442 return Parser.
Error(EqualLoc,
6443 "invalid reassignment of non-absolute variable '" +
6445 }
else if (
Name ==
".") {
6451 Sym->setRedefinable(allow_redef);
6463 if (
C.getTargetTriple().isSystemZ() &&
C.getTargetTriple().isOSzOS())
6464 return new HLASMAsmParser(SM,
C, Out, MAI, CB);
6466 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
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This file contains constants used for implementing Dwarf debug support.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static bool isDigit(const char C)
static bool isHexDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)
Factory for NaN values.
Class for arbitrary precision integers.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
APInt getHiBits(unsigned numBits) const
Compute an APInt containing numBits highbits from this APInt.
unsigned getBitWidth() const
Return the number of bits in the APInt.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
AsmCond - Class to support conditional assembly.
ConditionalAssemblyType TheCond
AsmLexer - Lexer class for assembly files.
Target independent representation for an assembler token.
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Holds state from .cv_file and .cv_loc directives for later emission.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool useParensForSymbolVariant() const
bool preserveAsmComments() const
Return true if assembly (inline or otherwise) should be parsed.
bool isLittleEndian() const
True if the target is little endian.
unsigned getAssemblerDialect() const
bool doesAllowAtInName() const
StringRef getPrivateLabelPrefix() const
bool 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 MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printRegName(raw_ostream &OS, MCRegister Reg) 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.
void setBeginSymbol(MCSymbol *Sym)
MCSymbol * getBeginSymbol()
Streaming machine code generation interface.
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI)
Create the default sections and set the initial one.
void setStartTokLocPtr(const SMLoc *Loc)
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static VariantKind getVariantKindForName(StringRef Name)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool isWeakExternal() const
bool isVariable() const
isVariable - Check if this is a variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSubtargetInfo & getSTI() const
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
static const MCUnaryExpr * createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
This represents an "assembler immediate".
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
StringRef getBuffer() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
constexpr bool isSuccess() const
Wrapper class representing virtual and physical registers.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
SourceMgr::DiagKind getKind() const
StringRef getLineContents() const
StringRef getMessage() const
ArrayRef< std::pair< unsigned, unsigned > > getRanges() const
const SourceMgr * getSourceMgr() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
void * getDiagContext() const
unsigned getMainFileID() const
DiagHandlerTy getDiagHandler() const
const MemoryBuffer * getMemoryBuffer(unsigned i) const
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
SMLoc getParentIncludeLoc(unsigned i) const
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
std::string upper() const
Convert the given ASCII string to uppercase.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
std::string lower() const
int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
This class represents a function that is read from a sample profile.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
@ C
The default llvm calling convention, compatible with C.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value)
Returns whether the given symbol is used anywhere in the given expression, or subexpressions.
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
MCAsmParserExtension * createCOFFAsmParser()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::tuple< uint64_t, uint32_t > InlineSite
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
std::vector< MCAsmMacroParameter > MCAsmMacroParameters
auto unique(Range &&R, Predicate P)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MCAsmParserExtension * createXCOFFAsmParser()
MCAsmParserExtension * createGOFFAsmParser()
auto reverse(ContainerTy &&C)
cl::opt< unsigned > AsmMacroMaxNestingDepth
const char AsmRewritePrecedence[]
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
static bool hasDiscriminator(uint32_t Flags)
MCAsmParserExtension * createWasmAsmParser()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance for parsing assembly similar to gas syntax.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
MCAsmParserExtension * createELFAsmParser()
MCAsmParserExtension * createDarwinAsmParser()
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
@ MCSA_Memtag
.memtag (ELF)
@ MCSA_PrivateExtern
.private_extern (MachO)
@ MCSA_WeakReference
.weak_reference (MachO)
@ MCSA_LazyReference
.lazy_reference (MachO)
@ MCSA_Reference
.reference (MachO)
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
@ MCSA_WeakDefinition
.weak_definition (MachO)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
ArrayRef< int > hi(ArrayRef< int > Vuu)
ArrayRef< int > lo(ArrayRef< int > Vuu)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
std::vector< AsmToken > Value
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
std::optional< StringRef > Source
The source code of the file.