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;
486 DirectiveKindMap[
Directive] = DirectiveKindMap[Alias];
500 if (AssemblerDialect == ~0U)
503 return AssemblerDialect;
506 AssemblerDialect = i;
515 enum ExpandKind { ExpandMacros, DoNotExpandMacros };
520 ParsingMSInlineAsm =
V;
551 SMLoc &EndLoc)
override;
560 enum IdentifierPositionKind { StandardPosition, StartOfStatement };
573 const AsmToken peekTok(
bool ShouldSkipSpace =
true);
575 bool parseStatement(ParseStatementInfo &Info,
578 bool parseCppHashLineFilenameComment(
SMLoc L);
583 const std::vector<std::string> &Locals,
SMLoc L);
586 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
592 bool handleMacroEntry(
603 void handleMacroExit();
612 parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A,
615 void printMacroInstantiations();
617 bool expandStatement(
SMLoc Loc);
632 bool enabledGenDwarfForAssembly();
635 bool enterIncludeFile(
const std::string &Filename);
643 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0,
644 bool EndStatementAtEOF =
true);
658 bool parseTextItem(std::string &Data);
663 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
664 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
665 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
667 bool parseRegisterOrRegisterNumber(int64_t &
Register,
SMLoc DirectiveLoc);
670 bool parseCVFileId(int64_t &FileId,
StringRef DirectiveName);
675 DK_HANDLER_DIRECTIVE,
740 DK_CV_INLINE_SITE_ID,
743 DK_CV_INLINE_LINETABLE,
748 DK_CV_FILECHECKSUM_OFFSET,
754 DK_CFI_DEF_CFA_OFFSET,
755 DK_CFI_ADJUST_CFA_OFFSET,
756 DK_CFI_DEF_CFA_REGISTER,
761 DK_CFI_REMEMBER_STATE,
762 DK_CFI_RESTORE_STATE,
766 DK_CFI_RETURN_COLUMN,
804 bool isMacroLikeDirective();
807 enum CVDefRangeType {
809 CVDR_DEFRANGE_REGISTER,
810 CVDR_DEFRANGE_FRAMEPOINTER_REL,
811 CVDR_DEFRANGE_SUBFIELD_REGISTER,
812 CVDR_DEFRANGE_REGISTER_REL
845 const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol,
SMLoc StartLoc);
847 std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
851 bool parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated);
855 bool parseScalarInitializer(
unsigned Size,
857 unsigned StringPadLength = 0);
858 bool parseScalarInstList(
861 bool emitIntegralValues(
unsigned Size,
unsigned *Count =
nullptr);
864 bool parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
868 bool emitRealValues(
const fltSemantics &Semantics,
unsigned *Count =
nullptr);
872 bool parseRealInstList(
875 bool parseDirectiveNamedRealValue(
StringRef TypeName,
880 bool parseOptionalAngleBracketOpen();
881 bool parseAngleBracketClose(
const Twine &Msg =
"expected '>'");
883 bool parseFieldInitializer(
const FieldInfo &
Field,
884 FieldInitializer &Initializer);
885 bool parseFieldInitializer(
const FieldInfo &
Field,
886 const IntFieldInfo &Contents,
887 FieldInitializer &Initializer);
888 bool parseFieldInitializer(
const FieldInfo &
Field,
889 const RealFieldInfo &Contents,
890 FieldInitializer &Initializer);
891 bool parseFieldInitializer(
const FieldInfo &
Field,
892 const StructFieldInfo &Contents,
893 FieldInitializer &Initializer);
895 bool parseStructInitializer(
const StructInfo &Structure,
896 StructInitializer &Initializer);
897 bool parseStructInstList(
898 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
901 bool emitFieldValue(
const FieldInfo &
Field);
902 bool emitFieldValue(
const FieldInfo &
Field,
const IntFieldInfo &Contents);
903 bool emitFieldValue(
const FieldInfo &
Field,
const RealFieldInfo &Contents);
904 bool emitFieldValue(
const FieldInfo &
Field,
const StructFieldInfo &Contents);
906 bool emitFieldInitializer(
const FieldInfo &
Field,
907 const FieldInitializer &Initializer);
908 bool emitFieldInitializer(
const FieldInfo &
Field,
909 const IntFieldInfo &Contents,
910 const IntFieldInfo &Initializer);
911 bool emitFieldInitializer(
const FieldInfo &
Field,
912 const RealFieldInfo &Contents,
913 const RealFieldInfo &Initializer);
914 bool emitFieldInitializer(
const FieldInfo &
Field,
915 const StructFieldInfo &Contents,
916 const StructFieldInfo &Initializer);
918 bool emitStructInitializer(
const StructInfo &Structure,
919 const StructInitializer &Initializer);
922 bool emitStructValues(
const StructInfo &Structure,
unsigned *Count =
nullptr);
923 bool addStructField(
StringRef Name,
const StructInfo &Structure);
924 bool parseDirectiveStructValue(
const StructInfo &Structure,
926 bool parseDirectiveNamedStructValue(
const StructInfo &Structure,
932 DirectiveKind DirKind,
SMLoc NameLoc);
934 bool parseDirectiveOrg();
936 bool emitAlignTo(int64_t Alignment);
937 bool parseDirectiveAlign();
938 bool parseDirectiveEven();
941 bool parseDirectiveFile(
SMLoc DirectiveLoc);
942 bool parseDirectiveLine();
943 bool parseDirectiveLoc();
944 bool parseDirectiveStabs();
948 bool parseDirectiveCVFile();
949 bool parseDirectiveCVFuncId();
950 bool parseDirectiveCVInlineSiteId();
951 bool parseDirectiveCVLoc();
952 bool parseDirectiveCVLinetable();
953 bool parseDirectiveCVInlineLinetable();
954 bool parseDirectiveCVDefRange();
955 bool parseDirectiveCVString();
956 bool parseDirectiveCVStringTable();
957 bool parseDirectiveCVFileChecksums();
958 bool parseDirectiveCVFileChecksumOffset();
959 bool parseDirectiveCVFPOData();
962 bool parseDirectiveCFIRegister(
SMLoc DirectiveLoc);
963 bool parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc);
964 bool parseDirectiveCFISections();
965 bool parseDirectiveCFIStartProc();
966 bool parseDirectiveCFIEndProc();
967 bool parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc);
968 bool parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc);
969 bool parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc);
970 bool parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc);
971 bool parseDirectiveCFIOffset(
SMLoc DirectiveLoc);
972 bool parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc);
973 bool parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality);
974 bool parseDirectiveCFIRememberState(
SMLoc DirectiveLoc);
975 bool parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc);
976 bool parseDirectiveCFISameValue(
SMLoc DirectiveLoc);
977 bool parseDirectiveCFIRestore(
SMLoc DirectiveLoc);
978 bool parseDirectiveCFIEscape(
SMLoc DirectiveLoc);
979 bool parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc);
980 bool parseDirectiveCFISignalFrame();
981 bool parseDirectiveCFIUndefined(
SMLoc DirectiveLoc);
984 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
994 bool parseDirectiveNestedEnds();
996 bool parseDirectiveExtern();
1002 bool parseDirectiveComm(
bool IsLocal);
1004 bool parseDirectiveComment(
SMLoc DirectiveLoc);
1006 bool parseDirectiveInclude();
1009 bool parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
1011 bool parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1014 bool parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1015 bool CaseInsensitive);
1017 bool parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
1019 bool parseDirectiveElseIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
1021 bool parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1023 bool parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
1026 bool parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1027 bool CaseInsensitive);
1028 bool parseDirectiveElse(
SMLoc DirectiveLoc);
1029 bool parseDirectiveEndIf(
SMLoc DirectiveLoc);
1042 bool parseDirectiveWhile(
SMLoc DirectiveLoc);
1045 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
1049 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
1052 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
1055 bool parseDirectiveError(
SMLoc DirectiveLoc);
1057 bool parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1059 bool parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
bool ExpectDefined);
1062 bool parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1063 bool CaseInsensitive);
1065 bool parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero);
1068 bool parseDirectiveRadix(
SMLoc DirectiveLoc);
1071 bool parseDirectiveEcho(
SMLoc DirectiveLoc);
1073 void initializeDirectiveKindMap();
1074 void initializeCVDefRangeTypeMap();
1075 void initializeBuiltinSymbolMap();
1091 const MCAsmInfo &MAI,
struct tm TM,
unsigned CB)
1092 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI),
SrcMgr(SM),
1093 CurBuffer(CB ? CB : SM.getMainFileID()),
TM(
TM) {
1101 EndStatementAtEOFStack.push_back(
true);
1113 initializeDirectiveKindMap();
1114 PlatformParser->Initialize(*
this);
1115 initializeCVDefRangeTypeMap();
1116 initializeBuiltinSymbolMap();
1118 NumOfMacroInstantiations = 0;
1121MasmParser::~MasmParser() {
1122 assert((HadError || ActiveMacros.empty()) &&
1123 "Unexpected active macro instantiation!");
1130void MasmParser::printMacroInstantiations() {
1132 for (std::vector<MacroInstantiation *>::const_reverse_iterator
1133 it = ActiveMacros.rbegin(),
1134 ie = ActiveMacros.rend();
1137 "while in macro instantiation");
1141 printPendingErrors();
1143 printMacroInstantiations();
1147 if (getTargetParser().getTargetOptions().MCNoWarn)
1149 if (getTargetParser().getTargetOptions().MCFatalWarnings)
1152 printMacroInstantiations();
1159 printMacroInstantiations();
1163bool MasmParser::enterIncludeFile(
const std::string &Filename) {
1164 std::string IncludedFile;
1172 EndStatementAtEOFStack.push_back(
true);
1176void MasmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer,
1177 bool EndStatementAtEOF) {
1183bool MasmParser::expandMacros() {
1193 if (handleMacroInvocation(M, MacroLoc)) {
1200 std::optional<std::string> ExpandedValue;
1201 auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1202 if (BuiltinIt != BuiltinSymbolMap.end()) {
1204 evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.
getLoc());
1206 auto VarIt = Variables.
find(IDLower);
1207 if (VarIt != Variables.
end() && VarIt->getValue().IsText) {
1208 ExpandedValue = VarIt->getValue().TextValue;
1214 std::unique_ptr<MemoryBuffer> Instantiation =
1222 EndStatementAtEOFStack.push_back(
false);
1227const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {
1234 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
1243 if (StartOfStatement) {
1278 if (ParentIncludeLoc !=
SMLoc()) {
1279 EndStatementAtEOFStack.pop_back();
1280 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1283 EndStatementAtEOFStack.pop_back();
1284 assert(EndStatementAtEOFStack.empty());
1290const AsmToken MasmParser::peekTok(
bool ShouldSkipSpace) {
1294 size_t ReadCount = Lexer.
peekTokens(Buf, ShouldSkipSpace);
1296 if (ReadCount == 0) {
1300 if (ParentIncludeLoc !=
SMLoc()) {
1301 EndStatementAtEOFStack.pop_back();
1302 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1303 return peekTok(ShouldSkipSpace);
1305 EndStatementAtEOFStack.pop_back();
1306 assert(EndStatementAtEOFStack.empty());
1313bool MasmParser::enabledGenDwarfForAssembly() {
1315 if (!getContext().getGenDwarfForAssembly())
1320 if (getContext().getGenDwarfFileNumber() == 0) {
1323 if (!FirstCppHashFilename.
empty())
1324 getContext().setMCLineTableRootFile(
1325 0, getContext().getCompilationDir(), FirstCppHashFilename,
1326 std::nullopt, std::nullopt);
1328 getContext().getMCDwarfLineTable(0).getRootFile();
1329 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
1330 0, getContext().getCompilationDir(), RootFile.
Name,
1336bool MasmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
1338 if (!NoInitialTextSection)
1345 AsmCond StartingCondState = TheCondState;
1352 if (getContext().getGenDwarfForAssembly()) {
1353 MCSection *Sec = getStreamer().getCurrentSectionOnly();
1355 MCSymbol *SectionStartSym = getContext().createTempSymbol();
1356 getStreamer().emitLabel(SectionStartSym);
1359 bool InsertResult = getContext().addGenDwarfSection(Sec);
1360 assert(InsertResult &&
".text section should not have debug info yet");
1364 getTargetParser().onBeginOfFile();
1373 ParseStatementInfo
Info(&AsmStrRewrites);
1374 bool Parsed = parseStatement(Info,
nullptr);
1384 printPendingErrors();
1387 if (Parsed && !getLexer().isAtStartOfStatement())
1388 eatToEndOfStatement();
1391 getTargetParser().onEndOfFile();
1392 printPendingErrors();
1395 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1397 getTargetParser().flushPendingInstructions(getStreamer());
1401 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1403 const auto &LineTables = getContext().getMCDwarfLineTables();
1404 if (!LineTables.empty()) {
1406 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1407 if (
File.Name.empty() && Index != 0)
1408 printError(getTok().getLoc(),
"unassigned file number: " +
1410 " for .file directives");
1426 if (
Sym &&
Sym->isTemporary() && !
Sym->isVariable() &&
1431 printError(getTok().getLoc(),
"assembler local symbol '" +
1432 Sym->getName() +
"' not defined");
1438 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1439 if (std::get<2>(LocSym)->isUndefined()) {
1442 CppHashInfo = std::get<1>(LocSym);
1443 printError(std::get<0>(LocSym),
"directional label undefined");
1450 if (!HadError && !NoFinalize)
1453 return HadError || getContext().hadError();
1456bool MasmParser::checkForValidSection() {
1457 if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1459 return Error(getTok().getLoc(),
1460 "expected section directive before assembly directive");
1466void MasmParser::eatToEndOfStatement() {
1470 if (ParentIncludeLoc ==
SMLoc()) {
1474 EndStatementAtEOFStack.pop_back();
1475 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1489 const char *Start = getTok().getLoc().getPointer();
1490 while (Lexer.
isNot(EndTok)) {
1493 if (ParentIncludeLoc ==
SMLoc()) {
1496 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1498 EndStatementAtEOFStack.pop_back();
1499 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1501 Start = getTok().getLoc().getPointer();
1506 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1514 Str.append(S.str());
1519StringRef MasmParser::parseStringToEndOfStatement() {
1520 const char *Start = getTok().getLoc().getPointer();
1525 const char *
End = getTok().getLoc().getPointer();
1534bool MasmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1535 if (parseExpression(Res))
1538 return parseRParen();
1546bool MasmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1547 if (parseExpression(Res))
1549 EndLoc = getTok().getEndLoc();
1550 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1563bool MasmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1565 SMLoc FirstTokenLoc = getLexer().getLoc();
1567 switch (FirstTokenKind) {
1569 return TokError(
"unknown token in expression");
1575 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1583 if (parseIdentifier(Identifier)) {
1594 EndLoc = FirstTokenLoc;
1597 return Error(FirstTokenLoc,
"invalid token in expression");
1602 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1613 return Error(FirstTokenLoc,
"Expected @@ label before @B reference");
1618 std::pair<StringRef, StringRef>
Split;
1624 parseIdentifier(VName);
1627 "unexpected token in variant, expected ')'"))
1629 Split = std::make_pair(Identifier, VName);
1637 return Error(getLexer().getLoc(),
"expected a symbol reference");
1642 if (!
Split.second.empty()) {
1650 "invalid variant '" +
Split.second +
"'");
1657 if (
Split.second.empty()) {
1660 if (lookUpField(SymbolName,
Split.second, Info)) {
1661 std::pair<StringRef, StringRef> BaseMember =
Split.second.split(
'.');
1663 lookUpField(
Base, Member, Info);
1671 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1674 auto BuiltinIt = BuiltinSymbolMap.find(
SymbolName.lower());
1675 const BuiltinSymbol
Symbol = (BuiltinIt == BuiltinSymbolMap.end())
1677 : BuiltinIt->getValue();
1678 if (Symbol != BI_NO_SYMBOL) {
1679 const MCExpr *
Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
1689 if (VarIt != Variables.
end())
1691 Sym = getContext().getOrCreateSymbol(SymbolName);
1696 if (
Sym->isVariable()) {
1697 auto V =
Sym->getVariableValue(
false);
1698 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1699 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1700 DoInline = TV->inlineAssignedExpr();
1703 return Error(EndLoc,
"unexpected modifier on variable reference");
1704 Res =
Sym->getVariableValue(
false);
1720 if (
Info.Type.Name.empty()) {
1722 if (TypeIt != KnownType.
end()) {
1723 Info.Type = TypeIt->second;
1727 *TypeInfo =
Info.Type;
1732 return TokError(
"literal value out of range for directive");
1734 int64_t
IntVal = getTok().getIntVal();
1742 SMLoc ValueLoc = getTok().getLoc();
1744 if (parseEscapedString(
Value))
1746 if (
Value.size() > 8)
1747 return Error(ValueLoc,
"literal value out of range");
1749 for (
const unsigned char CharVal :
Value)
1750 IntValue = (IntValue << 8) | CharVal;
1755 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1774 return parseParenExpr(Res, EndLoc);
1776 if (!PlatformParser->HasBracketExpressions())
1777 return TokError(
"brackets expression not supported on this target");
1779 return parseBracketExpr(Res, EndLoc);
1782 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1788 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1794 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1826 return TokError(
"expected '(' after operator");
1828 if (parseExpression(Res, EndLoc))
1832 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1837bool MasmParser::parseExpression(
const MCExpr *&Res) {
1839 return parseExpression(Res, EndLoc);
1850 "Argument to the function cannot be a NULL value");
1852 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1853 (*CharPtr !=
'\0')) {
1854 if (*CharPtr ==
'!')
1858 if (*CharPtr ==
'>') {
1868 for (
size_t Pos = 0; Pos < BracketContents.
size(); Pos++) {
1869 if (BracketContents[Pos] ==
'!')
1871 Res += BracketContents[Pos];
1886bool MasmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1889 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1890 parseBinOpRHS(1, Res, EndLoc))
1896 if (Res->evaluateAsAbsolute(
Value))
1902bool MasmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1904 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1907bool MasmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1909 if (parseParenExpr(Res, EndLoc))
1912 for (; ParenDepth > 0; --ParenDepth) {
1913 if (parseBinOpRHS(1, Res, EndLoc))
1918 if (ParenDepth - 1 > 0) {
1919 EndLoc = getTok().getEndLoc();
1927bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1931 if (parseExpression(Expr))
1934 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1935 return Error(StartLoc,
"expected absolute expression");
1942 bool ShouldUseLogicalShr,
1943 bool EndExpressionAtGreater) {
1971 if (EndExpressionAtGreater)
2012 if (EndExpressionAtGreater)
2023 AngleBracketDepth > 0);
2028bool MasmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
2050 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
2054 if (TokPrec < Precedence)
2061 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
2067 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
2068 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
2081bool MasmParser::parseStatement(ParseStatementInfo &Info,
2083 assert(!hasPendingError() &&
"parseStatement started with pending error");
2089 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
2090 getTok().getString().front() ==
'\n')
2099 SMLoc ExpansionLoc = getTok().getLoc();
2110 return parseCppHashLineFilenameComment(IDLoc);
2117 IDVal = getTok().getString();
2120 return Error(IDLoc,
"unexpected token at start of statement");
2121 }
else if (parseIdentifier(IDVal, StartOfStatement)) {
2122 if (!TheCondState.
Ignore) {
2124 return Error(IDLoc,
"unexpected token at start of statement");
2133 DirectiveKindMap.find(IDVal.
lower());
2134 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
2136 : DirKindIt->getValue();
2142 return parseDirectiveIf(IDLoc, DirKind);
2144 return parseDirectiveIfb(IDLoc,
true);
2146 return parseDirectiveIfb(IDLoc,
false);
2148 return parseDirectiveIfdef(IDLoc,
true);
2150 return parseDirectiveIfdef(IDLoc,
false);
2152 return parseDirectiveIfidn(IDLoc,
false,
2155 return parseDirectiveIfidn(IDLoc,
false,
2158 return parseDirectiveIfidn(IDLoc,
true,
2161 return parseDirectiveIfidn(IDLoc,
true,
2165 return parseDirectiveElseIf(IDLoc, DirKind);
2167 return parseDirectiveElseIfb(IDLoc,
true);
2169 return parseDirectiveElseIfb(IDLoc,
false);
2171 return parseDirectiveElseIfdef(IDLoc,
true);
2173 return parseDirectiveElseIfdef(IDLoc,
false);
2175 return parseDirectiveElseIfidn(IDLoc,
false,
2178 return parseDirectiveElseIfidn(IDLoc,
false,
2181 return parseDirectiveElseIfidn(IDLoc,
true,
2184 return parseDirectiveElseIfidn(IDLoc,
true,
2187 return parseDirectiveElse(IDLoc);
2189 return parseDirectiveEndIf(IDLoc);
2194 if (TheCondState.
Ignore) {
2195 eatToEndOfStatement();
2205 if (checkForValidSection())
2213 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
2221 if (ParsingMSInlineAsm && SI) {
2223 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
2225 "We should have an internal name here.");
2228 IDVal = RewrittenLabel;
2231 if (IDVal ==
"@@") {
2234 Sym = getContext().getOrCreateSymbol(IDVal);
2253 getTargetParser().doBeforeLabelEmit(
Sym, IDLoc);
2256 if (!getTargetParser().isParsingMSInlineAsm())
2261 if (enabledGenDwarfForAssembly())
2265 getTargetParser().onLabelParsed(
Sym);
2272 return handleMacroEntry(M, IDLoc);
2277 if (DirKind != DK_NO_DIRECTIVE) {
2289 getTargetParser().flushPendingInstructions(getStreamer());
2295 return parseDirectiveNestedEnds();
2300 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2303 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2309 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2311 "Should only return Failure iff there was an error");
2323 return parseDirectiveAscii(IDVal,
false);
2326 return parseDirectiveAscii(IDVal,
true);
2330 return parseDirectiveValue(IDVal, 1);
2334 return parseDirectiveValue(IDVal, 2);
2338 return parseDirectiveValue(IDVal, 4);
2341 return parseDirectiveValue(IDVal, 6);
2345 return parseDirectiveValue(IDVal, 8);
2347 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2349 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2351 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2354 return parseDirectiveNestedStruct(IDVal, DirKind);
2356 return parseDirectiveNestedEnds();
2358 return parseDirectiveAlign();
2360 return parseDirectiveEven();
2362 return parseDirectiveOrg();
2364 return parseDirectiveExtern();
2366 return parseDirectiveSymbolAttribute(
MCSA_Global);
2368 return parseDirectiveComm(
false);
2370 return parseDirectiveComment(IDLoc);
2372 return parseDirectiveInclude();
2374 return parseDirectiveRepeat(IDLoc, IDVal);
2376 return parseDirectiveWhile(IDLoc);
2378 return parseDirectiveFor(IDLoc, IDVal);
2380 return parseDirectiveForc(IDLoc, IDVal);
2382 return parseDirectiveFile(IDLoc);
2384 return parseDirectiveLine();
2386 return parseDirectiveLoc();
2388 return parseDirectiveStabs();
2390 return parseDirectiveCVFile();
2392 return parseDirectiveCVFuncId();
2393 case DK_CV_INLINE_SITE_ID:
2394 return parseDirectiveCVInlineSiteId();
2396 return parseDirectiveCVLoc();
2397 case DK_CV_LINETABLE:
2398 return parseDirectiveCVLinetable();
2399 case DK_CV_INLINE_LINETABLE:
2400 return parseDirectiveCVInlineLinetable();
2401 case DK_CV_DEF_RANGE:
2402 return parseDirectiveCVDefRange();
2404 return parseDirectiveCVString();
2405 case DK_CV_STRINGTABLE:
2406 return parseDirectiveCVStringTable();
2407 case DK_CV_FILECHECKSUMS:
2408 return parseDirectiveCVFileChecksums();
2409 case DK_CV_FILECHECKSUM_OFFSET:
2410 return parseDirectiveCVFileChecksumOffset();
2411 case DK_CV_FPO_DATA:
2412 return parseDirectiveCVFPOData();
2413 case DK_CFI_SECTIONS:
2414 return parseDirectiveCFISections();
2415 case DK_CFI_STARTPROC:
2416 return parseDirectiveCFIStartProc();
2417 case DK_CFI_ENDPROC:
2418 return parseDirectiveCFIEndProc();
2419 case DK_CFI_DEF_CFA:
2420 return parseDirectiveCFIDefCfa(IDLoc);
2421 case DK_CFI_DEF_CFA_OFFSET:
2422 return parseDirectiveCFIDefCfaOffset(IDLoc);
2423 case DK_CFI_ADJUST_CFA_OFFSET:
2424 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2425 case DK_CFI_DEF_CFA_REGISTER:
2426 return parseDirectiveCFIDefCfaRegister(IDLoc);
2428 return parseDirectiveCFIOffset(IDLoc);
2429 case DK_CFI_REL_OFFSET:
2430 return parseDirectiveCFIRelOffset(IDLoc);
2431 case DK_CFI_PERSONALITY:
2432 return parseDirectiveCFIPersonalityOrLsda(
true);
2434 return parseDirectiveCFIPersonalityOrLsda(
false);
2435 case DK_CFI_REMEMBER_STATE:
2436 return parseDirectiveCFIRememberState(IDLoc);
2437 case DK_CFI_RESTORE_STATE:
2438 return parseDirectiveCFIRestoreState(IDLoc);
2439 case DK_CFI_SAME_VALUE:
2440 return parseDirectiveCFISameValue(IDLoc);
2441 case DK_CFI_RESTORE:
2442 return parseDirectiveCFIRestore(IDLoc);
2444 return parseDirectiveCFIEscape(IDLoc);
2445 case DK_CFI_RETURN_COLUMN:
2446 return parseDirectiveCFIReturnColumn(IDLoc);
2447 case DK_CFI_SIGNAL_FRAME:
2448 return parseDirectiveCFISignalFrame();
2449 case DK_CFI_UNDEFINED:
2450 return parseDirectiveCFIUndefined(IDLoc);
2451 case DK_CFI_REGISTER:
2452 return parseDirectiveCFIRegister(IDLoc);
2453 case DK_CFI_WINDOW_SAVE:
2454 return parseDirectiveCFIWindowSave(IDLoc);
2456 Info.ExitValue =
"";
2457 return parseDirectiveExitMacro(IDLoc, IDVal, *
Info.ExitValue);
2459 Info.ExitValue =
"";
2460 return parseDirectiveEndMacro(IDVal);
2462 return parseDirectivePurgeMacro(IDLoc);
2464 return parseDirectiveEnd(IDLoc);
2466 return parseDirectiveError(IDLoc);
2468 return parseDirectiveErrorIfb(IDLoc,
true);
2470 return parseDirectiveErrorIfb(IDLoc,
false);
2472 return parseDirectiveErrorIfdef(IDLoc,
true);
2474 return parseDirectiveErrorIfdef(IDLoc,
false);
2476 return parseDirectiveErrorIfidn(IDLoc,
false,
2479 return parseDirectiveErrorIfidn(IDLoc,
false,
2482 return parseDirectiveErrorIfidn(IDLoc,
true,
2485 return parseDirectiveErrorIfidn(IDLoc,
true,
2488 return parseDirectiveErrorIfe(IDLoc,
true);
2490 return parseDirectiveErrorIfe(IDLoc,
false);
2492 return parseDirectiveRadix(IDLoc);
2494 return parseDirectiveEcho(IDLoc);
2497 return Error(IDLoc,
"unknown directive");
2501 auto IDIt = Structs.
find(IDVal.
lower());
2502 if (IDIt != Structs.
end())
2503 return parseDirectiveStructValue(IDIt->getValue(), IDVal,
2511 const AsmToken afterNextTok = peekTok();
2522 getTargetParser().flushPendingInstructions(getStreamer());
2528 return parseDirectiveEnds(IDVal, IDLoc);
2533 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2535 if (Handler.first) {
2538 return (*Handler.second)(Handler.first, nextVal, nextLoc);
2543 DirKindIt = DirectiveKindMap.find(nextVal.
lower());
2544 DirKind = (DirKindIt == DirectiveKindMap.end())
2546 : DirKindIt->getValue();
2554 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
2565 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2576 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2587 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2597 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2608 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2611 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2615 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2619 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2624 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2627 return parseDirectiveEnds(IDVal, IDLoc);
2630 return parseDirectiveMacro(IDVal, IDLoc);
2634 auto NextIt = Structs.
find(nextVal.
lower());
2635 if (NextIt != Structs.
end()) {
2637 return parseDirectiveNamedStructValue(NextIt->getValue(),
2638 nextVal, nextLoc, IDVal);
2642 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2643 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2644 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2647 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2648 return parseDirectiveMSAlign(IDLoc, Info);
2650 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2652 if (checkForValidSection())
2656 std::string OpcodeStr = IDVal.
lower();
2658 bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr,
ID,
2659 Info.ParsedOperands);
2660 Info.ParseError = ParseHadError;
2663 if (getShowParsedOperands()) {
2666 OS <<
"parsed instruction: [";
2667 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2670 Info.ParsedOperands[i]->print(
OS);
2678 if (hasPendingError() || ParseHadError)
2683 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2684 getContext().getGenDwarfSectionSyms().
count(
2685 getStreamer().getCurrentSectionOnly())) {
2687 if (ActiveMacros.empty())
2691 ActiveMacros.front()->ExitBuffer);
2696 if (!CppHashInfo.Filename.empty()) {
2697 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2699 getContext().setGenDwarfFileNumber(FileNumber);
2701 unsigned CppHashLocLineNo =
2703 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2706 getStreamer().emitDwarfLocDirective(
2707 getContext().getGenDwarfFileNumber(), Line, 0,
2713 if (!ParseHadError) {
2715 if (getTargetParser().matchAndEmitInstruction(
2717 getTargetParser().isParsingMSInlineAsm()))
2724bool MasmParser::parseCurlyBlockScope(
2743bool MasmParser::parseCppHashLineFilenameComment(
SMLoc L) {
2748 "Lexing Cpp line comment: Expected Integer");
2749 int64_t LineNumber = getTok().getIntVal();
2752 "Lexing Cpp line comment: Expected String");
2761 CppHashInfo.Loc =
L;
2763 CppHashInfo.LineNumber = LineNumber;
2764 CppHashInfo.Buf = CurBuffer;
2765 if (FirstCppHashFilename.
empty())
2772void MasmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2773 const MasmParser *Parser =
static_cast<const MasmParser *
>(Context);
2779 unsigned CppHashBuf =
2780 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2785 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2794 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2795 DiagBuf != CppHashBuf) {
2796 if (Parser->SavedDiagHandler)
2797 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2806 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2809 int CppHashLocLineNo =
2810 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2812 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2818 if (Parser->SavedDiagHandler)
2819 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2821 NewDiag.print(
nullptr,
OS);
2827 return isAlnum(
C) ||
C ==
'_' ||
C ==
'$' ||
C ==
'@' ||
C ==
'?';
2833 const std::vector<std::string> &Locals,
SMLoc L) {
2835 if (NParameters !=
A.size())
2836 return Error(L,
"Wrong number of arguments");
2848 std::optional<char> CurrentQuote;
2849 while (!Body.
empty()) {
2851 std::size_t
End = Body.
size(), Pos = 0;
2852 std::size_t IdentifierPos =
End;
2853 for (; Pos !=
End; ++Pos) {
2856 if (Body[Pos] ==
'&')
2861 if (IdentifierPos ==
End)
2862 IdentifierPos = Pos;
2864 IdentifierPos =
End;
2868 if (!CurrentQuote) {
2869 if (Body[Pos] ==
'\'' || Body[Pos] ==
'"')
2870 CurrentQuote = Body[Pos];
2871 }
else if (Body[Pos] == CurrentQuote) {
2872 if (Pos + 1 !=
End && Body[Pos + 1] == CurrentQuote) {
2877 CurrentQuote.reset();
2881 if (IdentifierPos !=
End) {
2884 Pos = IdentifierPos;
2885 IdentifierPos =
End;
2896 bool InitialAmpersand = (Body[
I] ==
'&');
2897 if (InitialAmpersand) {
2904 const char *Begin = Body.
data() + Pos;
2906 const std::string ArgumentLower =
Argument.lower();
2910 if (Parameters[Index].
Name.equals_insensitive(ArgumentLower))
2913 if (Index == NParameters) {
2914 if (InitialAmpersand)
2916 auto it = LocalSymbols.
find(ArgumentLower);
2917 if (it != LocalSymbols.
end())
2923 for (
const AsmToken &Token :
A[Index]) {
2933 OS << Token.getIntVal();
2935 OS << Token.getString();
2939 if (Pos <
End && Body[Pos] ==
'&') {
2982class AsmLexerSkipSpaceRAII {
2984 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2988 ~AsmLexerSkipSpaceRAII() {
2999 MCAsmMacroArgument &MA,
3002 if (Lexer.
isNot(EndTok)) {
3013 const char *StrChar = StrLoc.
getPointer() + 1;
3014 const char *EndChar = EndLoc.
getPointer() - 1;
3015 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3022 unsigned ParenLevel = 0;
3025 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
3032 return TokError(
"unexpected token");
3034 if (ParenLevel == 0) {
3048 MA.push_back(getTok());
3074 MA.push_back(getTok());
3078 if (ParenLevel != 0)
3079 return TokError(
"unbalanced parentheses in argument");
3081 if (MA.empty() && MP) {
3083 return TokError(
"missing value for required parameter '" + MP->
Name +
3093bool MasmParser::parseMacroArguments(
const MCAsmMacro *M,
3094 MCAsmMacroArguments &
A,
3096 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
3097 bool NamedParametersFound =
false;
3100 A.resize(NParameters);
3101 FALocs.
resize(NParameters);
3106 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
3112 if (parseIdentifier(FA.
Name))
3113 return Error(IDLoc,
"invalid argument identifier for formal argument");
3116 return TokError(
"expected '=' after formal parameter identifier");
3120 NamedParametersFound =
true;
3123 if (NamedParametersFound && FA.
Name.
empty())
3124 return Error(IDLoc,
"cannot mix positional and keyword arguments");
3126 unsigned PI = Parameter;
3128 assert(M &&
"expected macro to be defined");
3130 for (FAI = 0; FAI < NParameters; ++FAI)
3131 if (
M->Parameters[FAI].Name == FA.
Name)
3134 if (FAI >= NParameters) {
3135 return Error(IDLoc,
"parameter named '" + FA.
Name +
3136 "' does not exist for macro '" +
M->Name +
"'");
3141 if (M && PI < NParameters)
3142 MP = &
M->Parameters[PI];
3147 const MCExpr *AbsoluteExp;
3151 if (parseExpression(AbsoluteExp, EndLoc))
3153 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
3154 getStreamer().getAssemblerPtr()))
3155 return Error(StrLoc,
"expected absolute expression");
3160 FA.
Value.push_back(newToken);
3161 }
else if (parseMacroArgument(MP, FA.
Value, EndTok)) {
3163 return addErrorSuffix(
" in '" +
M->Name +
"' macro");
3168 if (!FA.
Value.empty()) {
3173 if (FALocs.
size() <= PI)
3176 FALocs[PI] = Lexer.
getLoc();
3182 if (Lexer.
is(EndTok)) {
3184 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
3185 if (
A[FAI].empty()) {
3186 if (
M->Parameters[FAI].Required) {
3188 "missing value for required parameter "
3190 M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
3194 if (!
M->Parameters[FAI].Value.empty())
3195 A[FAI] =
M->Parameters[FAI].Value;
3205 return TokError(
"too many positional arguments");
3213 if (ActiveMacros.size() == MaxNestingDepth) {
3214 std::ostringstream MaxNestingDepthError;
3215 MaxNestingDepthError <<
"macros cannot be nested more than "
3216 << MaxNestingDepth <<
" levels deep."
3217 <<
" Use -asm-macro-max-nesting-depth to increase "
3219 return TokError(MaxNestingDepthError.str());
3222 MCAsmMacroArguments
A;
3223 if (parseMacroArguments(M,
A, ArgumentEndTok))
3232 if (expandMacro(
OS, Body,
M->Parameters,
A,
M->Locals, getTok().getLoc()))
3239 std::unique_ptr<MemoryBuffer> Instantiation =
3244 MacroInstantiation *
MI =
new MacroInstantiation{
3245 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
3246 ActiveMacros.push_back(
MI);
3248 ++NumOfMacroInstantiations;
3253 EndStatementAtEOFStack.push_back(
true);
3259void MasmParser::handleMacroExit() {
3261 EndStatementAtEOFStack.pop_back();
3262 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
3263 EndStatementAtEOFStack.back());
3267 delete ActiveMacros.back();
3268 ActiveMacros.pop_back();
3271bool MasmParser::handleMacroInvocation(
const MCAsmMacro *M,
SMLoc NameLoc) {
3273 return Error(NameLoc,
"cannot invoke macro procedure as function");
3276 "' requires arguments in parentheses") ||
3281 std::string ExitValue;
3284 ParseStatementInfo
Info(&AsmStrRewrites);
3285 bool Parsed = parseStatement(Info,
nullptr);
3287 if (!Parsed &&
Info.ExitValue) {
3288 ExitValue = std::move(*
Info.ExitValue);
3300 printPendingErrors();
3303 if (Parsed && !getLexer().isAtStartOfStatement())
3304 eatToEndOfStatement();
3313 std::unique_ptr<MemoryBuffer> MacroValue =
3321 EndStatementAtEOFStack.push_back(
false);
3330bool MasmParser::parseIdentifier(
StringRef &Res,
3331 IdentifierPositionKind Position) {
3338 SMLoc PrefixLoc = getLexer().getLoc();
3363 Res = getTok().getIdentifier();
3367 ExpandKind ExpandNextToken = ExpandMacros;
3368 if (Position == StartOfStatement &&
3370 .CaseLower(
"echo",
true)
3371 .CasesLower(
"ifdef",
"ifndef",
"elseifdef",
"elseifndef",
true)
3373 ExpandNextToken = DoNotExpandMacros;
3375 Lex(ExpandNextToken);
3386 DirectiveKind DirKind,
SMLoc NameLoc) {
3387 auto BuiltinIt = BuiltinSymbolMap.find(
Name.lower());
3388 if (BuiltinIt != BuiltinSymbolMap.end())
3389 return Error(NameLoc,
"cannot redefine a built-in symbol");
3391 Variable &Var = Variables[
Name.lower()];
3392 if (Var.Name.empty()) {
3397 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3400 std::string TextItem;
3401 if (!parseTextItem(TextItem)) {
3405 auto parseItem = [&]() ->
bool {
3406 if (parseTextItem(TextItem))
3407 return TokError(
"expected text item");
3412 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3414 if (!Var.IsText || Var.TextValue !=
Value) {
3415 switch (Var.Redefinable) {
3416 case Variable::NOT_REDEFINABLE:
3417 return Error(getTok().getLoc(),
"invalid variable redefinition");
3418 case Variable::WARN_ON_REDEFINITION:
3420 "', already defined on the command line")) {
3429 Var.TextValue =
Value;
3430 Var.Redefinable = Variable::REDEFINABLE;
3435 if (DirKind == DK_TEXTEQU)
3436 return TokError(
"expected <text> in '" +
Twine(IDVal) +
"' directive");
3441 if (parseExpression(Expr, EndLoc))
3442 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3447 if (!Expr->evaluateAsAbsolute(
Value, getStreamer().getAssemblerPtr())) {
3448 if (DirKind == DK_ASSIGN)
3451 "expected absolute expression; not all symbols have known values",
3452 {StartLoc, EndLoc});
3455 if (!Var.IsText || Var.TextValue != ExprAsString) {
3456 switch (Var.Redefinable) {
3457 case Variable::NOT_REDEFINABLE:
3458 return Error(getTok().getLoc(),
"invalid variable redefinition");
3459 case Variable::WARN_ON_REDEFINITION:
3461 "', already defined on the command line")) {
3471 Var.TextValue = ExprAsString.
str();
3472 Var.Redefinable = Variable::REDEFINABLE;
3477 MCSymbol *
Sym = getContext().getOrCreateSymbol(Var.Name);
3480 Sym->isVariable() ? dyn_cast_or_null<MCConstantExpr>(
3481 Sym->getVariableValue(
false))
3483 if (Var.IsText || !PrevValue || PrevValue->
getValue() !=
Value) {
3484 switch (Var.Redefinable) {
3485 case Variable::NOT_REDEFINABLE:
3486 return Error(getTok().getLoc(),
"invalid variable redefinition");
3487 case Variable::WARN_ON_REDEFINITION:
3489 "', already defined on the command line")) {
3499 Var.TextValue.clear();
3500 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
3501 : Variable::NOT_REDEFINABLE;
3503 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
3504 Sym->setVariableValue(Expr);
3505 Sym->setExternal(
false);
3510bool MasmParser::parseEscapedString(std::string &Data) {
3515 char Quote = getTok().getString().front();
3516 StringRef Str = getTok().getStringContents();
3517 Data.reserve(Str.size());
3518 for (
size_t i = 0, e = Str.size(); i != e; ++i) {
3519 Data.push_back(Str[i]);
3520 if (Str[i] == Quote) {
3524 if (i + 1 == Str.size())
3525 return Error(getTok().getLoc(),
"missing quotation mark in string");
3526 if (Str[i + 1] == Quote)
3535bool MasmParser::parseAngleBracketString(std::string &Data) {
3536 SMLoc EndLoc, StartLoc = getTok().getLoc();
3538 const char *StartChar = StartLoc.
getPointer() + 1;
3539 const char *EndChar = EndLoc.
getPointer() - 1;
3540 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3551bool MasmParser::parseTextItem(std::string &Data) {
3552 switch (getTok().getKind()) {
3559 Data = std::to_string(Res);
3566 return parseAngleBracketString(Data);
3570 SMLoc StartLoc = getTok().getLoc();
3571 if (parseIdentifier(
ID))
3575 bool Expanded =
false;
3578 auto BuiltinIt = BuiltinSymbolMap.find(
ID.lower());
3579 if (BuiltinIt != BuiltinSymbolMap.end()) {
3580 std::optional<std::string> BuiltinText =
3581 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
3586 Data = std::move(*BuiltinText);
3593 auto VarIt = Variables.
find(
ID.lower());
3594 if (VarIt != Variables.
end()) {
3595 const Variable &Var = VarIt->getValue();
3600 Data = Var.TextValue;
3623bool MasmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3624 auto parseOp = [&]() ->
bool {
3626 if (checkForValidSection() || parseEscapedString(Data))
3628 getStreamer().emitBytes(Data);
3630 getStreamer().emitBytes(
StringRef(
"\0", 1));
3634 if (parseMany(parseOp))
3635 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3643 int64_t IntValue = MCE->getValue();
3645 return Error(MCE->getLoc(),
"out of range literal value");
3646 getStreamer().emitIntValue(IntValue,
Size);
3651 getStreamer().emitIntValue(0,
Size);
3659bool MasmParser::parseScalarInitializer(
unsigned Size,
3661 unsigned StringPadLength) {
3664 if (parseEscapedString(
Value))
3667 for (
const unsigned char CharVal :
Value)
3671 for (
size_t i =
Value.size(); i < StringPadLength; ++i)
3675 if (parseExpression(
Value))
3678 getTok().getString().equals_insensitive(
"dup")) {
3683 "cannot repeat value a non-constant number of times");
3684 const int64_t Repetitions = MCE->
getValue();
3685 if (Repetitions < 0)
3687 "cannot repeat value a negative number of times");
3691 "parentheses required for 'dup' contents") ||
3692 parseScalarInstList(
Size, DuplicatedValues) || parseRParen())
3695 for (
int i = 0; i < Repetitions; ++i)
3704bool MasmParser::parseScalarInstList(
unsigned Size,
3707 while (getTok().
isNot(EndToken) &&
3710 parseScalarInitializer(
Size, Values);
3720bool MasmParser::emitIntegralValues(
unsigned Size,
unsigned *Count) {
3722 if (checkForValidSection() || parseScalarInstList(
Size, Values))
3725 for (
const auto *
Value : Values) {
3729 *Count = Values.size();
3735 StructInfo &
Struct = StructInProgress.
back();
3737 IntFieldInfo &IntInfo =
Field.Contents.IntInfo;
3741 if (parseScalarInstList(
Size, IntInfo.Values))
3744 Field.SizeOf =
Field.Type * IntInfo.Values.size();
3745 Field.LengthOf = IntInfo.Values.size();
3748 Struct.NextOffset = FieldEnd;
3756bool MasmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3757 if (StructInProgress.
empty()) {
3759 if (emitIntegralValues(
Size))
3760 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3761 }
else if (addIntegralField(
"",
Size)) {
3762 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3770bool MasmParser::parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
3772 if (StructInProgress.
empty()) {
3775 getStreamer().emitLabel(
Sym);
3777 if (emitIntegralValues(
Size, &Count))
3778 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3784 Type.Length = Count;
3786 }
else if (addIntegralField(
Name,
Size)) {
3787 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3796 return Asm.TokError(
"unknown token in expression");
3797 SMLoc ExprLoc = Asm.getTok().getLoc();
3798 APInt IntValue = Asm.getTok().getAPIntVal();
3800 if (!IntValue.
isIntN(128))
3801 return Asm.Error(ExprLoc,
"out of range literal value");
3802 if (!IntValue.
isIntN(64)) {
3818 SignLoc = getLexer().getLoc();
3822 SignLoc = getLexer().getLoc();
3827 return TokError(Lexer.
getErr());
3830 return TokError(
"unexpected token in directive");
3843 return TokError(
"invalid floating point literal");
3847 unsigned SizeInBits =
Value.getSizeInBits(Semantics);
3848 if (SizeInBits != (IDVal.
size() << 2))
3849 return TokError(
"invalid floating point literal");
3854 Res =
APInt(SizeInBits, IDVal, 16);
3856 return Warning(SignLoc,
"MASM-style hex floats ignore explicit sign");
3859 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3861 return TokError(
"invalid floating point literal");
3869 Res =
Value.bitcastToAPInt();
3874bool MasmParser::parseRealInstList(
const fltSemantics &Semantics,
3877 while (getTok().
isNot(EndToken) ||
3880 const AsmToken NextTok = peekTok();
3889 "cannot repeat value a non-constant number of times");
3890 const int64_t Repetitions = MCE->
getValue();
3891 if (Repetitions < 0)
3893 "cannot repeat value a negative number of times");
3897 "parentheses required for 'dup' contents") ||
3898 parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
3901 for (
int i = 0; i < Repetitions; ++i)
3902 ValuesAsInt.
append(DuplicatedValues.
begin(), DuplicatedValues.
end());
3905 if (parseRealValue(Semantics, AsInt))
3920bool MasmParser::emitRealValues(
const fltSemantics &Semantics,
3922 if (checkForValidSection())
3926 if (parseRealInstList(Semantics, ValuesAsInt))
3929 for (
const APInt &AsInt : ValuesAsInt) {
3930 getStreamer().emitIntValue(AsInt);
3933 *Count = ValuesAsInt.size();
3940 StructInfo &
Struct = StructInProgress.
back();
3942 RealFieldInfo &RealInfo =
Field.Contents.RealInfo;
3946 if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3949 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3950 Field.LengthOf = RealInfo.AsIntValues.size();
3955 Struct.NextOffset = FieldEnd;
3963bool MasmParser::parseDirectiveRealValue(
StringRef IDVal,
3966 if (StructInProgress.
empty()) {
3968 if (emitRealValues(Semantics))
3969 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3970 }
else if (addRealField(
"", Semantics,
Size)) {
3971 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3978bool MasmParser::parseDirectiveNamedRealValue(
StringRef TypeName,
3982 if (StructInProgress.
empty()) {
3985 getStreamer().emitLabel(
Sym);
3987 if (emitRealValues(Semantics, &Count))
3988 return addErrorSuffix(
" in '" + TypeName +
"' directive");
3994 Type.Length = Count;
3996 }
else if (addRealField(
Name, Semantics,
Size)) {
3997 return addErrorSuffix(
" in '" + TypeName +
"' directive");
4002bool MasmParser::parseOptionalAngleBracketOpen() {
4005 AngleBracketDepth++;
4009 AngleBracketDepth++;
4013 AngleBracketDepth++;
4020bool MasmParser::parseAngleBracketClose(
const Twine &Msg) {
4027 AngleBracketDepth--;
4031bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4032 const IntFieldInfo &Contents,
4033 FieldInitializer &Initializer) {
4034 SMLoc Loc = getTok().getLoc();
4039 return Error(Loc,
"Cannot initialize scalar field with array value");
4043 }
else if (parseOptionalAngleBracketOpen()) {
4045 return Error(Loc,
"Cannot initialize scalar field with array value");
4047 parseAngleBracketClose())
4049 }
else if (
Field.LengthOf > 1 &&
Field.Type > 1) {
4050 return Error(Loc,
"Cannot initialize array field with scalar value");
4051 }
else if (parseScalarInitializer(
Field.Type, Values,
4057 return Error(Loc,
"Initializer too long for field; expected at most " +
4058 std::to_string(
Field.LengthOf) +
" elements, got " +
4059 std::to_string(Values.
size()));
4062 Values.
append(Contents.Values.begin() + Values.
size(), Contents.Values.end());
4064 Initializer = FieldInitializer(std::move(Values));
4068bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4069 const RealFieldInfo &Contents,
4070 FieldInitializer &Initializer) {
4072 switch (
Field.Type) {
4074 Semantics = &APFloat::IEEEsingle();
4077 Semantics = &APFloat::IEEEdouble();
4080 Semantics = &APFloat::x87DoubleExtended();
4086 SMLoc Loc = getTok().getLoc();
4090 if (
Field.LengthOf == 1)
4091 return Error(Loc,
"Cannot initialize scalar field with array value");
4095 }
else if (parseOptionalAngleBracketOpen()) {
4096 if (
Field.LengthOf == 1)
4097 return Error(Loc,
"Cannot initialize scalar field with array value");
4099 parseAngleBracketClose())
4101 }
else if (
Field.LengthOf > 1) {
4102 return Error(Loc,
"Cannot initialize array field with scalar value");
4105 if (parseRealValue(*Semantics, AsIntValues.
back()))
4109 if (AsIntValues.
size() >
Field.LengthOf) {
4110 return Error(Loc,
"Initializer too long for field; expected at most " +
4111 std::to_string(
Field.LengthOf) +
" elements, got " +
4112 std::to_string(AsIntValues.
size()));
4115 AsIntValues.
append(Contents.AsIntValues.begin() + AsIntValues.
size(),
4116 Contents.AsIntValues.end());
4118 Initializer = FieldInitializer(std::move(AsIntValues));
4122bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4123 const StructFieldInfo &Contents,
4124 FieldInitializer &Initializer) {
4125 SMLoc Loc = getTok().getLoc();
4127 std::vector<StructInitializer> Initializers;
4128 if (
Field.LengthOf > 1) {
4130 if (parseStructInstList(Contents.Structure, Initializers,
4134 }
else if (parseOptionalAngleBracketOpen()) {
4135 if (parseStructInstList(Contents.Structure, Initializers,
4137 parseAngleBracketClose())
4140 return Error(Loc,
"Cannot initialize array field with scalar value");
4143 Initializers.emplace_back();
4144 if (parseStructInitializer(Contents.Structure, Initializers.back()))
4148 if (Initializers.size() >
Field.LengthOf) {
4149 return Error(Loc,
"Initializer too long for field; expected at most " +
4150 std::to_string(
Field.LengthOf) +
" elements, got " +
4151 std::to_string(Initializers.size()));
4154 Initializers.insert(Initializers.end(),
4155 Contents.Initializers.begin() + Initializers.size(),
4156 Contents.Initializers.end());
4158 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
4162bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4163 FieldInitializer &Initializer) {
4164 switch (
Field.Contents.FT) {
4166 return parseFieldInitializer(
Field,
Field.Contents.IntInfo, Initializer);
4168 return parseFieldInitializer(
Field,
Field.Contents.RealInfo, Initializer);
4170 return parseFieldInitializer(
Field,
Field.Contents.StructInfo, Initializer);
4175bool MasmParser::parseStructInitializer(
const StructInfo &Structure,
4176 StructInitializer &Initializer) {
4177 const AsmToken FirstToken = getTok();
4179 std::optional<AsmToken::TokenKind> EndToken;
4182 }
else if (parseOptionalAngleBracketOpen()) {
4184 AngleBracketDepth++;
4191 return Error(FirstToken.
getLoc(),
"Expected struct initializer");
4194 auto &FieldInitializers = Initializer.FieldInitializers;
4195 size_t FieldIndex = 0;
4198 while (getTok().
isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
4199 const FieldInfo &
Field = Structure.Fields[FieldIndex++];
4203 FieldInitializers.push_back(
Field.Contents);
4207 FieldInitializers.emplace_back(
Field.Contents.FT);
4208 if (parseFieldInitializer(
Field, FieldInitializers.back()))
4212 SMLoc CommaLoc = getTok().getLoc();
4215 if (FieldIndex == Structure.Fields.size())
4216 return Error(CommaLoc,
"'" + Structure.Name +
4217 "' initializer initializes too many fields");
4223 FieldInitializers.push_back(
Field.Contents);
4227 return parseAngleBracketClose();
4229 return parseToken(*EndToken);
4235bool MasmParser::parseStructInstList(
4236 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
4238 while (getTok().
isNot(EndToken) ||
4241 const AsmToken NextTok = peekTok();
4250 "cannot repeat value a non-constant number of times");
4251 const int64_t Repetitions = MCE->
getValue();
4252 if (Repetitions < 0)
4254 "cannot repeat value a negative number of times");
4256 std::vector<StructInitializer> DuplicatedValues;
4258 "parentheses required for 'dup' contents") ||
4259 parseStructInstList(Structure, DuplicatedValues) || parseRParen())
4262 for (
int i = 0; i < Repetitions; ++i)
4265 Initializers.emplace_back();
4266 if (parseStructInitializer(Structure, Initializers.back()))
4279bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4280 const IntFieldInfo &Contents) {
4289bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4290 const RealFieldInfo &Contents) {
4291 for (
const APInt &AsInt : Contents.AsIntValues) {
4298bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4299 const StructFieldInfo &Contents) {
4300 for (
const auto &Initializer : Contents.Initializers) {
4302 for (
const auto &SubField : Contents.Structure.Fields) {
4303 getStreamer().emitZeros(SubField.Offset -
Offset);
4304 Offset = SubField.Offset + SubField.SizeOf;
4305 emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);
4311bool MasmParser::emitFieldValue(
const FieldInfo &
Field) {
4312 switch (
Field.Contents.FT) {
4314 return emitFieldValue(
Field,
Field.Contents.IntInfo);
4316 return emitFieldValue(
Field,
Field.Contents.RealInfo);
4318 return emitFieldValue(
Field,
Field.Contents.StructInfo);
4323bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4324 const IntFieldInfo &Contents,
4325 const IntFieldInfo &Initializer) {
4326 for (
const auto &
Value : Initializer.Values) {
4331 for (
const auto &
Value :
4339bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4340 const RealFieldInfo &Contents,
4341 const RealFieldInfo &Initializer) {
4342 for (
const auto &AsInt : Initializer.AsIntValues) {
4347 for (
const auto &AsInt :
4355bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4356 const StructFieldInfo &Contents,
4357 const StructFieldInfo &Initializer) {
4358 for (
const auto &
Init : Initializer.Initializers) {
4359 if (emitStructInitializer(Contents.Structure,
Init))
4364 Initializer.Initializers.size())) {
4365 if (emitStructInitializer(Contents.Structure,
Init))
4371bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4372 const FieldInitializer &Initializer) {
4373 switch (
Field.Contents.FT) {
4375 return emitFieldInitializer(
Field,
Field.Contents.IntInfo,
4376 Initializer.IntInfo);
4378 return emitFieldInitializer(
Field,
Field.Contents.RealInfo,
4379 Initializer.RealInfo);
4381 return emitFieldInitializer(
Field,
Field.Contents.StructInfo,
4382 Initializer.StructInfo);
4387bool MasmParser::emitStructInitializer(
const StructInfo &Structure,
4388 const StructInitializer &Initializer) {
4389 if (!Structure.Initializable)
4390 return Error(getLexer().getLoc(),
4391 "cannot initialize a value of type '" + Structure.Name +
4392 "'; 'org' was used in the type's declaration");
4394 for (
const auto &
Init : Initializer.FieldInitializers) {
4395 const auto &
Field = Structure.Fields[
Index++];
4403 Structure.Fields, Initializer.FieldInitializers.size())) {
4406 if (emitFieldValue(
Field))
4410 if (
Offset != Structure.Size)
4411 getStreamer().emitZeros(Structure.Size -
Offset);
4416bool MasmParser::emitStructValues(
const StructInfo &Structure,
4418 std::vector<StructInitializer> Initializers;
4419 if (parseStructInstList(Structure, Initializers))
4422 for (
const auto &Initializer : Initializers) {
4423 if (emitStructInitializer(Structure, Initializer))
4428 *Count = Initializers.size();
4433bool MasmParser::addStructField(
StringRef Name,
const StructInfo &Structure) {
4434 StructInfo &OwningStruct = StructInProgress.
back();
4436 OwningStruct.addField(
Name, FT_STRUCT, Structure.AlignmentSize);
4437 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4439 StructInfo.Structure = Structure;
4442 if (parseStructInstList(Structure, StructInfo.Initializers))
4445 Field.LengthOf = StructInfo.Initializers.size();
4449 if (!OwningStruct.IsUnion) {
4450 OwningStruct.NextOffset = FieldEnd;
4452 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
4460bool MasmParser::parseDirectiveStructValue(
const StructInfo &Structure,
4462 if (StructInProgress.
empty()) {
4463 if (emitStructValues(Structure))
4465 }
else if (addStructField(
"", Structure)) {
4466 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4474bool MasmParser::parseDirectiveNamedStructValue(
const StructInfo &Structure,
4477 if (StructInProgress.
empty()) {
4480 getStreamer().emitLabel(
Sym);
4482 if (emitStructValues(Structure, &Count))
4485 Type.Name = Structure.Name;
4486 Type.Size = Structure.Size * Count;
4487 Type.ElementSize = Structure.Size;
4488 Type.Length = Count;
4490 }
else if (addStructField(
Name, Structure)) {
4491 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4509 int64_t AlignmentValue = 1;
4512 parseAbsoluteExpression(AlignmentValue)) {
4513 return addErrorSuffix(
" in alignment value for '" +
Twine(
Directive) +
4517 return Error(NextTok.
getLoc(),
"alignment must be a power of two; was " +
4518 std::to_string(AlignmentValue));
4524 QualifierLoc = getTok().getLoc();
4525 if (parseIdentifier(Qualifier))
4526 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4527 if (!
Qualifier.equals_insensitive(
"nonunique"))
4528 return Error(QualifierLoc,
"Unrecognized qualifier for '" +
4530 "' directive; expected none or NONUNIQUE");
4534 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4545 DirectiveKind DirKind) {
4546 if (StructInProgress.
empty())
4547 return TokError(
"missing name in top-level '" +
Twine(
Directive) +
4552 Name = getTok().getIdentifier();
4556 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4560 StructInProgress.
reserve(StructInProgress.
size() + 1);
4562 StructInProgress.
back().Alignment);
4567 if (StructInProgress.
empty())
4568 return Error(NameLoc,
"ENDS directive without matching STRUC/STRUCT/UNION");
4569 if (StructInProgress.
size() > 1)
4570 return Error(NameLoc,
"unexpected name in nested ENDS directive");
4571 if (StructInProgress.
back().Name.compare_insensitive(
Name))
4572 return Error(NameLoc,
"mismatched name in ENDS directive; expected '" +
4573 StructInProgress.
back().Name +
"'");
4574 StructInfo Structure = StructInProgress.
pop_back_val();
4578 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4579 Structs[
Name.lower()] = Structure;
4582 return addErrorSuffix(
" in ENDS directive");
4587bool MasmParser::parseDirectiveNestedEnds() {
4588 if (StructInProgress.
empty())
4589 return TokError(
"ENDS directive without matching STRUC/STRUCT/UNION");
4590 if (StructInProgress.
size() == 1)
4591 return TokError(
"missing name in top-level ENDS directive");
4594 return addErrorSuffix(
" in nested ENDS directive");
4596 StructInfo Structure = StructInProgress.
pop_back_val();
4598 Structure.Size =
llvm::alignTo(Structure.Size, Structure.Alignment);
4600 StructInfo &ParentStruct = StructInProgress.
back();
4601 if (Structure.Name.empty()) {
4604 const size_t OldFields = ParentStruct.Fields.size();
4605 ParentStruct.Fields.insert(
4606 ParentStruct.Fields.end(),
4607 std::make_move_iterator(Structure.Fields.begin()),
4608 std::make_move_iterator(Structure.Fields.end()));
4609 for (
const auto &FieldByName : Structure.FieldsByName) {
4610 ParentStruct.FieldsByName[FieldByName.getKey()] =
4611 FieldByName.getValue() + OldFields;
4614 unsigned FirstFieldOffset = 0;
4615 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
4617 ParentStruct.NextOffset,
4618 std::min(ParentStruct.Alignment, Structure.AlignmentSize));
4621 if (ParentStruct.IsUnion) {
4622 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4627 const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
4628 if (!ParentStruct.IsUnion) {
4629 ParentStruct.NextOffset = StructureEnd;
4631 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4634 FieldInfo &
Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4635 Structure.AlignmentSize);
4636 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4642 if (!ParentStruct.IsUnion) {
4643 ParentStruct.NextOffset = StructureEnd;
4645 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4647 StructInfo.Structure = Structure;
4648 StructInfo.Initializers.emplace_back();
4649 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4650 for (
const auto &SubField : Structure.Fields) {
4651 FieldInitializers.push_back(SubField.Contents);
4660bool MasmParser::parseDirectiveOrg() {
4663 if (checkForValidSection() || parseExpression(
Offset))
4666 return addErrorSuffix(
" in 'org' directive");
4668 if (StructInProgress.
empty()) {
4670 if (checkForValidSection())
4671 return addErrorSuffix(
" in 'org' directive");
4673 getStreamer().emitValueToOffset(
Offset, 0, OffsetLoc);
4676 StructInfo &Structure = StructInProgress.
back();
4678 if (!
Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
4679 return Error(OffsetLoc,
4680 "expected absolute expression in 'org' directive");
4684 "expected non-negative value in struct's 'org' directive; was " +
4685 std::to_string(OffsetRes));
4686 Structure.NextOffset =
static_cast<unsigned>(OffsetRes);
4689 Structure.Initializable =
false;
4695bool MasmParser::emitAlignTo(int64_t Alignment) {
4696 if (StructInProgress.
empty()) {
4698 if (checkForValidSection())
4704 assert(Section &&
"must have section to emit alignment");
4705 if (
Section->useCodeAlign()) {
4706 getStreamer().emitCodeAlignment(
Align(Alignment),
4707 &getTargetParser().getSTI(),
4711 getStreamer().emitValueToAlignment(
Align(Alignment), 0,
4717 StructInfo &Structure = StructInProgress.
back();
4718 Structure.NextOffset =
llvm::alignTo(Structure.NextOffset, Alignment);
4726bool MasmParser::parseDirectiveAlign() {
4727 SMLoc AlignmentLoc = getLexer().getLoc();
4733 "align directive with no operand is ignored") &&
4736 if (parseAbsoluteExpression(Alignment) || parseEOL())
4737 return addErrorSuffix(
" in align directive");
4740 bool ReturnVal =
false;
4747 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2; was " +
4748 std::to_string(Alignment));
4750 if (emitAlignTo(Alignment))
4751 ReturnVal |= addErrorSuffix(
" in align directive");
4758bool MasmParser::parseDirectiveEven() {
4759 if (parseEOL() || emitAlignTo(2))
4760 return addErrorSuffix(
" in even directive");
4768bool MasmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
4770 int64_t FileNumber = -1;
4772 FileNumber = getTok().getIntVal();
4776 return TokError(
"negative file number");
4784 "unexpected token in '.file' directive") ||
4785 parseEscapedString(Path))
4790 std::string FilenameData;
4792 if (check(FileNumber == -1,
4793 "explicit path specified, but no file number") ||
4794 parseEscapedString(FilenameData))
4803 bool HasMD5 =
false;
4805 std::optional<StringRef>
Source;
4806 bool HasSource =
false;
4807 std::string SourceString;
4812 "unexpected token in '.file' directive") ||
4813 parseIdentifier(Keyword))
4815 if (Keyword ==
"md5") {
4817 if (check(FileNumber == -1,
4818 "MD5 checksum specified, but no file number") ||
4821 }
else if (Keyword ==
"source") {
4823 if (check(FileNumber == -1,
4824 "source specified, but no file number") ||
4826 "unexpected token in '.file' directive") ||
4827 parseEscapedString(SourceString))
4830 return TokError(
"unexpected token in '.file' directive");
4834 if (FileNumber == -1) {
4838 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4839 getStreamer().emitFileDirective(Filename);
4849 std::optional<MD5::MD5Result> CKMem;
4852 for (
unsigned i = 0; i != 8; ++i) {
4853 Sum[i] =
uint8_t(MD5Hi >> ((7 - i) * 8));
4854 Sum[i + 8] =
uint8_t(MD5Lo >> ((7 - i) * 8));
4859 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
4860 memcpy(SourceBuf, SourceString.data(), SourceString.size());
4863 if (FileNumber == 0) {
4865 return Warning(DirectiveLoc,
"file 0 not supported prior to DWARF-5");
4866 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4869 FileNumber, Directory, Filename, CKMem, Source);
4876 ReportedInconsistentMD5 =
true;
4877 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
4886bool MasmParser::parseDirectiveLine() {
4889 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
4907bool MasmParser::parseDirectiveLoc() {
4908 int64_t FileNumber = 0, LineNumber = 0;
4909 SMLoc Loc = getTok().getLoc();
4910 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
4912 "file number less than one in '.loc' directive") ||
4913 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4914 "unassigned file number in '.loc' directive"))
4919 LineNumber = getTok().getIntVal();
4921 return TokError(
"line number less than zero in '.loc' directive");
4925 int64_t ColumnPos = 0;
4927 ColumnPos = getTok().getIntVal();
4929 return TokError(
"column position less than zero in '.loc' directive");
4933 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4938 auto parseLocOp = [&]() ->
bool {
4940 SMLoc Loc = getTok().getLoc();
4941 if (parseIdentifier(
Name))
4942 return TokError(
"unexpected token in '.loc' directive");
4944 if (
Name ==
"basic_block")
4946 else if (
Name ==
"prologue_end")
4948 else if (
Name ==
"epilogue_begin")
4950 else if (
Name ==
"is_stmt") {
4951 Loc = getTok().getLoc();
4953 if (parseExpression(
Value))
4959 Flags &= ~DWARF2_FLAG_IS_STMT;
4960 else if (
Value == 1)
4963 return Error(Loc,
"is_stmt value not 0 or 1");
4965 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
4967 }
else if (
Name ==
"isa") {
4968 Loc = getTok().getLoc();
4970 if (parseExpression(
Value))
4976 return Error(Loc,
"isa number less than zero");
4979 return Error(Loc,
"isa number not a constant value");
4981 }
else if (
Name ==
"discriminator") {
4982 if (parseAbsoluteExpression(Discriminator))
4985 return Error(Loc,
"unknown sub-directive in '.loc' directive");
4990 if (parseMany(parseLocOp,
false ))
4993 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
5001bool MasmParser::parseDirectiveStabs() {
5002 return TokError(
"unsupported directive '.stabs'");
5007bool MasmParser::parseDirectiveCVFile() {
5008 SMLoc FileNumberLoc = getTok().getLoc();
5011 std::string Checksum;
5014 if (parseIntToken(FileNumber,
5015 "expected file number in '.cv_file' directive") ||
5016 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
5018 "unexpected token in '.cv_file' directive") ||
5019 parseEscapedString(Filename))
5023 "unexpected token in '.cv_file' directive") ||
5024 parseEscapedString(Checksum) ||
5025 parseIntToken(ChecksumKind,
5026 "expected checksum kind in '.cv_file' directive") ||
5031 Checksum = fromHex(Checksum);
5032 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
5033 memcpy(CKMem, Checksum.data(), Checksum.size());
5037 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
5038 static_cast<uint8_t>(ChecksumKind)))
5039 return Error(FileNumberLoc,
"file number already allocated");
5044bool MasmParser::parseCVFunctionId(int64_t &
FunctionId,
5047 return parseTokenLoc(Loc) ||
5048 parseIntToken(
FunctionId,
"expected function id in '" + DirectiveName +
5050 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
5051 "expected function id within range [0, UINT_MAX)");
5054bool MasmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
5056 return parseTokenLoc(Loc) ||
5057 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
5059 check(FileNumber < 1, Loc,
"file number less than one in '" +
5060 DirectiveName +
"' directive") ||
5061 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
5062 "unassigned file number in '" + DirectiveName +
"' directive");
5069bool MasmParser::parseDirectiveCVFuncId() {
5070 SMLoc FunctionIdLoc = getTok().getLoc();
5073 if (parseCVFunctionId(
FunctionId,
".cv_func_id") || parseEOL())
5076 if (!getStreamer().emitCVFuncIdDirective(
FunctionId))
5077 return Error(FunctionIdLoc,
"function id already allocated");
5090bool MasmParser::parseDirectiveCVInlineSiteId() {
5091 SMLoc FunctionIdLoc = getTok().getLoc();
5099 if (parseCVFunctionId(
FunctionId,
".cv_inline_site_id"))
5104 getTok().getIdentifier() !=
"within"),
5105 "expected 'within' identifier in '.cv_inline_site_id' directive"))
5110 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
5115 getTok().getIdentifier() !=
"inlined_at"),
5116 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
5122 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
5123 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
5128 IACol = getTok().getIntVal();
5135 if (!getStreamer().emitCVInlineSiteIdDirective(
FunctionId, IAFunc, IAFile,
5136 IALine, IACol, FunctionIdLoc))
5137 return Error(FunctionIdLoc,
"function id already allocated");
5149bool MasmParser::parseDirectiveCVLoc() {
5150 SMLoc DirectiveLoc = getTok().getLoc();
5152 if (parseCVFunctionId(
FunctionId,
".cv_loc") ||
5153 parseCVFileId(FileNumber,
".cv_loc"))
5156 int64_t LineNumber = 0;
5158 LineNumber = getTok().getIntVal();
5160 return TokError(
"line number less than zero in '.cv_loc' directive");
5164 int64_t ColumnPos = 0;
5166 ColumnPos = getTok().getIntVal();
5168 return TokError(
"column position less than zero in '.cv_loc' directive");
5172 bool PrologueEnd =
false;
5175 auto parseOp = [&]() ->
bool {
5177 SMLoc Loc = getTok().getLoc();
5178 if (parseIdentifier(
Name))
5179 return TokError(
"unexpected token in '.cv_loc' directive");
5180 if (
Name ==
"prologue_end")
5182 else if (
Name ==
"is_stmt") {
5183 Loc = getTok().getLoc();
5185 if (parseExpression(
Value))
5189 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
5193 return Error(Loc,
"is_stmt value not 0 or 1");
5195 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
5200 if (parseMany(parseOp,
false ))
5203 getStreamer().emitCVLocDirective(
FunctionId, FileNumber, LineNumber,
5204 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
5211bool MasmParser::parseDirectiveCVLinetable() {
5214 SMLoc Loc = getTok().getLoc();
5215 if (parseCVFunctionId(
FunctionId,
".cv_linetable") ||
5217 "unexpected token in '.cv_linetable' directive") ||
5218 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5219 "expected identifier in directive") ||
5221 "unexpected token in '.cv_linetable' directive") ||
5222 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5223 "expected identifier in directive"))
5226 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5227 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5229 getStreamer().emitCVLinetableDirective(
FunctionId, FnStartSym, FnEndSym);
5235bool MasmParser::parseDirectiveCVInlineLinetable() {
5236 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
5238 SMLoc Loc = getTok().getLoc();
5239 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
5240 parseTokenLoc(Loc) ||
5243 "expected SourceField in '.cv_inline_linetable' directive") ||
5244 check(SourceFileId <= 0, Loc,
5245 "File id less than zero in '.cv_inline_linetable' directive") ||
5246 parseTokenLoc(Loc) ||
5249 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
5250 check(SourceLineNum < 0, Loc,
5251 "Line number less than zero in '.cv_inline_linetable' directive") ||
5252 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5253 "expected identifier in directive") ||
5254 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5255 "expected identifier in directive"))
5261 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5262 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5263 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
5264 SourceLineNum, FnStartSym,
5269void MasmParser::initializeCVDefRangeTypeMap() {
5270 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
5271 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
5272 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
5273 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
5278bool MasmParser::parseDirectiveCVDefRange() {
5280 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
5282 Loc = getLexer().getLoc();
5284 if (parseIdentifier(GapStartName))
5285 return Error(Loc,
"expected identifier in directive");
5286 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
5288 Loc = getLexer().getLoc();
5290 if (parseIdentifier(GapEndName))
5291 return Error(Loc,
"expected identifier in directive");
5292 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
5294 Ranges.push_back({GapStartSym, GapEndSym});
5300 "expected comma before def_range type in .cv_def_range directive") ||
5301 parseIdentifier(CVDefRangeTypeStr))
5302 return Error(Loc,
"expected def_range type in directive");
5305 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
5306 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
5308 : CVTypeIt->getValue();
5310 case CVDR_DEFRANGE_REGISTER: {
5312 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5313 ".cv_def_range directive") ||
5314 parseAbsoluteExpression(DRRegister))
5315 return Error(Loc,
"expected register number");
5320 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5323 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
5326 "expected comma before offset in .cv_def_range directive") ||
5327 parseAbsoluteExpression(DROffset))
5328 return Error(Loc,
"expected offset value");
5332 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5335 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
5337 int64_t DROffsetInParent;
5338 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5339 ".cv_def_range directive") ||
5340 parseAbsoluteExpression(DRRegister))
5341 return Error(Loc,
"expected register number");
5343 "expected comma before offset in .cv_def_range directive") ||
5344 parseAbsoluteExpression(DROffsetInParent))
5345 return Error(Loc,
"expected offset value");
5351 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5354 case CVDR_DEFRANGE_REGISTER_REL: {
5357 int64_t DRBasePointerOffset;
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 value");
5364 "expected comma before flag value in .cv_def_range directive") ||
5365 parseAbsoluteExpression(DRFlags))
5366 return Error(Loc,
"expected flag value");
5367 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
5368 "in .cv_def_range directive") ||
5369 parseAbsoluteExpression(DRBasePointerOffset))
5370 return Error(Loc,
"expected base pointer offset value");
5374 DRHdr.
Flags = DRFlags;
5376 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5380 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
5387bool MasmParser::parseDirectiveCVString() {
5389 if (checkForValidSection() || parseEscapedString(Data))
5390 return addErrorSuffix(
" in '.cv_string' directive");
5393 std::pair<StringRef, unsigned> Insertion =
5394 getCVContext().addToStringTable(Data);
5395 getStreamer().emitIntValue(Insertion.second, 4);
5401bool MasmParser::parseDirectiveCVStringTable() {
5402 getStreamer().emitCVStringTableDirective();
5408bool MasmParser::parseDirectiveCVFileChecksums() {
5409 getStreamer().emitCVFileChecksumsDirective();
5415bool MasmParser::parseDirectiveCVFileChecksumOffset() {
5417 if (parseIntToken(FileNo,
"expected identifier in directive"))
5421 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
5427bool MasmParser::parseDirectiveCVFPOData() {
5428 SMLoc DirLoc = getLexer().getLoc();
5430 if (parseIdentifier(ProcName))
5431 return TokError(
"expected symbol name");
5432 if (parseEOL(
"unexpected tokens"))
5433 return addErrorSuffix(
" in '.cv_fpo_data' directive");
5434 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
5435 getStreamer().emitCVFPOData(ProcSym, DirLoc);
5441bool MasmParser::parseDirectiveCFISections() {
5446 if (parseIdentifier(
Name))
5447 return TokError(
"Expected an identifier");
5449 if (
Name ==
".eh_frame")
5451 else if (
Name ==
".debug_frame")
5457 if (parseIdentifier(
Name))
5458 return TokError(
"Expected an identifier");
5460 if (
Name ==
".eh_frame")
5462 else if (
Name ==
".debug_frame")
5466 getStreamer().emitCFISections(EH,
Debug);
5472bool MasmParser::parseDirectiveCFIStartProc() {
5475 if (check(parseIdentifier(
Simple) ||
Simple !=
"simple",
5476 "unexpected token") ||
5478 return addErrorSuffix(
" in '.cfi_startproc' directive");
5486 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
5492bool MasmParser::parseDirectiveCFIEndProc() {
5493 getStreamer().emitCFIEndProc();
5498bool MasmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
5499 SMLoc DirectiveLoc) {
5503 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
5505 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo,
true);
5507 return parseAbsoluteExpression(
Register);
5514bool MasmParser::parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc) {
5516 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5518 parseAbsoluteExpression(
Offset))
5527bool MasmParser::parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc) {
5529 if (parseAbsoluteExpression(
Offset))
5532 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
5538bool MasmParser::parseDirectiveCFIRegister(
SMLoc DirectiveLoc) {
5539 int64_t Register1 = 0, Register2 = 0;
5540 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
5542 parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
5545 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
5551bool MasmParser::parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc) {
5552 getStreamer().emitCFIWindowSave(DirectiveLoc);
5558bool MasmParser::parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc) {
5559 int64_t Adjustment = 0;
5560 if (parseAbsoluteExpression(Adjustment))
5563 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
5569bool MasmParser::parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc) {
5571 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5574 getStreamer().emitCFIDefCfaRegister(
Register);
5580bool MasmParser::parseDirectiveCFIOffset(
SMLoc DirectiveLoc) {
5584 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5586 parseAbsoluteExpression(
Offset))
5595bool MasmParser::parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc) {
5598 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5600 parseAbsoluteExpression(
Offset))
5608 if (Encoding & ~0xff)
5614 const unsigned Format = Encoding & 0xf;
5621 const unsigned Application = Encoding & 0x70;
5633bool MasmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
5634 int64_t Encoding = 0;
5635 if (parseAbsoluteExpression(Encoding))
5643 check(parseIdentifier(
Name),
"expected identifier in directive"))
5649 getStreamer().emitCFIPersonality(
Sym, Encoding);
5651 getStreamer().emitCFILsda(
Sym, Encoding);
5657bool MasmParser::parseDirectiveCFIRememberState(
SMLoc DirectiveLoc) {
5658 getStreamer().emitCFIRememberState(DirectiveLoc);
5664bool MasmParser::parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc) {
5665 getStreamer().emitCFIRestoreState(DirectiveLoc);
5671bool MasmParser::parseDirectiveCFISameValue(
SMLoc DirectiveLoc) {
5674 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5677 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
5683bool MasmParser::parseDirectiveCFIRestore(
SMLoc DirectiveLoc) {
5685 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5688 getStreamer().emitCFIRestore(
Register);
5694bool MasmParser::parseDirectiveCFIEscape(
SMLoc DirectiveLoc) {
5697 if (parseAbsoluteExpression(CurrValue))
5705 if (parseAbsoluteExpression(CurrValue))
5708 Values.push_back((
uint8_t)CurrValue);
5711 getStreamer().emitCFIEscape(Values, DirectiveLoc);
5717bool MasmParser::parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc) {
5719 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5721 getStreamer().emitCFIReturnColumn(
Register);
5727bool MasmParser::parseDirectiveCFISignalFrame() {
5731 getStreamer().emitCFISignalFrame();
5737bool MasmParser::parseDirectiveCFIUndefined(
SMLoc DirectiveLoc) {
5740 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5743 getStreamer().emitCFIUndefined(
Register);
5758 "Vararg parameter '" +
Parameters.back().Name +
5759 "' should be last in the list of parameters");
5762 if (parseIdentifier(Parameter.
Name))
5763 return TokError(
"expected identifier in 'macro' directive");
5767 if (CurrParam.Name.equals_insensitive(Parameter.
Name))
5768 return TokError(
"macro '" +
Name +
"' has multiple parameters"
5769 " named '" + Parameter.
Name +
"'");
5778 ParamLoc = Lexer.
getLoc();
5779 if (parseMacroArgument(
nullptr, Parameter.
Value))
5785 QualLoc = Lexer.
getLoc();
5786 if (parseIdentifier(Qualifier))
5787 return Error(QualLoc,
"missing parameter qualifier for "
5789 Parameter.
Name +
"' in macro '" +
Name +
5792 if (
Qualifier.equals_insensitive(
"req"))
5794 else if (
Qualifier.equals_insensitive(
"vararg"))
5797 return Error(QualLoc,
5798 Qualifier +
" is not a valid parameter qualifier for '" +
5799 Parameter.
Name +
"' in macro '" +
Name +
"'");
5812 std::vector<std::string>
Locals;
5814 getTok().getIdentifier().equals_insensitive(
"local")) {
5819 if (parseIdentifier(
ID))
5831 AsmToken EndToken, StartToken = getTok();
5832 unsigned MacroDepth = 0;
5833 bool IsMacroFunction =
false;
5843 return Error(NameLoc,
"no matching 'endm' in definition");
5848 if (getTok().getIdentifier().equals_insensitive(
"endm")) {
5849 if (MacroDepth == 0) {
5850 EndToken = getTok();
5853 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
5860 }
else if (getTok().getIdentifier().equals_insensitive(
"exitm")) {
5862 IsMacroFunction =
true;
5864 }
else if (isMacroLikeDirective()) {
5872 eatToEndOfStatement();
5875 if (getContext().lookupMacro(
Name.lower())) {
5876 return Error(NameLoc,
"macro '" +
Name +
"' is already defined");
5886 getContext().defineMacro(
Name.lower(), std::move(
Macro));
5892bool MasmParser::parseDirectiveExitMacro(
SMLoc DirectiveLoc,
5894 std::string &
Value) {
5895 SMLoc EndLoc = getTok().getLoc();
5897 return Error(EndLoc,
5898 "unable to parse text item in '" +
Directive +
"' directive");
5899 eatToEndOfStatement();
5901 if (!isInsideMacroInstantiation())
5902 return TokError(
"unexpected '" +
Directive +
"' in file, "
5903 "no current macro definition");
5906 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5907 TheCondState = TheCondStack.back();
5908 TheCondStack.pop_back();
5919 return TokError(
"unexpected token in '" +
Directive +
"' directive");
5923 if (isInsideMacroInstantiation()) {
5930 return TokError(
"unexpected '" +
Directive +
"' in file, "
5931 "no current macro definition");
5936bool MasmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
5940 if (parseTokenLoc(NameLoc) ||
5941 check(parseIdentifier(
Name), NameLoc,
5942 "expected identifier in 'purge' directive"))
5946 <<
"Un-defining macro: " <<
Name <<
"\n");
5947 if (!getContext().lookupMacro(
Name.lower()))
5948 return Error(NameLoc,
"macro '" +
Name +
"' is not defined");
5949 getContext().undefineMacro(
Name.lower());
5959bool MasmParser::parseDirectiveExtern() {
5961 auto parseOp = [&]() ->
bool {
5963 SMLoc NameLoc = getTok().getLoc();
5964 if (parseIdentifier(
Name))
5965 return Error(NameLoc,
"expected name");
5970 SMLoc TypeLoc = getTok().getLoc();
5971 if (parseIdentifier(TypeName))
5972 return Error(TypeLoc,
"expected type");
5973 if (!
TypeName.equals_insensitive(
"proc")) {
5975 if (lookUpType(TypeName,
Type))
5976 return Error(TypeLoc,
"unrecognized type");
5981 Sym->setExternal(
true);
5987 if (parseMany(parseOp))
5988 return addErrorSuffix(
" in directive 'extern'");
5994bool MasmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
5995 auto parseOp = [&]() ->
bool {
5997 SMLoc Loc = getTok().getLoc();
5998 if (parseIdentifier(
Name))
5999 return Error(Loc,
"expected identifier");
6003 if (
Sym->isTemporary())
6004 return Error(Loc,
"non-local symbol required");
6006 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
6007 return Error(Loc,
"unable to emit symbol attribute");
6011 if (parseMany(parseOp))
6012 return addErrorSuffix(
" in directive");
6018bool MasmParser::parseDirectiveComm(
bool IsLocal) {
6019 if (checkForValidSection())
6022 SMLoc IDLoc = getLexer().getLoc();
6024 if (parseIdentifier(
Name))
6025 return TokError(
"expected identifier in directive");
6031 return TokError(
"unexpected token in directive");
6035 SMLoc SizeLoc = getLexer().getLoc();
6036 if (parseAbsoluteExpression(
Size))
6039 int64_t Pow2Alignment = 0;
6040 SMLoc Pow2AlignmentLoc;
6043 Pow2AlignmentLoc = getLexer().getLoc();
6044 if (parseAbsoluteExpression(Pow2Alignment))
6049 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
6055 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
6056 Pow2Alignment =
Log2_64(Pow2Alignment);
6066 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
6067 "be less than zero");
6072 if (Pow2Alignment < 0)
6073 return Error(Pow2AlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
6074 "alignment, can't be less than zero");
6076 Sym->redefineIfPossible();
6077 if (!
Sym->isUndefined())
6078 return Error(IDLoc,
"invalid symbol redefinition");
6082 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
6083 Align(1ULL << Pow2Alignment));
6087 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
6095bool MasmParser::parseDirectiveComment(
SMLoc DirectiveLoc) {
6097 size_t DelimiterEnd = FirstLine.find_first_of(
"\b\t\v\f\r\x1A ");
6098 assert(DelimiterEnd != std::string::npos);
6100 if (Delimiter.
empty())
6101 return Error(DirectiveLoc,
"no delimiter in 'comment' directive");
6104 return Error(DirectiveLoc,
"unmatched delimiter in 'comment' directive");
6114bool MasmParser::parseDirectiveInclude() {
6117 SMLoc IncludeLoc = getTok().getLoc();
6119 if (parseAngleBracketString(Filename))
6121 if (check(
Filename.empty(),
"missing filename in 'include' directive") ||
6123 "unexpected token in 'include' directive") ||
6126 check(enterIncludeFile(Filename), IncludeLoc,
6127 "Could not find include file '" + Filename +
"'"))
6135bool MasmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
6136 TheCondStack.push_back(TheCondState);
6138 if (TheCondState.
Ignore) {
6139 eatToEndOfStatement();
6142 if (parseAbsoluteExpression(ExprValue) || parseEOL())
6151 ExprValue = ExprValue == 0;
6155 TheCondState.
CondMet = ExprValue;
6164bool MasmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6165 TheCondStack.push_back(TheCondState);
6168 if (TheCondState.
Ignore) {
6169 eatToEndOfStatement();
6172 if (parseTextItem(Str))
6173 return TokError(
"expected text item parameter for 'ifb' directive");
6178 TheCondState.
CondMet = ExpectBlank == Str.empty();
6187bool MasmParser::parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6188 bool CaseInsensitive) {
6189 std::string String1, String2;
6191 if (parseTextItem(String1)) {
6193 return TokError(
"expected text item parameter for 'ifidn' directive");
6194 return TokError(
"expected text item parameter for 'ifdif' directive");
6200 "expected comma after first string for 'ifidn' directive");
6201 return TokError(
"expected comma after first string for 'ifdif' directive");
6205 if (parseTextItem(String2)) {
6207 return TokError(
"expected text item parameter for 'ifidn' directive");
6208 return TokError(
"expected text item parameter for 'ifdif' directive");
6211 TheCondStack.push_back(TheCondState);
6213 if (CaseInsensitive)
6217 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6226bool MasmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
6227 TheCondStack.push_back(TheCondState);
6230 if (TheCondState.
Ignore) {
6231 eatToEndOfStatement();
6233 bool is_defined =
false;
6235 SMLoc StartLoc, EndLoc;
6237 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6240 if (check(parseIdentifier(
Name),
"expected identifier after 'ifdef'") ||
6244 if (BuiltinSymbolMap.contains(
Name.lower())) {
6250 is_defined = (
Sym && !
Sym->isUndefined(
false));
6254 TheCondState.
CondMet = (is_defined == expect_defined);
6263bool MasmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc,
6264 DirectiveKind DirKind) {
6267 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
6268 " .if or an .elseif");
6271 bool LastIgnoreState =
false;
6272 if (!TheCondStack.empty())
6273 LastIgnoreState = TheCondStack.back().Ignore;
6274 if (LastIgnoreState || TheCondState.
CondMet) {
6275 TheCondState.
Ignore =
true;
6276 eatToEndOfStatement();
6279 if (parseAbsoluteExpression(ExprValue))
6291 ExprValue = ExprValue == 0;
6295 TheCondState.
CondMet = ExprValue;
6304bool MasmParser::parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6307 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6308 " if or an elseif");
6311 bool LastIgnoreState =
false;
6312 if (!TheCondStack.empty())
6313 LastIgnoreState = TheCondStack.back().Ignore;
6314 if (LastIgnoreState || TheCondState.
CondMet) {
6315 TheCondState.
Ignore =
true;
6316 eatToEndOfStatement();
6319 if (parseTextItem(Str)) {
6321 return TokError(
"expected text item parameter for 'elseifb' directive");
6322 return TokError(
"expected text item parameter for 'elseifnb' directive");
6328 TheCondState.
CondMet = ExpectBlank == Str.empty();
6338bool MasmParser::parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
6339 bool expect_defined) {
6342 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6343 " if or an elseif");
6346 bool LastIgnoreState =
false;
6347 if (!TheCondStack.empty())
6348 LastIgnoreState = TheCondStack.back().Ignore;
6349 if (LastIgnoreState || TheCondState.
CondMet) {
6350 TheCondState.
Ignore =
true;
6351 eatToEndOfStatement();
6353 bool is_defined =
false;
6355 SMLoc StartLoc, EndLoc;
6357 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6360 if (check(parseIdentifier(
Name),
6361 "expected identifier after 'elseifdef'") ||
6365 if (BuiltinSymbolMap.contains(
Name.lower())) {
6371 is_defined = (
Sym && !
Sym->isUndefined(
false));
6375 TheCondState.
CondMet = (is_defined == expect_defined);
6384bool MasmParser::parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6385 bool CaseInsensitive) {
6388 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6389 " if or an elseif");
6392 bool LastIgnoreState =
false;
6393 if (!TheCondStack.empty())
6394 LastIgnoreState = TheCondStack.back().Ignore;
6395 if (LastIgnoreState || TheCondState.
CondMet) {
6396 TheCondState.
Ignore =
true;
6397 eatToEndOfStatement();
6399 std::string String1, String2;
6401 if (parseTextItem(String1)) {
6404 "expected text item parameter for 'elseifidn' directive");
6405 return TokError(
"expected text item parameter for 'elseifdif' directive");
6411 "expected comma after first string for 'elseifidn' directive");
6413 "expected comma after first string for 'elseifdif' directive");
6417 if (parseTextItem(String2)) {
6420 "expected text item parameter for 'elseifidn' directive");
6421 return TokError(
"expected text item parameter for 'elseifdif' directive");
6424 if (CaseInsensitive)
6428 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6437bool MasmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
6443 return Error(DirectiveLoc,
"Encountered an else that doesn't follow an if"
6446 bool LastIgnoreState =
false;
6447 if (!TheCondStack.empty())
6448 LastIgnoreState = TheCondStack.back().Ignore;
6449 if (LastIgnoreState || TheCondState.
CondMet)
6450 TheCondState.
Ignore =
true;
6452 TheCondState.
Ignore =
false;
6459bool MasmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
6471bool MasmParser::parseDirectiveError(
SMLoc DirectiveLoc) {
6472 if (!TheCondStack.empty()) {
6473 if (TheCondStack.back().Ignore) {
6474 eatToEndOfStatement();
6479 std::string Message =
".err directive invoked in source file";
6484 return Error(DirectiveLoc, Message);
6489bool MasmParser::parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6490 if (!TheCondStack.empty()) {
6491 if (TheCondStack.back().Ignore) {
6492 eatToEndOfStatement();
6498 if (parseTextItem(Text))
6499 return Error(getTok().getLoc(),
"missing text item in '.errb' directive");
6501 std::string Message =
".errb directive invoked in source file";
6504 return addErrorSuffix(
" in '.errb' directive");
6509 if (
Text.empty() == ExpectBlank)
6510 return Error(DirectiveLoc, Message);
6516bool MasmParser::parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
6517 bool ExpectDefined) {
6518 if (!TheCondStack.empty()) {
6519 if (TheCondStack.back().Ignore) {
6520 eatToEndOfStatement();
6525 bool IsDefined =
false;
6527 SMLoc StartLoc, EndLoc;
6529 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6532 if (check(parseIdentifier(
Name),
"expected identifier after '.errdef'"))
6535 if (BuiltinSymbolMap.contains(
Name.lower())) {
6541 IsDefined = (
Sym && !
Sym->isUndefined(
false));
6545 std::string Message =
".errdef directive invoked in source file";
6548 return addErrorSuffix(
" in '.errdef' directive");
6553 if (IsDefined == ExpectDefined)
6554 return Error(DirectiveLoc, Message);
6560bool MasmParser::parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6561 bool CaseInsensitive) {
6562 if (!TheCondStack.empty()) {
6563 if (TheCondStack.back().Ignore) {
6564 eatToEndOfStatement();
6569 std::string String1, String2;
6571 if (parseTextItem(String1)) {
6573 return TokError(
"expected string parameter for '.erridn' directive");
6574 return TokError(
"expected string parameter for '.errdif' directive");
6580 "expected comma after first string for '.erridn' directive");
6582 "expected comma after first string for '.errdif' directive");
6586 if (parseTextItem(String2)) {
6588 return TokError(
"expected string parameter for '.erridn' directive");
6589 return TokError(
"expected string parameter for '.errdif' directive");
6592 std::string Message;
6594 Message =
".erridn directive invoked in source file";
6596 Message =
".errdif directive invoked in source file";
6599 return addErrorSuffix(
" in '.erridn' directive");
6604 if (CaseInsensitive)
6608 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6611 if ((CaseInsensitive &&
6613 (ExpectEqual == (String1 == String2)))
6614 return Error(DirectiveLoc, Message);
6620bool MasmParser::parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero) {
6621 if (!TheCondStack.empty()) {
6622 if (TheCondStack.back().Ignore) {
6623 eatToEndOfStatement();
6629 if (parseAbsoluteExpression(ExprValue))
6630 return addErrorSuffix(
" in '.erre' directive");
6632 std::string Message =
".erre directive invoked in source file";
6635 return addErrorSuffix(
" in '.erre' directive");
6640 if ((ExprValue == 0) == ExpectZero)
6641 return Error(DirectiveLoc, Message);
6647bool MasmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
6652 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
6654 if (!TheCondStack.empty()) {
6655 TheCondState = TheCondStack.back();
6656 TheCondStack.pop_back();
6662void MasmParser::initializeDirectiveKindMap() {
6663 DirectiveKindMap[
"="] = DK_ASSIGN;
6664 DirectiveKindMap[
"equ"] = DK_EQU;
6665 DirectiveKindMap[
"textequ"] = DK_TEXTEQU;
6669 DirectiveKindMap[
"byte"] = DK_BYTE;
6670 DirectiveKindMap[
"sbyte"] = DK_SBYTE;
6671 DirectiveKindMap[
"word"] = DK_WORD;
6672 DirectiveKindMap[
"sword"] = DK_SWORD;
6673 DirectiveKindMap[
"dword"] = DK_DWORD;
6674 DirectiveKindMap[
"sdword"] = DK_SDWORD;
6675 DirectiveKindMap[
"fword"] = DK_FWORD;
6676 DirectiveKindMap[
"qword"] = DK_QWORD;
6677 DirectiveKindMap[
"sqword"] = DK_SQWORD;
6678 DirectiveKindMap[
"real4"] = DK_REAL4;
6679 DirectiveKindMap[
"real8"] = DK_REAL8;
6680 DirectiveKindMap[
"real10"] = DK_REAL10;
6681 DirectiveKindMap[
"align"] = DK_ALIGN;
6682 DirectiveKindMap[
"even"] = DK_EVEN;
6683 DirectiveKindMap[
"org"] = DK_ORG;
6684 DirectiveKindMap[
"extern"] = DK_EXTERN;
6685 DirectiveKindMap[
"extrn"] = DK_EXTERN;
6686 DirectiveKindMap[
"public"] = DK_PUBLIC;
6688 DirectiveKindMap[
"comment"] = DK_COMMENT;
6689 DirectiveKindMap[
"include"] = DK_INCLUDE;
6690 DirectiveKindMap[
"repeat"] = DK_REPEAT;
6691 DirectiveKindMap[
"rept"] = DK_REPEAT;
6692 DirectiveKindMap[
"while"] = DK_WHILE;
6693 DirectiveKindMap[
"for"] = DK_FOR;
6694 DirectiveKindMap[
"irp"] = DK_FOR;
6695 DirectiveKindMap[
"forc"] = DK_FORC;
6696 DirectiveKindMap[
"irpc"] = DK_FORC;
6697 DirectiveKindMap[
"if"] = DK_IF;
6698 DirectiveKindMap[
"ife"] = DK_IFE;
6699 DirectiveKindMap[
"ifb"] = DK_IFB;
6700 DirectiveKindMap[
"ifnb"] = DK_IFNB;
6701 DirectiveKindMap[
"ifdef"] = DK_IFDEF;
6702 DirectiveKindMap[
"ifndef"] = DK_IFNDEF;
6703 DirectiveKindMap[
"ifdif"] = DK_IFDIF;
6704 DirectiveKindMap[
"ifdifi"] = DK_IFDIFI;
6705 DirectiveKindMap[
"ifidn"] = DK_IFIDN;
6706 DirectiveKindMap[
"ifidni"] = DK_IFIDNI;
6707 DirectiveKindMap[
"elseif"] = DK_ELSEIF;
6708 DirectiveKindMap[
"elseifdef"] = DK_ELSEIFDEF;
6709 DirectiveKindMap[
"elseifndef"] = DK_ELSEIFNDEF;
6710 DirectiveKindMap[
"elseifdif"] = DK_ELSEIFDIF;
6711 DirectiveKindMap[
"elseifidn"] = DK_ELSEIFIDN;
6712 DirectiveKindMap[
"else"] = DK_ELSE;
6713 DirectiveKindMap[
"end"] = DK_END;
6714 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, {}, {},
M->Locals, getTok().getLoc()))
6960 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
6969bool MasmParser::parseDirectiveWhile(
SMLoc DirectiveLoc) {
6971 SMLoc CondLoc = getTok().getLoc();
6972 if (parseExpression(CondExpr))
6985 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
6986 return Error(CondLoc,
"expected absolute expression in 'while' directive");
6990 if (expandMacro(
OS,
M->Body, {}, {},
M->Locals, getTok().getLoc()))
6992 instantiateMacroLikeBody(M, DirectiveLoc, DirectiveLoc,
OS);
7002bool MasmParser::parseDirectiveFor(
SMLoc DirectiveLoc,
StringRef Dir) {
7004 MCAsmMacroArguments
A;
7005 if (check(parseIdentifier(Parameter.
Name),
7006 "expected identifier in '" + Dir +
"' directive"))
7015 ParamLoc = Lexer.
getLoc();
7016 if (parseMacroArgument(
nullptr, Parameter.
Value))
7022 QualLoc = Lexer.
getLoc();
7023 if (parseIdentifier(Qualifier))
7024 return Error(QualLoc,
"missing parameter qualifier for "
7026 Parameter.
Name +
"' in '" + Dir +
7029 if (
Qualifier.equals_insensitive(
"req"))
7032 return Error(QualLoc,
7033 Qualifier +
" is not a valid parameter qualifier for '" +
7034 Parameter.
Name +
"' in '" + Dir +
"' directive");
7039 "expected comma in '" + Dir +
"' directive") ||
7041 "values in '" + Dir +
7042 "' directive must be enclosed in angle brackets"))
7048 return addErrorSuffix(
" in arguments for '" + Dir +
"' directive");
7057 "values in '" + Dir +
7058 "' directive must be enclosed in angle brackets") ||
7072 for (
const MCAsmMacroArgument &Arg :
A) {
7073 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
7077 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
7090 if (check(parseIdentifier(Parameter.
Name),
7091 "expected identifier in '" +
Directive +
"' directive") ||
7093 "expected comma in '" +
Directive +
"' directive"))
7095 if (parseAngleBracketString(
Argument)) {
7123 for (std::size_t
I = 0,
End = Values.size();
I !=
End; ++
I) {
7124 MCAsmMacroArgument Arg;
7127 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
7131 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
7136bool MasmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
7139 SMLoc ExprLoc = getLexer().getLoc();
7140 if (parseExpression(
Value))
7144 return Error(ExprLoc,
"unexpected expression in _emit");
7146 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
7147 return Error(ExprLoc,
"literal value out of range for directive");
7153bool MasmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
7155 SMLoc ExprLoc = getLexer().getLoc();
7156 if (parseExpression(
Value))
7160 return Error(ExprLoc,
"unexpected expression in align");
7163 return Error(ExprLoc,
"literal value not a power of two greater then zero");
7169bool MasmParser::parseDirectiveRadix(
SMLoc DirectiveLoc) {
7170 const SMLoc Loc = getLexer().getLoc();
7176 "radix must be a decimal number in the range 2 to 16; was " +
7179 if (Radix < 2 || Radix > 16)
7180 return Error(Loc,
"radix must be in the range 2 to 16; was " +
7181 std::to_string(Radix));
7182 getLexer().setMasmDefaultRadix(Radix);
7188bool MasmParser::parseDirectiveEcho(
SMLoc DirectiveLoc) {
7191 if (!
StringRef(Message).ends_with(
"\n"))
7220 Variable &Var = Variables[
Name.lower()];
7221 if (Var.Name.empty()) {
7223 }
else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {
7224 return Error(
SMLoc(),
"invalid variable redefinition");
7225 }
else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&
7227 "', already defined on the command line")) {
7230 Var.Redefinable = Variable::WARN_ON_REDEFINITION;
7232 Var.TextValue =
Value.str();
7237 const std::pair<StringRef, StringRef> BaseMember =
Name.split(
'.');
7239 return lookUpField(
Base, Member, Info);
7248 if (
Base.contains(
'.') && !lookUpField(
Base, BaseInfo))
7251 auto StructIt = Structs.
find(
Base.lower());
7252 auto TypeIt = KnownType.
find(
Base.lower());
7253 if (TypeIt != KnownType.
end()) {
7254 StructIt = Structs.
find(TypeIt->second.Name.lower());
7256 if (StructIt != Structs.
end())
7257 return lookUpField(StructIt->second, Member, Info);
7262bool MasmParser::lookUpField(
const StructInfo &Structure,
StringRef Member,
7265 Info.Type.Name = Structure.Name;
7266 Info.Type.Size = Structure.Size;
7267 Info.Type.ElementSize = Structure.Size;
7268 Info.Type.Length = 1;
7272 std::pair<StringRef, StringRef>
Split =
Member.split(
'.');
7275 auto StructIt = Structs.
find(FieldName.
lower());
7276 if (StructIt != Structs.
end())
7277 return lookUpField(StructIt->second, FieldMember, Info);
7279 auto FieldIt = Structure.FieldsByName.find(FieldName.
lower());
7280 if (FieldIt == Structure.FieldsByName.end())
7283 const FieldInfo &
Field = Structure.Fields[FieldIt->second];
7284 if (FieldMember.empty()) {
7289 if (
Field.Contents.FT == FT_STRUCT)
7290 Info.Type.Name =
Field.Contents.StructInfo.Structure.Name;
7292 Info.Type.Name =
"";
7296 if (
Field.Contents.FT != FT_STRUCT)
7298 const StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
7300 if (lookUpField(StructInfo.Structure, FieldMember, Info))
7326 auto StructIt = Structs.
find(
Name.lower());
7327 if (StructIt != Structs.
end()) {
7328 const StructInfo &Structure = StructIt->second;
7330 Info.ElementSize = Structure.Size;
7332 Info.Size = Structure.Size;
7339bool MasmParser::parseMSInlineAsm(
7340 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
7359 unsigned InputIdx = 0;
7360 unsigned OutputIdx = 0;
7363 if (parseCurlyBlockScope(AsmStrRewrites))
7366 ParseStatementInfo
Info(&AsmStrRewrites);
7367 bool StatementErr = parseStatement(Info, &SI);
7369 if (StatementErr ||
Info.ParseError) {
7371 printPendingErrors();
7376 assert(!hasPendingError() &&
"unexpected error from parseStatement");
7378 if (
Info.Opcode == ~0U)
7384 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
7389 !getTargetParser().omitRegisterFromClobberLists(Operand.
getReg())) {
7390 unsigned NumDefs =
Desc.getNumDefs();
7399 if (SymName.
empty())
7407 if (Operand.
isImm()) {
7415 bool isOutput = (i == 1) &&
Desc.mayStore();
7421 OutputConstraints.
push_back((
"=" + Constraint).str());
7427 if (
Desc.operands()[i - 1].isBranchTarget())
7439 NumOutputs = OutputDecls.
size();
7440 NumInputs = InputDecls.
size();
7445 Clobbers.
assign(ClobberRegs.
size(), std::string());
7446 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
7452 if (NumOutputs || NumInputs) {
7453 unsigned NumExprs = NumOutputs + NumInputs;
7454 OpDecls.resize(NumExprs);
7455 Constraints.
resize(NumExprs);
7456 for (
unsigned i = 0; i < NumOutputs; ++i) {
7457 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
7458 Constraints[i] = OutputConstraints[i];
7460 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
7461 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
7462 Constraints[
j] = InputConstraints[i];
7467 std::string AsmStringIR;
7471 const char *AsmStart = ASMString.
begin();
7472 const char *AsmEnd = ASMString.
end();
7474 for (
auto I = AsmStrRewrites.
begin(), E = AsmStrRewrites.
end();
I != E; ++
I) {
7482 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
7485 if (
unsigned Len = Loc - AsmStart)
7490 AsmStart = Loc + AR.
Len;
7494 unsigned AdditionalSkip = 0;
7516 size_t OffsetLen = OffsetName.
size();
7517 auto rewrite_it = std::find_if(
7519 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
7520 (FusingAR.Kind == AOK_Input ||
7521 FusingAR.Kind == AOK_CallInput);
7523 if (rewrite_it == AsmStrRewrites.
end()) {
7524 OS <<
"offset " << OffsetName;
7526 OS <<
"${" << InputIdx++ <<
":P}";
7527 rewrite_it->Done =
true;
7529 OS <<
'$' << InputIdx++;
7530 rewrite_it->Done =
true;
7542 OS <<
'$' << InputIdx++;
7545 OS <<
"${" << InputIdx++ <<
":P}";
7548 OS <<
'$' << OutputIdx++;
7553 case 8:
OS <<
"byte ptr ";
break;
7554 case 16:
OS <<
"word ptr ";
break;
7555 case 32:
OS <<
"dword ptr ";
break;
7556 case 64:
OS <<
"qword ptr ";
break;
7557 case 80:
OS <<
"xword ptr ";
break;
7558 case 128:
OS <<
"xmmword ptr ";
break;
7559 case 256:
OS <<
"ymmword ptr ";
break;
7569 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
7574 unsigned Val = AR.
Val;
7576 assert(Val < 10 &&
"Expected alignment less then 2^10.");
7577 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
7589 AsmStart = Loc + AR.
Len + AdditionalSkip;
7593 if (AsmStart != AsmEnd)
7596 AsmString =
OS.str();
7600void MasmParser::initializeBuiltinSymbolMap() {
7602 BuiltinSymbolMap[
"@version"] = BI_VERSION;
7603 BuiltinSymbolMap[
"@line"] = BI_LINE;
7606 BuiltinSymbolMap[
"@date"] = BI_DATE;
7607 BuiltinSymbolMap[
"@time"] = BI_TIME;
7608 BuiltinSymbolMap[
"@filecur"] = BI_FILECUR;
7609 BuiltinSymbolMap[
"@filename"] = BI_FILENAME;
7610 BuiltinSymbolMap[
"@curseg"] = BI_CURSEG;
7613 if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
7631const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,
7641 if (ActiveMacros.empty())
7645 ActiveMacros.front()->ExitBuffer);
7652std::optional<std::string>
7653MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
SMLoc StartLoc) {
7659 char TmpBuffer[
sizeof(
"mm/dd/yy")];
7660 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%D", &TM);
7661 return std::string(TmpBuffer, Len);
7665 char TmpBuffer[
sizeof(
"hh:mm:ss")];
7666 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%T", &TM);
7667 return std::string(TmpBuffer, Len);
7672 ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)
7680 return getStreamer().getCurrentSectionOnly()->getName().str();
7688 struct tm TM,
unsigned CB) {
7689 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
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
#define DEBUG_WITH_TYPE(TYPE,...)
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 '!'.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
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())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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 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 void setAssemblerDialect(unsigned i)
virtual MCContext & getContext()=0
virtual void setParsingMSInlineAsm(bool V)=0
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, MCInstPrinter *IP, MCAsmParserSemaCallback &SI)=0
Parse MS-style inline assembly.
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)
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...
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const
SourceMgr::DiagKind getKind() const
StringRef getLineContents() const
StringRef getMessage() const
ArrayRef< std::pair< unsigned, unsigned > > getRanges() const
const SourceMgr * getSourceMgr() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
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...
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
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.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
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
auto unique(Range &&R, Predicate P)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
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...
const char * toString(DWARFSectionKind Kind)
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.