80typedef std::vector<AsmToken> MCAsmMacroArgument;
81typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
84struct MacroInstantiation {
86 SMLoc InstantiationLoc;
95 size_t CondStackDepth;
98struct ParseStatementInfo {
103 unsigned Opcode = ~0
U;
106 bool ParseError =
false;
109 std::optional<std::string> ExitValue;
113 ParseStatementInfo() =
delete;
115 : AsmRewrites(rewrites) {}
128 bool Initializable =
true;
129 unsigned Alignment = 0;
130 unsigned AlignmentSize = 0;
131 unsigned NextOffset = 0;
133 std::vector<FieldInfo> Fields;
136 FieldInfo &addField(
StringRef FieldName, FieldType FT,
137 unsigned FieldAlignmentSize);
139 StructInfo() =
default;
140 StructInfo(
StringRef StructName,
bool Union,
unsigned AlignmentValue);
148struct StructInitializer;
152 IntFieldInfo() =
default;
156struct RealFieldInfo {
159 RealFieldInfo() =
default;
163struct StructFieldInfo {
164 std::vector<StructInitializer> Initializers;
165 StructInfo Structure;
167 StructFieldInfo() =
default;
168 StructFieldInfo(std::vector<StructInitializer> V, StructInfo S);
171class FieldInitializer {
175 IntFieldInfo IntInfo;
176 RealFieldInfo RealInfo;
177 StructFieldInfo StructInfo;
181 FieldInitializer(FieldType FT);
185 FieldInitializer(std::vector<StructInitializer> &&Initializers,
186 struct StructInfo Structure);
188 FieldInitializer(
const FieldInitializer &Initializer);
189 FieldInitializer(FieldInitializer &&Initializer);
191 FieldInitializer &operator=(
const FieldInitializer &Initializer);
192 FieldInitializer &operator=(FieldInitializer &&Initializer);
195struct StructInitializer {
196 std::vector<FieldInitializer> FieldInitializers;
207 unsigned LengthOf = 0;
212 FieldInitializer Contents;
214 FieldInfo(FieldType FT) : Contents(FT) {}
217StructFieldInfo::StructFieldInfo(std::vector<StructInitializer> V,
219 Initializers = std::move(V);
223StructInfo::StructInfo(
StringRef StructName,
bool Union,
224 unsigned AlignmentValue)
227FieldInfo &StructInfo::addField(
StringRef FieldName, FieldType FT,
228 unsigned FieldAlignmentSize) {
229 if (!FieldName.
empty())
230 FieldsByName[FieldName.
lower()] = Fields.size();
231 Fields.emplace_back(FT);
232 FieldInfo &
Field = Fields.back();
234 llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize));
238 AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
242FieldInitializer::~FieldInitializer() {
245 IntInfo.~IntFieldInfo();
248 RealInfo.~RealFieldInfo();
251 StructInfo.~StructFieldInfo();
256FieldInitializer::FieldInitializer(FieldType FT) : FT(FT) {
259 new (&IntInfo) IntFieldInfo();
262 new (&RealInfo) RealFieldInfo();
265 new (&StructInfo) StructFieldInfo();
272 new (&IntInfo) IntFieldInfo(std::move(Values));
277 new (&RealInfo) RealFieldInfo(std::move(AsIntValues));
280FieldInitializer::FieldInitializer(
281 std::vector<StructInitializer> &&Initializers,
struct StructInfo Structure)
283 new (&StructInfo) StructFieldInfo(std::move(Initializers), Structure);
286FieldInitializer::FieldInitializer(
const FieldInitializer &Initializer)
287 : FT(Initializer.FT) {
290 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
293 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
296 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
301FieldInitializer::FieldInitializer(FieldInitializer &&Initializer)
302 : FT(Initializer.FT) {
305 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
308 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
311 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
317FieldInitializer::operator=(
const FieldInitializer &Initializer) {
318 if (FT != Initializer.FT) {
321 IntInfo.~IntFieldInfo();
324 RealInfo.~RealFieldInfo();
327 StructInfo.~StructFieldInfo();
334 IntInfo = Initializer.IntInfo;
337 RealInfo = Initializer.RealInfo;
340 StructInfo = Initializer.StructInfo;
346FieldInitializer &FieldInitializer::operator=(FieldInitializer &&Initializer) {
347 if (FT != Initializer.FT) {
350 IntInfo.~IntFieldInfo();
353 RealInfo.~RealFieldInfo();
356 StructInfo.~StructFieldInfo();
363 IntInfo = Initializer.IntInfo;
366 RealInfo = Initializer.RealInfo;
369 StructInfo = Initializer.StructInfo;
386 void *SavedDiagContext;
387 std::unique_ptr<MCAsmParserExtension> PlatformParser;
399 std::vector<AsmCond> TheCondStack;
408 enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE };
411 RedefinableKind Redefinable = REDEFINABLE;
413 std::string TextValue;
427 std::vector<MacroInstantiation*> ActiveMacros;
430 std::deque<MCAsmMacro> MacroLikeBodies;
433 unsigned NumOfMacroInstantiations;
436 struct CppHashInfoTy {
441 CppHashInfoTy() : LineNumber(0), Buf(0) {}
443 CppHashInfoTy CppHashInfo;
453 unsigned AssemblerDialect = 1U;
456 bool IsDarwin =
false;
459 bool ParsingMSInlineAsm =
false;
462 bool ReportedInconsistentMD5 =
false;
465 unsigned AngleBracketDepth = 0
U;
472 const MCAsmInfo &MAI,
struct tm TM,
unsigned CB = 0);
473 MasmParser(
const MasmParser &) =
delete;
474 MasmParser &
operator=(
const MasmParser &) =
delete;
475 ~MasmParser()
override;
477 bool Run(
bool NoInitialTextSection,
bool NoFinalize =
false)
override;
480 ExtensionDirectiveHandler Handler)
override {
481 ExtensionDirectiveMap[
Directive] = Handler;
482 if (!DirectiveKindMap.contains(
Directive)) {
483 DirectiveKindMap[
Directive] = DK_HANDLER_DIRECTIVE;
488 DirectiveKindMap[
Directive] = DirectiveKindMap[Alias];
502 if (AssemblerDialect == ~0U)
505 return AssemblerDialect;
508 AssemblerDialect = i;
517 enum ExpandKind { ExpandMacros, DoNotExpandMacros };
522 ParsingMSInlineAsm =
V;
553 SMLoc &EndLoc)
override;
562 enum IdentifierPositionKind { StandardPosition, StartOfStatement };
575 const AsmToken peekTok(
bool ShouldSkipSpace =
true);
577 bool parseStatement(ParseStatementInfo &Info,
580 bool parseCppHashLineFilenameComment(
SMLoc L);
585 const std::vector<std::string> &Locals,
SMLoc L);
588 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
594 bool handleMacroEntry(
605 void handleMacroExit();
614 parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A,
617 void printMacroInstantiations();
619 bool expandStatement(
SMLoc Loc);
634 bool enabledGenDwarfForAssembly();
637 bool enterIncludeFile(
const std::string &Filename);
645 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0,
646 bool EndStatementAtEOF =
true);
660 bool parseTextItem(std::string &Data);
665 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
666 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
667 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
669 bool parseRegisterOrRegisterNumber(int64_t &
Register,
SMLoc DirectiveLoc);
672 bool parseCVFileId(int64_t &FileId,
StringRef DirectiveName);
677 DK_HANDLER_DIRECTIVE,
742 DK_CV_INLINE_SITE_ID,
745 DK_CV_INLINE_LINETABLE,
750 DK_CV_FILECHECKSUM_OFFSET,
756 DK_CFI_DEF_CFA_OFFSET,
757 DK_CFI_ADJUST_CFA_OFFSET,
758 DK_CFI_DEF_CFA_REGISTER,
763 DK_CFI_REMEMBER_STATE,
764 DK_CFI_RESTORE_STATE,
768 DK_CFI_RETURN_COLUMN,
806 bool isMacroLikeDirective();
809 enum CVDefRangeType {
811 CVDR_DEFRANGE_REGISTER,
812 CVDR_DEFRANGE_FRAMEPOINTER_REL,
813 CVDR_DEFRANGE_SUBFIELD_REGISTER,
814 CVDR_DEFRANGE_REGISTER_REL
847 const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol,
SMLoc StartLoc);
849 std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
853 bool parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated);
857 bool parseScalarInitializer(
unsigned Size,
859 unsigned StringPadLength = 0);
860 bool parseScalarInstList(
863 bool emitIntegralValues(
unsigned Size,
unsigned *Count =
nullptr);
866 bool parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
870 bool emitRealValues(
const fltSemantics &Semantics,
unsigned *Count =
nullptr);
874 bool parseRealInstList(
877 bool parseDirectiveNamedRealValue(
StringRef TypeName,
882 bool parseOptionalAngleBracketOpen();
883 bool parseAngleBracketClose(
const Twine &Msg =
"expected '>'");
885 bool parseFieldInitializer(
const FieldInfo &
Field,
886 FieldInitializer &Initializer);
887 bool parseFieldInitializer(
const FieldInfo &
Field,
888 const IntFieldInfo &Contents,
889 FieldInitializer &Initializer);
890 bool parseFieldInitializer(
const FieldInfo &
Field,
891 const RealFieldInfo &Contents,
892 FieldInitializer &Initializer);
893 bool parseFieldInitializer(
const FieldInfo &
Field,
894 const StructFieldInfo &Contents,
895 FieldInitializer &Initializer);
897 bool parseStructInitializer(
const StructInfo &Structure,
898 StructInitializer &Initializer);
899 bool parseStructInstList(
900 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
903 bool emitFieldValue(
const FieldInfo &
Field);
904 bool emitFieldValue(
const FieldInfo &
Field,
const IntFieldInfo &Contents);
905 bool emitFieldValue(
const FieldInfo &
Field,
const RealFieldInfo &Contents);
906 bool emitFieldValue(
const FieldInfo &
Field,
const StructFieldInfo &Contents);
908 bool emitFieldInitializer(
const FieldInfo &
Field,
909 const FieldInitializer &Initializer);
910 bool emitFieldInitializer(
const FieldInfo &
Field,
911 const IntFieldInfo &Contents,
912 const IntFieldInfo &Initializer);
913 bool emitFieldInitializer(
const FieldInfo &
Field,
914 const RealFieldInfo &Contents,
915 const RealFieldInfo &Initializer);
916 bool emitFieldInitializer(
const FieldInfo &
Field,
917 const StructFieldInfo &Contents,
918 const StructFieldInfo &Initializer);
920 bool emitStructInitializer(
const StructInfo &Structure,
921 const StructInitializer &Initializer);
924 bool emitStructValues(
const StructInfo &Structure,
unsigned *Count =
nullptr);
925 bool addStructField(
StringRef Name,
const StructInfo &Structure);
926 bool parseDirectiveStructValue(
const StructInfo &Structure,
928 bool parseDirectiveNamedStructValue(
const StructInfo &Structure,
934 DirectiveKind DirKind,
SMLoc NameLoc);
936 bool parseDirectiveOrg();
938 bool emitAlignTo(int64_t Alignment);
939 bool parseDirectiveAlign();
940 bool parseDirectiveEven();
943 bool parseDirectiveFile(
SMLoc DirectiveLoc);
944 bool parseDirectiveLine();
945 bool parseDirectiveLoc();
946 bool parseDirectiveStabs();
950 bool parseDirectiveCVFile();
951 bool parseDirectiveCVFuncId();
952 bool parseDirectiveCVInlineSiteId();
953 bool parseDirectiveCVLoc();
954 bool parseDirectiveCVLinetable();
955 bool parseDirectiveCVInlineLinetable();
956 bool parseDirectiveCVDefRange();
957 bool parseDirectiveCVString();
958 bool parseDirectiveCVStringTable();
959 bool parseDirectiveCVFileChecksums();
960 bool parseDirectiveCVFileChecksumOffset();
961 bool parseDirectiveCVFPOData();
964 bool parseDirectiveCFIRegister(
SMLoc DirectiveLoc);
965 bool parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc);
966 bool parseDirectiveCFISections();
967 bool parseDirectiveCFIStartProc();
968 bool parseDirectiveCFIEndProc();
969 bool parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc);
970 bool parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc);
971 bool parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc);
972 bool parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc);
973 bool parseDirectiveCFIOffset(
SMLoc DirectiveLoc);
974 bool parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc);
975 bool parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality);
976 bool parseDirectiveCFIRememberState(
SMLoc DirectiveLoc);
977 bool parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc);
978 bool parseDirectiveCFISameValue(
SMLoc DirectiveLoc);
979 bool parseDirectiveCFIRestore(
SMLoc DirectiveLoc);
980 bool parseDirectiveCFIEscape(
SMLoc DirectiveLoc);
981 bool parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc);
982 bool parseDirectiveCFISignalFrame();
983 bool parseDirectiveCFIUndefined(
SMLoc DirectiveLoc);
986 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
996 bool parseDirectiveNestedEnds();
998 bool parseDirectiveExtern();
1004 bool parseDirectiveComm(
bool IsLocal);
1006 bool parseDirectiveComment(
SMLoc DirectiveLoc);
1008 bool parseDirectiveInclude();
1011 bool parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
1013 bool parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1016 bool parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1017 bool CaseInsensitive);
1019 bool parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
1021 bool parseDirectiveElseIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
1023 bool parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1025 bool parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
1028 bool parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1029 bool CaseInsensitive);
1030 bool parseDirectiveElse(
SMLoc DirectiveLoc);
1031 bool parseDirectiveEndIf(
SMLoc DirectiveLoc);
1044 bool parseDirectiveWhile(
SMLoc DirectiveLoc);
1047 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
1051 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
1054 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
1057 bool parseDirectiveError(
SMLoc DirectiveLoc);
1059 bool parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
1061 bool parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
bool ExpectDefined);
1064 bool parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
1065 bool CaseInsensitive);
1067 bool parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero);
1070 bool parseDirectiveRadix(
SMLoc DirectiveLoc);
1073 bool parseDirectiveEcho(
SMLoc DirectiveLoc);
1075 void initializeDirectiveKindMap();
1076 void initializeCVDefRangeTypeMap();
1077 void initializeBuiltinSymbolMap();
1093 const MCAsmInfo &MAI,
struct tm TM,
unsigned CB)
1094 : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI),
SrcMgr(SM),
1095 CurBuffer(CB ? CB : SM.getMainFileID()),
TM(
TM) {
1103 EndStatementAtEOFStack.push_back(
true);
1115 initializeDirectiveKindMap();
1116 PlatformParser->Initialize(*
this);
1117 initializeCVDefRangeTypeMap();
1118 initializeBuiltinSymbolMap();
1120 NumOfMacroInstantiations = 0;
1123MasmParser::~MasmParser() {
1124 assert((HadError || ActiveMacros.empty()) &&
1125 "Unexpected active macro instantiation!");
1132void MasmParser::printMacroInstantiations() {
1134 for (std::vector<MacroInstantiation *>::const_reverse_iterator
1135 it = ActiveMacros.rbegin(),
1136 ie = ActiveMacros.rend();
1139 "while in macro instantiation");
1143 printPendingErrors();
1145 printMacroInstantiations();
1149 if (getTargetParser().getTargetOptions().MCNoWarn)
1151 if (getTargetParser().getTargetOptions().MCFatalWarnings)
1154 printMacroInstantiations();
1161 printMacroInstantiations();
1165bool MasmParser::enterIncludeFile(
const std::string &Filename) {
1166 std::string IncludedFile;
1174 EndStatementAtEOFStack.push_back(
true);
1178void MasmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer,
1179 bool EndStatementAtEOF) {
1185bool MasmParser::expandMacros() {
1195 if (handleMacroInvocation(M, MacroLoc)) {
1202 std::optional<std::string> ExpandedValue;
1203 auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1204 if (BuiltinIt != BuiltinSymbolMap.end()) {
1206 evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.
getLoc());
1208 auto VarIt = Variables.
find(IDLower);
1209 if (VarIt != Variables.
end() && VarIt->getValue().IsText) {
1210 ExpandedValue = VarIt->getValue().TextValue;
1216 std::unique_ptr<MemoryBuffer> Instantiation =
1224 EndStatementAtEOFStack.push_back(
false);
1229const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {
1236 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
1245 if (StartOfStatement) {
1280 if (ParentIncludeLoc !=
SMLoc()) {
1281 EndStatementAtEOFStack.pop_back();
1282 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1285 EndStatementAtEOFStack.pop_back();
1286 assert(EndStatementAtEOFStack.empty());
1292const AsmToken MasmParser::peekTok(
bool ShouldSkipSpace) {
1296 size_t ReadCount = Lexer.
peekTokens(Buf, ShouldSkipSpace);
1298 if (ReadCount == 0) {
1302 if (ParentIncludeLoc !=
SMLoc()) {
1303 EndStatementAtEOFStack.pop_back();
1304 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1305 return peekTok(ShouldSkipSpace);
1307 EndStatementAtEOFStack.pop_back();
1308 assert(EndStatementAtEOFStack.empty());
1315bool MasmParser::enabledGenDwarfForAssembly() {
1317 if (!getContext().getGenDwarfForAssembly())
1322 if (getContext().getGenDwarfFileNumber() == 0) {
1325 if (!FirstCppHashFilename.
empty())
1326 getContext().setMCLineTableRootFile(
1327 0, getContext().getCompilationDir(), FirstCppHashFilename,
1328 std::nullopt, std::nullopt);
1330 getContext().getMCDwarfLineTable(0).getRootFile();
1331 getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
1332 0, getContext().getCompilationDir(), RootFile.
Name,
1338bool MasmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
1340 if (!NoInitialTextSection)
1347 AsmCond StartingCondState = TheCondState;
1354 if (getContext().getGenDwarfForAssembly()) {
1355 MCSection *Sec = getStreamer().getCurrentSectionOnly();
1357 MCSymbol *SectionStartSym = getContext().createTempSymbol();
1358 getStreamer().emitLabel(SectionStartSym);
1361 bool InsertResult = getContext().addGenDwarfSection(Sec);
1362 assert(InsertResult &&
".text section should not have debug info yet");
1366 getTargetParser().onBeginOfFile();
1375 ParseStatementInfo
Info(&AsmStrRewrites);
1376 bool Parsed = parseStatement(Info,
nullptr);
1386 printPendingErrors();
1389 if (Parsed && !getLexer().isAtStartOfStatement())
1390 eatToEndOfStatement();
1393 getTargetParser().onEndOfFile();
1394 printPendingErrors();
1397 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1399 getTargetParser().flushPendingInstructions(getStreamer());
1403 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1405 const auto &LineTables = getContext().getMCDwarfLineTables();
1406 if (!LineTables.empty()) {
1408 for (
const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1410 printError(getTok().getLoc(),
"unassigned file number: " +
1412 " for .file directives");
1428 if (
Sym &&
Sym->isTemporary() && !
Sym->isVariable() &&
1433 printError(getTok().getLoc(),
"assembler local symbol '" +
1434 Sym->getName() +
"' not defined");
1440 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1441 if (std::get<2>(LocSym)->isUndefined()) {
1444 CppHashInfo = std::get<1>(LocSym);
1445 printError(std::get<0>(LocSym),
"directional label undefined");
1452 if (!HadError && !NoFinalize)
1455 return HadError || getContext().hadError();
1458bool MasmParser::checkForValidSection() {
1459 if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1461 return Error(getTok().getLoc(),
1462 "expected section directive before assembly directive");
1468void MasmParser::eatToEndOfStatement() {
1472 if (ParentIncludeLoc ==
SMLoc()) {
1476 EndStatementAtEOFStack.pop_back();
1477 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1491 const char *Start = getTok().getLoc().getPointer();
1492 while (Lexer.
isNot(EndTok)) {
1495 if (ParentIncludeLoc ==
SMLoc()) {
1498 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1500 EndStatementAtEOFStack.pop_back();
1501 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1503 Start = getTok().getLoc().getPointer();
1508 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1516 Str.append(S.str());
1521StringRef MasmParser::parseStringToEndOfStatement() {
1522 const char *Start = getTok().getLoc().getPointer();
1527 const char *
End = getTok().getLoc().getPointer();
1536bool MasmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1537 if (parseExpression(Res))
1540 return parseRParen();
1548bool MasmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1549 if (parseExpression(Res))
1551 EndLoc = getTok().getEndLoc();
1552 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1565bool MasmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1567 SMLoc FirstTokenLoc = getLexer().getLoc();
1569 switch (FirstTokenKind) {
1571 return TokError(
"unknown token in expression");
1577 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1585 if (parseIdentifier(Identifier)) {
1596 EndLoc = FirstTokenLoc;
1599 return Error(FirstTokenLoc,
"invalid token in expression");
1604 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1615 return Error(FirstTokenLoc,
"Expected @@ label before @B reference");
1620 std::pair<StringRef, StringRef>
Split;
1626 parseIdentifier(VName);
1629 "unexpected token in variant, expected ')'"))
1631 Split = std::make_pair(Identifier, VName);
1639 return Error(getLexer().getLoc(),
"expected a symbol reference");
1644 if (!
Split.second.empty()) {
1652 "invalid variant '" +
Split.second +
"'");
1659 if (
Split.second.empty()) {
1662 if (lookUpField(SymbolName,
Split.second, Info)) {
1663 std::pair<StringRef, StringRef> BaseMember =
Split.second.split(
'.');
1665 lookUpField(
Base, Member, Info);
1673 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1676 auto BuiltinIt = BuiltinSymbolMap.find(
SymbolName.lower());
1677 const BuiltinSymbol
Symbol = (BuiltinIt == BuiltinSymbolMap.end())
1679 : BuiltinIt->getValue();
1680 if (Symbol != BI_NO_SYMBOL) {
1681 const MCExpr *
Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
1691 if (VarIt != Variables.
end())
1693 Sym = getContext().getOrCreateSymbol(SymbolName);
1698 if (
Sym->isVariable()) {
1699 auto V =
Sym->getVariableValue(
false);
1700 bool DoInline = isa<MCConstantExpr>(V) && !
Variant;
1701 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1702 DoInline = TV->inlineAssignedExpr();
1705 return Error(EndLoc,
"unexpected modifier on variable reference");
1706 Res =
Sym->getVariableValue(
false);
1722 if (
Info.Type.Name.empty()) {
1724 if (TypeIt != KnownType.
end()) {
1725 Info.Type = TypeIt->second;
1729 *TypeInfo =
Info.Type;
1734 return TokError(
"literal value out of range for directive");
1736 int64_t
IntVal = getTok().getIntVal();
1744 SMLoc ValueLoc = getTok().getLoc();
1746 if (parseEscapedString(
Value))
1748 if (
Value.size() > 8)
1749 return Error(ValueLoc,
"literal value out of range");
1751 for (
const unsigned char CharVal :
Value)
1752 IntValue = (IntValue << 8) | CharVal;
1757 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1776 return parseParenExpr(Res, EndLoc);
1778 if (!PlatformParser->HasBracketExpressions())
1779 return TokError(
"brackets expression not supported on this target");
1781 return parseBracketExpr(Res, EndLoc);
1784 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1790 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1796 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1828 return TokError(
"expected '(' after operator");
1830 if (parseExpression(Res, EndLoc))
1834 Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1839bool MasmParser::parseExpression(
const MCExpr *&Res) {
1841 return parseExpression(Res, EndLoc);
1852 "Argument to the function cannot be a NULL value");
1854 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1855 (*CharPtr !=
'\0')) {
1856 if (*CharPtr ==
'!')
1860 if (*CharPtr ==
'>') {
1870 for (
size_t Pos = 0; Pos < BracketContents.
size(); Pos++) {
1871 if (BracketContents[Pos] ==
'!')
1873 Res += BracketContents[Pos];
1888bool MasmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1891 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1892 parseBinOpRHS(1, Res, EndLoc))
1898 if (Res->evaluateAsAbsolute(
Value))
1904bool MasmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1906 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1909bool MasmParser::parseParenExprOfDepth(
unsigned ParenDepth,
const MCExpr *&Res,
1911 if (parseParenExpr(Res, EndLoc))
1914 for (; ParenDepth > 0; --ParenDepth) {
1915 if (parseBinOpRHS(1, Res, EndLoc))
1920 if (ParenDepth - 1 > 0) {
1921 EndLoc = getTok().getEndLoc();
1929bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1933 if (parseExpression(Expr))
1936 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1937 return Error(StartLoc,
"expected absolute expression");
1944 bool ShouldUseLogicalShr,
1945 bool EndExpressionAtGreater) {
1973 if (EndExpressionAtGreater)
2014 if (EndExpressionAtGreater)
2025 AngleBracketDepth > 0);
2030bool MasmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
2052 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
2056 if (TokPrec < Precedence)
2063 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
2069 unsigned NextTokPrec = getBinOpPrecedence(Lexer.
getKind(), Dummy);
2070 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
2083bool MasmParser::parseStatement(ParseStatementInfo &Info,
2085 assert(!hasPendingError() &&
"parseStatement started with pending error");
2091 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
2092 getTok().getString().front() ==
'\n')
2101 SMLoc ExpansionLoc = getTok().getLoc();
2112 return parseCppHashLineFilenameComment(IDLoc);
2119 IDVal = getTok().getString();
2122 return Error(IDLoc,
"unexpected token at start of statement");
2123 }
else if (parseIdentifier(IDVal, StartOfStatement)) {
2124 if (!TheCondState.
Ignore) {
2126 return Error(IDLoc,
"unexpected token at start of statement");
2135 DirectiveKindMap.find(IDVal.
lower());
2136 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
2138 : DirKindIt->getValue();
2144 return parseDirectiveIf(IDLoc, DirKind);
2146 return parseDirectiveIfb(IDLoc,
true);
2148 return parseDirectiveIfb(IDLoc,
false);
2150 return parseDirectiveIfdef(IDLoc,
true);
2152 return parseDirectiveIfdef(IDLoc,
false);
2154 return parseDirectiveIfidn(IDLoc,
false,
2157 return parseDirectiveIfidn(IDLoc,
false,
2160 return parseDirectiveIfidn(IDLoc,
true,
2163 return parseDirectiveIfidn(IDLoc,
true,
2167 return parseDirectiveElseIf(IDLoc, DirKind);
2169 return parseDirectiveElseIfb(IDLoc,
true);
2171 return parseDirectiveElseIfb(IDLoc,
false);
2173 return parseDirectiveElseIfdef(IDLoc,
true);
2175 return parseDirectiveElseIfdef(IDLoc,
false);
2177 return parseDirectiveElseIfidn(IDLoc,
false,
2180 return parseDirectiveElseIfidn(IDLoc,
false,
2183 return parseDirectiveElseIfidn(IDLoc,
true,
2186 return parseDirectiveElseIfidn(IDLoc,
true,
2189 return parseDirectiveElse(IDLoc);
2191 return parseDirectiveEndIf(IDLoc);
2196 if (TheCondState.
Ignore) {
2197 eatToEndOfStatement();
2207 if (checkForValidSection())
2215 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
2223 if (ParsingMSInlineAsm && SI) {
2225 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
2227 "We should have an internal name here.");
2230 IDVal = RewrittenLabel;
2233 if (IDVal ==
"@@") {
2236 Sym = getContext().getOrCreateSymbol(IDVal);
2255 getTargetParser().doBeforeLabelEmit(
Sym, IDLoc);
2258 if (!getTargetParser().isParsingMSInlineAsm())
2263 if (enabledGenDwarfForAssembly())
2267 getTargetParser().onLabelParsed(
Sym);
2274 return handleMacroEntry(M, IDLoc);
2279 if (DirKind != DK_NO_DIRECTIVE) {
2291 getTargetParser().flushPendingInstructions(getStreamer());
2297 return parseDirectiveNestedEnds();
2302 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2305 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2311 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2313 "Should only return Failure iff there was an error");
2325 return parseDirectiveAscii(IDVal,
false);
2328 return parseDirectiveAscii(IDVal,
true);
2332 return parseDirectiveValue(IDVal, 1);
2336 return parseDirectiveValue(IDVal, 2);
2340 return parseDirectiveValue(IDVal, 4);
2343 return parseDirectiveValue(IDVal, 6);
2347 return parseDirectiveValue(IDVal, 8);
2349 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2351 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2353 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2356 return parseDirectiveNestedStruct(IDVal, DirKind);
2358 return parseDirectiveNestedEnds();
2360 return parseDirectiveAlign();
2362 return parseDirectiveEven();
2364 return parseDirectiveOrg();
2366 return parseDirectiveExtern();
2368 return parseDirectiveSymbolAttribute(
MCSA_Global);
2370 return parseDirectiveComm(
false);
2372 return parseDirectiveComment(IDLoc);
2374 return parseDirectiveInclude();
2376 return parseDirectiveRepeat(IDLoc, IDVal);
2378 return parseDirectiveWhile(IDLoc);
2380 return parseDirectiveFor(IDLoc, IDVal);
2382 return parseDirectiveForc(IDLoc, IDVal);
2384 return parseDirectiveFile(IDLoc);
2386 return parseDirectiveLine();
2388 return parseDirectiveLoc();
2390 return parseDirectiveStabs();
2392 return parseDirectiveCVFile();
2394 return parseDirectiveCVFuncId();
2395 case DK_CV_INLINE_SITE_ID:
2396 return parseDirectiveCVInlineSiteId();
2398 return parseDirectiveCVLoc();
2399 case DK_CV_LINETABLE:
2400 return parseDirectiveCVLinetable();
2401 case DK_CV_INLINE_LINETABLE:
2402 return parseDirectiveCVInlineLinetable();
2403 case DK_CV_DEF_RANGE:
2404 return parseDirectiveCVDefRange();
2406 return parseDirectiveCVString();
2407 case DK_CV_STRINGTABLE:
2408 return parseDirectiveCVStringTable();
2409 case DK_CV_FILECHECKSUMS:
2410 return parseDirectiveCVFileChecksums();
2411 case DK_CV_FILECHECKSUM_OFFSET:
2412 return parseDirectiveCVFileChecksumOffset();
2413 case DK_CV_FPO_DATA:
2414 return parseDirectiveCVFPOData();
2415 case DK_CFI_SECTIONS:
2416 return parseDirectiveCFISections();
2417 case DK_CFI_STARTPROC:
2418 return parseDirectiveCFIStartProc();
2419 case DK_CFI_ENDPROC:
2420 return parseDirectiveCFIEndProc();
2421 case DK_CFI_DEF_CFA:
2422 return parseDirectiveCFIDefCfa(IDLoc);
2423 case DK_CFI_DEF_CFA_OFFSET:
2424 return parseDirectiveCFIDefCfaOffset(IDLoc);
2425 case DK_CFI_ADJUST_CFA_OFFSET:
2426 return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2427 case DK_CFI_DEF_CFA_REGISTER:
2428 return parseDirectiveCFIDefCfaRegister(IDLoc);
2430 return parseDirectiveCFIOffset(IDLoc);
2431 case DK_CFI_REL_OFFSET:
2432 return parseDirectiveCFIRelOffset(IDLoc);
2433 case DK_CFI_PERSONALITY:
2434 return parseDirectiveCFIPersonalityOrLsda(
true);
2436 return parseDirectiveCFIPersonalityOrLsda(
false);
2437 case DK_CFI_REMEMBER_STATE:
2438 return parseDirectiveCFIRememberState(IDLoc);
2439 case DK_CFI_RESTORE_STATE:
2440 return parseDirectiveCFIRestoreState(IDLoc);
2441 case DK_CFI_SAME_VALUE:
2442 return parseDirectiveCFISameValue(IDLoc);
2443 case DK_CFI_RESTORE:
2444 return parseDirectiveCFIRestore(IDLoc);
2446 return parseDirectiveCFIEscape(IDLoc);
2447 case DK_CFI_RETURN_COLUMN:
2448 return parseDirectiveCFIReturnColumn(IDLoc);
2449 case DK_CFI_SIGNAL_FRAME:
2450 return parseDirectiveCFISignalFrame();
2451 case DK_CFI_UNDEFINED:
2452 return parseDirectiveCFIUndefined(IDLoc);
2453 case DK_CFI_REGISTER:
2454 return parseDirectiveCFIRegister(IDLoc);
2455 case DK_CFI_WINDOW_SAVE:
2456 return parseDirectiveCFIWindowSave(IDLoc);
2458 Info.ExitValue =
"";
2459 return parseDirectiveExitMacro(IDLoc, IDVal, *
Info.ExitValue);
2461 Info.ExitValue =
"";
2462 return parseDirectiveEndMacro(IDVal);
2464 return parseDirectivePurgeMacro(IDLoc);
2466 return parseDirectiveEnd(IDLoc);
2468 return parseDirectiveError(IDLoc);
2470 return parseDirectiveErrorIfb(IDLoc,
true);
2472 return parseDirectiveErrorIfb(IDLoc,
false);
2474 return parseDirectiveErrorIfdef(IDLoc,
true);
2476 return parseDirectiveErrorIfdef(IDLoc,
false);
2478 return parseDirectiveErrorIfidn(IDLoc,
false,
2481 return parseDirectiveErrorIfidn(IDLoc,
false,
2484 return parseDirectiveErrorIfidn(IDLoc,
true,
2487 return parseDirectiveErrorIfidn(IDLoc,
true,
2490 return parseDirectiveErrorIfe(IDLoc,
true);
2492 return parseDirectiveErrorIfe(IDLoc,
false);
2494 return parseDirectiveRadix(IDLoc);
2496 return parseDirectiveEcho(IDLoc);
2499 return Error(IDLoc,
"unknown directive");
2503 auto IDIt = Structs.
find(IDVal.
lower());
2504 if (IDIt != Structs.
end())
2505 return parseDirectiveStructValue(IDIt->getValue(), IDVal,
2513 const AsmToken afterNextTok = peekTok();
2524 getTargetParser().flushPendingInstructions(getStreamer());
2530 return parseDirectiveEnds(IDVal, IDLoc);
2535 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2537 if (Handler.first) {
2540 return (*Handler.second)(Handler.first, nextVal, nextLoc);
2545 DirKindIt = DirectiveKindMap.find(nextVal.
lower());
2546 DirKind = (DirKindIt == DirectiveKindMap.end())
2548 : DirKindIt->getValue();
2556 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
2567 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2578 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2589 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2599 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2610 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2613 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2617 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2621 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2626 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2629 return parseDirectiveEnds(IDVal, IDLoc);
2632 return parseDirectiveMacro(IDVal, IDLoc);
2636 auto NextIt = Structs.
find(nextVal.
lower());
2637 if (NextIt != Structs.
end()) {
2639 return parseDirectiveNamedStructValue(NextIt->getValue(),
2640 nextVal, nextLoc, IDVal);
2644 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2645 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2646 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2649 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2650 return parseDirectiveMSAlign(IDLoc, Info);
2652 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2654 if (checkForValidSection())
2658 std::string OpcodeStr = IDVal.
lower();
2660 bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
ID,
2661 Info.ParsedOperands);
2662 Info.ParseError = ParseHadError;
2665 if (getShowParsedOperands()) {
2668 OS <<
"parsed instruction: [";
2669 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2672 Info.ParsedOperands[i]->print(
OS);
2680 if (hasPendingError() || ParseHadError)
2685 if (!ParseHadError && enabledGenDwarfForAssembly() &&
2686 getContext().getGenDwarfSectionSyms().
count(
2687 getStreamer().getCurrentSectionOnly())) {
2689 if (ActiveMacros.empty())
2693 ActiveMacros.front()->ExitBuffer);
2698 if (!CppHashInfo.Filename.empty()) {
2699 unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2701 getContext().setGenDwarfFileNumber(FileNumber);
2703 unsigned CppHashLocLineNo =
2705 Line = CppHashInfo.LineNumber - 1 + (
Line - CppHashLocLineNo);
2708 getStreamer().emitDwarfLocDirective(
2709 getContext().getGenDwarfFileNumber(), Line, 0,
2715 if (!ParseHadError) {
2717 if (getTargetParser().MatchAndEmitInstruction(
2719 getTargetParser().isParsingMSInlineAsm()))
2726bool MasmParser::parseCurlyBlockScope(
2745bool MasmParser::parseCppHashLineFilenameComment(
SMLoc L) {
2750 "Lexing Cpp line comment: Expected Integer");
2751 int64_t LineNumber = getTok().getIntVal();
2754 "Lexing Cpp line comment: Expected String");
2763 CppHashInfo.Loc =
L;
2765 CppHashInfo.LineNumber = LineNumber;
2766 CppHashInfo.Buf = CurBuffer;
2767 if (FirstCppHashFilename.
empty())
2774void MasmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2775 const MasmParser *Parser =
static_cast<const MasmParser *
>(Context);
2781 unsigned CppHashBuf =
2782 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2787 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2796 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2797 DiagBuf != CppHashBuf) {
2798 if (Parser->SavedDiagHandler)
2799 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2808 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2811 int CppHashLocLineNo =
2812 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2814 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2820 if (Parser->SavedDiagHandler)
2821 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2823 NewDiag.print(
nullptr,
OS);
2829 return isAlnum(
C) ||
C ==
'_' ||
C ==
'$' ||
C ==
'@' ||
C ==
'?';
2835 const std::vector<std::string> &Locals,
SMLoc L) {
2837 if (NParameters !=
A.size())
2838 return Error(L,
"Wrong number of arguments");
2850 std::optional<char> CurrentQuote;
2851 while (!Body.
empty()) {
2853 std::size_t
End = Body.
size(), Pos = 0;
2854 std::size_t IdentifierPos =
End;
2855 for (; Pos !=
End; ++Pos) {
2858 if (Body[Pos] ==
'&')
2863 if (IdentifierPos ==
End)
2864 IdentifierPos = Pos;
2866 IdentifierPos =
End;
2870 if (!CurrentQuote) {
2871 if (Body[Pos] ==
'\'' || Body[Pos] ==
'"')
2872 CurrentQuote = Body[Pos];
2873 }
else if (Body[Pos] == CurrentQuote) {
2874 if (Pos + 1 !=
End && Body[Pos + 1] == CurrentQuote) {
2879 CurrentQuote.reset();
2883 if (IdentifierPos !=
End) {
2886 Pos = IdentifierPos;
2887 IdentifierPos =
End;
2898 bool InitialAmpersand = (Body[
I] ==
'&');
2899 if (InitialAmpersand) {
2906 const char *Begin = Body.
data() + Pos;
2908 const std::string ArgumentLower =
Argument.lower();
2912 if (Parameters[
Index].
Name.equals_insensitive(ArgumentLower))
2915 if (
Index == NParameters) {
2916 if (InitialAmpersand)
2918 auto it = LocalSymbols.
find(ArgumentLower);
2919 if (it != LocalSymbols.
end())
2935 OS << Token.getIntVal();
2937 OS << Token.getString();
2941 if (Pos <
End && Body[Pos] ==
'&') {
2984class AsmLexerSkipSpaceRAII {
2986 AsmLexerSkipSpaceRAII(
AsmLexer &Lexer,
bool SkipSpace) : Lexer(Lexer) {
2990 ~AsmLexerSkipSpaceRAII() {
3001 MCAsmMacroArgument &MA,
3004 if (Lexer.
isNot(EndTok)) {
3015 const char *StrChar = StrLoc.
getPointer() + 1;
3016 const char *EndChar = EndLoc.
getPointer() - 1;
3017 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3024 unsigned ParenLevel = 0;
3027 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
3034 return TokError(
"unexpected token");
3036 if (ParenLevel == 0) {
3050 MA.push_back(getTok());
3076 MA.push_back(getTok());
3080 if (ParenLevel != 0)
3081 return TokError(
"unbalanced parentheses in argument");
3083 if (MA.empty() && MP) {
3085 return TokError(
"missing value for required parameter '" + MP->
Name +
3095bool MasmParser::parseMacroArguments(
const MCAsmMacro *M,
3096 MCAsmMacroArguments &
A,
3098 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
3099 bool NamedParametersFound =
false;
3102 A.resize(NParameters);
3103 FALocs.
resize(NParameters);
3108 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
3114 if (parseIdentifier(FA.
Name))
3115 return Error(IDLoc,
"invalid argument identifier for formal argument");
3118 return TokError(
"expected '=' after formal parameter identifier");
3122 NamedParametersFound =
true;
3125 if (NamedParametersFound && FA.
Name.
empty())
3126 return Error(IDLoc,
"cannot mix positional and keyword arguments");
3128 unsigned PI = Parameter;
3130 assert(M &&
"expected macro to be defined");
3132 for (FAI = 0; FAI < NParameters; ++FAI)
3133 if (
M->Parameters[FAI].Name == FA.
Name)
3136 if (FAI >= NParameters) {
3137 return Error(IDLoc,
"parameter named '" + FA.
Name +
3138 "' does not exist for macro '" +
M->Name +
"'");
3143 if (M && PI < NParameters)
3144 MP = &
M->Parameters[PI];
3149 const MCExpr *AbsoluteExp;
3153 if (parseExpression(AbsoluteExp, EndLoc))
3155 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
3156 getStreamer().getAssemblerPtr()))
3157 return Error(StrLoc,
"expected absolute expression");
3162 FA.
Value.push_back(newToken);
3163 }
else if (parseMacroArgument(MP, FA.
Value, EndTok)) {
3165 return addErrorSuffix(
" in '" +
M->Name +
"' macro");
3170 if (!FA.
Value.empty()) {
3175 if (FALocs.
size() <= PI)
3178 FALocs[PI] = Lexer.
getLoc();
3184 if (Lexer.
is(EndTok)) {
3186 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
3187 if (
A[FAI].empty()) {
3188 if (
M->Parameters[FAI].Required) {
3190 "missing value for required parameter "
3192 M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
3196 if (!
M->Parameters[FAI].Value.empty())
3197 A[FAI] =
M->Parameters[FAI].Value;
3207 return TokError(
"too many positional arguments");
3215 if (ActiveMacros.size() == MaxNestingDepth) {
3216 std::ostringstream MaxNestingDepthError;
3217 MaxNestingDepthError <<
"macros cannot be nested more than "
3218 << MaxNestingDepth <<
" levels deep."
3219 <<
" Use -asm-macro-max-nesting-depth to increase "
3221 return TokError(MaxNestingDepthError.str());
3224 MCAsmMacroArguments
A;
3225 if (parseMacroArguments(M,
A, ArgumentEndTok))
3234 if (expandMacro(
OS, Body,
M->Parameters,
A,
M->Locals, getTok().getLoc()))
3241 std::unique_ptr<MemoryBuffer> Instantiation =
3246 MacroInstantiation *
MI =
new MacroInstantiation{
3247 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
3248 ActiveMacros.push_back(
MI);
3250 ++NumOfMacroInstantiations;
3255 EndStatementAtEOFStack.push_back(
true);
3261void MasmParser::handleMacroExit() {
3263 EndStatementAtEOFStack.pop_back();
3264 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
3265 EndStatementAtEOFStack.back());
3269 delete ActiveMacros.back();
3270 ActiveMacros.pop_back();
3273bool MasmParser::handleMacroInvocation(
const MCAsmMacro *M,
SMLoc NameLoc) {
3275 return Error(NameLoc,
"cannot invoke macro procedure as function");
3278 "' requires arguments in parentheses") ||
3283 std::string ExitValue;
3286 ParseStatementInfo
Info(&AsmStrRewrites);
3287 bool Parsed = parseStatement(Info,
nullptr);
3289 if (!Parsed &&
Info.ExitValue) {
3290 ExitValue = std::move(*
Info.ExitValue);
3302 printPendingErrors();
3305 if (Parsed && !getLexer().isAtStartOfStatement())
3306 eatToEndOfStatement();
3315 std::unique_ptr<MemoryBuffer> MacroValue =
3323 EndStatementAtEOFStack.push_back(
false);
3332bool MasmParser::parseIdentifier(
StringRef &Res,
3333 IdentifierPositionKind Position) {
3340 SMLoc PrefixLoc = getLexer().getLoc();
3365 Res = getTok().getIdentifier();
3369 ExpandKind ExpandNextToken = ExpandMacros;
3370 if (Position == StartOfStatement &&
3372 .CaseLower(
"echo",
true)
3373 .CasesLower(
"ifdef",
"ifndef",
"elseifdef",
"elseifndef",
true)
3375 ExpandNextToken = DoNotExpandMacros;
3377 Lex(ExpandNextToken);
3388 DirectiveKind DirKind,
SMLoc NameLoc) {
3389 auto BuiltinIt = BuiltinSymbolMap.find(
Name.lower());
3390 if (BuiltinIt != BuiltinSymbolMap.end())
3391 return Error(NameLoc,
"cannot redefine a built-in symbol");
3393 Variable &Var = Variables[
Name.lower()];
3394 if (Var.Name.empty()) {
3399 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3402 std::string TextItem;
3403 if (!parseTextItem(TextItem)) {
3407 auto parseItem = [&]() ->
bool {
3408 if (parseTextItem(TextItem))
3409 return TokError(
"expected text item");
3414 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3416 if (!Var.IsText || Var.TextValue !=
Value) {
3417 switch (Var.Redefinable) {
3418 case Variable::NOT_REDEFINABLE:
3419 return Error(getTok().getLoc(),
"invalid variable redefinition");
3420 case Variable::WARN_ON_REDEFINITION:
3422 "', already defined on the command line")) {
3431 Var.TextValue =
Value;
3432 Var.Redefinable = Variable::REDEFINABLE;
3437 if (DirKind == DK_TEXTEQU)
3438 return TokError(
"expected <text> in '" +
Twine(IDVal) +
"' directive");
3443 if (parseExpression(Expr, EndLoc))
3444 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3449 if (!Expr->evaluateAsAbsolute(
Value, getStreamer().getAssemblerPtr())) {
3450 if (DirKind == DK_ASSIGN)
3453 "expected absolute expression; not all symbols have known values",
3454 {StartLoc, EndLoc});
3457 if (!Var.IsText || Var.TextValue != ExprAsString) {
3458 switch (Var.Redefinable) {
3459 case Variable::NOT_REDEFINABLE:
3460 return Error(getTok().getLoc(),
"invalid variable redefinition");
3461 case Variable::WARN_ON_REDEFINITION:
3463 "', already defined on the command line")) {
3473 Var.TextValue = ExprAsString.
str();
3474 Var.Redefinable = Variable::REDEFINABLE;
3479 MCSymbol *
Sym = getContext().getOrCreateSymbol(Var.Name);
3482 Sym->isVariable() ? dyn_cast_or_null<MCConstantExpr>(
3483 Sym->getVariableValue(
false))
3485 if (Var.IsText || !PrevValue || PrevValue->
getValue() !=
Value) {
3486 switch (Var.Redefinable) {
3487 case Variable::NOT_REDEFINABLE:
3488 return Error(getTok().getLoc(),
"invalid variable redefinition");
3489 case Variable::WARN_ON_REDEFINITION:
3491 "', already defined on the command line")) {
3501 Var.TextValue.clear();
3502 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
3503 : Variable::NOT_REDEFINABLE;
3505 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
3506 Sym->setVariableValue(Expr);
3507 Sym->setExternal(
false);
3512bool MasmParser::parseEscapedString(std::string &Data) {
3517 char Quote = getTok().getString().front();
3518 StringRef Str = getTok().getStringContents();
3519 Data.reserve(Str.size());
3520 for (
size_t i = 0, e = Str.size(); i != e; ++i) {
3521 Data.push_back(Str[i]);
3522 if (Str[i] == Quote) {
3526 if (i + 1 == Str.size())
3527 return Error(getTok().getLoc(),
"missing quotation mark in string");
3528 if (Str[i + 1] == Quote)
3537bool MasmParser::parseAngleBracketString(std::string &Data) {
3538 SMLoc EndLoc, StartLoc = getTok().getLoc();
3540 const char *StartChar = StartLoc.
getPointer() + 1;
3541 const char *EndChar = EndLoc.
getPointer() - 1;
3542 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3553bool MasmParser::parseTextItem(std::string &Data) {
3554 switch (getTok().getKind()) {
3561 Data = std::to_string(Res);
3568 return parseAngleBracketString(Data);
3572 SMLoc StartLoc = getTok().getLoc();
3573 if (parseIdentifier(
ID))
3577 bool Expanded =
false;
3580 auto BuiltinIt = BuiltinSymbolMap.find(
ID.lower());
3581 if (BuiltinIt != BuiltinSymbolMap.end()) {
3582 std::optional<std::string> BuiltinText =
3583 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
3588 Data = std::move(*BuiltinText);
3595 auto VarIt = Variables.
find(
ID.lower());
3596 if (VarIt != Variables.
end()) {
3597 const Variable &Var = VarIt->getValue();
3602 Data = Var.TextValue;
3625bool MasmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3626 auto parseOp = [&]() ->
bool {
3628 if (checkForValidSection() || parseEscapedString(Data))
3630 getStreamer().emitBytes(Data);
3632 getStreamer().emitBytes(
StringRef(
"\0", 1));
3636 if (parseMany(parseOp))
3637 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3645 int64_t IntValue = MCE->getValue();
3647 return Error(MCE->getLoc(),
"out of range literal value");
3648 getStreamer().emitIntValue(IntValue,
Size);
3653 getStreamer().emitIntValue(0,
Size);
3661bool MasmParser::parseScalarInitializer(
unsigned Size,
3663 unsigned StringPadLength) {
3666 if (parseEscapedString(
Value))
3669 for (
const unsigned char CharVal :
Value)
3673 for (
size_t i =
Value.size(); i < StringPadLength; ++i)
3677 if (parseExpression(
Value))
3680 getTok().getString().equals_insensitive(
"dup")) {
3685 "cannot repeat value a non-constant number of times");
3686 const int64_t Repetitions = MCE->
getValue();
3687 if (Repetitions < 0)
3689 "cannot repeat value a negative number of times");
3693 "parentheses required for 'dup' contents") ||
3694 parseScalarInstList(
Size, DuplicatedValues) || parseRParen())
3697 for (
int i = 0; i < Repetitions; ++i)
3706bool MasmParser::parseScalarInstList(
unsigned Size,
3709 while (getTok().
isNot(EndToken) &&
3712 parseScalarInitializer(
Size, Values);
3722bool MasmParser::emitIntegralValues(
unsigned Size,
unsigned *Count) {
3724 if (checkForValidSection() || parseScalarInstList(
Size, Values))
3727 for (
const auto *
Value : Values) {
3731 *Count = Values.size();
3737 StructInfo &
Struct = StructInProgress.
back();
3739 IntFieldInfo &IntInfo =
Field.Contents.IntInfo;
3743 if (parseScalarInstList(
Size, IntInfo.Values))
3746 Field.SizeOf =
Field.Type * IntInfo.Values.size();
3747 Field.LengthOf = IntInfo.Values.size();
3750 Struct.NextOffset = FieldEnd;
3758bool MasmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3759 if (StructInProgress.
empty()) {
3761 if (emitIntegralValues(
Size))
3762 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3763 }
else if (addIntegralField(
"",
Size)) {
3764 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3772bool MasmParser::parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
3774 if (StructInProgress.
empty()) {
3777 getStreamer().emitLabel(
Sym);
3779 if (emitIntegralValues(
Size, &Count))
3780 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3786 Type.Length = Count;
3788 }
else if (addIntegralField(
Name,
Size)) {
3789 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3798 return Asm.TokError(
"unknown token in expression");
3799 SMLoc ExprLoc = Asm.getTok().getLoc();
3800 APInt IntValue = Asm.getTok().getAPIntVal();
3802 if (!IntValue.
isIntN(128))
3803 return Asm.Error(ExprLoc,
"out of range literal value");
3804 if (!IntValue.
isIntN(64)) {
3820 SignLoc = getLexer().getLoc();
3824 SignLoc = getLexer().getLoc();
3829 return TokError(Lexer.
getErr());
3832 return TokError(
"unexpected token in directive");
3845 return TokError(
"invalid floating point literal");
3849 unsigned SizeInBits =
Value.getSizeInBits(Semantics);
3850 if (SizeInBits != (IDVal.
size() << 2))
3851 return TokError(
"invalid floating point literal");
3856 Res =
APInt(SizeInBits, IDVal, 16);
3858 return Warning(SignLoc,
"MASM-style hex floats ignore explicit sign");
3861 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3863 return TokError(
"invalid floating point literal");
3871 Res =
Value.bitcastToAPInt();
3876bool MasmParser::parseRealInstList(
const fltSemantics &Semantics,
3879 while (getTok().
isNot(EndToken) ||
3882 const AsmToken NextTok = peekTok();
3891 "cannot repeat value a non-constant number of times");
3892 const int64_t Repetitions = MCE->
getValue();
3893 if (Repetitions < 0)
3895 "cannot repeat value a negative number of times");
3899 "parentheses required for 'dup' contents") ||
3900 parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
3903 for (
int i = 0; i < Repetitions; ++i)
3904 ValuesAsInt.
append(DuplicatedValues.
begin(), DuplicatedValues.
end());
3907 if (parseRealValue(Semantics, AsInt))
3922bool MasmParser::emitRealValues(
const fltSemantics &Semantics,
3924 if (checkForValidSection())
3928 if (parseRealInstList(Semantics, ValuesAsInt))
3931 for (
const APInt &AsInt : ValuesAsInt) {
3932 getStreamer().emitIntValue(AsInt);
3935 *Count = ValuesAsInt.size();
3942 StructInfo &
Struct = StructInProgress.
back();
3944 RealFieldInfo &RealInfo =
Field.Contents.RealInfo;
3948 if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3951 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3952 Field.LengthOf = RealInfo.AsIntValues.size();
3957 Struct.NextOffset = FieldEnd;
3965bool MasmParser::parseDirectiveRealValue(
StringRef IDVal,
3968 if (StructInProgress.
empty()) {
3970 if (emitRealValues(Semantics))
3971 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3972 }
else if (addRealField(
"", Semantics,
Size)) {
3973 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3980bool MasmParser::parseDirectiveNamedRealValue(
StringRef TypeName,
3984 if (StructInProgress.
empty()) {
3987 getStreamer().emitLabel(
Sym);
3989 if (emitRealValues(Semantics, &Count))
3990 return addErrorSuffix(
" in '" + TypeName +
"' directive");
3996 Type.Length = Count;
3998 }
else if (addRealField(
Name, Semantics,
Size)) {
3999 return addErrorSuffix(
" in '" + TypeName +
"' directive");
4004bool MasmParser::parseOptionalAngleBracketOpen() {
4007 AngleBracketDepth++;
4011 AngleBracketDepth++;
4015 AngleBracketDepth++;
4022bool MasmParser::parseAngleBracketClose(
const Twine &Msg) {
4029 AngleBracketDepth--;
4033bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4034 const IntFieldInfo &Contents,
4035 FieldInitializer &Initializer) {
4036 SMLoc Loc = getTok().getLoc();
4041 return Error(Loc,
"Cannot initialize scalar field with array value");
4045 }
else if (parseOptionalAngleBracketOpen()) {
4047 return Error(Loc,
"Cannot initialize scalar field with array value");
4049 parseAngleBracketClose())
4051 }
else if (
Field.LengthOf > 1 &&
Field.Type > 1) {
4052 return Error(Loc,
"Cannot initialize array field with scalar value");
4053 }
else if (parseScalarInitializer(
Field.Type, Values,
4059 return Error(Loc,
"Initializer too long for field; expected at most " +
4060 std::to_string(
Field.LengthOf) +
" elements, got " +
4061 std::to_string(Values.
size()));
4064 Values.
append(Contents.Values.begin() + Values.
size(), Contents.Values.end());
4066 Initializer = FieldInitializer(std::move(Values));
4070bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4071 const RealFieldInfo &Contents,
4072 FieldInitializer &Initializer) {
4074 switch (
Field.Type) {
4076 Semantics = &APFloat::IEEEsingle();
4079 Semantics = &APFloat::IEEEdouble();
4082 Semantics = &APFloat::x87DoubleExtended();
4088 SMLoc Loc = getTok().getLoc();
4092 if (
Field.LengthOf == 1)
4093 return Error(Loc,
"Cannot initialize scalar field with array value");
4097 }
else if (parseOptionalAngleBracketOpen()) {
4098 if (
Field.LengthOf == 1)
4099 return Error(Loc,
"Cannot initialize scalar field with array value");
4101 parseAngleBracketClose())
4103 }
else if (
Field.LengthOf > 1) {
4104 return Error(Loc,
"Cannot initialize array field with scalar value");
4107 if (parseRealValue(*Semantics, AsIntValues.
back()))
4111 if (AsIntValues.
size() >
Field.LengthOf) {
4112 return Error(Loc,
"Initializer too long for field; expected at most " +
4113 std::to_string(
Field.LengthOf) +
" elements, got " +
4114 std::to_string(AsIntValues.
size()));
4117 AsIntValues.
append(Contents.AsIntValues.begin() + AsIntValues.
size(),
4118 Contents.AsIntValues.end());
4120 Initializer = FieldInitializer(std::move(AsIntValues));
4124bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4125 const StructFieldInfo &Contents,
4126 FieldInitializer &Initializer) {
4127 SMLoc Loc = getTok().getLoc();
4129 std::vector<StructInitializer> Initializers;
4130 if (
Field.LengthOf > 1) {
4132 if (parseStructInstList(Contents.Structure, Initializers,
4136 }
else if (parseOptionalAngleBracketOpen()) {
4137 if (parseStructInstList(Contents.Structure, Initializers,
4139 parseAngleBracketClose())
4142 return Error(Loc,
"Cannot initialize array field with scalar value");
4145 Initializers.emplace_back();
4146 if (parseStructInitializer(Contents.Structure, Initializers.back()))
4150 if (Initializers.size() >
Field.LengthOf) {
4151 return Error(Loc,
"Initializer too long for field; expected at most " +
4152 std::to_string(
Field.LengthOf) +
" elements, got " +
4153 std::to_string(Initializers.size()));
4156 Initializers.insert(Initializers.end(),
4157 Contents.Initializers.begin() + Initializers.size(),
4158 Contents.Initializers.end());
4160 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
4164bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
4165 FieldInitializer &Initializer) {
4166 switch (
Field.Contents.FT) {
4168 return parseFieldInitializer(
Field,
Field.Contents.IntInfo, Initializer);
4170 return parseFieldInitializer(
Field,
Field.Contents.RealInfo, Initializer);
4172 return parseFieldInitializer(
Field,
Field.Contents.StructInfo, Initializer);
4177bool MasmParser::parseStructInitializer(
const StructInfo &Structure,
4178 StructInitializer &Initializer) {
4179 const AsmToken FirstToken = getTok();
4181 std::optional<AsmToken::TokenKind> EndToken;
4184 }
else if (parseOptionalAngleBracketOpen()) {
4186 AngleBracketDepth++;
4193 return Error(FirstToken.
getLoc(),
"Expected struct initializer");
4196 auto &FieldInitializers = Initializer.FieldInitializers;
4197 size_t FieldIndex = 0;
4200 while (getTok().
isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
4201 const FieldInfo &
Field = Structure.Fields[FieldIndex++];
4205 FieldInitializers.push_back(
Field.Contents);
4209 FieldInitializers.emplace_back(
Field.Contents.FT);
4210 if (parseFieldInitializer(
Field, FieldInitializers.back()))
4214 SMLoc CommaLoc = getTok().getLoc();
4217 if (FieldIndex == Structure.Fields.size())
4218 return Error(CommaLoc,
"'" + Structure.Name +
4219 "' initializer initializes too many fields");
4225 FieldInitializers.push_back(
Field.Contents);
4229 return parseAngleBracketClose();
4231 return parseToken(*EndToken);
4237bool MasmParser::parseStructInstList(
4238 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
4240 while (getTok().
isNot(EndToken) ||
4243 const AsmToken NextTok = peekTok();
4252 "cannot repeat value a non-constant number of times");
4253 const int64_t Repetitions = MCE->
getValue();
4254 if (Repetitions < 0)
4256 "cannot repeat value a negative number of times");
4258 std::vector<StructInitializer> DuplicatedValues;
4260 "parentheses required for 'dup' contents") ||
4261 parseStructInstList(Structure, DuplicatedValues) || parseRParen())
4264 for (
int i = 0; i < Repetitions; ++i)
4267 Initializers.emplace_back();
4268 if (parseStructInitializer(Structure, Initializers.back()))
4281bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4282 const IntFieldInfo &Contents) {
4291bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4292 const RealFieldInfo &Contents) {
4293 for (
const APInt &AsInt : Contents.AsIntValues) {
4300bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
4301 const StructFieldInfo &Contents) {
4302 for (
const auto &Initializer : Contents.Initializers) {
4304 for (
const auto &SubField : Contents.Structure.Fields) {
4305 getStreamer().emitZeros(SubField.Offset -
Offset);
4306 Offset = SubField.Offset + SubField.SizeOf;
4307 emitFieldInitializer(SubField, Initializer.FieldInitializers[
Index++]);
4313bool MasmParser::emitFieldValue(
const FieldInfo &
Field) {
4314 switch (
Field.Contents.FT) {
4316 return emitFieldValue(
Field,
Field.Contents.IntInfo);
4318 return emitFieldValue(
Field,
Field.Contents.RealInfo);
4320 return emitFieldValue(
Field,
Field.Contents.StructInfo);
4325bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4326 const IntFieldInfo &Contents,
4327 const IntFieldInfo &Initializer) {
4328 for (
const auto &
Value : Initializer.Values) {
4333 for (
const auto &
Value :
4341bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4342 const RealFieldInfo &Contents,
4343 const RealFieldInfo &Initializer) {
4344 for (
const auto &AsInt : Initializer.AsIntValues) {
4349 for (
const auto &AsInt :
4357bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4358 const StructFieldInfo &Contents,
4359 const StructFieldInfo &Initializer) {
4360 for (
const auto &
Init : Initializer.Initializers) {
4361 if (emitStructInitializer(Contents.Structure,
Init))
4366 Initializer.Initializers.size())) {
4367 if (emitStructInitializer(Contents.Structure,
Init))
4373bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
4374 const FieldInitializer &Initializer) {
4375 switch (
Field.Contents.FT) {
4377 return emitFieldInitializer(
Field,
Field.Contents.IntInfo,
4378 Initializer.IntInfo);
4380 return emitFieldInitializer(
Field,
Field.Contents.RealInfo,
4381 Initializer.RealInfo);
4383 return emitFieldInitializer(
Field,
Field.Contents.StructInfo,
4384 Initializer.StructInfo);
4389bool MasmParser::emitStructInitializer(
const StructInfo &Structure,
4390 const StructInitializer &Initializer) {
4391 if (!Structure.Initializable)
4392 return Error(getLexer().getLoc(),
4393 "cannot initialize a value of type '" + Structure.Name +
4394 "'; 'org' was used in the type's declaration");
4396 for (
const auto &
Init : Initializer.FieldInitializers) {
4397 const auto &
Field = Structure.Fields[
Index++];
4405 Structure.Fields, Initializer.FieldInitializers.size())) {
4408 if (emitFieldValue(
Field))
4412 if (
Offset != Structure.Size)
4413 getStreamer().emitZeros(Structure.Size -
Offset);
4418bool MasmParser::emitStructValues(
const StructInfo &Structure,
4420 std::vector<StructInitializer> Initializers;
4421 if (parseStructInstList(Structure, Initializers))
4424 for (
const auto &Initializer : Initializers) {
4425 if (emitStructInitializer(Structure, Initializer))
4430 *Count = Initializers.size();
4435bool MasmParser::addStructField(
StringRef Name,
const StructInfo &Structure) {
4436 StructInfo &OwningStruct = StructInProgress.
back();
4438 OwningStruct.addField(
Name, FT_STRUCT, Structure.AlignmentSize);
4439 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4441 StructInfo.Structure = Structure;
4444 if (parseStructInstList(Structure, StructInfo.Initializers))
4447 Field.LengthOf = StructInfo.Initializers.size();
4451 if (!OwningStruct.IsUnion) {
4452 OwningStruct.NextOffset = FieldEnd;
4454 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
4462bool MasmParser::parseDirectiveStructValue(
const StructInfo &Structure,
4464 if (StructInProgress.
empty()) {
4465 if (emitStructValues(Structure))
4467 }
else if (addStructField(
"", Structure)) {
4468 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4476bool MasmParser::parseDirectiveNamedStructValue(
const StructInfo &Structure,
4479 if (StructInProgress.
empty()) {
4482 getStreamer().emitLabel(
Sym);
4484 if (emitStructValues(Structure, &Count))
4487 Type.Name = Structure.Name;
4488 Type.Size = Structure.Size * Count;
4489 Type.ElementSize = Structure.Size;
4490 Type.Length = Count;
4492 }
else if (addStructField(
Name, Structure)) {
4493 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4511 int64_t AlignmentValue = 1;
4514 parseAbsoluteExpression(AlignmentValue)) {
4515 return addErrorSuffix(
" in alignment value for '" +
Twine(
Directive) +
4519 return Error(NextTok.
getLoc(),
"alignment must be a power of two; was " +
4520 std::to_string(AlignmentValue));
4526 QualifierLoc = getTok().getLoc();
4527 if (parseIdentifier(Qualifier))
4528 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4529 if (!
Qualifier.equals_insensitive(
"nonunique"))
4530 return Error(QualifierLoc,
"Unrecognized qualifier for '" +
4532 "' directive; expected none or NONUNIQUE");
4536 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4547 DirectiveKind DirKind) {
4548 if (StructInProgress.
empty())
4549 return TokError(
"missing name in top-level '" +
Twine(
Directive) +
4554 Name = getTok().getIdentifier();
4558 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4562 StructInProgress.
reserve(StructInProgress.
size() + 1);
4564 StructInProgress.
back().Alignment);
4569 if (StructInProgress.
empty())
4570 return Error(NameLoc,
"ENDS directive without matching STRUC/STRUCT/UNION");
4571 if (StructInProgress.
size() > 1)
4572 return Error(NameLoc,
"unexpected name in nested ENDS directive");
4573 if (StructInProgress.
back().Name.compare_insensitive(
Name))
4574 return Error(NameLoc,
"mismatched name in ENDS directive; expected '" +
4575 StructInProgress.
back().Name +
"'");
4576 StructInfo Structure = StructInProgress.
pop_back_val();
4580 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4581 Structs[
Name.lower()] = Structure;
4584 return addErrorSuffix(
" in ENDS directive");
4589bool MasmParser::parseDirectiveNestedEnds() {
4590 if (StructInProgress.
empty())
4591 return TokError(
"ENDS directive without matching STRUC/STRUCT/UNION");
4592 if (StructInProgress.
size() == 1)
4593 return TokError(
"missing name in top-level ENDS directive");
4596 return addErrorSuffix(
" in nested ENDS directive");
4598 StructInfo Structure = StructInProgress.
pop_back_val();
4600 Structure.Size =
llvm::alignTo(Structure.Size, Structure.Alignment);
4602 StructInfo &ParentStruct = StructInProgress.
back();
4603 if (Structure.Name.empty()) {
4606 const size_t OldFields = ParentStruct.Fields.size();
4607 ParentStruct.Fields.insert(
4608 ParentStruct.Fields.end(),
4609 std::make_move_iterator(Structure.Fields.begin()),
4610 std::make_move_iterator(Structure.Fields.end()));
4611 for (
const auto &FieldByName : Structure.FieldsByName) {
4612 ParentStruct.FieldsByName[FieldByName.getKey()] =
4613 FieldByName.getValue() + OldFields;
4616 unsigned FirstFieldOffset = 0;
4617 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
4619 ParentStruct.NextOffset,
4620 std::min(ParentStruct.Alignment, Structure.AlignmentSize));
4623 if (ParentStruct.IsUnion) {
4624 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4629 const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
4630 if (!ParentStruct.IsUnion) {
4631 ParentStruct.NextOffset = StructureEnd;
4633 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4636 FieldInfo &
Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4637 Structure.AlignmentSize);
4638 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4644 if (!ParentStruct.IsUnion) {
4645 ParentStruct.NextOffset = StructureEnd;
4647 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4649 StructInfo.Structure = Structure;
4650 StructInfo.Initializers.emplace_back();
4651 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4652 for (
const auto &SubField : Structure.Fields) {
4653 FieldInitializers.push_back(SubField.Contents);
4662bool MasmParser::parseDirectiveOrg() {
4665 if (checkForValidSection() || parseExpression(
Offset))
4668 return addErrorSuffix(
" in 'org' directive");
4670 if (StructInProgress.
empty()) {
4672 if (checkForValidSection())
4673 return addErrorSuffix(
" in 'org' directive");
4675 getStreamer().emitValueToOffset(
Offset, 0, OffsetLoc);
4678 StructInfo &Structure = StructInProgress.
back();
4680 if (!
Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
4681 return Error(OffsetLoc,
4682 "expected absolute expression in 'org' directive");
4686 "expected non-negative value in struct's 'org' directive; was " +
4687 std::to_string(OffsetRes));
4688 Structure.NextOffset =
static_cast<unsigned>(OffsetRes);
4691 Structure.Initializable =
false;
4697bool MasmParser::emitAlignTo(int64_t Alignment) {
4698 if (StructInProgress.
empty()) {
4700 if (checkForValidSection())
4706 assert(Section &&
"must have section to emit alignment");
4707 if (
Section->useCodeAlign()) {
4708 getStreamer().emitCodeAlignment(
Align(Alignment),
4709 &getTargetParser().getSTI(),
4713 getStreamer().emitValueToAlignment(
Align(Alignment), 0,
4719 StructInfo &Structure = StructInProgress.
back();
4720 Structure.NextOffset =
llvm::alignTo(Structure.NextOffset, Alignment);
4728bool MasmParser::parseDirectiveAlign() {
4729 SMLoc AlignmentLoc = getLexer().getLoc();
4735 "align directive with no operand is ignored") &&
4738 if (parseAbsoluteExpression(Alignment) || parseEOL())
4739 return addErrorSuffix(
" in align directive");
4742 bool ReturnVal =
false;
4749 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2; was " +
4750 std::to_string(Alignment));
4752 if (emitAlignTo(Alignment))
4753 ReturnVal |= addErrorSuffix(
" in align directive");
4760bool MasmParser::parseDirectiveEven() {
4761 if (parseEOL() || emitAlignTo(2))
4762 return addErrorSuffix(
" in even directive");
4770bool MasmParser::parseDirectiveFile(
SMLoc DirectiveLoc) {
4772 int64_t FileNumber = -1;
4774 FileNumber = getTok().getIntVal();
4778 return TokError(
"negative file number");
4786 "unexpected token in '.file' directive") ||
4787 parseEscapedString(Path))
4792 std::string FilenameData;
4794 if (check(FileNumber == -1,
4795 "explicit path specified, but no file number") ||
4796 parseEscapedString(FilenameData))
4805 bool HasMD5 =
false;
4807 std::optional<StringRef>
Source;
4808 bool HasSource =
false;
4809 std::string SourceString;
4814 "unexpected token in '.file' directive") ||
4815 parseIdentifier(Keyword))
4817 if (Keyword ==
"md5") {
4819 if (check(FileNumber == -1,
4820 "MD5 checksum specified, but no file number") ||
4823 }
else if (Keyword ==
"source") {
4825 if (check(FileNumber == -1,
4826 "source specified, but no file number") ||
4828 "unexpected token in '.file' directive") ||
4829 parseEscapedString(SourceString))
4832 return TokError(
"unexpected token in '.file' directive");
4836 if (FileNumber == -1) {
4840 if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4841 getStreamer().emitFileDirective(Filename);
4851 std::optional<MD5::MD5Result> CKMem;
4854 for (
unsigned i = 0; i != 8; ++i) {
4855 Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4856 Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4861 char *SourceBuf =
static_cast<char *
>(Ctx.
allocate(SourceString.size()));
4862 memcpy(SourceBuf, SourceString.data(), SourceString.size());
4865 if (FileNumber == 0) {
4867 return Warning(DirectiveLoc,
"file 0 not supported prior to DWARF-5");
4868 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4871 FileNumber, Directory, Filename, CKMem, Source);
4878 ReportedInconsistentMD5 =
true;
4879 return Warning(DirectiveLoc,
"inconsistent use of MD5 checksums");
4888bool MasmParser::parseDirectiveLine() {
4891 if (parseIntToken(LineNumber,
"unexpected token in '.line' directive"))
4909bool MasmParser::parseDirectiveLoc() {
4910 int64_t FileNumber = 0, LineNumber = 0;
4911 SMLoc Loc = getTok().getLoc();
4912 if (parseIntToken(FileNumber,
"unexpected token in '.loc' directive") ||
4914 "file number less than one in '.loc' directive") ||
4915 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4916 "unassigned file number in '.loc' directive"))
4921 LineNumber = getTok().getIntVal();
4923 return TokError(
"line number less than zero in '.loc' directive");
4927 int64_t ColumnPos = 0;
4929 ColumnPos = getTok().getIntVal();
4931 return TokError(
"column position less than zero in '.loc' directive");
4935 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4940 auto parseLocOp = [&]() ->
bool {
4942 SMLoc Loc = getTok().getLoc();
4943 if (parseIdentifier(
Name))
4944 return TokError(
"unexpected token in '.loc' directive");
4946 if (
Name ==
"basic_block")
4948 else if (
Name ==
"prologue_end")
4950 else if (
Name ==
"epilogue_begin")
4952 else if (
Name ==
"is_stmt") {
4953 Loc = getTok().getLoc();
4955 if (parseExpression(
Value))
4961 Flags &= ~DWARF2_FLAG_IS_STMT;
4962 else if (
Value == 1)
4965 return Error(Loc,
"is_stmt value not 0 or 1");
4967 return Error(Loc,
"is_stmt value not the constant value of 0 or 1");
4969 }
else if (
Name ==
"isa") {
4970 Loc = getTok().getLoc();
4972 if (parseExpression(
Value))
4978 return Error(Loc,
"isa number less than zero");
4981 return Error(Loc,
"isa number not a constant value");
4983 }
else if (
Name ==
"discriminator") {
4984 if (parseAbsoluteExpression(Discriminator))
4987 return Error(Loc,
"unknown sub-directive in '.loc' directive");
4992 if (parseMany(parseLocOp,
false ))
4995 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
5003bool MasmParser::parseDirectiveStabs() {
5004 return TokError(
"unsupported directive '.stabs'");
5009bool MasmParser::parseDirectiveCVFile() {
5010 SMLoc FileNumberLoc = getTok().getLoc();
5013 std::string Checksum;
5016 if (parseIntToken(FileNumber,
5017 "expected file number in '.cv_file' directive") ||
5018 check(FileNumber < 1, FileNumberLoc,
"file number less than one") ||
5020 "unexpected token in '.cv_file' directive") ||
5021 parseEscapedString(Filename))
5025 "unexpected token in '.cv_file' directive") ||
5026 parseEscapedString(Checksum) ||
5027 parseIntToken(ChecksumKind,
5028 "expected checksum kind in '.cv_file' directive") ||
5033 Checksum = fromHex(Checksum);
5034 void *CKMem = Ctx.
allocate(Checksum.size(), 1);
5035 memcpy(CKMem, Checksum.data(), Checksum.size());
5039 if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
5040 static_cast<uint8_t
>(ChecksumKind)))
5041 return Error(FileNumberLoc,
"file number already allocated");
5046bool MasmParser::parseCVFunctionId(int64_t &
FunctionId,
5049 return parseTokenLoc(Loc) ||
5050 parseIntToken(
FunctionId,
"expected function id in '" + DirectiveName +
5052 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
5053 "expected function id within range [0, UINT_MAX)");
5056bool MasmParser::parseCVFileId(int64_t &FileNumber,
StringRef DirectiveName) {
5058 return parseTokenLoc(Loc) ||
5059 parseIntToken(FileNumber,
"expected integer in '" + DirectiveName +
5061 check(FileNumber < 1, Loc,
"file number less than one in '" +
5062 DirectiveName +
"' directive") ||
5063 check(!getCVContext().isValidFileNumber(FileNumber), Loc,
5064 "unassigned file number in '" + DirectiveName +
"' directive");
5071bool MasmParser::parseDirectiveCVFuncId() {
5072 SMLoc FunctionIdLoc = getTok().getLoc();
5075 if (parseCVFunctionId(
FunctionId,
".cv_func_id") || parseEOL())
5078 if (!getStreamer().emitCVFuncIdDirective(
FunctionId))
5079 return Error(FunctionIdLoc,
"function id already allocated");
5092bool MasmParser::parseDirectiveCVInlineSiteId() {
5093 SMLoc FunctionIdLoc = getTok().getLoc();
5101 if (parseCVFunctionId(
FunctionId,
".cv_inline_site_id"))
5106 getTok().getIdentifier() !=
"within"),
5107 "expected 'within' identifier in '.cv_inline_site_id' directive"))
5112 if (parseCVFunctionId(IAFunc,
".cv_inline_site_id"))
5117 getTok().getIdentifier() !=
"inlined_at"),
5118 "expected 'inlined_at' identifier in '.cv_inline_site_id' "
5124 if (parseCVFileId(IAFile,
".cv_inline_site_id") ||
5125 parseIntToken(IALine,
"expected line number after 'inlined_at'"))
5130 IACol = getTok().getIntVal();
5137 if (!getStreamer().emitCVInlineSiteIdDirective(
FunctionId, IAFunc, IAFile,
5138 IALine, IACol, FunctionIdLoc))
5139 return Error(FunctionIdLoc,
"function id already allocated");
5151bool MasmParser::parseDirectiveCVLoc() {
5152 SMLoc DirectiveLoc = getTok().getLoc();
5154 if (parseCVFunctionId(
FunctionId,
".cv_loc") ||
5155 parseCVFileId(FileNumber,
".cv_loc"))
5158 int64_t LineNumber = 0;
5160 LineNumber = getTok().getIntVal();
5162 return TokError(
"line number less than zero in '.cv_loc' directive");
5166 int64_t ColumnPos = 0;
5168 ColumnPos = getTok().getIntVal();
5170 return TokError(
"column position less than zero in '.cv_loc' directive");
5174 bool PrologueEnd =
false;
5177 auto parseOp = [&]() ->
bool {
5179 SMLoc Loc = getTok().getLoc();
5180 if (parseIdentifier(
Name))
5181 return TokError(
"unexpected token in '.cv_loc' directive");
5182 if (
Name ==
"prologue_end")
5184 else if (
Name ==
"is_stmt") {
5185 Loc = getTok().getLoc();
5187 if (parseExpression(
Value))
5191 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value))
5195 return Error(Loc,
"is_stmt value not 0 or 1");
5197 return Error(Loc,
"unknown sub-directive in '.cv_loc' directive");
5202 if (parseMany(parseOp,
false ))
5205 getStreamer().emitCVLocDirective(
FunctionId, FileNumber, LineNumber,
5206 ColumnPos, PrologueEnd, IsStmt,
StringRef(),
5213bool MasmParser::parseDirectiveCVLinetable() {
5216 SMLoc Loc = getTok().getLoc();
5217 if (parseCVFunctionId(
FunctionId,
".cv_linetable") ||
5219 "unexpected token in '.cv_linetable' directive") ||
5220 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5221 "expected identifier in directive") ||
5223 "unexpected token in '.cv_linetable' directive") ||
5224 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5225 "expected identifier in directive"))
5228 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5229 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5231 getStreamer().emitCVLinetableDirective(
FunctionId, FnStartSym, FnEndSym);
5237bool MasmParser::parseDirectiveCVInlineLinetable() {
5238 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
5240 SMLoc Loc = getTok().getLoc();
5241 if (parseCVFunctionId(PrimaryFunctionId,
".cv_inline_linetable") ||
5242 parseTokenLoc(Loc) ||
5245 "expected SourceField in '.cv_inline_linetable' directive") ||
5246 check(SourceFileId <= 0, Loc,
5247 "File id less than zero in '.cv_inline_linetable' directive") ||
5248 parseTokenLoc(Loc) ||
5251 "expected SourceLineNum in '.cv_inline_linetable' directive") ||
5252 check(SourceLineNum < 0, Loc,
5253 "Line number less than zero in '.cv_inline_linetable' directive") ||
5254 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5255 "expected identifier in directive") ||
5256 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5257 "expected identifier in directive"))
5263 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5264 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5265 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
5266 SourceLineNum, FnStartSym,
5271void MasmParser::initializeCVDefRangeTypeMap() {
5272 CVDefRangeTypeMap[
"reg"] = CVDR_DEFRANGE_REGISTER;
5273 CVDefRangeTypeMap[
"frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
5274 CVDefRangeTypeMap[
"subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
5275 CVDefRangeTypeMap[
"reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
5280bool MasmParser::parseDirectiveCVDefRange() {
5282 std::vector<std::pair<const MCSymbol *, const MCSymbol *>>
Ranges;
5284 Loc = getLexer().getLoc();
5286 if (parseIdentifier(GapStartName))
5287 return Error(Loc,
"expected identifier in directive");
5288 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
5290 Loc = getLexer().getLoc();
5292 if (parseIdentifier(GapEndName))
5293 return Error(Loc,
"expected identifier in directive");
5294 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
5296 Ranges.push_back({GapStartSym, GapEndSym});
5302 "expected comma before def_range type in .cv_def_range directive") ||
5303 parseIdentifier(CVDefRangeTypeStr))
5304 return Error(Loc,
"expected def_range type in directive");
5307 CVDefRangeTypeMap.find(CVDefRangeTypeStr);
5308 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
5310 : CVTypeIt->getValue();
5312 case CVDR_DEFRANGE_REGISTER: {
5314 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5315 ".cv_def_range directive") ||
5316 parseAbsoluteExpression(DRRegister))
5317 return Error(Loc,
"expected register number");
5322 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5325 case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
5328 "expected comma before offset in .cv_def_range directive") ||
5329 parseAbsoluteExpression(DROffset))
5330 return Error(Loc,
"expected offset value");
5334 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5337 case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
5339 int64_t DROffsetInParent;
5340 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5341 ".cv_def_range directive") ||
5342 parseAbsoluteExpression(DRRegister))
5343 return Error(Loc,
"expected register number");
5345 "expected comma before offset in .cv_def_range directive") ||
5346 parseAbsoluteExpression(DROffsetInParent))
5347 return Error(Loc,
"expected offset value");
5353 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5356 case CVDR_DEFRANGE_REGISTER_REL: {
5359 int64_t DRBasePointerOffset;
5360 if (parseToken(
AsmToken::Comma,
"expected comma before register number in "
5361 ".cv_def_range directive") ||
5362 parseAbsoluteExpression(DRRegister))
5363 return Error(Loc,
"expected register value");
5366 "expected comma before flag value in .cv_def_range directive") ||
5367 parseAbsoluteExpression(DRFlags))
5368 return Error(Loc,
"expected flag value");
5369 if (parseToken(
AsmToken::Comma,
"expected comma before base pointer offset "
5370 "in .cv_def_range directive") ||
5371 parseAbsoluteExpression(DRBasePointerOffset))
5372 return Error(Loc,
"expected base pointer offset value");
5376 DRHdr.
Flags = DRFlags;
5378 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5382 return Error(Loc,
"unexpected def_range type in .cv_def_range directive");
5389bool MasmParser::parseDirectiveCVString() {
5391 if (checkForValidSection() || parseEscapedString(Data))
5392 return addErrorSuffix(
" in '.cv_string' directive");
5395 std::pair<StringRef, unsigned> Insertion =
5396 getCVContext().addToStringTable(Data);
5397 getStreamer().emitIntValue(Insertion.second, 4);
5403bool MasmParser::parseDirectiveCVStringTable() {
5404 getStreamer().emitCVStringTableDirective();
5410bool MasmParser::parseDirectiveCVFileChecksums() {
5411 getStreamer().emitCVFileChecksumsDirective();
5417bool MasmParser::parseDirectiveCVFileChecksumOffset() {
5419 if (parseIntToken(FileNo,
"expected identifier in directive"))
5423 getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
5429bool MasmParser::parseDirectiveCVFPOData() {
5430 SMLoc DirLoc = getLexer().getLoc();
5432 if (parseIdentifier(ProcName))
5433 return TokError(
"expected symbol name");
5434 if (parseEOL(
"unexpected tokens"))
5435 return addErrorSuffix(
" in '.cv_fpo_data' directive");
5436 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
5437 getStreamer().emitCVFPOData(ProcSym, DirLoc);
5443bool MasmParser::parseDirectiveCFISections() {
5448 if (parseIdentifier(
Name))
5449 return TokError(
"Expected an identifier");
5451 if (
Name ==
".eh_frame")
5453 else if (
Name ==
".debug_frame")
5459 if (parseIdentifier(
Name))
5460 return TokError(
"Expected an identifier");
5462 if (
Name ==
".eh_frame")
5464 else if (
Name ==
".debug_frame")
5468 getStreamer().emitCFISections(EH,
Debug);
5474bool MasmParser::parseDirectiveCFIStartProc() {
5477 if (check(parseIdentifier(
Simple) ||
Simple !=
"simple",
5478 "unexpected token") ||
5480 return addErrorSuffix(
" in '.cfi_startproc' directive");
5488 getStreamer().emitCFIStartProc(!
Simple.empty(), Lexer.
getLoc());
5494bool MasmParser::parseDirectiveCFIEndProc() {
5495 getStreamer().emitCFIEndProc();
5500bool MasmParser::parseRegisterOrRegisterNumber(int64_t &
Register,
5501 SMLoc DirectiveLoc) {
5505 if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
5507 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo,
true);
5509 return parseAbsoluteExpression(
Register);
5516bool MasmParser::parseDirectiveCFIDefCfa(
SMLoc DirectiveLoc) {
5518 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5520 parseAbsoluteExpression(
Offset))
5529bool MasmParser::parseDirectiveCFIDefCfaOffset(
SMLoc DirectiveLoc) {
5531 if (parseAbsoluteExpression(
Offset))
5534 getStreamer().emitCFIDefCfaOffset(
Offset, DirectiveLoc);
5540bool MasmParser::parseDirectiveCFIRegister(
SMLoc DirectiveLoc) {
5541 int64_t Register1 = 0, Register2 = 0;
5542 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
5544 parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
5547 getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
5553bool MasmParser::parseDirectiveCFIWindowSave(
SMLoc DirectiveLoc) {
5554 getStreamer().emitCFIWindowSave(DirectiveLoc);
5560bool MasmParser::parseDirectiveCFIAdjustCfaOffset(
SMLoc DirectiveLoc) {
5561 int64_t Adjustment = 0;
5562 if (parseAbsoluteExpression(Adjustment))
5565 getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
5571bool MasmParser::parseDirectiveCFIDefCfaRegister(
SMLoc DirectiveLoc) {
5573 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5576 getStreamer().emitCFIDefCfaRegister(
Register);
5582bool MasmParser::parseDirectiveCFIOffset(
SMLoc DirectiveLoc) {
5586 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5588 parseAbsoluteExpression(
Offset))
5597bool MasmParser::parseDirectiveCFIRelOffset(
SMLoc DirectiveLoc) {
5600 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc) ||
5602 parseAbsoluteExpression(
Offset))
5610 if (Encoding & ~0xff)
5616 const unsigned Format = Encoding & 0xf;
5623 const unsigned Application = Encoding & 0x70;
5635bool MasmParser::parseDirectiveCFIPersonalityOrLsda(
bool IsPersonality) {
5636 int64_t Encoding = 0;
5637 if (parseAbsoluteExpression(Encoding))
5645 check(parseIdentifier(
Name),
"expected identifier in directive"))
5651 getStreamer().emitCFIPersonality(
Sym, Encoding);
5653 getStreamer().emitCFILsda(
Sym, Encoding);
5659bool MasmParser::parseDirectiveCFIRememberState(
SMLoc DirectiveLoc) {
5660 getStreamer().emitCFIRememberState(DirectiveLoc);
5666bool MasmParser::parseDirectiveCFIRestoreState(
SMLoc DirectiveLoc) {
5667 getStreamer().emitCFIRestoreState(DirectiveLoc);
5673bool MasmParser::parseDirectiveCFISameValue(
SMLoc DirectiveLoc) {
5676 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5679 getStreamer().emitCFISameValue(
Register, DirectiveLoc);
5685bool MasmParser::parseDirectiveCFIRestore(
SMLoc DirectiveLoc) {
5687 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5690 getStreamer().emitCFIRestore(
Register);
5696bool MasmParser::parseDirectiveCFIEscape(
SMLoc DirectiveLoc) {
5699 if (parseAbsoluteExpression(CurrValue))
5707 if (parseAbsoluteExpression(CurrValue))
5710 Values.push_back((uint8_t)CurrValue);
5713 getStreamer().emitCFIEscape(Values, DirectiveLoc);
5719bool MasmParser::parseDirectiveCFIReturnColumn(
SMLoc DirectiveLoc) {
5721 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5723 getStreamer().emitCFIReturnColumn(
Register);
5729bool MasmParser::parseDirectiveCFISignalFrame() {
5733 getStreamer().emitCFISignalFrame();
5739bool MasmParser::parseDirectiveCFIUndefined(
SMLoc DirectiveLoc) {
5742 if (parseRegisterOrRegisterNumber(
Register, DirectiveLoc))
5745 getStreamer().emitCFIUndefined(
Register);
5760 "Vararg parameter '" +
Parameters.back().Name +
5761 "' should be last in the list of parameters");
5764 if (parseIdentifier(Parameter.
Name))
5765 return TokError(
"expected identifier in 'macro' directive");
5769 if (CurrParam.Name.equals_insensitive(Parameter.
Name))
5770 return TokError(
"macro '" +
Name +
"' has multiple parameters"
5771 " named '" + Parameter.
Name +
"'");
5780 ParamLoc = Lexer.
getLoc();
5781 if (parseMacroArgument(
nullptr, Parameter.
Value))
5787 QualLoc = Lexer.
getLoc();
5788 if (parseIdentifier(Qualifier))
5789 return Error(QualLoc,
"missing parameter qualifier for "
5791 Parameter.
Name +
"' in macro '" +
Name +
5794 if (
Qualifier.equals_insensitive(
"req"))
5796 else if (
Qualifier.equals_insensitive(
"vararg"))
5799 return Error(QualLoc,
5800 Qualifier +
" is not a valid parameter qualifier for '" +
5801 Parameter.
Name +
"' in macro '" +
Name +
"'");
5814 std::vector<std::string>
Locals;
5816 getTok().getIdentifier().equals_insensitive(
"local")) {
5821 if (parseIdentifier(
ID))
5833 AsmToken EndToken, StartToken = getTok();
5834 unsigned MacroDepth = 0;
5835 bool IsMacroFunction =
false;
5845 return Error(NameLoc,
"no matching 'endm' in definition");
5850 if (getTok().getIdentifier().equals_insensitive(
"endm")) {
5851 if (MacroDepth == 0) {
5852 EndToken = getTok();
5855 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
5862 }
else if (getTok().getIdentifier().equals_insensitive(
"exitm")) {
5864 IsMacroFunction =
true;
5866 }
else if (isMacroLikeDirective()) {
5874 eatToEndOfStatement();
5877 if (getContext().lookupMacro(
Name.lower())) {
5878 return Error(NameLoc,
"macro '" +
Name +
"' is already defined");
5888 getContext().defineMacro(
Name.lower(), std::move(
Macro));
5894bool MasmParser::parseDirectiveExitMacro(
SMLoc DirectiveLoc,
5896 std::string &
Value) {
5897 SMLoc EndLoc = getTok().getLoc();
5899 return Error(EndLoc,
5900 "unable to parse text item in '" +
Directive +
"' directive");
5901 eatToEndOfStatement();
5903 if (!isInsideMacroInstantiation())
5904 return TokError(
"unexpected '" +
Directive +
"' in file, "
5905 "no current macro definition");
5908 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5909 TheCondState = TheCondStack.back();
5910 TheCondStack.pop_back();
5921 return TokError(
"unexpected token in '" +
Directive +
"' directive");
5925 if (isInsideMacroInstantiation()) {
5932 return TokError(
"unexpected '" +
Directive +
"' in file, "
5933 "no current macro definition");
5938bool MasmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
5942 if (parseTokenLoc(NameLoc) ||
5943 check(parseIdentifier(
Name), NameLoc,
5944 "expected identifier in 'purge' directive"))
5948 <<
"Un-defining macro: " <<
Name <<
"\n");
5949 if (!getContext().lookupMacro(
Name.lower()))
5950 return Error(NameLoc,
"macro '" +
Name +
"' is not defined");
5951 getContext().undefineMacro(
Name.lower());
5961bool MasmParser::parseDirectiveExtern() {
5963 auto parseOp = [&]() ->
bool {
5965 SMLoc NameLoc = getTok().getLoc();
5966 if (parseIdentifier(
Name))
5967 return Error(NameLoc,
"expected name");
5972 SMLoc TypeLoc = getTok().getLoc();
5973 if (parseIdentifier(TypeName))
5974 return Error(TypeLoc,
"expected type");
5975 if (!
TypeName.equals_insensitive(
"proc")) {
5977 if (lookUpType(TypeName,
Type))
5978 return Error(TypeLoc,
"unrecognized type");
5983 Sym->setExternal(
true);
5989 if (parseMany(parseOp))
5990 return addErrorSuffix(
" in directive 'extern'");
5996bool MasmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
5997 auto parseOp = [&]() ->
bool {
5999 SMLoc Loc = getTok().getLoc();
6000 if (parseIdentifier(
Name))
6001 return Error(Loc,
"expected identifier");
6005 if (
Sym->isTemporary())
6006 return Error(Loc,
"non-local symbol required");
6008 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
6009 return Error(Loc,
"unable to emit symbol attribute");
6013 if (parseMany(parseOp))
6014 return addErrorSuffix(
" in directive");
6020bool MasmParser::parseDirectiveComm(
bool IsLocal) {
6021 if (checkForValidSection())
6024 SMLoc IDLoc = getLexer().getLoc();
6026 if (parseIdentifier(
Name))
6027 return TokError(
"expected identifier in directive");
6033 return TokError(
"unexpected token in directive");
6037 SMLoc SizeLoc = getLexer().getLoc();
6038 if (parseAbsoluteExpression(
Size))
6041 int64_t Pow2Alignment = 0;
6042 SMLoc Pow2AlignmentLoc;
6045 Pow2AlignmentLoc = getLexer().getLoc();
6046 if (parseAbsoluteExpression(Pow2Alignment))
6051 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
6057 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
6058 Pow2Alignment =
Log2_64(Pow2Alignment);
6068 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
6069 "be less than zero");
6074 if (Pow2Alignment < 0)
6075 return Error(Pow2AlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
6076 "alignment, can't be less than zero");
6078 Sym->redefineIfPossible();
6079 if (!
Sym->isUndefined())
6080 return Error(IDLoc,
"invalid symbol redefinition");
6084 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
6085 Align(1ULL << Pow2Alignment));
6089 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
6097bool MasmParser::parseDirectiveComment(
SMLoc DirectiveLoc) {
6099 size_t DelimiterEnd = FirstLine.find_first_of(
"\b\t\v\f\r\x1A ");
6100 assert(DelimiterEnd != std::string::npos);
6102 if (Delimiter.
empty())
6103 return Error(DirectiveLoc,
"no delimiter in 'comment' directive");
6106 return Error(DirectiveLoc,
"unmatched delimiter in 'comment' directive");
6116bool MasmParser::parseDirectiveInclude() {
6119 SMLoc IncludeLoc = getTok().getLoc();
6121 if (parseAngleBracketString(Filename))
6123 if (check(
Filename.empty(),
"missing filename in 'include' directive") ||
6125 "unexpected token in 'include' directive") ||
6128 check(enterIncludeFile(Filename), IncludeLoc,
6129 "Could not find include file '" + Filename +
"'"))
6137bool MasmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
6138 TheCondStack.push_back(TheCondState);
6140 if (TheCondState.
Ignore) {
6141 eatToEndOfStatement();
6144 if (parseAbsoluteExpression(ExprValue) || parseEOL())
6153 ExprValue = ExprValue == 0;
6157 TheCondState.
CondMet = ExprValue;
6166bool MasmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6167 TheCondStack.push_back(TheCondState);
6170 if (TheCondState.
Ignore) {
6171 eatToEndOfStatement();
6174 if (parseTextItem(Str))
6175 return TokError(
"expected text item parameter for 'ifb' directive");
6180 TheCondState.
CondMet = ExpectBlank == Str.empty();
6189bool MasmParser::parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6190 bool CaseInsensitive) {
6191 std::string String1, String2;
6193 if (parseTextItem(String1)) {
6195 return TokError(
"expected text item parameter for 'ifidn' directive");
6196 return TokError(
"expected text item parameter for 'ifdif' directive");
6202 "expected comma after first string for 'ifidn' directive");
6203 return TokError(
"expected comma after first string for 'ifdif' directive");
6207 if (parseTextItem(String2)) {
6209 return TokError(
"expected text item parameter for 'ifidn' directive");
6210 return TokError(
"expected text item parameter for 'ifdif' directive");
6213 TheCondStack.push_back(TheCondState);
6215 if (CaseInsensitive)
6219 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6228bool MasmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
6229 TheCondStack.push_back(TheCondState);
6232 if (TheCondState.
Ignore) {
6233 eatToEndOfStatement();
6235 bool is_defined =
false;
6237 SMLoc StartLoc, EndLoc;
6239 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6242 if (check(parseIdentifier(
Name),
"expected identifier after 'ifdef'") ||
6246 if (BuiltinSymbolMap.contains(
Name.lower())) {
6252 is_defined = (
Sym && !
Sym->isUndefined(
false));
6256 TheCondState.
CondMet = (is_defined == expect_defined);
6265bool MasmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc,
6266 DirectiveKind DirKind) {
6269 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
6270 " .if or an .elseif");
6273 bool LastIgnoreState =
false;
6274 if (!TheCondStack.empty())
6275 LastIgnoreState = TheCondStack.back().Ignore;
6276 if (LastIgnoreState || TheCondState.
CondMet) {
6277 TheCondState.
Ignore =
true;
6278 eatToEndOfStatement();
6281 if (parseAbsoluteExpression(ExprValue))
6293 ExprValue = ExprValue == 0;
6297 TheCondState.
CondMet = ExprValue;
6306bool MasmParser::parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6309 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6310 " if or an elseif");
6313 bool LastIgnoreState =
false;
6314 if (!TheCondStack.empty())
6315 LastIgnoreState = TheCondStack.back().Ignore;
6316 if (LastIgnoreState || TheCondState.
CondMet) {
6317 TheCondState.
Ignore =
true;
6318 eatToEndOfStatement();
6321 if (parseTextItem(Str)) {
6323 return TokError(
"expected text item parameter for 'elseifb' directive");
6324 return TokError(
"expected text item parameter for 'elseifnb' directive");
6330 TheCondState.
CondMet = ExpectBlank == Str.empty();
6340bool MasmParser::parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
6341 bool expect_defined) {
6344 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6345 " if or an elseif");
6348 bool LastIgnoreState =
false;
6349 if (!TheCondStack.empty())
6350 LastIgnoreState = TheCondStack.back().Ignore;
6351 if (LastIgnoreState || TheCondState.
CondMet) {
6352 TheCondState.
Ignore =
true;
6353 eatToEndOfStatement();
6355 bool is_defined =
false;
6357 SMLoc StartLoc, EndLoc;
6359 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6362 if (check(parseIdentifier(
Name),
6363 "expected identifier after 'elseifdef'") ||
6367 if (BuiltinSymbolMap.contains(
Name.lower())) {
6373 is_defined = (
Sym && !
Sym->isUndefined(
false));
6377 TheCondState.
CondMet = (is_defined == expect_defined);
6386bool MasmParser::parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6387 bool CaseInsensitive) {
6390 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
6391 " if or an elseif");
6394 bool LastIgnoreState =
false;
6395 if (!TheCondStack.empty())
6396 LastIgnoreState = TheCondStack.back().Ignore;
6397 if (LastIgnoreState || TheCondState.
CondMet) {
6398 TheCondState.
Ignore =
true;
6399 eatToEndOfStatement();
6401 std::string String1, String2;
6403 if (parseTextItem(String1)) {
6406 "expected text item parameter for 'elseifidn' directive");
6407 return TokError(
"expected text item parameter for 'elseifdif' directive");
6413 "expected comma after first string for 'elseifidn' directive");
6415 "expected comma after first string for 'elseifdif' directive");
6419 if (parseTextItem(String2)) {
6422 "expected text item parameter for 'elseifidn' directive");
6423 return TokError(
"expected text item parameter for 'elseifdif' directive");
6426 if (CaseInsensitive)
6430 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6439bool MasmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
6445 return Error(DirectiveLoc,
"Encountered an else that doesn't follow an if"
6448 bool LastIgnoreState =
false;
6449 if (!TheCondStack.empty())
6450 LastIgnoreState = TheCondStack.back().Ignore;
6451 if (LastIgnoreState || TheCondState.
CondMet)
6452 TheCondState.
Ignore =
true;
6454 TheCondState.
Ignore =
false;
6461bool MasmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
6473bool MasmParser::parseDirectiveError(
SMLoc DirectiveLoc) {
6474 if (!TheCondStack.empty()) {
6475 if (TheCondStack.back().Ignore) {
6476 eatToEndOfStatement();
6481 std::string Message =
".err directive invoked in source file";
6486 return Error(DirectiveLoc, Message);
6491bool MasmParser::parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
6492 if (!TheCondStack.empty()) {
6493 if (TheCondStack.back().Ignore) {
6494 eatToEndOfStatement();
6500 if (parseTextItem(Text))
6501 return Error(getTok().getLoc(),
"missing text item in '.errb' directive");
6503 std::string Message =
".errb directive invoked in source file";
6506 return addErrorSuffix(
" in '.errb' directive");
6511 if (
Text.empty() == ExpectBlank)
6512 return Error(DirectiveLoc, Message);
6518bool MasmParser::parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
6519 bool ExpectDefined) {
6520 if (!TheCondStack.empty()) {
6521 if (TheCondStack.back().Ignore) {
6522 eatToEndOfStatement();
6527 bool IsDefined =
false;
6529 SMLoc StartLoc, EndLoc;
6531 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6534 if (check(parseIdentifier(
Name),
"expected identifier after '.errdef'"))
6537 if (BuiltinSymbolMap.contains(
Name.lower())) {
6543 IsDefined = (
Sym && !
Sym->isUndefined(
false));
6547 std::string Message =
".errdef directive invoked in source file";
6550 return addErrorSuffix(
" in '.errdef' directive");
6555 if (IsDefined == ExpectDefined)
6556 return Error(DirectiveLoc, Message);
6562bool MasmParser::parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
6563 bool CaseInsensitive) {
6564 if (!TheCondStack.empty()) {
6565 if (TheCondStack.back().Ignore) {
6566 eatToEndOfStatement();
6571 std::string String1, String2;
6573 if (parseTextItem(String1)) {
6575 return TokError(
"expected string parameter for '.erridn' directive");
6576 return TokError(
"expected string parameter for '.errdif' directive");
6582 "expected comma after first string for '.erridn' directive");
6584 "expected comma after first string for '.errdif' directive");
6588 if (parseTextItem(String2)) {
6590 return TokError(
"expected string parameter for '.erridn' directive");
6591 return TokError(
"expected string parameter for '.errdif' directive");
6594 std::string Message;
6596 Message =
".erridn directive invoked in source file";
6598 Message =
".errdif directive invoked in source file";
6601 return addErrorSuffix(
" in '.erridn' directive");
6606 if (CaseInsensitive)
6610 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
6613 if ((CaseInsensitive &&
6615 (ExpectEqual == (String1 == String2)))
6616 return Error(DirectiveLoc, Message);
6622bool MasmParser::parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero) {
6623 if (!TheCondStack.empty()) {
6624 if (TheCondStack.back().Ignore) {
6625 eatToEndOfStatement();
6631 if (parseAbsoluteExpression(ExprValue))
6632 return addErrorSuffix(
" in '.erre' directive");
6634 std::string Message =
".erre directive invoked in source file";
6637 return addErrorSuffix(
" in '.erre' directive");
6642 if ((ExprValue == 0) == ExpectZero)
6643 return Error(DirectiveLoc, Message);
6649bool MasmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
6654 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
6656 if (!TheCondStack.empty()) {
6657 TheCondState = TheCondStack.back();
6658 TheCondStack.pop_back();
6664void MasmParser::initializeDirectiveKindMap() {
6665 DirectiveKindMap[
"="] = DK_ASSIGN;
6666 DirectiveKindMap[
"equ"] = DK_EQU;
6667 DirectiveKindMap[
"textequ"] = DK_TEXTEQU;
6671 DirectiveKindMap[
"byte"] = DK_BYTE;
6672 DirectiveKindMap[
"sbyte"] = DK_SBYTE;
6673 DirectiveKindMap[
"word"] = DK_WORD;
6674 DirectiveKindMap[
"sword"] = DK_SWORD;
6675 DirectiveKindMap[
"dword"] = DK_DWORD;
6676 DirectiveKindMap[
"sdword"] = DK_SDWORD;
6677 DirectiveKindMap[
"fword"] = DK_FWORD;
6678 DirectiveKindMap[
"qword"] = DK_QWORD;
6679 DirectiveKindMap[
"sqword"] = DK_SQWORD;
6680 DirectiveKindMap[
"real4"] = DK_REAL4;
6681 DirectiveKindMap[
"real8"] = DK_REAL8;
6682 DirectiveKindMap[
"real10"] = DK_REAL10;
6683 DirectiveKindMap[
"align"] = DK_ALIGN;
6684 DirectiveKindMap[
"even"] = DK_EVEN;
6685 DirectiveKindMap[
"org"] = DK_ORG;
6686 DirectiveKindMap[
"extern"] = DK_EXTERN;
6687 DirectiveKindMap[
"extrn"] = DK_EXTERN;
6688 DirectiveKindMap[
"public"] = DK_PUBLIC;
6690 DirectiveKindMap[
"comment"] = DK_COMMENT;
6691 DirectiveKindMap[
"include"] = DK_INCLUDE;
6692 DirectiveKindMap[
"repeat"] = DK_REPEAT;
6693 DirectiveKindMap[
"rept"] = DK_REPEAT;
6694 DirectiveKindMap[
"while"] = DK_WHILE;
6695 DirectiveKindMap[
"for"] = DK_FOR;
6696 DirectiveKindMap[
"irp"] = DK_FOR;
6697 DirectiveKindMap[
"forc"] = DK_FORC;
6698 DirectiveKindMap[
"irpc"] = DK_FORC;
6699 DirectiveKindMap[
"if"] = DK_IF;
6700 DirectiveKindMap[
"ife"] = DK_IFE;
6701 DirectiveKindMap[
"ifb"] = DK_IFB;
6702 DirectiveKindMap[
"ifnb"] = DK_IFNB;
6703 DirectiveKindMap[
"ifdef"] = DK_IFDEF;
6704 DirectiveKindMap[
"ifndef"] = DK_IFNDEF;
6705 DirectiveKindMap[
"ifdif"] = DK_IFDIF;
6706 DirectiveKindMap[
"ifdifi"] = DK_IFDIFI;
6707 DirectiveKindMap[
"ifidn"] = DK_IFIDN;
6708 DirectiveKindMap[
"ifidni"] = DK_IFIDNI;
6709 DirectiveKindMap[
"elseif"] = DK_ELSEIF;
6710 DirectiveKindMap[
"elseifdef"] = DK_ELSEIFDEF;
6711 DirectiveKindMap[
"elseifndef"] = DK_ELSEIFNDEF;
6712 DirectiveKindMap[
"elseifdif"] = DK_ELSEIFDIF;
6713 DirectiveKindMap[
"elseifidn"] = DK_ELSEIFIDN;
6714 DirectiveKindMap[
"else"] = DK_ELSE;
6715 DirectiveKindMap[
"end"] = DK_END;
6716 DirectiveKindMap[
"endif"] = DK_ENDIF;
6755 DirectiveKindMap[
"macro"] = DK_MACRO;
6756 DirectiveKindMap[
"exitm"] = DK_EXITM;
6757 DirectiveKindMap[
"endm"] = DK_ENDM;
6758 DirectiveKindMap[
"purge"] = DK_PURGE;
6759 DirectiveKindMap[
".err"] = DK_ERR;
6760 DirectiveKindMap[
".errb"] = DK_ERRB;
6761 DirectiveKindMap[
".errnb"] = DK_ERRNB;
6762 DirectiveKindMap[
".errdef"] = DK_ERRDEF;
6763 DirectiveKindMap[
".errndef"] = DK_ERRNDEF;
6764 DirectiveKindMap[
".errdif"] = DK_ERRDIF;
6765 DirectiveKindMap[
".errdifi"] = DK_ERRDIFI;
6766 DirectiveKindMap[
".erridn"] = DK_ERRIDN;
6767 DirectiveKindMap[
".erridni"] = DK_ERRIDNI;
6768 DirectiveKindMap[
".erre"] = DK_ERRE;
6769 DirectiveKindMap[
".errnz"] = DK_ERRNZ;
6770 DirectiveKindMap[
".pushframe"] = DK_PUSHFRAME;
6771 DirectiveKindMap[
".pushreg"] = DK_PUSHREG;
6772 DirectiveKindMap[
".savereg"] = DK_SAVEREG;
6773 DirectiveKindMap[
".savexmm128"] = DK_SAVEXMM128;
6774 DirectiveKindMap[
".setframe"] = DK_SETFRAME;
6775 DirectiveKindMap[
".radix"] = DK_RADIX;
6776 DirectiveKindMap[
"db"] = DK_DB;
6777 DirectiveKindMap[
"dd"] = DK_DD;
6778 DirectiveKindMap[
"df"] = DK_DF;
6779 DirectiveKindMap[
"dq"] = DK_DQ;
6780 DirectiveKindMap[
"dw"] = DK_DW;
6781 DirectiveKindMap[
"echo"] = DK_ECHO;
6782 DirectiveKindMap[
"struc"] = DK_STRUCT;
6783 DirectiveKindMap[
"struct"] = DK_STRUCT;
6784 DirectiveKindMap[
"union"] = DK_UNION;
6785 DirectiveKindMap[
"ends"] = DK_ENDS;
6788bool MasmParser::isMacroLikeDirective() {
6800 peekTok().getIdentifier().equals_insensitive(
"macro"))
6807 AsmToken EndToken, StartToken = getTok();
6809 unsigned NestLevel = 0;
6813 printError(DirectiveLoc,
"no matching 'endm' in definition");
6817 if (isMacroLikeDirective())
6822 getTok().getIdentifier().equals_insensitive(
"endm")) {
6823 if (NestLevel == 0) {
6824 EndToken = getTok();
6827 printError(getTok().getLoc(),
"unexpected token in 'endm' directive");
6836 eatToEndOfStatement();
6845 return &MacroLikeBodies.back();
6848bool MasmParser::expandStatement(
SMLoc Loc) {
6850 SMLoc EndLoc = getTok().getLoc();
6856 for (
const auto &S : BuiltinSymbolMap) {
6857 const BuiltinSymbol &
Sym = S.getValue();
6858 if (std::optional<std::string> Text = evaluateBuiltinTextMacro(
Sym, Loc)) {
6859 BuiltinValues[S.getKey().lower()] = std::move(*Text);
6862 for (
const auto &
B : BuiltinValues) {
6864 MCAsmMacroArgument
A;
6865 P.Name =
B.getKey();
6873 for (
const auto &V : Variables) {
6874 const Variable &Var =
V.getValue();
6877 MCAsmMacroArgument
A;
6886 MacroLikeBodies.emplace_back(
StringRef(), Body, Parameters);
6892 if (expandMacro(
OS,
M.Body,
M.Parameters,
Arguments,
M.Locals, EndLoc))
6894 std::unique_ptr<MemoryBuffer>
Expansion =
6900 EndStatementAtEOFStack.push_back(
false);
6905void MasmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
6907 instantiateMacroLikeBody(M, DirectiveLoc, getTok().getLoc(),
OS);
6909void MasmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
6914 std::unique_ptr<MemoryBuffer> Instantiation =
6919 MacroInstantiation *
MI =
new MacroInstantiation{DirectiveLoc, CurBuffer,
6920 ExitLoc, TheCondStack.size()};
6921 ActiveMacros.push_back(
MI);
6926 EndStatementAtEOFStack.push_back(
true);
6934bool MasmParser::parseDirectiveRepeat(
SMLoc DirectiveLoc,
StringRef Dir) {
6936 SMLoc CountLoc = getTok().getLoc();
6937 if (parseExpression(CountExpr))
6941 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
6942 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
6945 if (check(Count < 0, CountLoc,
"Count is negative") || parseEOL())
6958 if (expandMacro(
OS,
M->Body, std::nullopt, std::nullopt,
M->Locals,
6962 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
6971bool MasmParser::parseDirectiveWhile(
SMLoc DirectiveLoc) {
6973 SMLoc CondLoc = getTok().getLoc();
6974 if (parseExpression(CondExpr))
6987 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
6988 return Error(CondLoc,
"expected absolute expression in 'while' directive");
6992 if (expandMacro(
OS,
M->Body, std::nullopt, std::nullopt,
M->Locals,
6995 instantiateMacroLikeBody(M, DirectiveLoc, DirectiveLoc,
OS);
7005bool MasmParser::parseDirectiveFor(
SMLoc DirectiveLoc,
StringRef Dir) {
7007 MCAsmMacroArguments
A;
7008 if (check(parseIdentifier(Parameter.
Name),
7009 "expected identifier in '" + Dir +
"' directive"))
7018 ParamLoc = Lexer.
getLoc();
7019 if (parseMacroArgument(
nullptr, Parameter.
Value))
7025 QualLoc = Lexer.
getLoc();
7026 if (parseIdentifier(Qualifier))
7027 return Error(QualLoc,
"missing parameter qualifier for "
7029 Parameter.
Name +
"' in '" + Dir +
7032 if (
Qualifier.equals_insensitive(
"req"))
7035 return Error(QualLoc,
7036 Qualifier +
" is not a valid parameter qualifier for '" +
7037 Parameter.
Name +
"' in '" + Dir +
"' directive");
7042 "expected comma in '" + Dir +
"' directive") ||
7044 "values in '" + Dir +
7045 "' directive must be enclosed in angle brackets"))
7051 return addErrorSuffix(
" in arguments for '" + Dir +
"' directive");
7060 "values in '" + Dir +
7061 "' directive must be enclosed in angle brackets") ||
7075 for (
const MCAsmMacroArgument &Arg :
A) {
7076 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
7080 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
7093 if (check(parseIdentifier(Parameter.
Name),
7094 "expected identifier in '" +
Directive +
"' directive") ||
7096 "expected comma in '" +
Directive +
"' directive"))
7098 if (parseAngleBracketString(
Argument)) {
7126 for (std::size_t
I = 0,
End = Values.size();
I !=
End; ++
I) {
7127 MCAsmMacroArgument Arg;
7130 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
7134 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
7139bool MasmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
7142 SMLoc ExprLoc = getLexer().getLoc();
7143 if (parseExpression(
Value))
7147 return Error(ExprLoc,
"unexpected expression in _emit");
7149 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
7150 return Error(ExprLoc,
"literal value out of range for directive");
7156bool MasmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
7158 SMLoc ExprLoc = getLexer().getLoc();
7159 if (parseExpression(
Value))
7163 return Error(ExprLoc,
"unexpected expression in align");
7166 return Error(ExprLoc,
"literal value not a power of two greater then zero");
7172bool MasmParser::parseDirectiveRadix(
SMLoc DirectiveLoc) {
7173 const SMLoc Loc = getLexer().getLoc();
7179 "radix must be a decimal number in the range 2 to 16; was " +
7182 if (Radix < 2 || Radix > 16)
7183 return Error(Loc,
"radix must be in the range 2 to 16; was " +
7184 std::to_string(Radix));
7185 getLexer().setMasmDefaultRadix(Radix);
7191bool MasmParser::parseDirectiveEcho(
SMLoc DirectiveLoc) {
7194 if (!
StringRef(Message).ends_with(
"\n"))
7223 Variable &Var = Variables[
Name.lower()];
7224 if (Var.Name.empty()) {
7226 }
else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {
7227 return Error(
SMLoc(),
"invalid variable redefinition");
7228 }
else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&
7230 "', already defined on the command line")) {
7233 Var.Redefinable = Variable::WARN_ON_REDEFINITION;
7235 Var.TextValue =
Value.str();
7240 const std::pair<StringRef, StringRef> BaseMember =
Name.split(
'.');
7242 return lookUpField(
Base, Member, Info);
7251 if (
Base.contains(
'.') && !lookUpField(
Base, BaseInfo))
7254 auto StructIt = Structs.
find(
Base.lower());
7255 auto TypeIt = KnownType.
find(
Base.lower());
7256 if (TypeIt != KnownType.
end()) {
7257 StructIt = Structs.
find(TypeIt->second.Name.lower());
7259 if (StructIt != Structs.
end())
7260 return lookUpField(StructIt->second, Member, Info);
7265bool MasmParser::lookUpField(
const StructInfo &Structure,
StringRef Member,
7268 Info.Type.Name = Structure.Name;
7269 Info.Type.Size = Structure.Size;
7270 Info.Type.ElementSize = Structure.Size;
7271 Info.Type.Length = 1;
7275 std::pair<StringRef, StringRef>
Split =
Member.split(
'.');
7278 auto StructIt = Structs.
find(FieldName.
lower());
7279 if (StructIt != Structs.
end())
7280 return lookUpField(StructIt->second, FieldMember, Info);
7282 auto FieldIt = Structure.FieldsByName.find(FieldName.
lower());
7283 if (FieldIt == Structure.FieldsByName.end())
7286 const FieldInfo &
Field = Structure.Fields[FieldIt->second];
7287 if (FieldMember.empty()) {
7292 if (
Field.Contents.FT == FT_STRUCT)
7293 Info.Type.Name =
Field.Contents.StructInfo.Structure.Name;
7295 Info.Type.Name =
"";
7299 if (
Field.Contents.FT != FT_STRUCT)
7301 const StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
7303 if (lookUpField(StructInfo.Structure, FieldMember, Info))
7329 auto StructIt = Structs.
find(
Name.lower());
7330 if (StructIt != Structs.
end()) {
7331 const StructInfo &Structure = StructIt->second;
7333 Info.ElementSize = Structure.Size;
7335 Info.Size = Structure.Size;
7342bool MasmParser::parseMSInlineAsm(
7343 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
7362 unsigned InputIdx = 0;
7363 unsigned OutputIdx = 0;
7366 if (parseCurlyBlockScope(AsmStrRewrites))
7369 ParseStatementInfo
Info(&AsmStrRewrites);
7370 bool StatementErr = parseStatement(Info, &SI);
7372 if (StatementErr ||
Info.ParseError) {
7374 printPendingErrors();
7379 assert(!hasPendingError() &&
"unexpected error from parseStatement");
7381 if (
Info.Opcode == ~0U)
7387 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
7392 !getTargetParser().OmitRegisterFromClobberLists(Operand.
getReg())) {
7393 unsigned NumDefs =
Desc.getNumDefs();
7402 if (SymName.
empty())
7410 if (Operand.
isImm()) {
7418 bool isOutput = (i == 1) &&
Desc.mayStore();
7424 OutputConstraints.
push_back((
"=" + Constraint).str());
7430 if (
Desc.operands()[i - 1].isBranchTarget())
7442 NumOutputs = OutputDecls.
size();
7443 NumInputs = InputDecls.
size();
7448 Clobbers.
assign(ClobberRegs.
size(), std::string());
7449 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
7455 if (NumOutputs || NumInputs) {
7456 unsigned NumExprs = NumOutputs + NumInputs;
7457 OpDecls.resize(NumExprs);
7458 Constraints.
resize(NumExprs);
7459 for (
unsigned i = 0; i < NumOutputs; ++i) {
7460 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
7461 Constraints[i] = OutputConstraints[i];
7463 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
7464 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
7465 Constraints[
j] = InputConstraints[i];
7470 std::string AsmStringIR;
7474 const char *AsmStart = ASMString.
begin();
7475 const char *AsmEnd = ASMString.
end();
7477 for (
auto I = AsmStrRewrites.
begin(), E = AsmStrRewrites.
end();
I != E; ++
I) {
7485 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
7488 if (
unsigned Len = Loc - AsmStart)
7493 AsmStart = Loc + AR.
Len;
7497 unsigned AdditionalSkip = 0;
7519 size_t OffsetLen = OffsetName.
size();
7520 auto rewrite_it = std::find_if(
7522 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
7523 (FusingAR.Kind == AOK_Input ||
7524 FusingAR.Kind == AOK_CallInput);
7526 if (rewrite_it == AsmStrRewrites.
end()) {
7527 OS <<
"offset " << OffsetName;
7529 OS <<
"${" << InputIdx++ <<
":P}";
7530 rewrite_it->Done =
true;
7532 OS <<
'$' << InputIdx++;
7533 rewrite_it->Done =
true;
7545 OS <<
'$' << InputIdx++;
7548 OS <<
"${" << InputIdx++ <<
":P}";
7551 OS <<
'$' << OutputIdx++;
7556 case 8:
OS <<
"byte ptr ";
break;
7557 case 16:
OS <<
"word ptr ";
break;
7558 case 32:
OS <<
"dword ptr ";
break;
7559 case 64:
OS <<
"qword ptr ";
break;
7560 case 80:
OS <<
"xword ptr ";
break;
7561 case 128:
OS <<
"xmmword ptr ";
break;
7562 case 256:
OS <<
"ymmword ptr ";
break;
7572 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
7577 unsigned Val = AR.
Val;
7579 assert(Val < 10 &&
"Expected alignment less then 2^10.");
7580 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
7592 AsmStart = Loc + AR.
Len + AdditionalSkip;
7596 if (AsmStart != AsmEnd)
7599 AsmString =
OS.str();
7603void MasmParser::initializeBuiltinSymbolMap() {
7605 BuiltinSymbolMap[
"@version"] = BI_VERSION;
7606 BuiltinSymbolMap[
"@line"] = BI_LINE;
7609 BuiltinSymbolMap[
"@date"] = BI_DATE;
7610 BuiltinSymbolMap[
"@time"] = BI_TIME;
7611 BuiltinSymbolMap[
"@filecur"] = BI_FILECUR;
7612 BuiltinSymbolMap[
"@filename"] = BI_FILENAME;
7613 BuiltinSymbolMap[
"@curseg"] = BI_CURSEG;
7616 if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
7634const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,
7644 if (ActiveMacros.empty())
7648 ActiveMacros.front()->ExitBuffer);
7655std::optional<std::string>
7656MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
SMLoc StartLoc) {
7662 char TmpBuffer[
sizeof(
"mm/dd/yy")];
7663 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%D", &TM);
7664 return std::string(TmpBuffer, Len);
7668 char TmpBuffer[
sizeof(
"hh:mm:ss")];
7669 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%T", &TM);
7670 return std::string(TmpBuffer, Len);
7675 ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)
7683 return getStreamer().getCurrentSectionOnly()->getName().str();
7691 struct tm TM,
unsigned CB) {
7692 return new MasmParser(SM,
C, Out, MAI, TM, CB);
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
AMDGPU Lower Kernel Arguments
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static Expected< std::vector< unsigned > > getSymbols(SymbolicFile *Obj, uint16_t Index, raw_ostream &SymNames, SymMap *SymMap)
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This file contains constants used for implementing Dwarf debug support.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_LINE_DEFAULT_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
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())
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)
Factory for NaN values.
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
APInt getHiBits(unsigned numBits) const
Compute an APInt containing numBits highbits from this APInt.
unsigned getBitWidth() const
Return the number of bits in the APInt.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
AsmCond - Class to support conditional assembly.
ConditionalAssemblyType TheCond
AsmLexer - Lexer class for assembly files.
size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true) override
Look ahead an arbitrary number of tokens.
const MCAsmInfo & getMAI() const
void setBuffer(StringRef Buf, const char *ptr=nullptr, bool EndStatementAtEOF=true)
Target independent representation for an assembler token.
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Holds state from .cv_file and .cv_loc directives for later emission.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool useParensForSymbolVariant() const
bool preserveAsmComments() const
Return true if assembly (inline or otherwise) should be parsed.
unsigned getAssemblerDialect() const
bool doesAllowAtInName() const
StringRef getPrivateLabelPrefix() const
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
bool shouldUseLogicalShr() const
bool hasSubsectionsViaSymbols() const
bool getCOMMDirectiveAlignmentIsInBytes() const
bool getDollarIsPC() const
Generic assembler lexer interface, for use by target specific assembly lexers.
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isAtStartOfStatement()
SMLoc getLoc() const
Get the current source location.
SMLoc getErrLoc()
Get the current error location.
void setLexMasmIntegers(bool V)
Set whether to lex masm-style binary (e.g., 0b1101) and radix-specified literals (e....
const AsmToken & getTok() const
Get the current (last) lexed token.
AsmToken::TokenKind getKind() const
Get the kind of current token.
void setSkipSpace(bool val)
Set whether spaces should be ignored by the lexer.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
const std::string & getErr()
Get the current error string.
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
Generic Sema callback for assembly parser.
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)=0
Emit an error at the location L, with the message Msg.
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool defineMacro(StringRef Name, StringRef Value)
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual StringRef parseStringToEndOfStatement()=0
Parse up to the end of statement and return the contents from the current token until the end of the ...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual SourceMgr & getSourceManager()=0
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo)=0
Parse a primary expression.
virtual bool checkForValidSection()=0
Ensure that we have a valid section set in the streamer.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
MCAsmParser & operator=(const MCAsmParser &)=delete
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
virtual bool isParsingMSInlineAsm()=0
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression of a specified parenthesis depth, assuming that the initial '(' charact...
virtual unsigned getAssemblerDialect()
virtual MCAsmLexer & getLexer()=0
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAngleBracketString(std::string &Data)=0
Parse an angle-bracket delimited string at the current position if one is present,...
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
virtual bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl< std::pair< void *, bool > > &OpDecls, SmallVectorImpl< std::string > &Constraints, SmallVectorImpl< std::string > &Clobbers, const MCInstrInfo *MII, const MCInstPrinter *IP, MCAsmParserSemaCallback &SI)=0
Parse MS-style inline assembly.
virtual void setAssemblerDialect(unsigned i)
virtual MCContext & getContext()=0
virtual void setParsingMSInlineAsm(bool V)=0
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ AShr
Arithmetic shift right.
@ LShr
Logical shift right.
@ GTE
Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).
@ GT
Signed greater than comparison (result is either 0 or some target-specific non-zero value)
@ Xor
Bitwise exclusive or.
@ LT
Signed less than comparison (result is either 0 or some target-specific non-zero value).
@ LTE
Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).
@ NE
Inequality comparison.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
void * allocate(unsigned Size, unsigned Align=8)
Environment getObjectFileType() const
bool isDwarfMD5UsageConsistent(unsigned CUID) const
Reports whether MD5 checksum usage is consistent (all-or-none).
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
bool getGenDwarfForAssembly()
void setGenDwarfForAssembly(bool Value)
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
CodeViewContext & getCVContext()
MCSymbol * createDirectionalLocalSymbol(unsigned LocalLabelVal)
Create the definition of a directional local symbol for numbered label (used for "1:" definitions).
uint16_t getDwarfVersion() const
const MCAsmInfo * getAsmInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printRegName(raw_ostream &OS, MCRegister Reg) const
Print the assembler register name.
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool needAddressOf() const
needAddressOf - Do we need to emit code to get the address of the variable/label? Only valid when par...
virtual MCRegister getReg() const =0
virtual bool isOffsetOfLocal() const
isOffsetOfLocal - Do we need to emit code to get the offset of the local variable,...
virtual StringRef getSymName()
virtual bool isImm() const =0
isImm - Is this an immediate operand?
unsigned getMCOperandNum()
StringRef getConstraint()
virtual void * getOpDecl()
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setBeginSymbol(MCSymbol *Sym)
MCSymbol * getBeginSymbol()
Streaming machine code generation interface.
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI)
Create the default sections and set the initial one.
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static VariantKind getVariantKindForName(StringRef Name)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
StringRef getBuffer() const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
constexpr bool isSuccess() const
Wrapper class representing virtual and physical registers.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
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...
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
std::string upper() const
Convert the given ASCII string to uppercase.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
std::string lower() const
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & CaseLower(StringLiteral S, T Value)
StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
This class represents a function that is read from a sample profile.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Reg
All possible values of the reg field in the ModR/M byte.
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
StringRef stem(StringRef path, Style style=Style::native)
Get stem.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
MCAsmParser * createMCMasmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, struct tm, unsigned CB=0)
Create an MCAsmParser instance for parsing Microsoft MASM-style assembly.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
std::vector< MCAsmMacroParameter > MCAsmMacroParameters
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...
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.