80typedef std::vector<AsmToken> MCAsmMacroArgument;
81typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
84struct MacroInstantiation {
86 SMLoc InstantiationLoc;
95 size_t CondStackDepth;
98struct ParseStatementInfo {
103 unsigned Opcode = ~0
U;
106 bool ParseError =
false;
109 std::optional<std::string> ExitValue;
113 ParseStatementInfo() =
delete;
115 : AsmRewrites(rewrites) {}
128 bool Initializable =
true;
129 unsigned Alignment = 0;
130 unsigned AlignmentSize = 0;
131 unsigned NextOffset = 0;
133 std::vector<FieldInfo> Fields;
136 FieldInfo &addField(
StringRef FieldName, FieldType FT,
137 unsigned FieldAlignmentSize);
139 StructInfo() =
default;
140 StructInfo(
StringRef StructName,
bool Union,
unsigned AlignmentValue);
148struct StructInitializer;
152 IntFieldInfo() =
default;
156struct RealFieldInfo {
159 RealFieldInfo() =
default;
163struct StructFieldInfo {
164 std::vector<StructInitializer> Initializers;
165 StructInfo Structure;
167 StructFieldInfo() =
default;
168 StructFieldInfo(std::vector<StructInitializer> V, StructInfo S);
171class FieldInitializer {
175 IntFieldInfo IntInfo;
176 RealFieldInfo RealInfo;
177 StructFieldInfo StructInfo;
181 FieldInitializer(FieldType FT);
185 FieldInitializer(std::vector<StructInitializer> &&Initializers,
186 struct StructInfo Structure);
188 FieldInitializer(
const FieldInitializer &Initializer);
189 FieldInitializer(FieldInitializer &&Initializer);
191 FieldInitializer &operator=(
const FieldInitializer &Initializer);
192 FieldInitializer &operator=(FieldInitializer &&Initializer);
195struct StructInitializer {
196 std::vector<FieldInitializer> FieldInitializers;
207 unsigned LengthOf = 0;
212 FieldInitializer Contents;
214 FieldInfo(FieldType FT) : Contents(FT) {}
217StructFieldInfo::StructFieldInfo(std::vector<StructInitializer> V,
219 Initializers = std::move(V);
223StructInfo::StructInfo(
StringRef StructName,
bool Union,
224 unsigned AlignmentValue)
227FieldInfo &StructInfo::addField(
StringRef FieldName, FieldType FT,
228 unsigned FieldAlignmentSize) {
229 if (!FieldName.
empty())
230 FieldsByName[FieldName.
lower()] = Fields.size();
231 Fields.emplace_back(FT);
232 FieldInfo &
Field = Fields.back();
234 llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize));
238 AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
242FieldInitializer::~FieldInitializer() {
245 IntInfo.~IntFieldInfo();
248 RealInfo.~RealFieldInfo();
251 StructInfo.~StructFieldInfo();
256FieldInitializer::FieldInitializer(FieldType FT) : FT(FT) {
259 new (&IntInfo) IntFieldInfo();
262 new (&RealInfo) RealFieldInfo();
265 new (&StructInfo) StructFieldInfo();
272 new (&IntInfo) IntFieldInfo(std::move(Values));
277 new (&RealInfo) RealFieldInfo(std::move(AsIntValues));
280FieldInitializer::FieldInitializer(
281 std::vector<StructInitializer> &&Initializers,
struct StructInfo Structure)
283 new (&StructInfo) StructFieldInfo(std::move(Initializers), Structure);
286FieldInitializer::FieldInitializer(
const FieldInitializer &Initializer)
287 : FT(Initializer.FT) {
290 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
293 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
296 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
301FieldInitializer::FieldInitializer(FieldInitializer &&Initializer)
302 : FT(Initializer.FT) {
305 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
308 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
311 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
317FieldInitializer::operator=(
const FieldInitializer &Initializer) {
318 if (FT != Initializer.FT) {
321 IntInfo.~IntFieldInfo();
324 RealInfo.~RealFieldInfo();
327 StructInfo.~StructFieldInfo();
334 IntInfo = Initializer.IntInfo;
337 RealInfo = Initializer.RealInfo;
340 StructInfo = Initializer.StructInfo;
346FieldInitializer &FieldInitializer::operator=(FieldInitializer &&Initializer) {
347 if (FT != Initializer.FT) {
350 IntInfo.~IntFieldInfo();
353 RealInfo.~RealFieldInfo();
356 StructInfo.~StructFieldInfo();
363 IntInfo = Initializer.IntInfo;
366 RealInfo = Initializer.RealInfo;
369 StructInfo = Initializer.StructInfo;
386 void *SavedDiagContext;
387 std::unique_ptr<MCAsmParserExtension> PlatformParser;
399 std::vector<AsmCond> TheCondStack;
408 enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE };
411 RedefinableKind Redefinable = REDEFINABLE;
413 std::string TextValue;
427 std::vector<MacroInstantiation*> ActiveMacros;
430 std::deque<MCAsmMacro> MacroLikeBodies;
433 unsigned NumOfMacroInstantiations;
436 struct CppHashInfoTy {
441 CppHashInfoTy() : LineNumber(0), Buf(0) {}
443 CppHashInfoTy CppHashInfo;
453 unsigned AssemblerDialect = 1U;
456 bool IsDarwin =
false;
459 bool ParsingMSInlineAsm =
false;
462 bool ReportedInconsistentMD5 =
false;
465 unsigned AngleBracketDepth = 0
U;
472 const MCAsmInfo &MAI,
struct tm TM,
unsigned CB = 0);
473 MasmParser(
const MasmParser &) =
delete;
474 MasmParser &
operator=(
const MasmParser &) =
delete;
475 ~MasmParser()
override;
477 bool Run(
bool NoInitialTextSection,
bool NoFinalize =
false)
override;
480 ExtensionDirectiveHandler Handler)
override {
481 ExtensionDirectiveMap[
Directive] = Handler;
482 if (!DirectiveKindMap.contains(
Directive)) {
483 DirectiveKindMap[
Directive] = DK_HANDLER_DIRECTIVE;
488 DirectiveKindMap[
Directive] = DirectiveKindMap[Alias];
502 if (AssemblerDialect == ~0U)
505 return AssemblerDialect;
508 AssemblerDialect = i;
513 SMRange Range = std::nullopt)
override;
515 SMRange Range = std::nullopt)
override;
517 enum ExpandKind { ExpandMacros, DoNotExpandMacros };
522 ParsingMSInlineAsm =
V;
553 SMLoc &EndLoc)
override;
562 enum IdentifierPositionKind { StandardPosition, StartOfStatement };
575 const AsmToken peekTok(
bool ShouldSkipSpace =
true);
577 bool parseStatement(ParseStatementInfo &Info,
580 bool parseCppHashLineFilenameComment(
SMLoc L);
585 const std::vector<std::string> &Locals,
SMLoc L);
588 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
594 bool handleMacroEntry(
605 void handleMacroExit();
614 parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A,
617 void printMacroInstantiations();
619 bool expandStatement(
SMLoc Loc);
622 SMRange Range = std::nullopt)
const {
634 bool enabledGenDwarfForAssembly();
637 bool enterIncludeFile(
const std::string &Filename);
645 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0,
646 bool EndStatementAtEOF =
true);
660 bool parseTextItem(std::string &Data);
665 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
666 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
667 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
669 bool parseRegisterOrRegisterNumber(int64_t &
Register,
SMLoc DirectiveLoc);
672 bool parseCVFileId(int64_t &FileId,
StringRef DirectiveName);
677 DK_HANDLER_DIRECTIVE,
742 DK_CV_INLINE_SITE_ID,
745 DK_CV_INLINE_LINETABLE,
750 DK_CV_FILECHECKSUM_OFFSET,
756 DK_CFI_DEF_CFA_OFFSET,
757 DK_CFI_ADJUST_CFA_OFFSET,
758 DK_CFI_DEF_CFA_REGISTER,
763 DK_CFI_REMEMBER_STATE,
764 DK_CFI_RESTORE_STATE,
768 DK_CFI_RETURN_COLUMN,
806 bool isMacroLikeDirective();
809 enum CVDefRangeType {
811 CVDR_DEFRANGE_REGISTER,
812 CVDR_DEFRANGE_FRAMEPOINTER_REL,
813 CVDR_DEFRANGE_SUBFIELD_REGISTER,
814 CVDR_DEFRANGE_REGISTER_REL
847 const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol,
SMLoc StartLoc);
849 std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
853 bool parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated);
857 bool parseScalarInitializer(
unsigned Size,
859 unsigned StringPadLength = 0);
860 bool parseScalarInstList(
863 bool emitIntegralValues(
unsigned Size,
unsigned *Count =
nullptr);
866 bool parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
870 bool emitRealValues(
const fltSemantics &Semantics,
unsigned *Count =
nullptr);
874 bool parseRealInstList(
877 bool parseDirectiveNamedRealValue(
StringRef TypeName,
882 bool parseOptionalAngleBracketOpen();
883 bool parseAngleBracketClose(
const Twine &Msg =
"expected '>'");
885 bool parseFieldInitializer(
const FieldInfo &
Field,
886 FieldInitializer &Initializer);
887 bool parseFieldInitializer(
const FieldInfo &
Field,
888 const IntFieldInfo &Contents,
889 FieldInitializer &Initializer);
890 bool parseFieldInitializer(
const FieldInfo &
Field,
891 const RealFieldInfo &Contents,
892 FieldInitializer &Initializer);
893 bool parseFieldInitializer(
const FieldInfo &
Field,
894 const StructFieldInfo &Contents,
895 FieldInitializer &Initializer);
897 bool parseStructInitializer(
const StructInfo &Structure,
898 StructInitializer &Initializer);
899 bool parseStructInstList(
900 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
903 bool emitFieldValue(
const FieldInfo &
Field);
904 bool emitFieldValue(
const FieldInfo &
Field,
const IntFieldInfo &Contents);
905 bool emitFieldValue(
const FieldInfo &
Field,
const RealFieldInfo &Contents);
906 bool emitFieldValue(
const FieldInfo &
Field,
const StructFieldInfo &Contents);
908 bool emitFieldInitializer(
const FieldInfo &
Field,
909 const FieldInitializer &Initializer);
910 bool emitFieldInitializer(
const FieldInfo &
Field,
911 const IntFieldInfo &Contents,
912 const IntFieldInfo &Initializer);
913 bool emitFieldInitializer(
const FieldInfo &
Field,
914 const RealFieldInfo &Contents,
915 const RealFieldInfo &Initializer);
916 bool emitFieldInitializer(
const FieldInfo &
Field,
917 const StructFieldInfo &Contents,
918 const StructFieldInfo &Initializer);
920 bool emitStructInitializer(
const StructInfo &Structure,
921 const StructInitializer &Initializer);
924 bool emitStructValues(
const StructInfo &Structure,
unsigned *Count =
nullptr);
925 bool addStructField(
StringRef Name,
const StructInfo &Structure);
926 bool parseDirectiveStructValue(
const StructInfo &Structure,
928 bool parseDirectiveNamedStructValue(
const StructInfo &Structure,
934 DirectiveKind DirKind,
SMLoc NameLoc);
936 bool parseDirectiveOrg();
938 bool emitAlignTo(int64_t Alignment);
939 bool parseDirectiveAlign();
940 bool parseDirectiveEven();
943 bool parseDirectiveFile(
SMLoc DirectiveLoc);
944 bool parseDirectiveLine();
945 bool parseDirectiveLoc();
946 bool parseDirectiveStabs();
950 bool parseDirectiveCVFile();
951 bool parseDirectiveCVFuncId();
952 bool parseDirectiveCVInlineSiteId();
953 bool parseDirectiveCVLoc();
954 bool parseDirectiveCVLinetable();
955 bool parseDirectiveCVInlineLinetable();
956 bool parseDirectiveCVDefRange();
957 bool parseDirectiveCVString();
958 bool parseDirectiveCVStringTable();
959 bool parseDirectiveCVFileChecksums();
960 bool parseDirectiveCVFileChecksumOffset();
961 bool parseDirectiveCVFPOData();
964 bool parseDirectiveCFIRegister(
SMLoc DirectiveLoc);
965 bool parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc);
966 bool parseDirectiveCFISections();
967 bool parseDirectiveCFIStartProc();
968 bool parseDirectiveCFIEndProc();
969 bool parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc);
970 bool parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc);
971 bool parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc);
972 bool parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc);
973 bool parseDirectiveCFIOffset(
SMLoc DirectiveLoc);
974 bool parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc);
975 bool parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality);
976 bool parseDirectiveCFIRememberState(
SMLoc DirectiveLoc);
977 bool parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc);
978 bool parseDirectiveCFISameValue(
SMLoc DirectiveLoc);
979 bool parseDirectiveCFIRestore(
SMLoc DirectiveLoc);
980 bool parseDirectiveCFIEscape(
SMLoc DirectiveLoc);
981 bool parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc);
982 bool parseDirectiveCFISignalFrame();
983 bool parseDirectiveCFIUndefined(
SMLoc DirectiveLoc);
986 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
996 bool parseDirectiveNestedEnds();
998 bool parseDirectiveExtern();
1004 bool parseDirectiveComm(
bool IsLocal);
1006 bool parseDirectiveComment(
SMLoc DirectiveLoc);
1008 bool parseDirectiveInclude();
1011 bool parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
1013 bool parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1016 bool parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1017 bool CaseInsensitive);
1019 bool parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
1021 bool parseDirectiveElseIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
1023 bool parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1025 bool parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
1028 bool parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1029 bool CaseInsensitive);
1030 bool parseDirectiveElse(
SMLoc DirectiveLoc);
1031 bool parseDirectiveEndIf(
SMLoc DirectiveLoc);
1044 bool parseDirectiveWhile(
SMLoc DirectiveLoc);
1047 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
1051 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
1054 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
1057 bool parseDirectiveError(
SMLoc DirectiveLoc);
1059 bool parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1061 bool parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
bool ExpectDefined);
1064 bool parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1065 bool CaseInsensitive);
1067 bool parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero);
1070 bool parseDirectiveRadix(
SMLoc DirectiveLoc);
1073 bool parseDirectiveEcho(
SMLoc DirectiveLoc);
1075 void initializeDirectiveKindMap();
1076 void initializeCVDefRangeTypeMap();
1077 void initializeBuiltinSymbolMap();
1094 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI),
SrcMgr(SM),
1095 CurBuffer(CB ? CB : SM.getMainFileID()),
TM(
TM) {
1103 EndStatementAtEOFStack.push_back(
true);
1115 initializeDirectiveKindMap();
1116 PlatformParser->Initialize(*
this);
1117 initializeCVDefRangeTypeMap();
1118 initializeBuiltinSymbolMap();
1120 NumOfMacroInstantiations = 0;
1123MasmParser::~MasmParser() {
1124 assert((HadError || ActiveMacros.empty()) &&
1125 "Unexpected active macro instantiation!");
1132void MasmParser::printMacroInstantiations() {
1134 for (std::vector<MacroInstantiation *>::const_reverse_iterator
1135 it = ActiveMacros.rbegin(),
1136 ie = ActiveMacros.rend();
1139 "while in macro instantiation");
1143 printPendingErrors();
1145 printMacroInstantiations();
1149 if (getTargetParser().getTargetOptions().MCNoWarn)
1151 if (getTargetParser().getTargetOptions().MCFatalWarnings)
1152 return Error(L, Msg, Range);
1154 printMacroInstantiations();
1161 printMacroInstantiations();
1165bool MasmParser::enterIncludeFile(
const std::string &Filename) {
1166 std::string IncludedFile;
1174 EndStatementAtEOFStack.push_back(
true);
1178void MasmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer,
1179 bool EndStatementAtEOF) {
1185bool MasmParser::expandMacros() {
1195 if (handleMacroInvocation(M, MacroLoc)) {
1202 std::optional<std::string> ExpandedValue;
1203 auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1204 if (BuiltinIt != BuiltinSymbolMap.end()) {
1206 evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.
getLoc());
1208 auto VarIt = Variables.
find(IDLower);
1209 if (VarIt != Variables.
end() && VarIt->getValue().IsText) {
1210 ExpandedValue = VarIt->getValue().TextValue;
1216 std::unique_ptr<MemoryBuffer> Instantiation =
1224 EndStatementAtEOFStack.push_back(
false);
1229const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {
1236 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
1245 if (StartOfStatement) {
1280 if (ParentIncludeLoc !=
SMLoc()) {
1281 EndStatementAtEOFStack.pop_back();
1282 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1285 EndStatementAtEOFStack.pop_back();
1286 assert(EndStatementAtEOFStack.empty());
1292const AsmToken MasmParser::peekTok(
bool ShouldSkipSpace) {
1296 size_t ReadCount = Lexer.
peekTokens(Buf, ShouldSkipSpace);
1298 if (ReadCount == 0) {
1302 if (ParentIncludeLoc !=
SMLoc()) {
1303 EndStatementAtEOFStack.pop_back();
1304 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1305 return peekTok(ShouldSkipSpace);
1307 EndStatementAtEOFStack.pop_back();
1308 assert(EndStatementAtEOFStack.empty());
1315bool MasmParser::enabledGenDwarfForAssembly() {
1317 if (!getContext().getGenDwarfForAssembly())
1322 if (getContext().getGenDwarfFileNumber() == 0) {
1325 if (!FirstCppHashFilename.
empty())
1326 getContext().setMCLineTableRootFile(
1327 0, getContext().getCompilationDir(), FirstCppHashFilename,
1328 std::nullopt, std::nullopt);
1330 getContext().getMCDwarfLineTable(0).getRootFile();
1331 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
1332 0, getContext().getCompilationDir(), RootFile.
Name,
1338bool MasmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
1340 if (!NoInitialTextSection)
1347 AsmCond StartingCondState = TheCondState;
1354 if (getContext().getGenDwarfForAssembly()) {
1355 MCSection *Sec = getStreamer().getCurrentSectionOnly();
1357 MCSymbol *SectionStartSym = getContext().createTempSymbol();
1358 getStreamer().emitLabel(SectionStartSym);
1361 bool InsertResult = getContext().addGenDwarfSection(Sec);
1362 assert(InsertResult &&
".text section should not have debug info yet");
1366 getTargetParser().onBeginOfFile();
1375 ParseStatementInfo
Info(&AsmStrRewrites);
1376 bool Parsed = parseStatement(Info,
nullptr);
1386 printPendingErrors();
1389 if (Parsed && !getLexer().isAtStartOfStatement())
1390 eatToEndOfStatement();
1393 getTargetParser().onEndOfFile();
1394 printPendingErrors();
1397 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1399 getTargetParser().flushPendingInstructions(getStreamer());
1403 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1405 const auto &LineTables = getContext().getMCDwarfLineTables();
1406 if (!LineTables.empty()) {
1408 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1410 printError(getTok().getLoc(),
"unassigned file number: " +
1412 " for .file directives");
1428 if (
Sym->isTemporary() && !
Sym->isVariable() && !
Sym->isDefined())
1432 printError(getTok().getLoc(),
"assembler local symbol '" +
1433 Sym->getName() +
"' not defined");
1439 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1440 if (std::get<2>(LocSym)->isUndefined()) {
1443 CppHashInfo = std::get<1>(LocSym);
1444 printError(std::get<0>(LocSym),
"directional label undefined");
1451 if (!HadError && !NoFinalize)
1454 return HadError || getContext().hadError();
1457bool MasmParser::checkForValidSection() {
1458 if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1460 return Error(getTok().getLoc(),
1461 "expected section directive before assembly directive");
1467void MasmParser::eatToEndOfStatement() {
1471 if (ParentIncludeLoc ==
SMLoc()) {
1475 EndStatementAtEOFStack.pop_back();
1476 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1490 const char *Start = getTok().getLoc().getPointer();
1491 while (Lexer.
isNot(EndTok)) {
1494 if (ParentIncludeLoc ==
SMLoc()) {
1497 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1499 EndStatementAtEOFStack.pop_back();
1500 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1502 Start = getTok().getLoc().getPointer();
1507 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1515 Str.append(S.str());
1520StringRef MasmParser::parseStringToEndOfStatement() {
1521 const char *Start = getTok().getLoc().getPointer();
1526 const char *
End = getTok().getLoc().getPointer();
1535bool MasmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1536 if (parseExpression(Res))
1539 return parseRParen();
1547bool MasmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1548 if (parseExpression(Res))
1550 EndLoc = getTok().getEndLoc();
1551 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1564bool MasmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1566 SMLoc FirstTokenLoc = getLexer().getLoc();
1568 switch (FirstTokenKind) {
1570 return TokError(
"unknown token in expression");
1576 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1584 if (parseIdentifier(Identifier)) {
1595 EndLoc = FirstTokenLoc;
1598 return Error(FirstTokenLoc,
"invalid token in expression");
1603 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1614 return Error(FirstTokenLoc,
"Expected @@ label before @B reference");
1619 std::pair<StringRef, StringRef>
Split;
1625 parseIdentifier(VName);
1628 "unexpected token in variant, expected ')'"))
1630 Split = std::make_pair(Identifier, VName);
1638 return Error(getLexer().getLoc(),
"expected a symbol reference");
1643 if (!
Split.second.empty()) {
1651 "invalid variant '" +
Split.second +
"'");
1658 if (
Split.second.empty()) {
1661 if (lookUpField(SymbolName,
Split.second, Info)) {
1662 std::pair<StringRef, StringRef> BaseMember =
Split.second.split(
'.');
1664 lookUpField(
Base, Member, Info);
1672 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1675 auto BuiltinIt = BuiltinSymbolMap.find(
SymbolName.lower());
1676 const BuiltinSymbol
Symbol = (BuiltinIt == BuiltinSymbolMap.end())
1678 : BuiltinIt->getValue();
1679 if (Symbol != BI_NO_SYMBOL) {
1680 const MCExpr *
Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
1690 if (VarIt != Variables.
end())
1692 Sym = getContext().getOrCreateSymbol(SymbolName);
1697 if (
Sym->isVariable()) {
1698 auto V =
Sym->getVariableValue(
false);
1699 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1700 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1701 DoInline = TV->inlineAssignedExpr();
1704 return Error(EndLoc,
"unexpected modifier on variable reference");
1705 Res =
Sym->getVariableValue(
false);
1721 if (
Info.Type.Name.empty()) {
1723 if (TypeIt != KnownType.
end()) {
1724 Info.Type = TypeIt->second;
1728 *TypeInfo =
Info.Type;
1733 return TokError(
"literal value out of range for directive");
1735 int64_t
IntVal = getTok().getIntVal();
1743 SMLoc ValueLoc = getTok().getLoc();
1745 if (parseEscapedString(
Value))
1747 if (
Value.size() > 8)
1748 return Error(ValueLoc,
"literal value out of range");
1750 for (
const unsigned char CharVal :
Value)
1751 IntValue = (IntValue << 8) | CharVal;
1756 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1775 return parseParenExpr(Res, EndLoc);
1777 if (!PlatformParser->HasBracketExpressions())
1778 return TokError(
"brackets expression not supported on this target");
1780 return parseBracketExpr(Res, EndLoc);
1783 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1789 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1795 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1827 return TokError(
"expected '(' after operator");
1829 if (parseExpression(Res, EndLoc))
1833 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1838bool MasmParser::parseExpression(
const MCExpr *&Res) {
1840 return parseExpression(Res, EndLoc);
1851 "Argument to the function cannot be a NULL value");
1853 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1854 (*CharPtr !=
'\0')) {
1855 if (*CharPtr ==
'!')
1859 if (*CharPtr ==
'>') {
1869 for (
size_t Pos = 0; Pos < BracketContents.
size(); Pos++) {
1870 if (BracketContents[Pos] ==
'!')
1872 Res += BracketContents[Pos];
1887bool MasmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1890 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1891 parseBinOpRHS(1, Res, EndLoc))
1897 if (Res->evaluateAsAbsolute(
Value))
1903bool MasmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1905 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1908bool MasmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1910 if (parseParenExpr(Res, EndLoc))
1913 for (; ParenDepth > 0; --ParenDepth) {
1914 if (parseBinOpRHS(1, Res, EndLoc))
1919 if (ParenDepth - 1 > 0) {
1920 EndLoc = getTok().getEndLoc();
1928bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1932 if (parseExpression(Expr))
1935 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1936 return Error(StartLoc,
"expected absolute expression");
1943 bool ShouldUseLogicalShr,
1944 bool EndExpressionAtGreater) {
1972 if (EndExpressionAtGreater)
2013 if (EndExpressionAtGreater)
2024 AngleBracketDepth > 0);
2029bool MasmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
2051 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
2055 if (TokPrec < Precedence)
2062 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
2068 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
2069 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
2082bool MasmParser::parseStatement(ParseStatementInfo &Info,
2084 assert(!hasPendingError() &&
"parseStatement started with pending error");
2090 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
2091 getTok().getString().front() ==
'\n')
2100 SMLoc ExpansionLoc = getTok().getLoc();
2111 return parseCppHashLineFilenameComment(IDLoc);
2118 IDVal = getTok().getString();
2121 return Error(IDLoc,
"unexpected token at start of statement");
2122 }
else if (parseIdentifier(IDVal, StartOfStatement)) {
2123 if (!TheCondState.
Ignore) {
2125 return Error(IDLoc,
"unexpected token at start of statement");
2134 DirectiveKindMap.find(IDVal.
lower());
2135 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
2137 : DirKindIt->getValue();
2143 return parseDirectiveIf(IDLoc, DirKind);
2145 return parseDirectiveIfb(IDLoc,
true);
2147 return parseDirectiveIfb(IDLoc,
false);
2149 return parseDirectiveIfdef(IDLoc,
true);
2151 return parseDirectiveIfdef(IDLoc,
false);
2153 return parseDirectiveIfidn(IDLoc,
false,
2156 return parseDirectiveIfidn(IDLoc,
false,
2159 return parseDirectiveIfidn(IDLoc,
true,
2162 return parseDirectiveIfidn(IDLoc,
true,
2166 return parseDirectiveElseIf(IDLoc, DirKind);
2168 return parseDirectiveElseIfb(IDLoc,
true);
2170 return parseDirectiveElseIfb(IDLoc,
false);
2172 return parseDirectiveElseIfdef(IDLoc,
true);
2174 return parseDirectiveElseIfdef(IDLoc,
false);
2176 return parseDirectiveElseIfidn(IDLoc,
false,
2179 return parseDirectiveElseIfidn(IDLoc,
false,
2182 return parseDirectiveElseIfidn(IDLoc,
true,
2185 return parseDirectiveElseIfidn(IDLoc,
true,
2188 return parseDirectiveElse(IDLoc);
2190 return parseDirectiveEndIf(IDLoc);
2195 if (TheCondState.
Ignore) {
2196 eatToEndOfStatement();
2206 if (checkForValidSection())
2214 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
2222 if (ParsingMSInlineAsm && SI) {
2224 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
2226 "We should have an internal name here.");
2229 IDVal = RewrittenLabel;
2232 if (IDVal ==
"@@") {
2235 Sym = getContext().getOrCreateSymbol(IDVal);
2254 getTargetParser().doBeforeLabelEmit(
Sym, IDLoc);
2257 if (!getTargetParser().isParsingMSInlineAsm())
2262 if (enabledGenDwarfForAssembly())
2266 getTargetParser().onLabelParsed(
Sym);
2273 return handleMacroEntry(M, IDLoc);
2278 if (DirKind != DK_NO_DIRECTIVE) {
2290 getTargetParser().flushPendingInstructions(getStreamer());
2296 return parseDirectiveNestedEnds();
2301 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2304 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2310 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2312 "Should only return Failure iff there was an error");
2324 return parseDirectiveAscii(IDVal,
false);
2327 return parseDirectiveAscii(IDVal,
true);
2331 return parseDirectiveValue(IDVal, 1);
2335 return parseDirectiveValue(IDVal, 2);
2339 return parseDirectiveValue(IDVal, 4);
2342 return parseDirectiveValue(IDVal, 6);
2346 return parseDirectiveValue(IDVal, 8);
2348 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2350 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2352 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2355 return parseDirectiveNestedStruct(IDVal, DirKind);
2357 return parseDirectiveNestedEnds();
2359 return parseDirectiveAlign();
2361 return parseDirectiveEven();
2363 return parseDirectiveOrg();
2365 return parseDirectiveExtern();
2367 return parseDirectiveSymbolAttribute(
MCSA_Global);
2369 return parseDirectiveComm(
false);
2371 return parseDirectiveComment(IDLoc);
2373 return parseDirectiveInclude();
2375 return parseDirectiveRepeat(IDLoc, IDVal);
2377 return parseDirectiveWhile(IDLoc);
2379 return parseDirectiveFor(IDLoc, IDVal);
2381 return parseDirectiveForc(IDLoc, IDVal);
2383 return parseDirectiveFile(IDLoc);
2385 return parseDirectiveLine();
2387 return parseDirectiveLoc();
2389 return parseDirectiveStabs();
2391 return parseDirectiveCVFile();
2393 return parseDirectiveCVFuncId();
2394 case DK_CV_INLINE_SITE_ID:
2395 return parseDirectiveCVInlineSiteId();
2397 return parseDirectiveCVLoc();
2398 case DK_CV_LINETABLE:
2399 return parseDirectiveCVLinetable();
2400 case DK_CV_INLINE_LINETABLE:
2401 return parseDirectiveCVInlineLinetable();
2402 case DK_CV_DEF_RANGE:
2403 return parseDirectiveCVDefRange();
2405 return parseDirectiveCVString();
2406 case DK_CV_STRINGTABLE:
2407 return parseDirectiveCVStringTable();
2408 case DK_CV_FILECHECKSUMS:
2409 return parseDirectiveCVFileChecksums();
2410 case DK_CV_FILECHECKSUM_OFFSET:
2411 return parseDirectiveCVFileChecksumOffset();
2412 case DK_CV_FPO_DATA:
2413 return parseDirectiveCVFPOData();
2414 case DK_CFI_SECTIONS:
2415 return parseDirectiveCFISections();
2416 case DK_CFI_STARTPROC:
2417 return parseDirectiveCFIStartProc();
2418 case DK_CFI_ENDPROC:
2419 return parseDirectiveCFIEndProc();
2420 case DK_CFI_DEF_CFA:
2421 return parseDirectiveCFIDefCfa(IDLoc);
2422 case DK_CFI_DEF_CFA_OFFSET:
2423 return parseDirectiveCFIDefCfaOffset(IDLoc);
2424 case DK_CFI_ADJUST_CFA_OFFSET:
2425 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2426 case DK_CFI_DEF_CFA_REGISTER:
2427 return parseDirectiveCFIDefCfaRegister(IDLoc);
2429 return parseDirectiveCFIOffset(IDLoc);
2430 case DK_CFI_REL_OFFSET:
2431 return parseDirectiveCFIRelOffset(IDLoc);
2432 case DK_CFI_PERSONALITY:
2433 return parseDirectiveCFIPersonalityOrLsda(
true);
2435 return parseDirectiveCFIPersonalityOrLsda(
false);
2436 case DK_CFI_REMEMBER_STATE:
2437 return parseDirectiveCFIRememberState(IDLoc);
2438 case DK_CFI_RESTORE_STATE:
2439 return parseDirectiveCFIRestoreState(IDLoc);
2440 case DK_CFI_SAME_VALUE:
2441 return parseDirectiveCFISameValue(IDLoc);
2442 case DK_CFI_RESTORE:
2443 return parseDirectiveCFIRestore(IDLoc);
2445 return parseDirectiveCFIEscape(IDLoc);
2446 case DK_CFI_RETURN_COLUMN:
2447 return parseDirectiveCFIReturnColumn(IDLoc);
2448 case DK_CFI_SIGNAL_FRAME:
2449 return parseDirectiveCFISignalFrame();
2450 case DK_CFI_UNDEFINED:
2451 return parseDirectiveCFIUndefined(IDLoc);
2452 case DK_CFI_REGISTER:
2453 return parseDirectiveCFIRegister(IDLoc);
2454 case DK_CFI_WINDOW_SAVE:
2455 return parseDirectiveCFIWindowSave(IDLoc);
2457 Info.ExitValue =
"";
2458 return parseDirectiveExitMacro(IDLoc, IDVal, *
Info.ExitValue);
2460 Info.ExitValue =
"";
2461 return parseDirectiveEndMacro(IDVal);
2463 return parseDirectivePurgeMacro(IDLoc);
2465 return parseDirectiveEnd(IDLoc);
2467 return parseDirectiveError(IDLoc);
2469 return parseDirectiveErrorIfb(IDLoc,
true);
2471 return parseDirectiveErrorIfb(IDLoc,
false);
2473 return parseDirectiveErrorIfdef(IDLoc,
true);
2475 return parseDirectiveErrorIfdef(IDLoc,
false);
2477 return parseDirectiveErrorIfidn(IDLoc,
false,
2480 return parseDirectiveErrorIfidn(IDLoc,
false,
2483 return parseDirectiveErrorIfidn(IDLoc,
true,
2486 return parseDirectiveErrorIfidn(IDLoc,
true,
2489 return parseDirectiveErrorIfe(IDLoc,
true);
2491 return parseDirectiveErrorIfe(IDLoc,
false);
2493 return parseDirectiveRadix(IDLoc);
2495 return parseDirectiveEcho(IDLoc);
2498 return Error(IDLoc,
"unknown directive");
2502 auto IDIt = Structs.
find(IDVal.
lower());
2503 if (IDIt != Structs.
end())
2504 return parseDirectiveStructValue(IDIt->getValue(), IDVal,
2512 const AsmToken afterNextTok = peekTok();
2523 getTargetParser().flushPendingInstructions(getStreamer());
2529 return parseDirectiveEnds(IDVal, IDLoc);
2534 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2536 if (Handler.first) {
2539 return (*Handler.second)(Handler.first, nextVal, nextLoc);
2544 DirKindIt = DirectiveKindMap.find(nextVal.
lower());
2545 DirKind = (DirKindIt == DirectiveKindMap.end())
2547 : DirKindIt->getValue();
2555 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
2566 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2577 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2588 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2598 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2609 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2612 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2616 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2620 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2625 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2628 return parseDirectiveEnds(IDVal, IDLoc);
2631 return parseDirectiveMacro(IDVal, IDLoc);
2635 auto NextIt = Structs.
find(nextVal.
lower());
2636 if (NextIt != Structs.
end()) {
2638 return parseDirectiveNamedStructValue(NextIt->getValue(),
2639 nextVal, nextLoc, IDVal);
2643 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2644 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2645 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2648 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2649 return parseDirectiveMSAlign(IDLoc, Info);
2651 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2653 if (checkForValidSection())
2657 std::string OpcodeStr = IDVal.
lower();
2659 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
ID,
2660 Info.ParsedOperands);
2661 Info.ParseError = ParseHadError;
2664 if (getShowParsedOperands()) {
2667 OS <<
"parsed instruction: [";
2668 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2671 Info.ParsedOperands[i]->print(
OS);
2679 if (hasPendingError() || ParseHadError)
2684 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2685 getContext().getGenDwarfSectionSyms().
count(
2686 getStreamer().getCurrentSectionOnly())) {
2688 if (ActiveMacros.empty())
2692 ActiveMacros.front()->ExitBuffer);
2697 if (!CppHashInfo.Filename.empty()) {
2698 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2700 getContext().setGenDwarfFileNumber(FileNumber);
2702 unsigned CppHashLocLineNo =
2704 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2707 getStreamer().emitDwarfLocDirective(
2708 getContext().getGenDwarfFileNumber(), Line, 0,
2714 if (!ParseHadError) {
2716 if (getTargetParser().MatchAndEmitInstruction(
2718 getTargetParser().isParsingMSInlineAsm()))
2725bool MasmParser::parseCurlyBlockScope(
2744bool MasmParser::parseCppHashLineFilenameComment(
SMLoc L) {
2749 "Lexing Cpp line comment: Expected Integer");
2750 int64_t LineNumber = getTok().getIntVal();
2753 "Lexing Cpp line comment: Expected String");
2762 CppHashInfo.Loc =
L;
2764 CppHashInfo.LineNumber = LineNumber;
2765 CppHashInfo.Buf = CurBuffer;
2766 if (FirstCppHashFilename.
empty())
2773void MasmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2774 const MasmParser *Parser =
static_cast<const MasmParser *
>(
Context);
2780 unsigned CppHashBuf =
2781 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2786 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2795 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2796 DiagBuf != CppHashBuf) {
2797 if (Parser->SavedDiagHandler)
2798 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2807 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2810 int CppHashLocLineNo =
2811 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2813 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2819 if (Parser->SavedDiagHandler)
2820 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2822 NewDiag.print(
nullptr,
OS);
2828 return isAlnum(
C) ||
C ==
'_' ||
C ==
'$' ||
C ==
'@' ||
C ==
'?';
2834 const std::vector<std::string> &Locals,
SMLoc L) {
2836 if (NParameters !=
A.size())
2837 return Error(L,
"Wrong number of arguments");
2849 std::optional<char> CurrentQuote;
2850 while (!Body.
empty()) {
2852 std::size_t
End = Body.
size(), Pos = 0;
2853 std::size_t IdentifierPos =
End;
2854 for (; Pos !=
End; ++Pos) {
2857 if (Body[Pos] ==
'&')
2862 if (IdentifierPos ==
End)
2863 IdentifierPos = Pos;
2865 IdentifierPos =
End;
2869 if (!CurrentQuote) {
2870 if (Body[Pos] ==
'\'' || Body[Pos] ==
'"')
2871 CurrentQuote = Body[Pos];
2872 }
else if (Body[Pos] == CurrentQuote) {
2873 if (Pos + 1 !=
End && Body[Pos + 1] == CurrentQuote) {
2878 CurrentQuote.reset();
2882 if (IdentifierPos !=
End) {
2885 Pos = IdentifierPos;
2886 IdentifierPos =
End;
2897 bool InitialAmpersand = (Body[
I] ==
'&');
2898 if (InitialAmpersand) {
2905 const char *Begin = Body.
data() + Pos;
2907 const std::string ArgumentLower =
Argument.lower();
2911 if (Parameters[
Index].
Name.equals_insensitive(ArgumentLower))
2914 if (
Index == NParameters) {
2915 if (InitialAmpersand)
2917 auto it = LocalSymbols.
find(ArgumentLower);
2918 if (it != LocalSymbols.
end())
2934 OS << Token.getIntVal();
2936 OS << Token.getString();
2940 if (Pos <
End && Body[Pos] ==
'&') {
2983class AsmLexerSkipSpaceRAII {
2985 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2989 ~AsmLexerSkipSpaceRAII() {
3000 MCAsmMacroArgument &MA,
3003 if (Lexer.
isNot(EndTok)) {
3014 const char *StrChar = StrLoc.
getPointer() + 1;
3015 const char *EndChar = EndLoc.
getPointer() - 1;
3016 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3023 unsigned ParenLevel = 0;
3026 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
3033 return TokError(
"unexpected token");
3035 if (ParenLevel == 0) {
3049 MA.push_back(getTok());
3075 MA.push_back(getTok());
3079 if (ParenLevel != 0)
3080 return TokError(
"unbalanced parentheses in argument");
3082 if (MA.empty() && MP) {
3084 return TokError(
"missing value for required parameter '" + MP->
Name +
3094bool MasmParser::parseMacroArguments(
const MCAsmMacro *M,
3095 MCAsmMacroArguments &
A,
3097 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
3098 bool NamedParametersFound =
false;
3101 A.resize(NParameters);
3102 FALocs.
resize(NParameters);
3107 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
3113 if (parseIdentifier(FA.
Name))
3114 return Error(IDLoc,
"invalid argument identifier for formal argument");
3117 return TokError(
"expected '=' after formal parameter identifier");
3121 NamedParametersFound =
true;
3124 if (NamedParametersFound && FA.
Name.
empty())
3125 return Error(IDLoc,
"cannot mix positional and keyword arguments");
3127 unsigned PI = Parameter;
3129 assert(M &&
"expected macro to be defined");
3131 for (FAI = 0; FAI < NParameters; ++FAI)
3132 if (
M->Parameters[FAI].Name == FA.
Name)
3135 if (FAI >= NParameters) {
3136 return Error(IDLoc,
"parameter named '" + FA.
Name +
3137 "' does not exist for macro '" +
M->Name +
"'");
3142 if (M && PI < NParameters)
3143 MP = &
M->Parameters[PI];
3148 const MCExpr *AbsoluteExp;
3152 if (parseExpression(AbsoluteExp, EndLoc))
3154 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
3155 getStreamer().getAssemblerPtr()))
3156 return Error(StrLoc,
"expected absolute expression");
3161 FA.
Value.push_back(newToken);
3162 }
else if (parseMacroArgument(MP, FA.
Value, EndTok)) {
3164 return addErrorSuffix(
" in '" +
M->Name +
"' macro");
3169 if (!FA.
Value.empty()) {
3174 if (FALocs.
size() <= PI)
3177 FALocs[PI] = Lexer.
getLoc();
3183 if (Lexer.
is(EndTok)) {
3185 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
3186 if (
A[FAI].empty()) {
3187 if (
M->Parameters[FAI].Required) {
3189 "missing value for required parameter "
3191 M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
3195 if (!
M->Parameters[FAI].Value.empty())
3196 A[FAI] =
M->Parameters[FAI].Value;
3206 return TokError(
"too many positional arguments");
3214 if (ActiveMacros.size() == MaxNestingDepth) {
3215 std::ostringstream MaxNestingDepthError;
3216 MaxNestingDepthError <<
"macros cannot be nested more than "
3217 << MaxNestingDepth <<
" levels deep."
3218 <<
" Use -asm-macro-max-nesting-depth to increase "
3220 return TokError(MaxNestingDepthError.str());
3223 MCAsmMacroArguments
A;
3224 if (parseMacroArguments(M,
A, ArgumentEndTok))
3233 if (expandMacro(
OS, Body,
M->Parameters,
A,
M->Locals, getTok().getLoc()))
3240 std::unique_ptr<MemoryBuffer> Instantiation =
3245 MacroInstantiation *
MI =
new MacroInstantiation{
3246 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
3247 ActiveMacros.push_back(
MI);
3249 ++NumOfMacroInstantiations;
3254 EndStatementAtEOFStack.push_back(
true);
3260void MasmParser::handleMacroExit() {
3262 EndStatementAtEOFStack.pop_back();
3263 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
3264 EndStatementAtEOFStack.back());
3268 delete ActiveMacros.back();
3269 ActiveMacros.pop_back();
3272bool MasmParser::handleMacroInvocation(
const MCAsmMacro *M,
SMLoc NameLoc) {
3274 return Error(NameLoc,
"cannot invoke macro procedure as function");
3277 "' requires arguments in parentheses") ||
3282 std::string ExitValue;
3285 ParseStatementInfo
Info(&AsmStrRewrites);
3286 bool Parsed = parseStatement(Info,
nullptr);
3288 if (!Parsed &&
Info.ExitValue) {
3289 ExitValue = std::move(*
Info.ExitValue);
3301 printPendingErrors();
3304 if (Parsed && !getLexer().isAtStartOfStatement())
3305 eatToEndOfStatement();
3314 std::unique_ptr<MemoryBuffer> MacroValue =
3322 EndStatementAtEOFStack.push_back(
false);
3331bool MasmParser::parseIdentifier(
StringRef &Res,
3332 IdentifierPositionKind Position) {
3339 SMLoc PrefixLoc = getLexer().getLoc();
3364 Res = getTok().getIdentifier();
3368 ExpandKind ExpandNextToken = ExpandMacros;
3369 if (Position == StartOfStatement &&
3371 .CaseLower(
"echo",
true)
3372 .CasesLower(
"ifdef",
"ifndef",
"elseifdef",
"elseifndef",
true)
3374 ExpandNextToken = DoNotExpandMacros;
3376 Lex(ExpandNextToken);
3387 DirectiveKind DirKind,
SMLoc NameLoc) {
3388 auto BuiltinIt = BuiltinSymbolMap.find(
Name.lower());
3389 if (BuiltinIt != BuiltinSymbolMap.end())
3390 return Error(NameLoc,
"cannot redefine a built-in symbol");
3392 Variable &Var = Variables[
Name.lower()];
3393 if (Var.Name.empty()) {
3398 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3401 std::string TextItem;
3402 if (!parseTextItem(TextItem)) {
3406 auto parseItem = [&]() ->
bool {
3407 if (parseTextItem(TextItem))
3408 return TokError(
"expected text item");
3413 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3415 if (!Var.IsText || Var.TextValue !=
Value) {
3416 switch (Var.Redefinable) {
3417 case Variable::NOT_REDEFINABLE:
3418 return Error(getTok().getLoc(),
"invalid variable redefinition");
3419 case Variable::WARN_ON_REDEFINITION:
3421 "', already defined on the command line")) {
3430 Var.TextValue =
Value;
3431 Var.Redefinable = Variable::REDEFINABLE;
3436 if (DirKind == DK_TEXTEQU)
3437 return TokError(
"expected <text> in '" +
Twine(IDVal) +
"' directive");
3442 if (parseExpression(Expr, EndLoc))
3443 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3448 if (!Expr->evaluateAsAbsolute(
Value, getStreamer().getAssemblerPtr())) {
3449 if (DirKind == DK_ASSIGN)
3452 "expected absolute expression; not all symbols have known values",
3453 {StartLoc, EndLoc});
3456 if (!Var.IsText || Var.TextValue != ExprAsString) {
3457 switch (Var.Redefinable) {
3458 case Variable::NOT_REDEFINABLE:
3459 return Error(getTok().getLoc(),
"invalid variable redefinition");
3460 case Variable::WARN_ON_REDEFINITION:
3462 "', already defined on the command line")) {
3472 Var.TextValue = ExprAsString.
str();
3473 Var.Redefinable = Variable::REDEFINABLE;
3478 MCSymbol *
Sym = getContext().getOrCreateSymbol(Var.Name);
3481 Sym->isVariable() ? dyn_cast_or_null<MCConstantExpr>(
3482 Sym->getVariableValue(
false))
3484 if (Var.IsText || !PrevValue || PrevValue->
getValue() !=
Value) {
3485 switch (Var.Redefinable) {
3486 case Variable::NOT_REDEFINABLE:
3487 return Error(getTok().getLoc(),
"invalid variable redefinition");
3488 case Variable::WARN_ON_REDEFINITION:
3490 "', already defined on the command line")) {
3500 Var.TextValue.clear();
3501 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
3502 : Variable::NOT_REDEFINABLE;
3504 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
3505 Sym->setVariableValue(Expr);
3506 Sym->setExternal(
false);
3511bool MasmParser::parseEscapedString(std::string &Data) {
3516 char Quote = getTok().getString().front();
3517 StringRef Str = getTok().getStringContents();
3518 Data.reserve(Str.size());
3519 for (
size_t i = 0, e = Str.size(); i != e; ++i) {
3520 Data.push_back(Str[i]);
3521 if (Str[i] == Quote) {
3525 if (i + 1 == Str.size())
3526 return Error(getTok().getLoc(),
"missing quotation mark in string");
3527 if (Str[i + 1] == Quote)
3536bool MasmParser::parseAngleBracketString(std::string &Data) {
3537 SMLoc EndLoc, StartLoc = getTok().getLoc();
3539 const char *StartChar = StartLoc.
getPointer() + 1;
3540 const char *EndChar = EndLoc.
getPointer() - 1;
3541 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3552bool MasmParser::parseTextItem(std::string &Data) {
3553 switch (getTok().getKind()) {
3560 Data = std::to_string(Res);
3567 return parseAngleBracketString(Data);
3571 SMLoc StartLoc = getTok().getLoc();
3572 if (parseIdentifier(
ID))
3576 bool Expanded =
false;
3579 auto BuiltinIt = BuiltinSymbolMap.find(
ID.lower());
3580 if (BuiltinIt != BuiltinSymbolMap.end()) {
3581 std::optional<std::string> BuiltinText =
3582 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
3587 Data = std::move(*BuiltinText);
3594 auto VarIt = Variables.
find(
ID.lower());
3595 if (VarIt != Variables.
end()) {
3596 const Variable &Var = VarIt->getValue();
3601 Data = Var.TextValue;
3624bool MasmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3625 auto parseOp = [&]() ->
bool {
3627 if (checkForValidSection() || parseEscapedString(Data))
3629 getStreamer().emitBytes(Data);
3631 getStreamer().emitBytes(
StringRef(
"\0", 1));
3635 if (parseMany(parseOp))
3636 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3644 int64_t IntValue = MCE->getValue();
3646 return Error(MCE->getLoc(),
"out of range literal value");
3647 getStreamer().emitIntValue(IntValue,
Size);
3652 getStreamer().emitIntValue(0,
Size);
3660bool MasmParser::parseScalarInitializer(
unsigned Size,
3662 unsigned StringPadLength) {
3665 if (parseEscapedString(
Value))
3668 for (
const unsigned char CharVal :
Value)
3672 for (
size_t i =
Value.size(); i < StringPadLength; ++i)
3676 if (parseExpression(
Value))
3679 getTok().getString().equals_insensitive(
"dup")) {
3684 "cannot repeat value a non-constant number of times");
3685 const int64_t Repetitions = MCE->
getValue();
3686 if (Repetitions < 0)
3688 "cannot repeat value a negative number of times");
3692 "parentheses required for 'dup' contents") ||
3693 parseScalarInstList(
Size, DuplicatedValues) || parseRParen())
3696 for (
int i = 0; i < Repetitions; ++i)
3705bool MasmParser::parseScalarInstList(
unsigned Size,
3708 while (getTok().
isNot(EndToken) &&
3711 parseScalarInitializer(
Size, Values);
3721bool MasmParser::emitIntegralValues(
unsigned Size,
unsigned *Count) {
3723 if (checkForValidSection() || parseScalarInstList(
Size, Values))
3726 for (
const auto *
Value : Values) {
3730 *Count = Values.size();
3736 StructInfo &
Struct = StructInProgress.
back();
3738 IntFieldInfo &IntInfo =
Field.Contents.IntInfo;
3742 if (parseScalarInstList(
Size, IntInfo.Values))
3745 Field.SizeOf =
Field.Type * IntInfo.Values.size();
3746 Field.LengthOf = IntInfo.Values.size();
3749 Struct.NextOffset = FieldEnd;
3757bool MasmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3758 if (StructInProgress.
empty()) {
3760 if (emitIntegralValues(
Size))
3761 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3762 }
else if (addIntegralField(
"",
Size)) {
3763 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3771bool MasmParser::parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
3773 if (StructInProgress.
empty()) {
3776 getStreamer().emitLabel(
Sym);
3778 if (emitIntegralValues(
Size, &Count))
3779 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3785 Type.Length = Count;
3787 }
else if (addIntegralField(
Name,
Size)) {
3788 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3797 return Asm.TokError(
"unknown token in expression");
3798 SMLoc ExprLoc = Asm.getTok().getLoc();
3799 APInt IntValue = Asm.getTok().getAPIntVal();
3801 if (!IntValue.
isIntN(128))
3802 return Asm.Error(ExprLoc,
"out of range literal value");
3803 if (!IntValue.
isIntN(64)) {
3819 SignLoc = getLexer().getLoc();
3823 SignLoc = getLexer().getLoc();
3828 return TokError(Lexer.
getErr());
3831 return TokError(
"unexpected token in directive");
3844 return TokError(
"invalid floating point literal");
3848 unsigned SizeInBits =
Value.getSizeInBits(Semantics);
3849 if (SizeInBits != (IDVal.
size() << 2))
3850 return TokError(
"invalid floating point literal");
3855 Res =
APInt(SizeInBits, IDVal, 16);
3857 return Warning(SignLoc,
"MASM-style hex floats ignore explicit sign");
3860 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3862 return TokError(
"invalid floating point literal");
3870 Res =
Value.bitcastToAPInt();
3875bool MasmParser::parseRealInstList(
const fltSemantics &Semantics,
3878 while (getTok().
isNot(EndToken) ||
3881 const AsmToken NextTok = peekTok();
3890 "cannot repeat value a non-constant number of times");
3891 const int64_t Repetitions = MCE->
getValue();
3892 if (Repetitions < 0)
3894 "cannot repeat value a negative number of times");
3898 "parentheses required for 'dup' contents") ||
3899 parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
3902 for (
int i = 0; i < Repetitions; ++i)
3903 ValuesAsInt.
append(DuplicatedValues.
begin(), DuplicatedValues.
end());
3906 if (parseRealValue(Semantics, AsInt))
3921bool MasmParser::emitRealValues(
const fltSemantics &Semantics,
3923 if (checkForValidSection())
3927 if (parseRealInstList(Semantics, ValuesAsInt))
3930 for (
const APInt &AsInt : ValuesAsInt) {
3931 getStreamer().emitIntValue(AsInt);
3934 *Count = ValuesAsInt.size();
3941 StructInfo &
Struct = StructInProgress.
back();
3943 RealFieldInfo &RealInfo =
Field.Contents.RealInfo;
3947 if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3950 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3951 Field.LengthOf = RealInfo.AsIntValues.size();
3956 Struct.NextOffset = FieldEnd;
3964bool MasmParser::parseDirectiveRealValue(
StringRef IDVal,
3967 if (StructInProgress.
empty()) {
3969 if (emitRealValues(Semantics))
3970 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3971 }
else if (addRealField(
"", Semantics,
Size)) {
3972 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3979bool MasmParser::parseDirectiveNamedRealValue(
StringRef TypeName,
3983 if (StructInProgress.
empty()) {
3986 getStreamer().emitLabel(
Sym);
3988 if (emitRealValues(Semantics, &Count))
3989 return addErrorSuffix(
" in '" + TypeName +
"' directive");
3995 Type.Length = Count;
3997 }
else if (addRealField(
Name, Semantics,
Size)) {
3998 return addErrorSuffix(
" in '" + TypeName +
"' directive");
4003bool MasmParser::parseOptionalAngleBracketOpen() {
4006 AngleBracketDepth++;
4010 AngleBracketDepth++;
4014 AngleBracketDepth++;
4021bool MasmParser::parseAngleBracketClose(
const Twine &Msg) {
4028 AngleBracketDepth--;
4032bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4033 const IntFieldInfo &Contents,
4034 FieldInitializer &Initializer) {
4035 SMLoc Loc = getTok().getLoc();
4040 return Error(Loc,
"Cannot initialize scalar field with array value");
4044 }
else if (parseOptionalAngleBracketOpen()) {
4046 return Error(Loc,
"Cannot initialize scalar field with array value");
4048 parseAngleBracketClose())
4050 }
else if (
Field.LengthOf > 1 &&
Field.Type > 1) {
4051 return Error(Loc,
"Cannot initialize array field with scalar value");
4052 }
else if (parseScalarInitializer(
Field.Type, Values,
4058 return Error(Loc,
"Initializer too long for field; expected at most " +
4059 std::to_string(
Field.LengthOf) +
" elements, got " +
4060 std::to_string(Values.
size()));
4063 Values.
append(Contents.Values.begin() + Values.
size(), Contents.Values.end());
4065 Initializer = FieldInitializer(std::move(Values));
4069bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4070 const RealFieldInfo &Contents,
4071 FieldInitializer &Initializer) {
4073 switch (
Field.Type) {
4075 Semantics = &APFloat::IEEEsingle();
4078 Semantics = &APFloat::IEEEdouble();
4081 Semantics = &APFloat::x87DoubleExtended();
4087 SMLoc Loc = getTok().getLoc();
4091 if (
Field.LengthOf == 1)
4092 return Error(Loc,
"Cannot initialize scalar field with array value");
4096 }
else if (parseOptionalAngleBracketOpen()) {
4097 if (
Field.LengthOf == 1)
4098 return Error(Loc,
"Cannot initialize scalar field with array value");
4100 parseAngleBracketClose())
4102 }
else if (
Field.LengthOf > 1) {
4103 return Error(Loc,
"Cannot initialize array field with scalar value");
4106 if (parseRealValue(*Semantics, AsIntValues.
back()))
4110 if (AsIntValues.
size() >
Field.LengthOf) {
4111 return Error(Loc,
"Initializer too long for field; expected at most " +
4112 std::to_string(
Field.LengthOf) +
" elements, got " +
4113 std::to_string(AsIntValues.
size()));
4116 AsIntValues.
append(Contents.AsIntValues.begin() + AsIntValues.
size(),
4117 Contents.AsIntValues.end());
4119 Initializer = FieldInitializer(std::move(AsIntValues));
4123bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4124 const StructFieldInfo &Contents,
4125 FieldInitializer &Initializer) {
4126 SMLoc Loc = getTok().getLoc();
4128 std::vector<StructInitializer> Initializers;
4129 if (
Field.LengthOf > 1) {
4131 if (parseStructInstList(Contents.Structure, Initializers,
4135 }
else if (parseOptionalAngleBracketOpen()) {
4136 if (parseStructInstList(Contents.Structure, Initializers,
4138 parseAngleBracketClose())
4141 return Error(Loc,
"Cannot initialize array field with scalar value");
4144 Initializers.emplace_back();
4145 if (parseStructInitializer(Contents.Structure, Initializers.back()))
4149 if (Initializers.size() >
Field.LengthOf) {
4150 return Error(Loc,
"Initializer too long for field; expected at most " +
4151 std::to_string(
Field.LengthOf) +
" elements, got " +
4152 std::to_string(Initializers.size()));
4155 Initializers.insert(Initializers.end(),
4156 Contents.Initializers.begin() + Initializers.size(),
4157 Contents.Initializers.end());
4159 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
4163bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4164 FieldInitializer &Initializer) {
4165 switch (
Field.Contents.FT) {
4167 return parseFieldInitializer(
Field,
Field.Contents.IntInfo, Initializer);
4169 return parseFieldInitializer(
Field,
Field.Contents.RealInfo, Initializer);
4171 return parseFieldInitializer(
Field,
Field.Contents.StructInfo, Initializer);
4176bool MasmParser::parseStructInitializer(
const StructInfo &Structure,
4177 StructInitializer &Initializer) {
4178 const AsmToken FirstToken = getTok();
4180 std::optional<AsmToken::TokenKind> EndToken;
4183 }
else if (parseOptionalAngleBracketOpen()) {
4185 AngleBracketDepth++;
4192 return Error(FirstToken.
getLoc(),
"Expected struct initializer");
4195 auto &FieldInitializers = Initializer.FieldInitializers;
4196 size_t FieldIndex = 0;
4199 while (getTok().
isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
4200 const FieldInfo &
Field = Structure.Fields[FieldIndex++];
4204 FieldInitializers.push_back(
Field.Contents);
4208 FieldInitializers.emplace_back(
Field.Contents.FT);
4209 if (parseFieldInitializer(
Field, FieldInitializers.back()))
4213 SMLoc CommaLoc = getTok().getLoc();
4216 if (FieldIndex == Structure.Fields.size())
4217 return Error(CommaLoc,
"'" + Structure.Name +
4218 "' initializer initializes too many fields");
4224 FieldInitializers.push_back(
Field.Contents);
4228 return parseAngleBracketClose();
4230 return parseToken(*EndToken);
4236bool MasmParser::parseStructInstList(
4237 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
4239 while (getTok().
isNot(EndToken) ||
4242 const AsmToken NextTok = peekTok();
4251 "cannot repeat value a non-constant number of times");
4252 const int64_t Repetitions = MCE->
getValue();
4253 if (Repetitions < 0)
4255 "cannot repeat value a negative number of times");
4257 std::vector<StructInitializer> DuplicatedValues;
4259 "parentheses required for 'dup' contents") ||
4260 parseStructInstList(Structure, DuplicatedValues) || parseRParen())
4263 for (
int i = 0; i < Repetitions; ++i)
4266 Initializers.emplace_back();
4267 if (parseStructInitializer(Structure, Initializers.back()))
4280bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4281 const IntFieldInfo &Contents) {
4290bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4291 const RealFieldInfo &Contents) {
4292 for (
const APInt &AsInt : Contents.AsIntValues) {
4299bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4300 const StructFieldInfo &Contents) {
4301 for (
const auto &Initializer : Contents.Initializers) {
4303 for (
const auto &SubField : Contents.Structure.Fields) {
4304 getStreamer().emitZeros(SubField.Offset -
Offset);
4305 Offset = SubField.Offset + SubField.SizeOf;
4306 emitFieldInitializer(SubField, Initializer.FieldInitializers[
Index++]);
4312bool MasmParser::emitFieldValue(
const FieldInfo &
Field) {
4313 switch (
Field.Contents.FT) {
4315 return emitFieldValue(
Field,
Field.Contents.IntInfo);
4317 return emitFieldValue(
Field,
Field.Contents.RealInfo);
4319 return emitFieldValue(
Field,
Field.Contents.StructInfo);
4324bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4325 const IntFieldInfo &Contents,
4326 const IntFieldInfo &Initializer) {
4327 for (
const auto &
Value : Initializer.Values) {
4332 for (
const auto &
Value :
4340bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4341 const RealFieldInfo &Contents,
4342 const RealFieldInfo &Initializer) {
4343 for (
const auto &AsInt : Initializer.AsIntValues) {
4348 for (
const auto &AsInt :
4356bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4357 const StructFieldInfo &Contents,
4358 const StructFieldInfo &Initializer) {
4359 for (
const auto &
Init : Initializer.Initializers) {
4360 if (emitStructInitializer(Contents.Structure,
Init))
4365 Initializer.Initializers.size())) {
4366 if (emitStructInitializer(Contents.Structure,
Init))
4372bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4373 const FieldInitializer &Initializer) {
4374 switch (
Field.Contents.FT) {
4376 return emitFieldInitializer(
Field,
Field.Contents.IntInfo,
4377 Initializer.IntInfo);
4379 return emitFieldInitializer(
Field,
Field.Contents.RealInfo,
4380 Initializer.RealInfo);
4382 return emitFieldInitializer(
Field,
Field.Contents.StructInfo,
4383 Initializer.StructInfo);
4388bool MasmParser::emitStructInitializer(
const StructInfo &Structure,
4389 const StructInitializer &Initializer) {
4390 if (!Structure.Initializable)
4391 return Error(getLexer().getLoc(),
4392 "cannot initialize a value of type '" + Structure.Name +
4393 "'; 'org' was used in the type's declaration");
4395 for (
const auto &
Init : Initializer.FieldInitializers) {
4396 const auto &
Field = Structure.Fields[
Index++];
4404 Structure.Fields, Initializer.FieldInitializers.size())) {
4407 if (emitFieldValue(
Field))
4411 if (
Offset != Structure.Size)
4412 getStreamer().emitZeros(Structure.Size -
Offset);
4417bool MasmParser::emitStructValues(
const StructInfo &Structure,
4419 std::vector<StructInitializer> Initializers;
4420 if (parseStructInstList(Structure, Initializers))
4423 for (
const auto &Initializer : Initializers) {
4424 if (emitStructInitializer(Structure, Initializer))
4429 *Count = Initializers.size();
4434bool MasmParser::addStructField(
StringRef Name,
const StructInfo &Structure) {
4435 StructInfo &OwningStruct = StructInProgress.
back();
4437 OwningStruct.addField(
Name, FT_STRUCT, Structure.AlignmentSize);
4438 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4440 StructInfo.Structure = Structure;
4443 if (parseStructInstList(Structure, StructInfo.Initializers))
4446 Field.LengthOf = StructInfo.Initializers.size();
4450 if (!OwningStruct.IsUnion) {
4451 OwningStruct.NextOffset = FieldEnd;
4453 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
4461bool MasmParser::parseDirectiveStructValue(
const StructInfo &Structure,
4463 if (StructInProgress.
empty()) {
4464 if (emitStructValues(Structure))
4466 }
else if (addStructField(
"", Structure)) {
4467 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4475bool MasmParser::parseDirectiveNamedStructValue(
const StructInfo &Structure,
4478 if (StructInProgress.
empty()) {
4481 getStreamer().emitLabel(
Sym);
4483 if (emitStructValues(Structure, &Count))
4486 Type.Name = Structure.Name;
4487 Type.Size = Structure.Size * Count;
4488 Type.ElementSize = Structure.Size;
4489 Type.Length = Count;
4491 }
else if (addStructField(
Name, Structure)) {
4492 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4510 int64_t AlignmentValue = 1;
4513 parseAbsoluteExpression(AlignmentValue)) {
4514 return addErrorSuffix(
" in alignment value for '" +
Twine(
Directive) +
4518 return Error(NextTok.
getLoc(),
"alignment must be a power of two; was " +
4519 std::to_string(AlignmentValue));
4525 QualifierLoc = getTok().getLoc();
4526 if (parseIdentifier(Qualifier))
4527 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4528 if (!
Qualifier.equals_insensitive(
"nonunique"))
4529 return Error(QualifierLoc,
"Unrecognized qualifier for '" +
4531 "' directive; expected none or NONUNIQUE");
4535 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4546 DirectiveKind DirKind) {
4547 if (StructInProgress.
empty())
4548 return TokError(
"missing name in top-level '" +
Twine(
Directive) +
4553 Name = getTok().getIdentifier();
4557 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4561 StructInProgress.
reserve(StructInProgress.
size() + 1);
4563 StructInProgress.
back().Alignment);
4568 if (StructInProgress.
empty())
4569 return Error(NameLoc,
"ENDS directive without matching STRUC/STRUCT/UNION");
4570 if (StructInProgress.
size() > 1)
4571 return Error(NameLoc,
"unexpected name in nested ENDS directive");
4572 if (StructInProgress.
back().Name.compare_insensitive(
Name))
4573 return Error(NameLoc,
"mismatched name in ENDS directive; expected '" +
4574 StructInProgress.
back().Name +
"'");
4575 StructInfo Structure = StructInProgress.
pop_back_val();
4579 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4580 Structs[
Name.lower()] = Structure;
4583 return addErrorSuffix(
" in ENDS directive");
4588bool MasmParser::parseDirectiveNestedEnds() {
4589 if (StructInProgress.
empty())
4590 return TokError(
"ENDS directive without matching STRUC/STRUCT/UNION");
4591 if (StructInProgress.
size() == 1)
4592 return TokError(
"missing name in top-level ENDS directive");
4595 return addErrorSuffix(
" in nested ENDS directive");
4597 StructInfo Structure = StructInProgress.
pop_back_val();
4599 Structure.Size =
llvm::alignTo(Structure.Size, Structure.Alignment);
4601 StructInfo &ParentStruct = StructInProgress.
back();
4602 if (Structure.Name.empty()) {
4605 const size_t OldFields = ParentStruct.Fields.size();
4606 ParentStruct.Fields.insert(
4607 ParentStruct.Fields.end(),
4608 std::make_move_iterator(Structure.Fields.begin()),
4609 std::make_move_iterator(Structure.Fields.end()));
4610 for (
const auto &FieldByName : Structure.FieldsByName) {
4611 ParentStruct.FieldsByName[FieldByName.getKey()] =
4612 FieldByName.getValue() + OldFields;
4615 unsigned FirstFieldOffset = 0;
4616 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
4618 ParentStruct.NextOffset,
4619 std::min(ParentStruct.Alignment, Structure.AlignmentSize));
4622 if (ParentStruct.IsUnion) {
4623 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4628 const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
4629 if (!ParentStruct.IsUnion) {
4630 ParentStruct.NextOffset = StructureEnd;
4632 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4635 FieldInfo &
Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4636 Structure.AlignmentSize);
4637 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4643 if (!ParentStruct.IsUnion) {
4644 ParentStruct.NextOffset = StructureEnd;
4646 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4648 StructInfo.Structure = Structure;
4649 StructInfo.Initializers.emplace_back();
4650 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4651 for (
const auto &SubField : Structure.Fields) {
4652 FieldInitializers.push_back(SubField.Contents);
4661bool MasmParser::parseDirectiveOrg() {
4664 if (checkForValidSection() || parseExpression(
Offset))
4667 return addErrorSuffix(
" in 'org' directive");
4669 if (StructInProgress.
empty()) {
4671 if (checkForValidSection())
4672 return addErrorSuffix(
" in 'org' directive");
4674 getStreamer().emitValueToOffset(
Offset, 0, OffsetLoc);
4677 StructInfo &Structure = StructInProgress.
back();
4679 if (!
Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
4680 return Error(OffsetLoc,
4681 "expected absolute expression in 'org' directive");
4685 "expected non-negative value in struct's 'org' directive; was " +
4686 std::to_string(OffsetRes));
4687 Structure.NextOffset =
static_cast<unsigned>(OffsetRes);
4690 Structure.Initializable =
false;
4696bool MasmParser::emitAlignTo(int64_t Alignment) {
4697 if (StructInProgress.
empty()) {
4699 if (checkForValidSection())
4705 assert(Section &&
"must have section to emit alignment");
4706 if (
Section->useCodeAlign()) {
4707 getStreamer().emitCodeAlignment(
Align(Alignment),
4708 &getTargetParser().getSTI(),
4712 getStreamer().emitValueToAlignment(
Align(Alignment), 0,
4718 StructInfo &Structure = StructInProgress.
back();
4719 Structure.NextOffset =
llvm::alignTo(Structure.NextOffset, Alignment);
4727bool MasmParser::parseDirectiveAlign() {
4728 SMLoc AlignmentLoc = getLexer().getLoc();
4734 "align directive with no operand is ignored") &&
4737 if (parseAbsoluteExpression(Alignment) || parseEOL())
4738 return addErrorSuffix(
" in align directive");
4741 bool ReturnVal =
false;
4748 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2; was " +
4749 std::to_string(Alignment));
4751 if (emitAlignTo(Alignment))
4752 ReturnVal |= addErrorSuffix(
" in align directive");
4759bool MasmParser::parseDirectiveEven() {
4760 if (parseEOL() || emitAlignTo(2))
4761 return addErrorSuffix(
" in even directive");
4769bool MasmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
4771 int64_t FileNumber = -1;
4773 FileNumber = getTok().getIntVal();
4777 return TokError(
"negative file number");
4785 "unexpected token in '.file' directive") ||
4786 parseEscapedString(Path))
4791 std::string FilenameData;
4793 if (
check(FileNumber == -1,
4794 "explicit path specified, but no file number") ||
4795 parseEscapedString(FilenameData))
4804 bool HasMD5 =
false;
4806 std::optional<StringRef>
Source;
4807 bool HasSource =
false;
4808 std::string SourceString;
4813 "unexpected token in '.file' directive") ||
4814 parseIdentifier(Keyword))
4816 if (Keyword ==
"md5") {
4818 if (
check(FileNumber == -1,
4819 "MD5 checksum specified, but no file number") ||
4822 }
else if (Keyword ==
"source") {
4824 if (
check(FileNumber == -1,
4825 "source specified, but no file number") ||
4827 "unexpected token in '.file' directive") ||
4828 parseEscapedString(SourceString))
4831 return TokError(
"unexpected token in '.file' directive");
4835 if (FileNumber == -1) {
4839 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4840 getStreamer().emitFileDirective(Filename);
4850 std::optional<MD5::MD5Result> CKMem;
4853 for (
unsigned i = 0; i != 8; ++i) {
4854 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4855 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4860 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
4861 memcpy(SourceBuf, SourceString.data(), SourceString.size());
4864 if (FileNumber == 0) {
4866 return Warning(DirectiveLoc,
"file 0 not supported prior to DWARF-5");
4867 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4870 FileNumber, Directory, Filename, CKMem, Source);
4877 ReportedInconsistentMD5 =
true;
4878 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
4887bool MasmParser::parseDirectiveLine() {
4890 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
4908bool MasmParser::parseDirectiveLoc() {
4909 int64_t FileNumber = 0, LineNumber = 0;
4910 SMLoc Loc = getTok().getLoc();
4911 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
4913 "file number less than one in '.loc' directive") ||
4914 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4915 "unassigned file number in '.loc' directive"))
4920 LineNumber = getTok().getIntVal();
4922 return TokError(
"line number less than zero in '.loc' directive");
4926 int64_t ColumnPos = 0;
4928 ColumnPos = getTok().getIntVal();
4930 return TokError(
"column position less than zero in '.loc' directive");
4934 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4939 auto parseLocOp = [&]() ->
bool {
4941 SMLoc Loc = getTok().getLoc();
4942 if (parseIdentifier(
Name))
4943 return TokError(
"unexpected token in '.loc' directive");
4945 if (
Name ==
"basic_block")
4947 else if (
Name ==
"prologue_end")
4949 else if (
Name ==
"epilogue_begin")
4951 else if (
Name ==
"is_stmt") {
4952 Loc = getTok().getLoc();
4954 if (parseExpression(
Value))
4960 Flags &= ~DWARF2_FLAG_IS_STMT;
4961 else if (
Value == 1)
4964 return Error(Loc,
"is_stmt value not 0 or 1");
4966 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
4968 }
else if (
Name ==
"isa") {
4969 Loc = getTok().getLoc();
4971 if (parseExpression(
Value))
4977 return Error(Loc,
"isa number less than zero");
4980 return Error(Loc,
"isa number not a constant value");
4982 }
else if (
Name ==
"discriminator") {
4983 if (parseAbsoluteExpression(Discriminator))
4986 return Error(Loc,
"unknown sub-directive in '.loc' directive");
4991 if (parseMany(parseLocOp,
false ))
4994 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
5002bool MasmParser::parseDirectiveStabs() {
5003 return TokError(
"unsupported directive '.stabs'");
5008bool MasmParser::parseDirectiveCVFile() {
5009 SMLoc FileNumberLoc = getTok().getLoc();
5012 std::string Checksum;
5015 if (parseIntToken(FileNumber,
5016 "expected file number in '.cv_file' directive") ||
5017 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
5019 "unexpected token in '.cv_file' directive") ||
5020 parseEscapedString(Filename))
5024 "unexpected token in '.cv_file' directive") ||
5025 parseEscapedString(Checksum) ||
5026 parseIntToken(ChecksumKind,
5027 "expected checksum kind in '.cv_file' directive") ||
5032 Checksum = fromHex(Checksum);
5033 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
5034 memcpy(CKMem, Checksum.data(), Checksum.size());
5038 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
5039 static_cast<uint8_t
>(ChecksumKind)))
5040 return Error(FileNumberLoc,
"file number already allocated");
5045bool MasmParser::parseCVFunctionId(int64_t &
FunctionId,
5048 return parseTokenLoc(Loc) ||
5049 parseIntToken(
FunctionId,
"expected function id in '" + DirectiveName +
5051 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
5052 "expected function id within range [0, UINT_MAX)");
5055bool MasmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
5057 return parseTokenLoc(Loc) ||
5058 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
5060 check(FileNumber < 1, Loc,
"file number less than one in '" +
5061 DirectiveName +
"' directive") ||
5062 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
5063 "unassigned file number in '" + DirectiveName +
"' directive");
5070bool MasmParser::parseDirectiveCVFuncId() {
5071 SMLoc FunctionIdLoc = getTok().getLoc();
5074 if (parseCVFunctionId(
FunctionId,
".cv_func_id") || parseEOL())
5077 if (!getStreamer().emitCVFuncIdDirective(
FunctionId))
5078 return Error(FunctionIdLoc,
"function id already allocated");
5091bool MasmParser::parseDirectiveCVInlineSiteId() {
5092 SMLoc FunctionIdLoc = getTok().getLoc();
5100 if (parseCVFunctionId(
FunctionId,
".cv_inline_site_id"))
5105 getTok().getIdentifier() !=
"within"),
5106 "expected 'within' identifier in '.cv_inline_site_id' directive"))
5111 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
5116 getTok().getIdentifier() !=
"inlined_at"),
5117 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
5123 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
5124 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
5129 IACol = getTok().getIntVal();
5136 if (!getStreamer().emitCVInlineSiteIdDirective(
FunctionId, IAFunc, IAFile,
5137 IALine, IACol, FunctionIdLoc))
5138 return Error(FunctionIdLoc,
"function id already allocated");
5150bool MasmParser::parseDirectiveCVLoc() {
5151 SMLoc DirectiveLoc = getTok().getLoc();
5153 if (parseCVFunctionId(
FunctionId,
".cv_loc") ||
5154 parseCVFileId(FileNumber,
".cv_loc"))
5157 int64_t LineNumber = 0;
5159 LineNumber = getTok().getIntVal();
5161 return TokError(
"line number less than zero in '.cv_loc' directive");
5165 int64_t ColumnPos = 0;
5167 ColumnPos = getTok().getIntVal();
5169 return TokError(
"column position less than zero in '.cv_loc' directive");
5173 bool PrologueEnd =
false;
5176 auto parseOp = [&]() ->
bool {
5178 SMLoc Loc = getTok().getLoc();
5179 if (parseIdentifier(
Name))
5180 return TokError(
"unexpected token in '.cv_loc' directive");
5181 if (
Name ==
"prologue_end")
5183 else if (
Name ==
"is_stmt") {
5184 Loc = getTok().getLoc();
5186 if (parseExpression(
Value))
5190 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
5194 return Error(Loc,
"is_stmt value not 0 or 1");
5196 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
5201 if (parseMany(parseOp,
false ))
5204 getStreamer().emitCVLocDirective(
FunctionId, FileNumber, LineNumber,
5205 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
5212bool MasmParser::parseDirectiveCVLinetable() {
5215 SMLoc Loc = getTok().getLoc();
5216 if (parseCVFunctionId(
FunctionId,
".cv_linetable") ||
5218 "unexpected token in '.cv_linetable' directive") ||
5219 parseTokenLoc(Loc) ||
check(parseIdentifier(FnStartName), Loc,
5220 "expected identifier in directive") ||
5222 "unexpected token in '.cv_linetable' directive") ||
5223 parseTokenLoc(Loc) ||
check(parseIdentifier(FnEndName), Loc,
5224 "expected identifier in directive"))
5227 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5228 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5230 getStreamer().emitCVLinetableDirective(
FunctionId, FnStartSym, FnEndSym);
5236bool MasmParser::parseDirectiveCVInlineLinetable() {
5237 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
5239 SMLoc Loc = getTok().getLoc();
5240 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
5241 parseTokenLoc(Loc) ||
5244 "expected SourceField in '.cv_inline_linetable' directive") ||
5245 check(SourceFileId <= 0, Loc,
5246 "File id less than zero in '.cv_inline_linetable' directive") ||
5247 parseTokenLoc(Loc) ||
5250 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
5251 check(SourceLineNum < 0, Loc,
5252 "Line number less than zero in '.cv_inline_linetable' directive") ||
5253 parseTokenLoc(Loc) ||
check(parseIdentifier(FnStartName), Loc,
5254 "expected identifier in directive") ||
5255 parseTokenLoc(Loc) ||
check(parseIdentifier(FnEndName), Loc,
5256 "expected identifier in directive"))
5262 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5263 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5264 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
5265 SourceLineNum, FnStartSym,
5270void MasmParser::initializeCVDefRangeTypeMap() {
5271 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
5272 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
5273 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
5274 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
5279bool MasmParser::parseDirectiveCVDefRange() {
5281 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
5283 Loc = getLexer().getLoc();
5285 if (parseIdentifier(GapStartName))
5286 return Error(Loc,
"expected identifier in directive");
5287 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
5289 Loc = getLexer().getLoc();
5291 if (parseIdentifier(GapEndName))
5292 return Error(Loc,
"expected identifier in directive");
5293 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
5295 Ranges.push_back({GapStartSym, GapEndSym});
5301 "expected comma before def_range type in .cv_def_range directive") ||
5302 parseIdentifier(CVDefRangeTypeStr))
5303 return Error(Loc,
"expected def_range type in directive");
5306 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
5307 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
5309 : CVTypeIt->getValue();
5311 case CVDR_DEFRANGE_REGISTER: {
5313 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5314 ".cv_def_range directive") ||
5315 parseAbsoluteExpression(DRRegister))
5316 return Error(Loc,
"expected register number");
5321 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5324 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
5327 "expected comma before offset in .cv_def_range directive") ||
5328 parseAbsoluteExpression(DROffset))
5329 return Error(Loc,
"expected offset value");
5333 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5336 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
5338 int64_t DROffsetInParent;
5339 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5340 ".cv_def_range directive") ||
5341 parseAbsoluteExpression(DRRegister))
5342 return Error(Loc,
"expected register number");
5344 "expected comma before offset in .cv_def_range directive") ||
5345 parseAbsoluteExpression(DROffsetInParent))
5346 return Error(Loc,
"expected offset value");
5352 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5355 case CVDR_DEFRANGE_REGISTER_REL: {
5358 int64_t DRBasePointerOffset;
5359 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5360 ".cv_def_range directive") ||
5361 parseAbsoluteExpression(DRRegister))
5362 return Error(Loc,
"expected register value");
5365 "expected comma before flag value in .cv_def_range directive") ||
5366 parseAbsoluteExpression(DRFlags))
5367 return Error(Loc,
"expected flag value");
5368 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
5369 "in .cv_def_range directive") ||
5370 parseAbsoluteExpression(DRBasePointerOffset))
5371 return Error(Loc,
"expected base pointer offset value");
5375 DRHdr.
Flags = DRFlags;
5377 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5381 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
5388bool MasmParser::parseDirectiveCVString() {
5390 if (checkForValidSection() || parseEscapedString(Data))
5391 return addErrorSuffix(
" in '.cv_string' directive");
5394 std::pair<StringRef, unsigned> Insertion =
5395 getCVContext().addToStringTable(Data);
5396 getStreamer().emitIntValue(Insertion.second, 4);
5402bool MasmParser::parseDirectiveCVStringTable() {
5403 getStreamer().emitCVStringTableDirective();
5409bool MasmParser::parseDirectiveCVFileChecksums() {
5410 getStreamer().emitCVFileChecksumsDirective();
5416bool MasmParser::parseDirectiveCVFileChecksumOffset() {
5418 if (parseIntToken(FileNo,
"expected identifier in directive"))
5422 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
5428bool MasmParser::parseDirectiveCVFPOData() {
5429 SMLoc DirLoc = getLexer().getLoc();
5431 if (parseIdentifier(ProcName))
5432 return TokError(
"expected symbol name");
5433 if (parseEOL(
"unexpected tokens"))
5434 return addErrorSuffix(
" in '.cv_fpo_data' directive");
5435 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
5436 getStreamer().emitCVFPOData(ProcSym, DirLoc);
5442bool MasmParser::parseDirectiveCFISections() {
5447 if (parseIdentifier(
Name))
5448 return TokError(
"Expected an identifier");
5450 if (
Name ==
".eh_frame")
5452 else if (
Name ==
".debug_frame")
5458 if (parseIdentifier(
Name))
5459 return TokError(
"Expected an identifier");
5461 if (
Name ==
".eh_frame")
5463 else if (
Name ==
".debug_frame")
5467 getStreamer().emitCFISections(EH,
Debug);
5473bool MasmParser::parseDirectiveCFIStartProc() {
5477 "unexpected token") ||
5479 return addErrorSuffix(
" in '.cfi_startproc' directive");
5487 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
5493bool MasmParser::parseDirectiveCFIEndProc() {
5494 getStreamer().emitCFIEndProc();
5499bool MasmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
5500 SMLoc DirectiveLoc) {
5504 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
5506 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo,
true);
5508 return parseAbsoluteExpression(
Register);
5515bool MasmParser::parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc) {
5517 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5519 parseAbsoluteExpression(
Offset))
5528bool MasmParser::parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc) {
5530 if (parseAbsoluteExpression(
Offset))
5533 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
5539bool MasmParser::parseDirectiveCFIRegister(
SMLoc DirectiveLoc) {
5540 int64_t Register1 = 0, Register2 = 0;
5541 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
5543 parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
5546 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
5552bool MasmParser::parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc) {
5553 getStreamer().emitCFIWindowSave(DirectiveLoc);
5559bool MasmParser::parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc) {
5560 int64_t Adjustment = 0;
5561 if (parseAbsoluteExpression(Adjustment))
5564 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
5570bool MasmParser::parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc) {
5572 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5575 getStreamer().emitCFIDefCfaRegister(
Register);
5581bool MasmParser::parseDirectiveCFIOffset(
SMLoc DirectiveLoc) {
5585 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5587 parseAbsoluteExpression(
Offset))
5596bool MasmParser::parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc) {
5599 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5601 parseAbsoluteExpression(
Offset))
5609 if (Encoding & ~0xff)
5615 const unsigned Format = Encoding & 0xf;
5622 const unsigned Application = Encoding & 0x70;
5634bool MasmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
5635 int64_t Encoding = 0;
5636 if (parseAbsoluteExpression(Encoding))
5644 check(parseIdentifier(
Name),
"expected identifier in directive"))
5650 getStreamer().emitCFIPersonality(
Sym, Encoding);
5652 getStreamer().emitCFILsda(
Sym, Encoding);
5658bool MasmParser::parseDirectiveCFIRememberState(
SMLoc DirectiveLoc) {
5659 getStreamer().emitCFIRememberState(DirectiveLoc);
5665bool MasmParser::parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc) {
5666 getStreamer().emitCFIRestoreState(DirectiveLoc);
5672bool MasmParser::parseDirectiveCFISameValue(
SMLoc DirectiveLoc) {
5675 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5678 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
5684bool MasmParser::parseDirectiveCFIRestore(
SMLoc DirectiveLoc) {
5686 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5689 getStreamer().emitCFIRestore(
Register);
5695bool MasmParser::parseDirectiveCFIEscape(
SMLoc DirectiveLoc) {
5698 if (parseAbsoluteExpression(CurrValue))
5706 if (parseAbsoluteExpression(CurrValue))
5709 Values.push_back((uint8_t)CurrValue);
5712 getStreamer().emitCFIEscape(Values, DirectiveLoc);
5718bool MasmParser::parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc) {
5720 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5722 getStreamer().emitCFIReturnColumn(
Register);
5728bool MasmParser::parseDirectiveCFISignalFrame() {
5732 getStreamer().emitCFISignalFrame();
5738bool MasmParser::parseDirectiveCFIUndefined(
SMLoc DirectiveLoc) {
5741 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5744 getStreamer().emitCFIUndefined(
Register);
5759 "Vararg parameter '" +
Parameters.back().Name +
5760 "' should be last in the list of parameters");
5763 if (parseIdentifier(Parameter.
Name))
5764 return TokError(
"expected identifier in 'macro' directive");
5768 if (CurrParam.Name.equals_insensitive(Parameter.
Name))
5769 return TokError(
"macro '" +
Name +
"' has multiple parameters"
5770 " named '" + Parameter.
Name +
"'");
5779 ParamLoc = Lexer.
getLoc();
5780 if (parseMacroArgument(
nullptr, Parameter.
Value))
5786 QualLoc = Lexer.
getLoc();
5787 if (parseIdentifier(Qualifier))
5788 return Error(QualLoc,
"missing parameter qualifier for "
5790 Parameter.
Name +
"' in macro '" +
Name +
5793 if (
Qualifier.equals_insensitive(
"req"))
5795 else if (
Qualifier.equals_insensitive(
"vararg"))
5798 return Error(QualLoc,
5799 Qualifier +
" is not a valid parameter qualifier for '" +
5800 Parameter.
Name +
"' in macro '" +
Name +
"'");
5813 std::vector<std::string>
Locals;
5815 getTok().getIdentifier().equals_insensitive(
"local")) {
5820 if (parseIdentifier(
ID))
5832 AsmToken EndToken, StartToken = getTok();
5833 unsigned MacroDepth = 0;
5834 bool IsMacroFunction =
false;
5844 return Error(NameLoc,
"no matching 'endm' in definition");
5849 if (getTok().getIdentifier().equals_insensitive(
"endm")) {
5850 if (MacroDepth == 0) {
5851 EndToken = getTok();
5854 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
5861 }
else if (getTok().getIdentifier().equals_insensitive(
"exitm")) {
5863 IsMacroFunction =
true;
5865 }
else if (isMacroLikeDirective()) {
5873 eatToEndOfStatement();
5876 if (getContext().lookupMacro(
Name.lower())) {
5877 return Error(NameLoc,
"macro '" +
Name +
"' is already defined");
5887 getContext().defineMacro(
Name.lower(), std::move(
Macro));
5893bool MasmParser::parseDirectiveExitMacro(
SMLoc DirectiveLoc,
5895 std::string &
Value) {
5896 SMLoc EndLoc = getTok().getLoc();
5898 return Error(EndLoc,
5899 "unable to parse text item in '" +
Directive +
"' directive");
5900 eatToEndOfStatement();
5902 if (!isInsideMacroInstantiation())
5903 return TokError(
"unexpected '" +
Directive +
"' in file, "
5904 "no current macro definition");
5907 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5908 TheCondState = TheCondStack.back();
5909 TheCondStack.pop_back();
5920 return TokError(
"unexpected token in '" +
Directive +
"' directive");
5924 if (isInsideMacroInstantiation()) {
5931 return TokError(
"unexpected '" +
Directive +
"' in file, "
5932 "no current macro definition");
5937bool MasmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
5941 if (parseTokenLoc(NameLoc) ||
5943 "expected identifier in 'purge' directive"))
5947 <<
"Un-defining macro: " <<
Name <<
"\n");
5948 if (!getContext().lookupMacro(
Name.lower()))
5949 return Error(NameLoc,
"macro '" +
Name +
"' is not defined");
5950 getContext().undefineMacro(
Name.lower());
5960bool MasmParser::parseDirectiveExtern() {
5962 auto parseOp = [&]() ->
bool {
5964 SMLoc NameLoc = getTok().getLoc();
5965 if (parseIdentifier(
Name))
5966 return Error(NameLoc,
"expected name");
5971 SMLoc TypeLoc = getTok().getLoc();
5972 if (parseIdentifier(TypeName))
5973 return Error(TypeLoc,
"expected type");
5974 if (!
TypeName.equals_insensitive(
"proc")) {
5976 if (lookUpType(TypeName,
Type))
5977 return Error(TypeLoc,
"unrecognized type");
5982 Sym->setExternal(
true);
5988 if (parseMany(parseOp))
5989 return addErrorSuffix(
" in directive 'extern'");
5995bool MasmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
5996 auto parseOp = [&]() ->
bool {
5998 SMLoc Loc = getTok().getLoc();
5999 if (parseIdentifier(
Name))
6000 return Error(Loc,
"expected identifier");
6004 if (
Sym->isTemporary())
6005 return Error(Loc,
"non-local symbol required");
6007 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
6008 return Error(Loc,
"unable to emit symbol attribute");
6012 if (parseMany(parseOp))
6013 return addErrorSuffix(
" in directive");
6019bool MasmParser::parseDirectiveComm(
bool IsLocal) {
6020 if (checkForValidSection())
6023 SMLoc IDLoc = getLexer().getLoc();
6025 if (parseIdentifier(
Name))
6026 return TokError(
"expected identifier in directive");
6032 return TokError(
"unexpected token in directive");
6036 SMLoc SizeLoc = getLexer().getLoc();
6037 if (parseAbsoluteExpression(
Size))
6040 int64_t Pow2Alignment = 0;
6041 SMLoc Pow2AlignmentLoc;
6044 Pow2AlignmentLoc = getLexer().getLoc();
6045 if (parseAbsoluteExpression(Pow2Alignment))
6050 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
6056 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
6057 Pow2Alignment =
Log2_64(Pow2Alignment);
6067 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
6068 "be less than zero");
6073 if (Pow2Alignment < 0)
6074 return Error(Pow2AlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
6075 "alignment, can't be less than zero");
6077 Sym->redefineIfPossible();
6078 if (!
Sym->isUndefined())
6079 return Error(IDLoc,
"invalid symbol redefinition");
6083 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
6084 Align(1ULL << Pow2Alignment));
6088 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
6096bool MasmParser::parseDirectiveComment(
SMLoc DirectiveLoc) {
6098 size_t DelimiterEnd = FirstLine.find_first_of(
"\b\t\v\f\r\x1A ");
6099 assert(DelimiterEnd != std::string::npos);
6101 if (Delimiter.
empty())
6102 return Error(DirectiveLoc,
"no delimiter in 'comment' directive");
6105 return Error(DirectiveLoc,
"unmatched delimiter in 'comment' directive");
6115bool MasmParser::parseDirectiveInclude() {
6118 SMLoc IncludeLoc = getTok().getLoc();
6120 if (parseAngleBracketString(Filename))
6122 if (
check(
Filename.empty(),
"missing filename in 'include' directive") ||
6124 "unexpected token in 'include' directive") ||
6127 check(enterIncludeFile(Filename), IncludeLoc,
6128 "Could not find include file '" + Filename +
"'"))
6136bool MasmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
6137 TheCondStack.push_back(TheCondState);
6139 if (TheCondState.
Ignore) {
6140 eatToEndOfStatement();
6143 if (parseAbsoluteExpression(ExprValue) || parseEOL())
6152 ExprValue = ExprValue == 0;
6156 TheCondState.
CondMet = ExprValue;
6165bool MasmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6166 TheCondStack.push_back(TheCondState);
6169 if (TheCondState.
Ignore) {
6170 eatToEndOfStatement();
6173 if (parseTextItem(Str))
6174 return TokError(
"expected text item parameter for 'ifb' directive");
6179 TheCondState.
CondMet = ExpectBlank == Str.empty();
6188bool MasmParser::parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6189 bool CaseInsensitive) {
6190 std::string String1, String2;
6192 if (parseTextItem(String1)) {
6194 return TokError(
"expected text item parameter for 'ifidn' directive");
6195 return TokError(
"expected text item parameter for 'ifdif' directive");
6201 "expected comma after first string for 'ifidn' directive");
6202 return TokError(
"expected comma after first string for 'ifdif' directive");
6206 if (parseTextItem(String2)) {
6208 return TokError(
"expected text item parameter for 'ifidn' directive");
6209 return TokError(
"expected text item parameter for 'ifdif' directive");
6212 TheCondStack.push_back(TheCondState);
6214 if (CaseInsensitive)
6218 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6227bool MasmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
6228 TheCondStack.push_back(TheCondState);
6231 if (TheCondState.
Ignore) {
6232 eatToEndOfStatement();
6234 bool is_defined =
false;
6236 SMLoc StartLoc, EndLoc;
6238 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6241 if (
check(parseIdentifier(
Name),
"expected identifier after 'ifdef'") ||
6245 if (BuiltinSymbolMap.contains(
Name.lower())) {
6251 is_defined = (
Sym && !
Sym->isUndefined(
false));
6255 TheCondState.
CondMet = (is_defined == expect_defined);
6264bool MasmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc,
6265 DirectiveKind DirKind) {
6268 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
6269 " .if or an .elseif");
6272 bool LastIgnoreState =
false;
6273 if (!TheCondStack.empty())
6274 LastIgnoreState = TheCondStack.back().Ignore;
6275 if (LastIgnoreState || TheCondState.
CondMet) {
6276 TheCondState.
Ignore =
true;
6277 eatToEndOfStatement();
6280 if (parseAbsoluteExpression(ExprValue))
6292 ExprValue = ExprValue == 0;
6296 TheCondState.
CondMet = ExprValue;
6305bool MasmParser::parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6308 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6309 " if or an elseif");
6312 bool LastIgnoreState =
false;
6313 if (!TheCondStack.empty())
6314 LastIgnoreState = TheCondStack.back().Ignore;
6315 if (LastIgnoreState || TheCondState.
CondMet) {
6316 TheCondState.
Ignore =
true;
6317 eatToEndOfStatement();
6320 if (parseTextItem(Str)) {
6322 return TokError(
"expected text item parameter for 'elseifb' directive");
6323 return TokError(
"expected text item parameter for 'elseifnb' directive");
6329 TheCondState.
CondMet = ExpectBlank == Str.empty();
6339bool MasmParser::parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
6340 bool expect_defined) {
6343 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6344 " if or an elseif");
6347 bool LastIgnoreState =
false;
6348 if (!TheCondStack.empty())
6349 LastIgnoreState = TheCondStack.back().Ignore;
6350 if (LastIgnoreState || TheCondState.
CondMet) {
6351 TheCondState.
Ignore =
true;
6352 eatToEndOfStatement();
6354 bool is_defined =
false;
6356 SMLoc StartLoc, EndLoc;
6358 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6362 "expected identifier after 'elseifdef'") ||
6366 if (BuiltinSymbolMap.contains(
Name.lower())) {
6372 is_defined = (
Sym && !
Sym->isUndefined(
false));
6376 TheCondState.
CondMet = (is_defined == expect_defined);
6385bool MasmParser::parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6386 bool CaseInsensitive) {
6389 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6390 " if or an elseif");
6393 bool LastIgnoreState =
false;
6394 if (!TheCondStack.empty())
6395 LastIgnoreState = TheCondStack.back().Ignore;
6396 if (LastIgnoreState || TheCondState.
CondMet) {
6397 TheCondState.
Ignore =
true;
6398 eatToEndOfStatement();
6400 std::string String1, String2;
6402 if (parseTextItem(String1)) {
6405 "expected text item parameter for 'elseifidn' directive");
6406 return TokError(
"expected text item parameter for 'elseifdif' directive");
6412 "expected comma after first string for 'elseifidn' directive");
6414 "expected comma after first string for 'elseifdif' directive");
6418 if (parseTextItem(String2)) {
6421 "expected text item parameter for 'elseifidn' directive");
6422 return TokError(
"expected text item parameter for 'elseifdif' directive");
6425 if (CaseInsensitive)
6429 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6438bool MasmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
6444 return Error(DirectiveLoc,
"Encountered an else that doesn't follow an if"
6447 bool LastIgnoreState =
false;
6448 if (!TheCondStack.empty())
6449 LastIgnoreState = TheCondStack.back().Ignore;
6450 if (LastIgnoreState || TheCondState.
CondMet)
6451 TheCondState.
Ignore =
true;
6453 TheCondState.
Ignore =
false;
6460bool MasmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
6472bool MasmParser::parseDirectiveError(
SMLoc DirectiveLoc) {
6473 if (!TheCondStack.empty()) {
6474 if (TheCondStack.back().Ignore) {
6475 eatToEndOfStatement();
6480 std::string Message =
".err directive invoked in source file";
6485 return Error(DirectiveLoc, Message);
6490bool MasmParser::parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6491 if (!TheCondStack.empty()) {
6492 if (TheCondStack.back().Ignore) {
6493 eatToEndOfStatement();
6499 if (parseTextItem(Text))
6500 return Error(getTok().getLoc(),
"missing text item in '.errb' directive");
6502 std::string Message =
".errb directive invoked in source file";
6505 return addErrorSuffix(
" in '.errb' directive");
6510 if (
Text.empty() == ExpectBlank)
6511 return Error(DirectiveLoc, Message);
6517bool MasmParser::parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
6518 bool ExpectDefined) {
6519 if (!TheCondStack.empty()) {
6520 if (TheCondStack.back().Ignore) {
6521 eatToEndOfStatement();
6526 bool IsDefined =
false;
6528 SMLoc StartLoc, EndLoc;
6530 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6533 if (
check(parseIdentifier(
Name),
"expected identifier after '.errdef'"))
6536 if (BuiltinSymbolMap.contains(
Name.lower())) {
6542 IsDefined = (
Sym && !
Sym->isUndefined(
false));
6546 std::string Message =
".errdef directive invoked in source file";
6549 return addErrorSuffix(
" in '.errdef' directive");
6554 if (IsDefined == ExpectDefined)
6555 return Error(DirectiveLoc, Message);
6561bool MasmParser::parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6562 bool CaseInsensitive) {
6563 if (!TheCondStack.empty()) {
6564 if (TheCondStack.back().Ignore) {
6565 eatToEndOfStatement();
6570 std::string String1, String2;
6572 if (parseTextItem(String1)) {
6574 return TokError(
"expected string parameter for '.erridn' directive");
6575 return TokError(
"expected string parameter for '.errdif' directive");
6581 "expected comma after first string for '.erridn' directive");
6583 "expected comma after first string for '.errdif' directive");
6587 if (parseTextItem(String2)) {
6589 return TokError(
"expected string parameter for '.erridn' directive");
6590 return TokError(
"expected string parameter for '.errdif' directive");
6593 std::string Message;
6595 Message =
".erridn directive invoked in source file";
6597 Message =
".errdif directive invoked in source file";
6600 return addErrorSuffix(
" in '.erridn' directive");
6605 if (CaseInsensitive)
6609 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6612 if ((CaseInsensitive &&
6614 (ExpectEqual == (String1 == String2)))
6615 return Error(DirectiveLoc, Message);
6621bool MasmParser::parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero) {
6622 if (!TheCondStack.empty()) {
6623 if (TheCondStack.back().Ignore) {
6624 eatToEndOfStatement();
6630 if (parseAbsoluteExpression(ExprValue))
6631 return addErrorSuffix(
" in '.erre' directive");
6633 std::string Message =
".erre directive invoked in source file";
6636 return addErrorSuffix(
" in '.erre' directive");
6641 if ((ExprValue == 0) == ExpectZero)
6642 return Error(DirectiveLoc, Message);
6648bool MasmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
6653 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
6655 if (!TheCondStack.empty()) {
6656 TheCondState = TheCondStack.back();
6657 TheCondStack.pop_back();
6663void MasmParser::initializeDirectiveKindMap() {
6664 DirectiveKindMap[
"="] = DK_ASSIGN;
6665 DirectiveKindMap[
"equ"] = DK_EQU;
6666 DirectiveKindMap[
"textequ"] = DK_TEXTEQU;
6670 DirectiveKindMap[
"byte"] = DK_BYTE;
6671 DirectiveKindMap[
"sbyte"] = DK_SBYTE;
6672 DirectiveKindMap[
"word"] = DK_WORD;
6673 DirectiveKindMap[
"sword"] = DK_SWORD;
6674 DirectiveKindMap[
"dword"] = DK_DWORD;
6675 DirectiveKindMap[
"sdword"] = DK_SDWORD;
6676 DirectiveKindMap[
"fword"] = DK_FWORD;
6677 DirectiveKindMap[
"qword"] = DK_QWORD;
6678 DirectiveKindMap[
"sqword"] = DK_SQWORD;
6679 DirectiveKindMap[
"real4"] = DK_REAL4;
6680 DirectiveKindMap[
"real8"] = DK_REAL8;
6681 DirectiveKindMap[
"real10"] = DK_REAL10;
6682 DirectiveKindMap[
"align"] = DK_ALIGN;
6683 DirectiveKindMap[
"even"] = DK_EVEN;
6684 DirectiveKindMap[
"org"] = DK_ORG;
6685 DirectiveKindMap[
"extern"] = DK_EXTERN;
6686 DirectiveKindMap[
"extrn"] = DK_EXTERN;
6687 DirectiveKindMap[
"public"] = DK_PUBLIC;
6689 DirectiveKindMap[
"comment"] = DK_COMMENT;
6690 DirectiveKindMap[
"include"] = DK_INCLUDE;
6691 DirectiveKindMap[
"repeat"] = DK_REPEAT;
6692 DirectiveKindMap[
"rept"] = DK_REPEAT;
6693 DirectiveKindMap[
"while"] = DK_WHILE;
6694 DirectiveKindMap[
"for"] = DK_FOR;
6695 DirectiveKindMap[
"irp"] = DK_FOR;
6696 DirectiveKindMap[
"forc"] = DK_FORC;
6697 DirectiveKindMap[
"irpc"] = DK_FORC;
6698 DirectiveKindMap[
"if"] = DK_IF;
6699 DirectiveKindMap[
"ife"] = DK_IFE;
6700 DirectiveKindMap[
"ifb"] = DK_IFB;
6701 DirectiveKindMap[
"ifnb"] = DK_IFNB;
6702 DirectiveKindMap[
"ifdef"] = DK_IFDEF;
6703 DirectiveKindMap[
"ifndef"] = DK_IFNDEF;
6704 DirectiveKindMap[
"ifdif"] = DK_IFDIF;
6705 DirectiveKindMap[
"ifdifi"] = DK_IFDIFI;
6706 DirectiveKindMap[
"ifidn"] = DK_IFIDN;
6707 DirectiveKindMap[
"ifidni"] = DK_IFIDNI;
6708 DirectiveKindMap[
"elseif"] = DK_ELSEIF;
6709 DirectiveKindMap[
"elseifdef"] = DK_ELSEIFDEF;
6710 DirectiveKindMap[
"elseifndef"] = DK_ELSEIFNDEF;
6711 DirectiveKindMap[
"elseifdif"] = DK_ELSEIFDIF;
6712 DirectiveKindMap[
"elseifidn"] = DK_ELSEIFIDN;
6713 DirectiveKindMap[
"else"] = DK_ELSE;
6714 DirectiveKindMap[
"end"] = DK_END;
6715 DirectiveKindMap[
"endif"] = DK_ENDIF;
6754 DirectiveKindMap[
"macro"] = DK_MACRO;
6755 DirectiveKindMap[
"exitm"] = DK_EXITM;
6756 DirectiveKindMap[
"endm"] = DK_ENDM;
6757 DirectiveKindMap[
"purge"] = DK_PURGE;
6758 DirectiveKindMap[
".err"] = DK_ERR;
6759 DirectiveKindMap[
".errb"] = DK_ERRB;
6760 DirectiveKindMap[
".errnb"] = DK_ERRNB;
6761 DirectiveKindMap[
".errdef"] = DK_ERRDEF;
6762 DirectiveKindMap[
".errndef"] = DK_ERRNDEF;
6763 DirectiveKindMap[
".errdif"] = DK_ERRDIF;
6764 DirectiveKindMap[
".errdifi"] = DK_ERRDIFI;
6765 DirectiveKindMap[
".erridn"] = DK_ERRIDN;
6766 DirectiveKindMap[
".erridni"] = DK_ERRIDNI;
6767 DirectiveKindMap[
".erre"] = DK_ERRE;
6768 DirectiveKindMap[
".errnz"] = DK_ERRNZ;
6769 DirectiveKindMap[
".pushframe"] = DK_PUSHFRAME;
6770 DirectiveKindMap[
".pushreg"] = DK_PUSHREG;
6771 DirectiveKindMap[
".savereg"] = DK_SAVEREG;
6772 DirectiveKindMap[
".savexmm128"] = DK_SAVEXMM128;
6773 DirectiveKindMap[
".setframe"] = DK_SETFRAME;
6774 DirectiveKindMap[
".radix"] = DK_RADIX;
6775 DirectiveKindMap[
"db"] = DK_DB;
6776 DirectiveKindMap[
"dd"] = DK_DD;
6777 DirectiveKindMap[
"df"] = DK_DF;
6778 DirectiveKindMap[
"dq"] = DK_DQ;
6779 DirectiveKindMap[
"dw"] = DK_DW;
6780 DirectiveKindMap[
"echo"] = DK_ECHO;
6781 DirectiveKindMap[
"struc"] = DK_STRUCT;
6782 DirectiveKindMap[
"struct"] = DK_STRUCT;
6783 DirectiveKindMap[
"union"] = DK_UNION;
6784 DirectiveKindMap[
"ends"] = DK_ENDS;
6787bool MasmParser::isMacroLikeDirective() {
6799 peekTok().getIdentifier().equals_insensitive(
"macro"))
6806 AsmToken EndToken, StartToken = getTok();
6808 unsigned NestLevel = 0;
6812 printError(DirectiveLoc,
"no matching 'endm' in definition");
6816 if (isMacroLikeDirective())
6821 getTok().getIdentifier().equals_insensitive(
"endm")) {
6822 if (NestLevel == 0) {
6823 EndToken = getTok();
6826 printError(getTok().getLoc(),
"unexpected token in 'endm' directive");
6835 eatToEndOfStatement();
6844 return &MacroLikeBodies.back();
6847bool MasmParser::expandStatement(
SMLoc Loc) {
6849 SMLoc EndLoc = getTok().getLoc();
6855 for (
const auto &S : BuiltinSymbolMap) {
6856 const BuiltinSymbol &
Sym = S.getValue();
6857 if (std::optional<std::string> Text = evaluateBuiltinTextMacro(
Sym, Loc)) {
6858 BuiltinValues[S.getKey().lower()] = std::move(*Text);
6861 for (
const auto &
B : BuiltinValues) {
6863 MCAsmMacroArgument
A;
6864 P.Name =
B.getKey();
6872 for (
const auto &V : Variables) {
6873 const Variable &Var =
V.getValue();
6876 MCAsmMacroArgument
A;
6885 MacroLikeBodies.emplace_back(
StringRef(), Body, Parameters);
6891 if (expandMacro(
OS,
M.Body,
M.Parameters,
Arguments,
M.Locals, EndLoc))
6893 std::unique_ptr<MemoryBuffer>
Expansion =
6899 EndStatementAtEOFStack.push_back(
false);
6904void MasmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
6906 instantiateMacroLikeBody(M, DirectiveLoc, getTok().getLoc(),
OS);
6908void MasmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
6913 std::unique_ptr<MemoryBuffer> Instantiation =
6918 MacroInstantiation *
MI =
new MacroInstantiation{DirectiveLoc, CurBuffer,
6919 ExitLoc, TheCondStack.size()};
6920 ActiveMacros.push_back(
MI);
6925 EndStatementAtEOFStack.push_back(
true);
6933bool MasmParser::parseDirectiveRepeat(
SMLoc DirectiveLoc,
StringRef Dir) {
6935 SMLoc CountLoc = getTok().getLoc();
6936 if (parseExpression(CountExpr))
6940 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
6941 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
6944 if (
check(Count < 0, CountLoc,
"Count is negative") || parseEOL())
6957 if (expandMacro(
OS,
M->Body, std::nullopt, std::nullopt,
M->Locals,
6961 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
6970bool MasmParser::parseDirectiveWhile(
SMLoc DirectiveLoc) {
6972 SMLoc CondLoc = getTok().getLoc();
6973 if (parseExpression(CondExpr))
6986 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
6987 return Error(CondLoc,
"expected absolute expression in 'while' directive");
6991 if (expandMacro(
OS,
M->Body, std::nullopt, std::nullopt,
M->Locals,
6994 instantiateMacroLikeBody(M, DirectiveLoc, DirectiveLoc,
OS);
7004bool MasmParser::parseDirectiveFor(
SMLoc DirectiveLoc,
StringRef Dir) {
7006 MCAsmMacroArguments
A;
7007 if (
check(parseIdentifier(Parameter.
Name),
7008 "expected identifier in '" + Dir +
"' directive"))
7017 ParamLoc = Lexer.
getLoc();
7018 if (parseMacroArgument(
nullptr, Parameter.
Value))
7024 QualLoc = Lexer.
getLoc();
7025 if (parseIdentifier(Qualifier))
7026 return Error(QualLoc,
"missing parameter qualifier for "
7028 Parameter.
Name +
"' in '" + Dir +
7031 if (
Qualifier.equals_insensitive(
"req"))
7034 return Error(QualLoc,
7035 Qualifier +
" is not a valid parameter qualifier for '" +
7036 Parameter.
Name +
"' in '" + Dir +
"' directive");
7041 "expected comma in '" + Dir +
"' directive") ||
7043 "values in '" + Dir +
7044 "' directive must be enclosed in angle brackets"))
7050 return addErrorSuffix(
" in arguments for '" + Dir +
"' directive");
7059 "values in '" + Dir +
7060 "' directive must be enclosed in angle brackets") ||
7074 for (
const MCAsmMacroArgument &Arg :
A) {
7075 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
7079 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
7092 if (
check(parseIdentifier(Parameter.
Name),
7093 "expected identifier in '" +
Directive +
"' directive") ||
7095 "expected comma in '" +
Directive +
"' directive"))
7097 if (parseAngleBracketString(
Argument)) {
7125 for (std::size_t
I = 0,
End = Values.size();
I !=
End; ++
I) {
7126 MCAsmMacroArgument Arg;
7129 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
7133 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
7138bool MasmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
7141 SMLoc ExprLoc = getLexer().getLoc();
7142 if (parseExpression(
Value))
7146 return Error(ExprLoc,
"unexpected expression in _emit");
7148 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
7149 return Error(ExprLoc,
"literal value out of range for directive");
7155bool MasmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
7157 SMLoc ExprLoc = getLexer().getLoc();
7158 if (parseExpression(
Value))
7162 return Error(ExprLoc,
"unexpected expression in align");
7165 return Error(ExprLoc,
"literal value not a power of two greater then zero");
7171bool MasmParser::parseDirectiveRadix(
SMLoc DirectiveLoc) {
7172 const SMLoc Loc = getLexer().getLoc();
7178 "radix must be a decimal number in the range 2 to 16; was " +
7181 if (Radix < 2 || Radix > 16)
7182 return Error(Loc,
"radix must be in the range 2 to 16; was " +
7183 std::to_string(Radix));
7184 getLexer().setMasmDefaultRadix(Radix);
7190bool MasmParser::parseDirectiveEcho(
SMLoc DirectiveLoc) {
7193 if (!
StringRef(Message).ends_with(
"\n"))
7222 Variable &Var = Variables[
Name.lower()];
7223 if (Var.Name.empty()) {
7225 }
else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {
7226 return Error(
SMLoc(),
"invalid variable redefinition");
7227 }
else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&
7229 "', already defined on the command line")) {
7232 Var.Redefinable = Variable::WARN_ON_REDEFINITION;
7234 Var.TextValue =
Value.str();
7239 const std::pair<StringRef, StringRef> BaseMember =
Name.split(
'.');
7241 return lookUpField(
Base, Member, Info);
7250 if (
Base.contains(
'.') && !lookUpField(
Base, BaseInfo))
7253 auto StructIt = Structs.
find(
Base.lower());
7254 auto TypeIt = KnownType.
find(
Base.lower());
7255 if (TypeIt != KnownType.
end()) {
7256 StructIt = Structs.
find(TypeIt->second.Name.lower());
7258 if (StructIt != Structs.
end())
7259 return lookUpField(StructIt->second, Member, Info);
7264bool MasmParser::lookUpField(
const StructInfo &Structure,
StringRef Member,
7267 Info.Type.Name = Structure.Name;
7268 Info.Type.Size = Structure.Size;
7269 Info.Type.ElementSize = Structure.Size;
7270 Info.Type.Length = 1;
7274 std::pair<StringRef, StringRef>
Split =
Member.split(
'.');
7277 auto StructIt = Structs.
find(FieldName.
lower());
7278 if (StructIt != Structs.
end())
7279 return lookUpField(StructIt->second, FieldMember, Info);
7281 auto FieldIt = Structure.FieldsByName.find(FieldName.
lower());
7282 if (FieldIt == Structure.FieldsByName.end())
7285 const FieldInfo &
Field = Structure.Fields[FieldIt->second];
7286 if (FieldMember.empty()) {
7291 if (
Field.Contents.FT == FT_STRUCT)
7292 Info.Type.Name =
Field.Contents.StructInfo.Structure.Name;
7294 Info.Type.Name =
"";
7298 if (
Field.Contents.FT != FT_STRUCT)
7300 const StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
7302 if (lookUpField(StructInfo.Structure, FieldMember, Info))
7328 auto StructIt = Structs.
find(
Name.lower());
7329 if (StructIt != Structs.
end()) {
7330 const StructInfo &Structure = StructIt->second;
7332 Info.ElementSize = Structure.Size;
7334 Info.Size = Structure.Size;
7341bool MasmParser::parseMSInlineAsm(
7342 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
7361 unsigned InputIdx = 0;
7362 unsigned OutputIdx = 0;
7365 if (parseCurlyBlockScope(AsmStrRewrites))
7368 ParseStatementInfo
Info(&AsmStrRewrites);
7369 bool StatementErr = parseStatement(Info, &SI);
7371 if (StatementErr ||
Info.ParseError) {
7373 printPendingErrors();
7378 assert(!hasPendingError() &&
"unexpected error from parseStatement");
7380 if (
Info.Opcode == ~0U)
7386 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
7391 !getTargetParser().OmitRegisterFromClobberLists(Operand.
getReg())) {
7392 unsigned NumDefs =
Desc.getNumDefs();
7401 if (SymName.
empty())
7409 if (Operand.
isImm()) {
7417 bool isOutput = (i == 1) &&
Desc.mayStore();
7423 OutputConstraints.
push_back((
"=" + Constraint).str());
7429 if (
Desc.operands()[i - 1].isBranchTarget())
7441 NumOutputs = OutputDecls.
size();
7442 NumInputs = InputDecls.
size();
7446 ClobberRegs.
erase(std::unique(ClobberRegs.
begin(), ClobberRegs.
end()),
7448 Clobbers.
assign(ClobberRegs.
size(), std::string());
7449 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
7455 if (NumOutputs || NumInputs) {
7456 unsigned NumExprs = NumOutputs + NumInputs;
7457 OpDecls.resize(NumExprs);
7458 Constraints.
resize(NumExprs);
7459 for (
unsigned i = 0; i < NumOutputs; ++i) {
7460 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
7461 Constraints[i] = OutputConstraints[i];
7463 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
7464 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
7465 Constraints[
j] = InputConstraints[i];
7470 std::string AsmStringIR;
7474 const char *AsmStart = ASMString.
begin();
7475 const char *AsmEnd = ASMString.
end();
7477 for (
auto it = AsmStrRewrites.
begin(); it != AsmStrRewrites.
end(); ++it) {
7485 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
7488 if (
unsigned Len = Loc - AsmStart)
7493 AsmStart = Loc + AR.
Len;
7497 unsigned AdditionalSkip = 0;
7519 size_t OffsetLen = OffsetName.
size();
7520 auto rewrite_it = std::find_if(
7522 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
7523 (FusingAR.Kind == AOK_Input ||
7524 FusingAR.Kind == AOK_CallInput);
7526 if (rewrite_it == AsmStrRewrites.
end()) {
7527 OS <<
"offset " << OffsetName;
7529 OS <<
"${" << InputIdx++ <<
":P}";
7530 rewrite_it->Done =
true;
7532 OS <<
'$' << InputIdx++;
7533 rewrite_it->Done =
true;
7545 OS <<
'$' << InputIdx++;
7548 OS <<
"${" << InputIdx++ <<
":P}";
7551 OS <<
'$' << OutputIdx++;
7556 case 8:
OS <<
"byte ptr ";
break;
7557 case 16:
OS <<
"word ptr ";
break;
7558 case 32:
OS <<
"dword ptr ";
break;
7559 case 64:
OS <<
"qword ptr ";
break;
7560 case 80:
OS <<
"xword ptr ";
break;
7561 case 128:
OS <<
"xmmword ptr ";
break;
7562 case 256:
OS <<
"ymmword ptr ";
break;
7572 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
7577 unsigned Val = AR.
Val;
7579 assert(Val < 10 &&
"Expected alignment less then 2^10.");
7580 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
7592 AsmStart = Loc + AR.
Len + AdditionalSkip;
7596 if (AsmStart != AsmEnd)
7599 AsmString =
OS.str();
7603void MasmParser::initializeBuiltinSymbolMap() {
7605 BuiltinSymbolMap[
"@version"] = BI_VERSION;
7606 BuiltinSymbolMap[
"@line"] = BI_LINE;
7609 BuiltinSymbolMap[
"@date"] = BI_DATE;
7610 BuiltinSymbolMap[
"@time"] = BI_TIME;
7611 BuiltinSymbolMap[
"@filecur"] = BI_FILECUR;
7612 BuiltinSymbolMap[
"@filename"] = BI_FILENAME;
7613 BuiltinSymbolMap[
"@curseg"] = BI_CURSEG;
7616 if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
7634const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,
7644 if (ActiveMacros.empty())
7648 ActiveMacros.front()->ExitBuffer);
7655std::optional<std::string>
7656MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
SMLoc StartLoc) {
7662 char TmpBuffer[
sizeof(
"mm/dd/yy")];
7663 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%D", &
TM);
7664 return std::string(TmpBuffer, Len);
7668 char TmpBuffer[
sizeof(
"hh:mm:ss")];
7669 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%T", &
TM);
7670 return std::string(TmpBuffer, Len);
7675 ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)
7683 return getStreamer().getCurrentSectionOnly()->getName().str();
7691 struct tm
TM,
unsigned CB) {
7692 return new MasmParser(SM,
C, Out, MAI,
TM, CB);
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
AMDGPU Lower Kernel Arguments
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)
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This file contains constants used for implementing Dwarf debug support.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
static bool isValidEncoding(int64_t Encoding)
static bool isMacroParameterChar(char C)
static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc)
This function checks if the next token is <string> type or arithmetic.
static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo)
static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr, bool EndExpressionAtGreater)
static int rewritesSort(const AsmRewrite *AsmRewriteA, const AsmRewrite *AsmRewriteB)
static bool isOperator(AsmToken::TokenKind kind)
static std::string angleBracketString(StringRef BracketContents)
creating a string without the escape characters '!'.
OptimizedStructLayoutField Field
const char LLVMTargetMachineRef TM
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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.
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
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.
size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true) override
Look ahead an arbitrary number of tokens.
const MCAsmInfo & getMAI() const
void setBuffer(StringRef Buf, const char *ptr=nullptr, bool EndStatementAtEOF=true)
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...
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.
unsigned getAssemblerDialect() const
bool doesAllowAtInName() const
StringRef getPrivateLabelPrefix() const
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
bool shouldUseLogicalShr() const
bool hasSubsectionsViaSymbols() const
bool getCOMMDirectiveAlignmentIsInBytes() const
bool getDollarIsPC() const
Generic assembler lexer interface, for use by target specific assembly lexers.
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isAtStartOfStatement()
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 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.
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.
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 bool defineMacro(StringRef Name, StringRef Value)
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.
virtual bool checkForValidSection()=0
Ensure that we have a valid section set in the streamer.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
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,...
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
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
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)
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
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
Base class for the full range of assembler expressions which are needed for parsing.
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 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 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.
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.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
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)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
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())
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
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
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
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
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) 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.
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)
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
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",...
iterator find(StringRef Key)
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
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.
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.
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
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & CaseLower(StringLiteral S, T Value)
StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, T Value)
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 TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Reg
All possible values of the reg field in the ModR/M byte.
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.
StringRef stem(StringRef path, Style style=Style::native)
Get stem.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
MCAsmParser * createMCMasmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, struct tm, unsigned CB=0)
Create an MCAsmParser instance for parsing Microsoft MASM-style assembly.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
std::vector< MCAsmMacroParameter > MCAsmMacroParameters
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
cl::opt< unsigned > AsmMacroMaxNestingDepth
MCAsmParserExtension * createCOFFMasmParser()
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.
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_Extern
.extern (XCOFF)
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.
uint64_t Offset
The offset of this field in the final layout.
uint64_t Size
The required size of this field in bytes.