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);
671 bool parseCVFunctionId(int64_t &FunctionId,
StringRef DirectiveName);
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();
966 bool parseDirectiveCFISections();
967 bool parseDirectiveCFIStartProc();
968 bool parseDirectiveCFIEndProc();
969 bool parseDirectiveCFIDefCfaOffset();
970 bool parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc);
971 bool parseDirectiveCFIAdjustCfaOffset();
972 bool parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc);
973 bool parseDirectiveCFIOffset(
SMLoc DirectiveLoc);
974 bool parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc);
975 bool parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality);
976 bool parseDirectiveCFIRememberState();
977 bool parseDirectiveCFIRestoreState();
978 bool parseDirectiveCFISameValue(
SMLoc DirectiveLoc);
979 bool parseDirectiveCFIRestore(
SMLoc DirectiveLoc);
980 bool parseDirectiveCFIEscape();
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");
1423 for (
const auto &TableEntry : getContext().
getSymbols()) {
1424 MCSymbol *Sym = TableEntry.getValue();
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))
1611 bool Before =
Identifier.equals_insensitive(
"@b");
1612 MCSymbol *Sym = getContext().getDirectionalLocalSymbol(0, Before);
1614 return Error(FirstTokenLoc,
"Expected @@ label before @B reference");
1619 std::pair<StringRef, StringRef>
Split;
1624 SMLoc AtLoc = getLexer().getLoc();
1626 if (parseIdentifier(VName))
1627 return Error(AtLoc,
"expected symbol variant after '@'");
1629 Split = std::make_pair(Identifier, VName);
1637 parseIdentifier(VName);
1640 "unexpected token in variant, expected ')'"))
1642 Split = std::make_pair(Identifier, VName);
1650 return Error(getLexer().getLoc(),
"expected a symbol reference");
1655 if (!
Split.second.empty()) {
1663 "invalid variant '" +
Split.second +
"'");
1670 if (
Split.second.empty()) {
1673 if (lookUpField(SymbolName,
Split.second, Info)) {
1674 std::pair<StringRef, StringRef> BaseMember =
Split.second.split(
'.');
1676 lookUpField(
Base, Member, Info);
1684 MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
1687 auto BuiltinIt = BuiltinSymbolMap.find(
SymbolName.lower());
1688 const BuiltinSymbol
Symbol = (BuiltinIt == BuiltinSymbolMap.end())
1690 : BuiltinIt->getValue();
1691 if (Symbol != BI_NO_SYMBOL) {
1692 const MCExpr *
Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
1702 if (VarIt != Variables.
end())
1704 Sym = getContext().getOrCreateSymbol(SymbolName);
1711 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1712 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1713 DoInline = TV->inlineAssignedExpr();
1716 return Error(EndLoc,
"unexpected modifier on variable reference");
1733 if (
Info.Type.Name.empty()) {
1735 if (TypeIt != KnownType.
end()) {
1736 Info.Type = TypeIt->second;
1740 *TypeInfo =
Info.Type;
1745 return TokError(
"literal value out of range for directive");
1747 int64_t
IntVal = getTok().getIntVal();
1755 SMLoc ValueLoc = getTok().getLoc();
1757 if (parseEscapedString(
Value))
1759 if (
Value.size() > 8)
1760 return Error(ValueLoc,
"literal value out of range");
1762 for (
const unsigned char CharVal :
Value)
1763 IntValue = (IntValue << 8) | CharVal;
1768 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1787 return parseParenExpr(Res, EndLoc);
1789 if (!PlatformParser->HasBracketExpressions())
1790 return TokError(
"brackets expression not supported on this target");
1792 return parseBracketExpr(Res, EndLoc);
1795 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1801 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1807 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1839 return TokError(
"expected '(' after operator");
1841 if (parseExpression(Res, EndLoc))
1845 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1850bool MasmParser::parseExpression(
const MCExpr *&Res) {
1852 return parseExpression(Res, EndLoc);
1863 "Argument to the function cannot be a NULL value");
1865 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1866 (*CharPtr !=
'\0')) {
1867 if (*CharPtr ==
'!')
1871 if (*CharPtr ==
'>') {
1881 for (
size_t Pos = 0; Pos < BracketContents.
size(); Pos++) {
1882 if (BracketContents[Pos] ==
'!')
1884 Res += BracketContents[Pos];
1899bool MasmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1902 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1903 parseBinOpRHS(1, Res, EndLoc))
1909 if (Res->evaluateAsAbsolute(
Value))
1915bool MasmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1917 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1920bool MasmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1922 if (parseParenExpr(Res, EndLoc))
1925 for (; ParenDepth > 0; --ParenDepth) {
1926 if (parseBinOpRHS(1, Res, EndLoc))
1931 if (ParenDepth - 1 > 0) {
1932 EndLoc = getTok().getEndLoc();
1940bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1944 if (parseExpression(Expr))
1947 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1948 return Error(StartLoc,
"expected absolute expression");
1955 bool ShouldUseLogicalShr,
1956 bool EndExpressionAtGreater) {
1984 if (EndExpressionAtGreater)
2025 if (EndExpressionAtGreater)
2036 AngleBracketDepth > 0);
2041bool MasmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
2063 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
2067 if (TokPrec < Precedence)
2074 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
2080 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
2081 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
2094bool MasmParser::parseStatement(ParseStatementInfo &Info,
2096 assert(!hasPendingError() &&
"parseStatement started with pending error");
2102 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
2103 getTok().getString().front() ==
'\n')
2112 SMLoc ExpansionLoc = getTok().getLoc();
2123 return parseCppHashLineFilenameComment(IDLoc);
2130 IDVal = getTok().getString();
2133 return Error(IDLoc,
"unexpected token at start of statement");
2134 }
else if (parseIdentifier(IDVal, StartOfStatement)) {
2135 if (!TheCondState.
Ignore) {
2137 return Error(IDLoc,
"unexpected token at start of statement");
2146 DirectiveKindMap.find(IDVal.
lower());
2147 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
2149 : DirKindIt->getValue();
2155 return parseDirectiveIf(IDLoc, DirKind);
2157 return parseDirectiveIfb(IDLoc,
true);
2159 return parseDirectiveIfb(IDLoc,
false);
2161 return parseDirectiveIfdef(IDLoc,
true);
2163 return parseDirectiveIfdef(IDLoc,
false);
2165 return parseDirectiveIfidn(IDLoc,
false,
2168 return parseDirectiveIfidn(IDLoc,
false,
2171 return parseDirectiveIfidn(IDLoc,
true,
2174 return parseDirectiveIfidn(IDLoc,
true,
2178 return parseDirectiveElseIf(IDLoc, DirKind);
2180 return parseDirectiveElseIfb(IDLoc,
true);
2182 return parseDirectiveElseIfb(IDLoc,
false);
2184 return parseDirectiveElseIfdef(IDLoc,
true);
2186 return parseDirectiveElseIfdef(IDLoc,
false);
2188 return parseDirectiveElseIfidn(IDLoc,
false,
2191 return parseDirectiveElseIfidn(IDLoc,
false,
2194 return parseDirectiveElseIfidn(IDLoc,
true,
2197 return parseDirectiveElseIfidn(IDLoc,
true,
2200 return parseDirectiveElse(IDLoc);
2202 return parseDirectiveEndIf(IDLoc);
2207 if (TheCondState.
Ignore) {
2208 eatToEndOfStatement();
2218 if (checkForValidSection())
2226 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
2234 if (ParsingMSInlineAsm && SI) {
2236 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
2238 "We should have an internal name here.");
2241 IDVal = RewrittenLabel;
2244 if (IDVal ==
"@@") {
2247 Sym = getContext().getOrCreateSymbol(IDVal);
2266 getTargetParser().doBeforeLabelEmit(Sym, IDLoc);
2269 if (!getTargetParser().isParsingMSInlineAsm())
2274 if (enabledGenDwarfForAssembly())
2278 getTargetParser().onLabelParsed(Sym);
2285 return handleMacroEntry(M, IDLoc);
2290 if (DirKind != DK_NO_DIRECTIVE) {
2302 getTargetParser().flushPendingInstructions(getStreamer());
2308 return parseDirectiveNestedEnds();
2313 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2316 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2319 SMLoc StartTokLoc = getTok().getLoc();
2320 bool TPDirectiveReturn =
2323 if (hasPendingError())
2330 if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
2333 if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
2342 return parseDirectiveAscii(IDVal,
false);
2345 return parseDirectiveAscii(IDVal,
true);
2349 return parseDirectiveValue(IDVal, 1);
2353 return parseDirectiveValue(IDVal, 2);
2357 return parseDirectiveValue(IDVal, 4);
2360 return parseDirectiveValue(IDVal, 6);
2364 return parseDirectiveValue(IDVal, 8);
2366 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2368 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2370 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2373 return parseDirectiveNestedStruct(IDVal, DirKind);
2375 return parseDirectiveNestedEnds();
2377 return parseDirectiveAlign();
2379 return parseDirectiveEven();
2381 return parseDirectiveOrg();
2383 return parseDirectiveExtern();
2385 return parseDirectiveSymbolAttribute(
MCSA_Global);
2387 return parseDirectiveComm(
false);
2389 return parseDirectiveComment(IDLoc);
2391 return parseDirectiveInclude();
2393 return parseDirectiveRepeat(IDLoc, IDVal);
2395 return parseDirectiveWhile(IDLoc);
2397 return parseDirectiveFor(IDLoc, IDVal);
2399 return parseDirectiveForc(IDLoc, IDVal);
2401 return parseDirectiveFile(IDLoc);
2403 return parseDirectiveLine();
2405 return parseDirectiveLoc();
2407 return parseDirectiveStabs();
2409 return parseDirectiveCVFile();
2411 return parseDirectiveCVFuncId();
2412 case DK_CV_INLINE_SITE_ID:
2413 return parseDirectiveCVInlineSiteId();
2415 return parseDirectiveCVLoc();
2416 case DK_CV_LINETABLE:
2417 return parseDirectiveCVLinetable();
2418 case DK_CV_INLINE_LINETABLE:
2419 return parseDirectiveCVInlineLinetable();
2420 case DK_CV_DEF_RANGE:
2421 return parseDirectiveCVDefRange();
2423 return parseDirectiveCVString();
2424 case DK_CV_STRINGTABLE:
2425 return parseDirectiveCVStringTable();
2426 case DK_CV_FILECHECKSUMS:
2427 return parseDirectiveCVFileChecksums();
2428 case DK_CV_FILECHECKSUM_OFFSET:
2429 return parseDirectiveCVFileChecksumOffset();
2430 case DK_CV_FPO_DATA:
2431 return parseDirectiveCVFPOData();
2432 case DK_CFI_SECTIONS:
2433 return parseDirectiveCFISections();
2434 case DK_CFI_STARTPROC:
2435 return parseDirectiveCFIStartProc();
2436 case DK_CFI_ENDPROC:
2437 return parseDirectiveCFIEndProc();
2438 case DK_CFI_DEF_CFA:
2439 return parseDirectiveCFIDefCfa(IDLoc);
2440 case DK_CFI_DEF_CFA_OFFSET:
2441 return parseDirectiveCFIDefCfaOffset();
2442 case DK_CFI_ADJUST_CFA_OFFSET:
2443 return parseDirectiveCFIAdjustCfaOffset();
2444 case DK_CFI_DEF_CFA_REGISTER:
2445 return parseDirectiveCFIDefCfaRegister(IDLoc);
2447 return parseDirectiveCFIOffset(IDLoc);
2448 case DK_CFI_REL_OFFSET:
2449 return parseDirectiveCFIRelOffset(IDLoc);
2450 case DK_CFI_PERSONALITY:
2451 return parseDirectiveCFIPersonalityOrLsda(
true);
2453 return parseDirectiveCFIPersonalityOrLsda(
false);
2454 case DK_CFI_REMEMBER_STATE:
2455 return parseDirectiveCFIRememberState();
2456 case DK_CFI_RESTORE_STATE:
2457 return parseDirectiveCFIRestoreState();
2458 case DK_CFI_SAME_VALUE:
2459 return parseDirectiveCFISameValue(IDLoc);
2460 case DK_CFI_RESTORE:
2461 return parseDirectiveCFIRestore(IDLoc);
2463 return parseDirectiveCFIEscape();
2464 case DK_CFI_RETURN_COLUMN:
2465 return parseDirectiveCFIReturnColumn(IDLoc);
2466 case DK_CFI_SIGNAL_FRAME:
2467 return parseDirectiveCFISignalFrame();
2468 case DK_CFI_UNDEFINED:
2469 return parseDirectiveCFIUndefined(IDLoc);
2470 case DK_CFI_REGISTER:
2471 return parseDirectiveCFIRegister(IDLoc);
2472 case DK_CFI_WINDOW_SAVE:
2473 return parseDirectiveCFIWindowSave();
2475 Info.ExitValue =
"";
2476 return parseDirectiveExitMacro(IDLoc, IDVal, *
Info.ExitValue);
2478 Info.ExitValue =
"";
2479 return parseDirectiveEndMacro(IDVal);
2481 return parseDirectivePurgeMacro(IDLoc);
2483 return parseDirectiveEnd(IDLoc);
2485 return parseDirectiveError(IDLoc);
2487 return parseDirectiveErrorIfb(IDLoc,
true);
2489 return parseDirectiveErrorIfb(IDLoc,
false);
2491 return parseDirectiveErrorIfdef(IDLoc,
true);
2493 return parseDirectiveErrorIfdef(IDLoc,
false);
2495 return parseDirectiveErrorIfidn(IDLoc,
false,
2498 return parseDirectiveErrorIfidn(IDLoc,
false,
2501 return parseDirectiveErrorIfidn(IDLoc,
true,
2504 return parseDirectiveErrorIfidn(IDLoc,
true,
2507 return parseDirectiveErrorIfe(IDLoc,
true);
2509 return parseDirectiveErrorIfe(IDLoc,
false);
2511 return parseDirectiveRadix(IDLoc);
2513 return parseDirectiveEcho(IDLoc);
2516 return Error(IDLoc,
"unknown directive");
2520 auto IDIt = Structs.
find(IDVal.
lower());
2521 if (IDIt != Structs.
end())
2522 return parseDirectiveStructValue(IDIt->getValue(), IDVal,
2530 const AsmToken afterNextTok = peekTok();
2541 getTargetParser().flushPendingInstructions(getStreamer());
2547 return parseDirectiveEnds(IDVal, IDLoc);
2552 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2554 if (Handler.first) {
2557 return (*Handler.second)(Handler.first, nextVal, nextLoc);
2562 DirKindIt = DirectiveKindMap.find(nextVal.
lower());
2563 DirKind = (DirKindIt == DirectiveKindMap.end())
2565 : DirKindIt->getValue();
2573 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
2584 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2595 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2606 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2616 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2627 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2630 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2634 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2638 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2643 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2646 return parseDirectiveEnds(IDVal, IDLoc);
2649 return parseDirectiveMacro(IDVal, IDLoc);
2653 auto NextIt = Structs.
find(nextVal.
lower());
2654 if (NextIt != Structs.
end()) {
2656 return parseDirectiveNamedStructValue(NextIt->getValue(),
2657 nextVal, nextLoc, IDVal);
2661 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2662 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2663 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2666 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2667 return parseDirectiveMSAlign(IDLoc, Info);
2669 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2671 if (checkForValidSection())
2675 std::string OpcodeStr = IDVal.
lower();
2677 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
ID,
2678 Info.ParsedOperands);
2679 Info.ParseError = ParseHadError;
2682 if (getShowParsedOperands()) {
2685 OS <<
"parsed instruction: [";
2686 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2689 Info.ParsedOperands[i]->print(
OS);
2697 if (hasPendingError() || ParseHadError)
2702 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2703 getContext().getGenDwarfSectionSyms().
count(
2704 getStreamer().getCurrentSectionOnly())) {
2706 if (ActiveMacros.empty())
2710 ActiveMacros.front()->ExitBuffer);
2715 if (!CppHashInfo.Filename.empty()) {
2716 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2718 getContext().setGenDwarfFileNumber(FileNumber);
2720 unsigned CppHashLocLineNo =
2722 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2725 getStreamer().emitDwarfLocDirective(
2726 getContext().getGenDwarfFileNumber(), Line, 0,
2732 if (!ParseHadError) {
2734 if (getTargetParser().MatchAndEmitInstruction(
2736 getTargetParser().isParsingMSInlineAsm()))
2743bool MasmParser::parseCurlyBlockScope(
2762bool MasmParser::parseCppHashLineFilenameComment(
SMLoc L) {
2767 "Lexing Cpp line comment: Expected Integer");
2768 int64_t LineNumber = getTok().getIntVal();
2771 "Lexing Cpp line comment: Expected String");
2780 CppHashInfo.Loc =
L;
2782 CppHashInfo.LineNumber = LineNumber;
2783 CppHashInfo.Buf = CurBuffer;
2784 if (FirstCppHashFilename.
empty())
2791void MasmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2792 const MasmParser *Parser =
static_cast<const MasmParser *
>(
Context);
2798 unsigned CppHashBuf =
2799 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2804 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2813 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2814 DiagBuf != CppHashBuf) {
2815 if (Parser->SavedDiagHandler)
2816 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2825 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2828 int CppHashLocLineNo =
2829 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2831 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2837 if (Parser->SavedDiagHandler)
2838 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2840 NewDiag.print(
nullptr,
OS);
2846 return isAlnum(
C) ||
C ==
'_' ||
C ==
'$' ||
C ==
'@' ||
C ==
'?';
2852 const std::vector<std::string> &Locals,
SMLoc L) {
2853 unsigned NParameters = Parameters.
size();
2854 if (NParameters !=
A.size())
2855 return Error(L,
"Wrong number of arguments");
2867 std::optional<char> CurrentQuote;
2868 while (!Body.
empty()) {
2870 std::size_t End = Body.
size(), Pos = 0;
2871 std::size_t IdentifierPos = End;
2872 for (; Pos != End; ++Pos) {
2875 if (Body[Pos] ==
'&')
2880 if (IdentifierPos == End)
2881 IdentifierPos = Pos;
2883 IdentifierPos = End;
2887 if (!CurrentQuote) {
2888 if (Body[Pos] ==
'\'' || Body[Pos] ==
'"')
2889 CurrentQuote = Body[Pos];
2890 }
else if (Body[Pos] == CurrentQuote) {
2891 if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {
2896 CurrentQuote.reset();
2900 if (IdentifierPos != End) {
2903 Pos = IdentifierPos;
2904 IdentifierPos = End;
2915 bool InitialAmpersand = (Body[
I] ==
'&');
2916 if (InitialAmpersand) {
2923 const char *Begin = Body.
data() + Pos;
2925 const std::string ArgumentLower =
Argument.lower();
2929 if (Parameters[
Index].
Name.equals_insensitive(ArgumentLower))
2932 if (
Index == NParameters) {
2933 if (InitialAmpersand)
2935 auto it = LocalSymbols.
find(ArgumentLower);
2936 if (it != LocalSymbols.
end())
2952 OS << Token.getIntVal();
2954 OS << Token.getString();
2958 if (Pos < End && Body[Pos] ==
'&') {
3001class AsmLexerSkipSpaceRAII {
3003 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
3007 ~AsmLexerSkipSpaceRAII() {
3018 MCAsmMacroArgument &MA,
3021 if (Lexer.
isNot(EndTok)) {
3032 const char *StrChar = StrLoc.
getPointer() + 1;
3033 const char *EndChar = EndLoc.
getPointer() - 1;
3034 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3041 unsigned ParenLevel = 0;
3044 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
3051 return TokError(
"unexpected token");
3053 if (ParenLevel == 0) {
3067 MA.push_back(getTok());
3093 MA.push_back(getTok());
3097 if (ParenLevel != 0)
3098 return TokError(
"unbalanced parentheses in argument");
3100 if (MA.empty() && MP) {
3102 return TokError(
"missing value for required parameter '" + MP->
Name +
3112bool MasmParser::parseMacroArguments(
const MCAsmMacro *M,
3113 MCAsmMacroArguments &
A,
3115 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
3116 bool NamedParametersFound =
false;
3119 A.resize(NParameters);
3120 FALocs.
resize(NParameters);
3125 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
3131 if (parseIdentifier(FA.
Name))
3132 return Error(IDLoc,
"invalid argument identifier for formal argument");
3135 return TokError(
"expected '=' after formal parameter identifier");
3139 NamedParametersFound =
true;
3142 if (NamedParametersFound && FA.
Name.
empty())
3143 return Error(IDLoc,
"cannot mix positional and keyword arguments");
3145 unsigned PI = Parameter;
3147 assert(M &&
"expected macro to be defined");
3149 for (FAI = 0; FAI < NParameters; ++FAI)
3150 if (
M->Parameters[FAI].Name == FA.
Name)
3153 if (FAI >= NParameters) {
3154 return Error(IDLoc,
"parameter named '" + FA.
Name +
3155 "' does not exist for macro '" +
M->Name +
"'");
3160 if (M && PI < NParameters)
3161 MP = &
M->Parameters[PI];
3166 const MCExpr *AbsoluteExp;
3170 if (parseExpression(AbsoluteExp, EndLoc))
3172 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
3173 getStreamer().getAssemblerPtr()))
3174 return Error(StrLoc,
"expected absolute expression");
3179 FA.
Value.push_back(newToken);
3180 }
else if (parseMacroArgument(MP, FA.
Value, EndTok)) {
3182 return addErrorSuffix(
" in '" +
M->Name +
"' macro");
3187 if (!FA.
Value.empty()) {
3192 if (FALocs.
size() <= PI)
3195 FALocs[PI] = Lexer.
getLoc();
3201 if (Lexer.
is(EndTok)) {
3203 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
3204 if (
A[FAI].empty()) {
3205 if (
M->Parameters[FAI].Required) {
3207 "missing value for required parameter "
3209 M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
3213 if (!
M->Parameters[FAI].Value.empty())
3214 A[FAI] =
M->Parameters[FAI].Value;
3224 return TokError(
"too many positional arguments");
3232 if (ActiveMacros.size() == MaxNestingDepth) {
3233 std::ostringstream MaxNestingDepthError;
3234 MaxNestingDepthError <<
"macros cannot be nested more than "
3235 << MaxNestingDepth <<
" levels deep."
3236 <<
" Use -asm-macro-max-nesting-depth to increase "
3238 return TokError(MaxNestingDepthError.str());
3241 MCAsmMacroArguments
A;
3242 if (parseMacroArguments(M,
A, ArgumentEndTok))
3251 if (expandMacro(
OS, Body,
M->Parameters,
A,
M->Locals, getTok().getLoc()))
3258 std::unique_ptr<MemoryBuffer> Instantiation =
3263 MacroInstantiation *
MI =
new MacroInstantiation{
3264 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
3265 ActiveMacros.push_back(
MI);
3267 ++NumOfMacroInstantiations;
3272 EndStatementAtEOFStack.push_back(
true);
3278void MasmParser::handleMacroExit() {
3280 EndStatementAtEOFStack.pop_back();
3281 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
3282 EndStatementAtEOFStack.back());
3286 delete ActiveMacros.back();
3287 ActiveMacros.pop_back();
3290bool MasmParser::handleMacroInvocation(
const MCAsmMacro *M,
SMLoc NameLoc) {
3292 return Error(NameLoc,
"cannot invoke macro procedure as function");
3295 "' requires arguments in parentheses") ||
3300 std::string ExitValue;
3303 ParseStatementInfo
Info(&AsmStrRewrites);
3304 bool Parsed = parseStatement(Info,
nullptr);
3306 if (!Parsed &&
Info.ExitValue) {
3307 ExitValue = std::move(*
Info.ExitValue);
3319 printPendingErrors();
3322 if (Parsed && !getLexer().isAtStartOfStatement())
3323 eatToEndOfStatement();
3332 std::unique_ptr<MemoryBuffer> MacroValue =
3340 EndStatementAtEOFStack.push_back(
false);
3349bool MasmParser::parseIdentifier(
StringRef &Res,
3350 IdentifierPositionKind Position) {
3357 SMLoc PrefixLoc = getLexer().getLoc();
3382 Res = getTok().getIdentifier();
3386 ExpandKind ExpandNextToken = ExpandMacros;
3387 if (Position == StartOfStatement &&
3389 .CaseLower(
"echo",
true)
3390 .CasesLower(
"ifdef",
"ifndef",
"elseifdef",
"elseifndef",
true)
3392 ExpandNextToken = DoNotExpandMacros;
3394 Lex(ExpandNextToken);
3405 DirectiveKind DirKind,
SMLoc NameLoc) {
3406 auto BuiltinIt = BuiltinSymbolMap.find(
Name.lower());
3407 if (BuiltinIt != BuiltinSymbolMap.end())
3408 return Error(NameLoc,
"cannot redefine a built-in symbol");
3410 Variable &Var = Variables[
Name.lower()];
3411 if (Var.Name.empty()) {
3416 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3419 std::string TextItem;
3420 if (!parseTextItem(TextItem)) {
3424 auto parseItem = [&]() ->
bool {
3425 if (parseTextItem(TextItem))
3426 return TokError(
"expected text item");
3431 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3433 if (!Var.IsText || Var.TextValue !=
Value) {
3434 switch (Var.Redefinable) {
3435 case Variable::NOT_REDEFINABLE:
3436 return Error(getTok().getLoc(),
"invalid variable redefinition");
3437 case Variable::WARN_ON_REDEFINITION:
3439 "', already defined on the command line")) {
3448 Var.TextValue =
Value;
3449 Var.Redefinable = Variable::REDEFINABLE;
3454 if (DirKind == DK_TEXTEQU)
3455 return TokError(
"expected <text> in '" +
Twine(IDVal) +
"' directive");
3460 if (parseExpression(Expr, EndLoc))
3461 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3466 if (!Expr->evaluateAsAbsolute(
Value, getStreamer().getAssemblerPtr())) {
3467 if (DirKind == DK_ASSIGN)
3470 "expected absolute expression; not all symbols have known values",
3471 {StartLoc, EndLoc});
3474 if (!Var.IsText || Var.TextValue != ExprAsString) {
3475 switch (Var.Redefinable) {
3476 case Variable::NOT_REDEFINABLE:
3477 return Error(getTok().getLoc(),
"invalid variable redefinition");
3478 case Variable::WARN_ON_REDEFINITION:
3480 "', already defined on the command line")) {
3490 Var.TextValue = ExprAsString.
str();
3491 Var.Redefinable = Variable::REDEFINABLE;
3496 MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
3499 Sym->
isVariable() ? dyn_cast_or_null<MCConstantExpr>(
3502 if (Var.IsText || !PrevValue || PrevValue->
getValue() !=
Value) {
3503 switch (Var.Redefinable) {
3504 case Variable::NOT_REDEFINABLE:
3505 return Error(getTok().getLoc(),
"invalid variable redefinition");
3506 case Variable::WARN_ON_REDEFINITION:
3508 "', already defined on the command line")) {
3518 Var.TextValue.clear();
3519 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
3520 : Variable::NOT_REDEFINABLE;
3522 Sym->
setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
3529bool MasmParser::parseEscapedString(std::string &
Data) {
3534 char Quote = getTok().getString().front();
3535 StringRef Str = getTok().getStringContents();
3536 Data.reserve(Str.size());
3537 for (
size_t i = 0, e = Str.size(); i != e; ++i) {
3538 Data.push_back(Str[i]);
3539 if (Str[i] == Quote) {
3543 if (i + 1 == Str.size())
3544 return Error(getTok().getLoc(),
"missing quotation mark in string");
3545 if (Str[i + 1] == Quote)
3554bool MasmParser::parseAngleBracketString(std::string &
Data) {
3555 SMLoc EndLoc, StartLoc = getTok().getLoc();
3557 const char *StartChar = StartLoc.
getPointer() + 1;
3558 const char *EndChar = EndLoc.
getPointer() - 1;
3559 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3570bool MasmParser::parseTextItem(std::string &
Data) {
3571 switch (getTok().getKind()) {
3578 Data = std::to_string(Res);
3585 return parseAngleBracketString(
Data);
3589 SMLoc StartLoc = getTok().getLoc();
3590 if (parseIdentifier(
ID))
3594 bool Expanded =
false;
3597 auto BuiltinIt = BuiltinSymbolMap.find(
ID.lower());
3598 if (BuiltinIt != BuiltinSymbolMap.end()) {
3599 std::optional<std::string> BuiltinText =
3600 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
3605 Data = std::move(*BuiltinText);
3612 auto VarIt = Variables.
find(
ID.lower());
3613 if (VarIt != Variables.
end()) {
3614 const Variable &Var = VarIt->getValue();
3619 Data = Var.TextValue;
3642bool MasmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3643 auto parseOp = [&]() ->
bool {
3645 if (checkForValidSection() || parseEscapedString(
Data))
3647 getStreamer().emitBytes(
Data);
3649 getStreamer().emitBytes(
StringRef(
"\0", 1));
3653 if (parseMany(parseOp))
3654 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3662 int64_t IntValue = MCE->getValue();
3664 return Error(MCE->getLoc(),
"out of range literal value");
3665 getStreamer().emitIntValue(IntValue,
Size);
3670 getStreamer().emitIntValue(0,
Size);
3678bool MasmParser::parseScalarInitializer(
unsigned Size,
3680 unsigned StringPadLength) {
3683 if (parseEscapedString(
Value))
3686 for (
const unsigned char CharVal :
Value)
3690 for (
size_t i =
Value.size(); i < StringPadLength; ++i)
3694 if (parseExpression(
Value))
3697 getTok().getString().equals_insensitive(
"dup")) {
3702 "cannot repeat value a non-constant number of times");
3703 const int64_t Repetitions = MCE->
getValue();
3704 if (Repetitions < 0)
3706 "cannot repeat value a negative number of times");
3710 "parentheses required for 'dup' contents") ||
3711 parseScalarInstList(
Size, DuplicatedValues) || parseRParen())
3714 for (
int i = 0; i < Repetitions; ++i)
3723bool MasmParser::parseScalarInstList(
unsigned Size,
3726 while (getTok().
isNot(EndToken) &&
3729 parseScalarInitializer(
Size, Values);
3739bool MasmParser::emitIntegralValues(
unsigned Size,
unsigned *Count) {
3741 if (checkForValidSection() || parseScalarInstList(
Size, Values))
3744 for (
const auto *
Value : Values) {
3748 *Count = Values.size();
3754 StructInfo &
Struct = StructInProgress.
back();
3756 IntFieldInfo &IntInfo =
Field.Contents.IntInfo;
3760 if (parseScalarInstList(
Size, IntInfo.Values))
3763 Field.SizeOf =
Field.Type * IntInfo.Values.size();
3764 Field.LengthOf = IntInfo.Values.size();
3767 Struct.NextOffset = FieldEnd;
3775bool MasmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3776 if (StructInProgress.
empty()) {
3778 if (emitIntegralValues(
Size))
3779 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3780 }
else if (addIntegralField(
"",
Size)) {
3781 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3789bool MasmParser::parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
3791 if (StructInProgress.
empty()) {
3794 getStreamer().emitLabel(Sym);
3796 if (emitIntegralValues(
Size, &Count))
3797 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3803 Type.Length = Count;
3805 }
else if (addIntegralField(
Name,
Size)) {
3806 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3815 return Asm.TokError(
"unknown token in expression");
3816 SMLoc ExprLoc = Asm.getTok().getLoc();
3817 APInt IntValue = Asm.getTok().getAPIntVal();
3819 if (!IntValue.
isIntN(128))
3820 return Asm.Error(ExprLoc,
"out of range literal value");
3821 if (!IntValue.
isIntN(64)) {
3837 SignLoc = getLexer().getLoc();
3841 SignLoc = getLexer().getLoc();
3846 return TokError(Lexer.
getErr());
3849 return TokError(
"unexpected token in directive");
3862 return TokError(
"invalid floating point literal");
3866 unsigned SizeInBits =
Value.getSizeInBits(Semantics);
3867 if (SizeInBits != (IDVal.
size() << 2))
3868 return TokError(
"invalid floating point literal");
3873 Res =
APInt(SizeInBits, IDVal, 16);
3875 return Warning(SignLoc,
"MASM-style hex floats ignore explicit sign");
3878 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3880 return TokError(
"invalid floating point literal");
3888 Res =
Value.bitcastToAPInt();
3893bool MasmParser::parseRealInstList(
const fltSemantics &Semantics,
3896 while (getTok().
isNot(EndToken) ||
3899 const AsmToken NextTok = peekTok();
3908 "cannot repeat value a non-constant number of times");
3909 const int64_t Repetitions = MCE->
getValue();
3910 if (Repetitions < 0)
3912 "cannot repeat value a negative number of times");
3916 "parentheses required for 'dup' contents") ||
3917 parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
3920 for (
int i = 0; i < Repetitions; ++i)
3921 ValuesAsInt.
append(DuplicatedValues.
begin(), DuplicatedValues.
end());
3924 if (parseRealValue(Semantics, AsInt))
3939bool MasmParser::emitRealValues(
const fltSemantics &Semantics,
3941 if (checkForValidSection())
3945 if (parseRealInstList(Semantics, ValuesAsInt))
3948 for (
const APInt &AsInt : ValuesAsInt) {
3949 getStreamer().emitIntValue(AsInt);
3952 *Count = ValuesAsInt.size();
3959 StructInfo &
Struct = StructInProgress.
back();
3961 RealFieldInfo &RealInfo =
Field.Contents.RealInfo;
3965 if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3968 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3969 Field.LengthOf = RealInfo.AsIntValues.size();
3974 Struct.NextOffset = FieldEnd;
3982bool MasmParser::parseDirectiveRealValue(
StringRef IDVal,
3985 if (StructInProgress.
empty()) {
3987 if (emitRealValues(Semantics))
3988 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3989 }
else if (addRealField(
"", Semantics,
Size)) {
3990 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3997bool MasmParser::parseDirectiveNamedRealValue(
StringRef TypeName,
4001 if (StructInProgress.
empty()) {
4004 getStreamer().emitLabel(Sym);
4006 if (emitRealValues(Semantics, &Count))
4007 return addErrorSuffix(
" in '" + TypeName +
"' directive");
4013 Type.Length = Count;
4015 }
else if (addRealField(
Name, Semantics,
Size)) {
4016 return addErrorSuffix(
" in '" + TypeName +
"' directive");
4021bool MasmParser::parseOptionalAngleBracketOpen() {
4024 AngleBracketDepth++;
4028 AngleBracketDepth++;
4032 AngleBracketDepth++;
4039bool MasmParser::parseAngleBracketClose(
const Twine &Msg) {
4046 AngleBracketDepth--;
4050bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4051 const IntFieldInfo &Contents,
4052 FieldInitializer &Initializer) {
4053 SMLoc Loc = getTok().getLoc();
4058 return Error(Loc,
"Cannot initialize scalar field with array value");
4062 }
else if (parseOptionalAngleBracketOpen()) {
4064 return Error(Loc,
"Cannot initialize scalar field with array value");
4066 parseAngleBracketClose())
4068 }
else if (
Field.LengthOf > 1 &&
Field.Type > 1) {
4069 return Error(Loc,
"Cannot initialize array field with scalar value");
4070 }
else if (parseScalarInitializer(
Field.Type, Values,
4076 return Error(Loc,
"Initializer too long for field; expected at most " +
4077 std::to_string(
Field.LengthOf) +
" elements, got " +
4078 std::to_string(Values.
size()));
4081 Values.
append(Contents.Values.begin() + Values.
size(), Contents.Values.end());
4083 Initializer = FieldInitializer(std::move(Values));
4087bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4088 const RealFieldInfo &Contents,
4089 FieldInitializer &Initializer) {
4091 switch (
Field.Type) {
4093 Semantics = &APFloat::IEEEsingle();
4096 Semantics = &APFloat::IEEEdouble();
4099 Semantics = &APFloat::x87DoubleExtended();
4105 SMLoc Loc = getTok().getLoc();
4109 if (
Field.LengthOf == 1)
4110 return Error(Loc,
"Cannot initialize scalar field with array value");
4114 }
else if (parseOptionalAngleBracketOpen()) {
4115 if (
Field.LengthOf == 1)
4116 return Error(Loc,
"Cannot initialize scalar field with array value");
4118 parseAngleBracketClose())
4120 }
else if (
Field.LengthOf > 1) {
4121 return Error(Loc,
"Cannot initialize array field with scalar value");
4124 if (parseRealValue(*Semantics, AsIntValues.
back()))
4128 if (AsIntValues.
size() >
Field.LengthOf) {
4129 return Error(Loc,
"Initializer too long for field; expected at most " +
4130 std::to_string(
Field.LengthOf) +
" elements, got " +
4131 std::to_string(AsIntValues.
size()));
4134 AsIntValues.
append(Contents.AsIntValues.begin() + AsIntValues.
size(),
4135 Contents.AsIntValues.end());
4137 Initializer = FieldInitializer(std::move(AsIntValues));
4141bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4142 const StructFieldInfo &Contents,
4143 FieldInitializer &Initializer) {
4144 SMLoc Loc = getTok().getLoc();
4146 std::vector<StructInitializer> Initializers;
4147 if (
Field.LengthOf > 1) {
4149 if (parseStructInstList(Contents.Structure, Initializers,
4153 }
else if (parseOptionalAngleBracketOpen()) {
4154 if (parseStructInstList(Contents.Structure, Initializers,
4156 parseAngleBracketClose())
4159 return Error(Loc,
"Cannot initialize array field with scalar value");
4162 Initializers.emplace_back();
4163 if (parseStructInitializer(Contents.Structure, Initializers.back()))
4167 if (Initializers.size() >
Field.LengthOf) {
4168 return Error(Loc,
"Initializer too long for field; expected at most " +
4169 std::to_string(
Field.LengthOf) +
" elements, got " +
4170 std::to_string(Initializers.size()));
4173 Initializers.insert(Initializers.end(),
4174 Contents.Initializers.begin() + Initializers.size(),
4175 Contents.Initializers.end());
4177 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
4181bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4182 FieldInitializer &Initializer) {
4183 switch (
Field.Contents.FT) {
4185 return parseFieldInitializer(
Field,
Field.Contents.IntInfo, Initializer);
4187 return parseFieldInitializer(
Field,
Field.Contents.RealInfo, Initializer);
4189 return parseFieldInitializer(
Field,
Field.Contents.StructInfo, Initializer);
4194bool MasmParser::parseStructInitializer(
const StructInfo &Structure,
4195 StructInitializer &Initializer) {
4196 const AsmToken FirstToken = getTok();
4198 std::optional<AsmToken::TokenKind> EndToken;
4201 }
else if (parseOptionalAngleBracketOpen()) {
4203 AngleBracketDepth++;
4210 return Error(FirstToken.
getLoc(),
"Expected struct initializer");
4213 auto &FieldInitializers = Initializer.FieldInitializers;
4214 size_t FieldIndex = 0;
4217 while (getTok().
isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
4218 const FieldInfo &
Field = Structure.Fields[FieldIndex++];
4222 FieldInitializers.push_back(
Field.Contents);
4226 FieldInitializers.emplace_back(
Field.Contents.FT);
4227 if (parseFieldInitializer(
Field, FieldInitializers.back()))
4231 SMLoc CommaLoc = getTok().getLoc();
4234 if (FieldIndex == Structure.Fields.size())
4235 return Error(CommaLoc,
"'" + Structure.Name +
4236 "' initializer initializes too many fields");
4242 FieldInitializers.push_back(
Field.Contents);
4246 return parseAngleBracketClose();
4248 return parseToken(*EndToken);
4254bool MasmParser::parseStructInstList(
4255 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
4257 while (getTok().
isNot(EndToken) ||
4260 const AsmToken NextTok = peekTok();
4269 "cannot repeat value a non-constant number of times");
4270 const int64_t Repetitions = MCE->
getValue();
4271 if (Repetitions < 0)
4273 "cannot repeat value a negative number of times");
4275 std::vector<StructInitializer> DuplicatedValues;
4277 "parentheses required for 'dup' contents") ||
4278 parseStructInstList(Structure, DuplicatedValues) || parseRParen())
4281 for (
int i = 0; i < Repetitions; ++i)
4284 Initializers.emplace_back();
4285 if (parseStructInitializer(Structure, Initializers.back()))
4298bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4299 const IntFieldInfo &Contents) {
4308bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4309 const RealFieldInfo &Contents) {
4310 for (
const APInt &AsInt : Contents.AsIntValues) {
4317bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4318 const StructFieldInfo &Contents) {
4319 for (
const auto &Initializer : Contents.Initializers) {
4321 for (
const auto &SubField : Contents.Structure.Fields) {
4322 getStreamer().emitZeros(SubField.Offset -
Offset);
4323 Offset = SubField.Offset + SubField.SizeOf;
4324 emitFieldInitializer(SubField, Initializer.FieldInitializers[
Index++]);
4330bool MasmParser::emitFieldValue(
const FieldInfo &
Field) {
4331 switch (
Field.Contents.FT) {
4333 return emitFieldValue(
Field,
Field.Contents.IntInfo);
4335 return emitFieldValue(
Field,
Field.Contents.RealInfo);
4337 return emitFieldValue(
Field,
Field.Contents.StructInfo);
4342bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4343 const IntFieldInfo &Contents,
4344 const IntFieldInfo &Initializer) {
4345 for (
const auto &
Value : Initializer.Values) {
4350 for (
const auto &
Value :
4358bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4359 const RealFieldInfo &Contents,
4360 const RealFieldInfo &Initializer) {
4361 for (
const auto &AsInt : Initializer.AsIntValues) {
4366 for (
const auto &AsInt :
4374bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4375 const StructFieldInfo &Contents,
4376 const StructFieldInfo &Initializer) {
4377 for (
const auto &
Init : Initializer.Initializers) {
4378 if (emitStructInitializer(Contents.Structure,
Init))
4383 Initializer.Initializers.size())) {
4384 if (emitStructInitializer(Contents.Structure,
Init))
4390bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4391 const FieldInitializer &Initializer) {
4392 switch (
Field.Contents.FT) {
4394 return emitFieldInitializer(
Field,
Field.Contents.IntInfo,
4395 Initializer.IntInfo);
4397 return emitFieldInitializer(
Field,
Field.Contents.RealInfo,
4398 Initializer.RealInfo);
4400 return emitFieldInitializer(
Field,
Field.Contents.StructInfo,
4401 Initializer.StructInfo);
4406bool MasmParser::emitStructInitializer(
const StructInfo &Structure,
4407 const StructInitializer &Initializer) {
4408 if (!Structure.Initializable)
4409 return Error(getLexer().getLoc(),
4410 "cannot initialize a value of type '" + Structure.Name +
4411 "'; 'org' was used in the type's declaration");
4413 for (
const auto &
Init : Initializer.FieldInitializers) {
4414 const auto &
Field = Structure.Fields[
Index++];
4422 Structure.Fields, Initializer.FieldInitializers.size())) {
4425 if (emitFieldValue(
Field))
4429 if (
Offset != Structure.Size)
4430 getStreamer().emitZeros(Structure.Size -
Offset);
4435bool MasmParser::emitStructValues(
const StructInfo &Structure,
4437 std::vector<StructInitializer> Initializers;
4438 if (parseStructInstList(Structure, Initializers))
4441 for (
const auto &Initializer : Initializers) {
4442 if (emitStructInitializer(Structure, Initializer))
4447 *Count = Initializers.size();
4452bool MasmParser::addStructField(
StringRef Name,
const StructInfo &Structure) {
4453 StructInfo &OwningStruct = StructInProgress.
back();
4455 OwningStruct.addField(
Name, FT_STRUCT, Structure.AlignmentSize);
4456 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4458 StructInfo.Structure = Structure;
4461 if (parseStructInstList(Structure, StructInfo.Initializers))
4464 Field.LengthOf = StructInfo.Initializers.size();
4468 if (!OwningStruct.IsUnion) {
4469 OwningStruct.NextOffset = FieldEnd;
4471 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
4479bool MasmParser::parseDirectiveStructValue(
const StructInfo &Structure,
4481 if (StructInProgress.
empty()) {
4482 if (emitStructValues(Structure))
4484 }
else if (addStructField(
"", Structure)) {
4485 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4493bool MasmParser::parseDirectiveNamedStructValue(
const StructInfo &Structure,
4496 if (StructInProgress.
empty()) {
4499 getStreamer().emitLabel(Sym);
4501 if (emitStructValues(Structure, &Count))
4504 Type.Name = Structure.Name;
4505 Type.Size = Structure.Size * Count;
4506 Type.ElementSize = Structure.Size;
4507 Type.Length = Count;
4509 }
else if (addStructField(
Name, Structure)) {
4510 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4528 int64_t AlignmentValue = 1;
4531 parseAbsoluteExpression(AlignmentValue)) {
4532 return addErrorSuffix(
" in alignment value for '" +
Twine(
Directive) +
4536 return Error(NextTok.
getLoc(),
"alignment must be a power of two; was " +
4537 std::to_string(AlignmentValue));
4543 QualifierLoc = getTok().getLoc();
4544 if (parseIdentifier(Qualifier))
4545 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4546 if (!
Qualifier.equals_insensitive(
"nonunique"))
4547 return Error(QualifierLoc,
"Unrecognized qualifier for '" +
4549 "' directive; expected none or NONUNIQUE");
4553 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4564 DirectiveKind DirKind) {
4565 if (StructInProgress.
empty())
4566 return TokError(
"missing name in top-level '" +
Twine(
Directive) +
4571 Name = getTok().getIdentifier();
4575 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4579 StructInProgress.
reserve(StructInProgress.
size() + 1);
4581 StructInProgress.
back().Alignment);
4586 if (StructInProgress.
empty())
4587 return Error(NameLoc,
"ENDS directive without matching STRUC/STRUCT/UNION");
4588 if (StructInProgress.
size() > 1)
4589 return Error(NameLoc,
"unexpected name in nested ENDS directive");
4590 if (StructInProgress.
back().Name.compare_insensitive(
Name))
4591 return Error(NameLoc,
"mismatched name in ENDS directive; expected '" +
4592 StructInProgress.
back().Name +
"'");
4593 StructInfo Structure = StructInProgress.
pop_back_val();
4597 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4598 Structs[
Name.lower()] = Structure;
4601 return addErrorSuffix(
" in ENDS directive");
4606bool MasmParser::parseDirectiveNestedEnds() {
4607 if (StructInProgress.
empty())
4608 return TokError(
"ENDS directive without matching STRUC/STRUCT/UNION");
4609 if (StructInProgress.
size() == 1)
4610 return TokError(
"missing name in top-level ENDS directive");
4613 return addErrorSuffix(
" in nested ENDS directive");
4615 StructInfo Structure = StructInProgress.
pop_back_val();
4617 Structure.Size =
llvm::alignTo(Structure.Size, Structure.Alignment);
4619 StructInfo &ParentStruct = StructInProgress.
back();
4620 if (Structure.Name.empty()) {
4623 const size_t OldFields = ParentStruct.Fields.size();
4624 ParentStruct.Fields.insert(
4625 ParentStruct.Fields.end(),
4626 std::make_move_iterator(Structure.Fields.begin()),
4627 std::make_move_iterator(Structure.Fields.end()));
4628 for (
const auto &FieldByName : Structure.FieldsByName) {
4629 ParentStruct.FieldsByName[FieldByName.getKey()] =
4630 FieldByName.getValue() + OldFields;
4633 unsigned FirstFieldOffset = 0;
4634 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
4636 ParentStruct.NextOffset,
4637 std::min(ParentStruct.Alignment, Structure.AlignmentSize));
4640 if (ParentStruct.IsUnion) {
4641 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4646 const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
4647 if (!ParentStruct.IsUnion) {
4648 ParentStruct.NextOffset = StructureEnd;
4650 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4653 FieldInfo &
Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4654 Structure.AlignmentSize);
4655 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4661 if (!ParentStruct.IsUnion) {
4662 ParentStruct.NextOffset = StructureEnd;
4664 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4666 StructInfo.Structure = Structure;
4667 StructInfo.Initializers.emplace_back();
4668 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4669 for (
const auto &SubField : Structure.Fields) {
4670 FieldInitializers.push_back(SubField.Contents);
4679bool MasmParser::parseDirectiveOrg() {
4682 if (checkForValidSection() || parseExpression(
Offset))
4685 return addErrorSuffix(
" in 'org' directive");
4687 if (StructInProgress.
empty()) {
4689 if (checkForValidSection())
4690 return addErrorSuffix(
" in 'org' directive");
4692 getStreamer().emitValueToOffset(
Offset, 0, OffsetLoc);
4695 StructInfo &Structure = StructInProgress.
back();
4697 if (!
Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
4698 return Error(OffsetLoc,
4699 "expected absolute expression in 'org' directive");
4703 "expected non-negative value in struct's 'org' directive; was " +
4704 std::to_string(OffsetRes));
4705 Structure.NextOffset =
static_cast<unsigned>(OffsetRes);
4708 Structure.Initializable =
false;
4714bool MasmParser::emitAlignTo(int64_t Alignment) {
4715 if (StructInProgress.
empty()) {
4717 if (checkForValidSection())
4723 assert(Section &&
"must have section to emit alignment");
4724 if (
Section->useCodeAlign()) {
4725 getStreamer().emitCodeAlignment(
Align(Alignment),
4726 &getTargetParser().getSTI(),
4730 getStreamer().emitValueToAlignment(
Align(Alignment), 0,
4736 StructInfo &Structure = StructInProgress.
back();
4737 Structure.NextOffset =
llvm::alignTo(Structure.NextOffset, Alignment);
4745bool MasmParser::parseDirectiveAlign() {
4746 SMLoc AlignmentLoc = getLexer().getLoc();
4752 "align directive with no operand is ignored") &&
4755 if (parseAbsoluteExpression(Alignment) ||
4757 return addErrorSuffix(
" in align directive");
4760 bool ReturnVal =
false;
4767 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2; was " +
4768 std::to_string(Alignment));
4770 if (emitAlignTo(Alignment))
4771 ReturnVal |= addErrorSuffix(
" in align directive");
4778bool MasmParser::parseDirectiveEven() {
4780 return addErrorSuffix(
" in even directive");
4788bool MasmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
4790 int64_t FileNumber = -1;
4792 FileNumber = getTok().getIntVal();
4796 return TokError(
"negative file number");
4804 "unexpected token in '.file' directive") ||
4805 parseEscapedString(Path))
4810 std::string FilenameData;
4812 if (
check(FileNumber == -1,
4813 "explicit path specified, but no file number") ||
4814 parseEscapedString(FilenameData))
4823 bool HasMD5 =
false;
4825 std::optional<StringRef>
Source;
4826 bool HasSource =
false;
4827 std::string SourceString;
4832 "unexpected token in '.file' directive") ||
4833 parseIdentifier(Keyword))
4835 if (Keyword ==
"md5") {
4837 if (
check(FileNumber == -1,
4838 "MD5 checksum specified, but no file number") ||
4841 }
else if (Keyword ==
"source") {
4843 if (
check(FileNumber == -1,
4844 "source specified, but no file number") ||
4846 "unexpected token in '.file' directive") ||
4847 parseEscapedString(SourceString))
4850 return TokError(
"unexpected token in '.file' directive");
4854 if (FileNumber == -1) {
4858 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4859 getStreamer().emitFileDirective(Filename);
4869 std::optional<MD5::MD5Result> CKMem;
4872 for (
unsigned i = 0; i != 8; ++i) {
4873 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4874 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4879 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
4880 memcpy(SourceBuf, SourceString.data(), SourceString.size());
4883 if (FileNumber == 0) {
4885 return Warning(DirectiveLoc,
"file 0 not supported prior to DWARF-5");
4886 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4889 FileNumber, Directory, Filename, CKMem, Source);
4896 ReportedInconsistentMD5 =
true;
4897 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
4906bool MasmParser::parseDirectiveLine() {
4909 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
4927bool MasmParser::parseDirectiveLoc() {
4928 int64_t FileNumber = 0, LineNumber = 0;
4929 SMLoc Loc = getTok().getLoc();
4930 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
4932 "file number less than one in '.loc' directive") ||
4933 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4934 "unassigned file number in '.loc' directive"))
4939 LineNumber = getTok().getIntVal();
4941 return TokError(
"line number less than zero in '.loc' directive");
4945 int64_t ColumnPos = 0;
4947 ColumnPos = getTok().getIntVal();
4949 return TokError(
"column position less than zero in '.loc' directive");
4953 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4958 auto parseLocOp = [&]() ->
bool {
4960 SMLoc Loc = getTok().getLoc();
4961 if (parseIdentifier(
Name))
4962 return TokError(
"unexpected token in '.loc' directive");
4964 if (
Name ==
"basic_block")
4966 else if (
Name ==
"prologue_end")
4968 else if (
Name ==
"epilogue_begin")
4970 else if (
Name ==
"is_stmt") {
4971 Loc = getTok().getLoc();
4973 if (parseExpression(
Value))
4979 Flags &= ~DWARF2_FLAG_IS_STMT;
4980 else if (
Value == 1)
4983 return Error(Loc,
"is_stmt value not 0 or 1");
4985 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
4987 }
else if (
Name ==
"isa") {
4988 Loc = getTok().getLoc();
4990 if (parseExpression(
Value))
4996 return Error(Loc,
"isa number less than zero");
4999 return Error(Loc,
"isa number not a constant value");
5001 }
else if (
Name ==
"discriminator") {
5002 if (parseAbsoluteExpression(Discriminator))
5005 return Error(Loc,
"unknown sub-directive in '.loc' directive");
5010 if (parseMany(parseLocOp,
false ))
5013 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
5021bool MasmParser::parseDirectiveStabs() {
5022 return TokError(
"unsupported directive '.stabs'");
5027bool MasmParser::parseDirectiveCVFile() {
5028 SMLoc FileNumberLoc = getTok().getLoc();
5031 std::string Checksum;
5034 if (parseIntToken(FileNumber,
5035 "expected file number in '.cv_file' directive") ||
5036 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
5038 "unexpected token in '.cv_file' directive") ||
5039 parseEscapedString(Filename))
5043 "unexpected token in '.cv_file' directive") ||
5044 parseEscapedString(Checksum) ||
5045 parseIntToken(ChecksumKind,
5046 "expected checksum kind in '.cv_file' directive") ||
5051 Checksum = fromHex(Checksum);
5052 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
5053 memcpy(CKMem, Checksum.data(), Checksum.size());
5057 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
5058 static_cast<uint8_t
>(ChecksumKind)))
5059 return Error(FileNumberLoc,
"file number already allocated");
5064bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
5067 return parseTokenLoc(Loc) ||
5068 parseIntToken(FunctionId,
"expected function id in '" + DirectiveName +
5070 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
5071 "expected function id within range [0, UINT_MAX)");
5074bool MasmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
5076 return parseTokenLoc(Loc) ||
5077 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
5079 check(FileNumber < 1, Loc,
"file number less than one in '" +
5080 DirectiveName +
"' directive") ||
5081 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
5082 "unassigned file number in '" + DirectiveName +
"' directive");
5089bool MasmParser::parseDirectiveCVFuncId() {
5090 SMLoc FunctionIdLoc = getTok().getLoc();
5093 if (parseCVFunctionId(FunctionId,
".cv_func_id") || parseEOL())
5096 if (!getStreamer().emitCVFuncIdDirective(FunctionId))
5097 return Error(FunctionIdLoc,
"function id already allocated");
5110bool MasmParser::parseDirectiveCVInlineSiteId() {
5111 SMLoc FunctionIdLoc = getTok().getLoc();
5119 if (parseCVFunctionId(FunctionId,
".cv_inline_site_id"))
5124 getTok().getIdentifier() !=
"within"),
5125 "expected 'within' identifier in '.cv_inline_site_id' directive"))
5130 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
5135 getTok().getIdentifier() !=
"inlined_at"),
5136 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
5142 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
5143 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
5148 IACol = getTok().getIntVal();
5155 if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
5156 IALine, IACol, FunctionIdLoc))
5157 return Error(FunctionIdLoc,
"function id already allocated");
5169bool MasmParser::parseDirectiveCVLoc() {
5170 SMLoc DirectiveLoc = getTok().getLoc();
5171 int64_t FunctionId, FileNumber;
5172 if (parseCVFunctionId(FunctionId,
".cv_loc") ||
5173 parseCVFileId(FileNumber,
".cv_loc"))
5176 int64_t LineNumber = 0;
5178 LineNumber = getTok().getIntVal();
5180 return TokError(
"line number less than zero in '.cv_loc' directive");
5184 int64_t ColumnPos = 0;
5186 ColumnPos = getTok().getIntVal();
5188 return TokError(
"column position less than zero in '.cv_loc' directive");
5192 bool PrologueEnd =
false;
5195 auto parseOp = [&]() ->
bool {
5197 SMLoc Loc = getTok().getLoc();
5198 if (parseIdentifier(
Name))
5199 return TokError(
"unexpected token in '.cv_loc' directive");
5200 if (
Name ==
"prologue_end")
5202 else if (
Name ==
"is_stmt") {
5203 Loc = getTok().getLoc();
5205 if (parseExpression(
Value))
5209 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
5213 return Error(Loc,
"is_stmt value not 0 or 1");
5215 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
5220 if (parseMany(parseOp,
false ))
5223 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
5224 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
5231bool MasmParser::parseDirectiveCVLinetable() {
5234 SMLoc Loc = getTok().getLoc();
5235 if (parseCVFunctionId(FunctionId,
".cv_linetable") ||
5237 "unexpected token in '.cv_linetable' directive") ||
5238 parseTokenLoc(Loc) ||
check(parseIdentifier(FnStartName), Loc,
5239 "expected identifier in directive") ||
5241 "unexpected token in '.cv_linetable' directive") ||
5242 parseTokenLoc(Loc) ||
check(parseIdentifier(FnEndName), Loc,
5243 "expected identifier in directive"))
5246 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5247 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5249 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
5255bool MasmParser::parseDirectiveCVInlineLinetable() {
5256 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
5258 SMLoc Loc = getTok().getLoc();
5259 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
5260 parseTokenLoc(Loc) ||
5263 "expected SourceField in '.cv_inline_linetable' directive") ||
5264 check(SourceFileId <= 0, Loc,
5265 "File id less than zero in '.cv_inline_linetable' directive") ||
5266 parseTokenLoc(Loc) ||
5269 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
5270 check(SourceLineNum < 0, Loc,
5271 "Line number less than zero in '.cv_inline_linetable' directive") ||
5272 parseTokenLoc(Loc) ||
check(parseIdentifier(FnStartName), Loc,
5273 "expected identifier in directive") ||
5274 parseTokenLoc(Loc) ||
check(parseIdentifier(FnEndName), Loc,
5275 "expected identifier in directive"))
5281 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5282 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5283 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
5284 SourceLineNum, FnStartSym,
5289void MasmParser::initializeCVDefRangeTypeMap() {
5290 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
5291 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
5292 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
5293 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
5298bool MasmParser::parseDirectiveCVDefRange() {
5300 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
5302 Loc = getLexer().getLoc();
5304 if (parseIdentifier(GapStartName))
5305 return Error(Loc,
"expected identifier in directive");
5306 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
5308 Loc = getLexer().getLoc();
5310 if (parseIdentifier(GapEndName))
5311 return Error(Loc,
"expected identifier in directive");
5312 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
5314 Ranges.push_back({GapStartSym, GapEndSym});
5320 "expected comma before def_range type in .cv_def_range directive") ||
5321 parseIdentifier(CVDefRangeTypeStr))
5322 return Error(Loc,
"expected def_range type in directive");
5325 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
5326 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
5328 : CVTypeIt->getValue();
5330 case CVDR_DEFRANGE_REGISTER: {
5332 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5333 ".cv_def_range directive") ||
5334 parseAbsoluteExpression(DRRegister))
5335 return Error(Loc,
"expected register number");
5340 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5343 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
5346 "expected comma before offset in .cv_def_range directive") ||
5347 parseAbsoluteExpression(DROffset))
5348 return Error(Loc,
"expected offset value");
5352 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5355 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
5357 int64_t DROffsetInParent;
5358 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5359 ".cv_def_range directive") ||
5360 parseAbsoluteExpression(DRRegister))
5361 return Error(Loc,
"expected register number");
5363 "expected comma before offset in .cv_def_range directive") ||
5364 parseAbsoluteExpression(DROffsetInParent))
5365 return Error(Loc,
"expected offset value");
5371 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5374 case CVDR_DEFRANGE_REGISTER_REL: {
5377 int64_t DRBasePointerOffset;
5378 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5379 ".cv_def_range directive") ||
5380 parseAbsoluteExpression(DRRegister))
5381 return Error(Loc,
"expected register value");
5384 "expected comma before flag value in .cv_def_range directive") ||
5385 parseAbsoluteExpression(DRFlags))
5386 return Error(Loc,
"expected flag value");
5387 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
5388 "in .cv_def_range directive") ||
5389 parseAbsoluteExpression(DRBasePointerOffset))
5390 return Error(Loc,
"expected base pointer offset value");
5394 DRHdr.
Flags = DRFlags;
5396 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5400 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
5407bool MasmParser::parseDirectiveCVString() {
5409 if (checkForValidSection() || parseEscapedString(
Data))
5410 return addErrorSuffix(
" in '.cv_string' directive");
5413 std::pair<StringRef, unsigned> Insertion =
5414 getCVContext().addToStringTable(
Data);
5415 getStreamer().emitIntValue(Insertion.second, 4);
5421bool MasmParser::parseDirectiveCVStringTable() {
5422 getStreamer().emitCVStringTableDirective();
5428bool MasmParser::parseDirectiveCVFileChecksums() {
5429 getStreamer().emitCVFileChecksumsDirective();
5435bool MasmParser::parseDirectiveCVFileChecksumOffset() {
5437 if (parseIntToken(FileNo,
"expected identifier in directive"))
5441 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
5447bool MasmParser::parseDirectiveCVFPOData() {
5448 SMLoc DirLoc = getLexer().getLoc();
5450 if (parseIdentifier(ProcName))
5451 return TokError(
"expected symbol name");
5452 if (parseEOL(
"unexpected tokens"))
5453 return addErrorSuffix(
" in '.cv_fpo_data' directive");
5454 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
5455 getStreamer().emitCVFPOData(ProcSym, DirLoc);