75typedef std::vector<AsmToken> MCAsmMacroArgument;
76typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
79struct MacroInstantiation {
81 SMLoc InstantiationLoc;
90 size_t CondStackDepth;
93struct ParseStatementInfo {
98 unsigned Opcode = ~0
U;
101 bool ParseError =
false;
104 std::optional<std::string> ExitValue;
108 ParseStatementInfo() =
delete;
110 : AsmRewrites(rewrites) {}
123 bool Initializable =
true;
124 unsigned Alignment = 0;
125 unsigned AlignmentSize = 0;
126 unsigned NextOffset = 0;
128 std::vector<FieldInfo> Fields;
131 FieldInfo &addField(
StringRef FieldName, FieldType FT,
132 unsigned FieldAlignmentSize);
134 StructInfo() =
default;
135 StructInfo(
StringRef StructName,
bool Union,
unsigned AlignmentValue);
143struct StructInitializer;
147 IntFieldInfo() =
default;
151struct RealFieldInfo {
154 RealFieldInfo() =
default;
158struct StructFieldInfo {
159 std::vector<StructInitializer> Initializers;
160 StructInfo Structure;
162 StructFieldInfo() =
default;
163 StructFieldInfo(std::vector<StructInitializer> V, StructInfo S);
166class FieldInitializer {
170 IntFieldInfo IntInfo;
171 RealFieldInfo RealInfo;
172 StructFieldInfo StructInfo;
176 FieldInitializer(FieldType FT);
180 FieldInitializer(std::vector<StructInitializer> &&Initializers,
181 struct StructInfo Structure);
183 FieldInitializer(
const FieldInitializer &Initializer);
184 FieldInitializer(FieldInitializer &&Initializer);
186 FieldInitializer &operator=(
const FieldInitializer &Initializer);
187 FieldInitializer &operator=(FieldInitializer &&Initializer);
190struct StructInitializer {
191 std::vector<FieldInitializer> FieldInitializers;
202 unsigned LengthOf = 0;
207 FieldInitializer Contents;
209 FieldInfo(FieldType FT) : Contents(FT) {}
212StructFieldInfo::StructFieldInfo(std::vector<StructInitializer> V,
214 Initializers = std::move(V);
218StructInfo::StructInfo(
StringRef StructName,
bool Union,
219 unsigned AlignmentValue)
222FieldInfo &StructInfo::addField(
StringRef FieldName, FieldType FT,
223 unsigned FieldAlignmentSize) {
224 if (!FieldName.
empty())
225 FieldsByName[FieldName.
lower()] = Fields.size();
226 Fields.emplace_back(FT);
227 FieldInfo &
Field = Fields.back();
229 llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize));
233 AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
237FieldInitializer::~FieldInitializer() {
240 IntInfo.~IntFieldInfo();
243 RealInfo.~RealFieldInfo();
246 StructInfo.~StructFieldInfo();
251FieldInitializer::FieldInitializer(FieldType FT) : FT(FT) {
254 new (&IntInfo) IntFieldInfo();
257 new (&RealInfo) RealFieldInfo();
260 new (&StructInfo) StructFieldInfo();
267 new (&IntInfo) IntFieldInfo(std::move(Values));
272 new (&RealInfo) RealFieldInfo(std::move(AsIntValues));
275FieldInitializer::FieldInitializer(
276 std::vector<StructInitializer> &&Initializers,
struct StructInfo Structure)
278 new (&StructInfo) StructFieldInfo(std::move(Initializers), Structure);
281FieldInitializer::FieldInitializer(
const FieldInitializer &Initializer)
282 : FT(Initializer.FT) {
285 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
288 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
291 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
296FieldInitializer::FieldInitializer(FieldInitializer &&Initializer)
297 : FT(Initializer.FT) {
300 new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
303 new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
306 new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
312FieldInitializer::operator=(
const FieldInitializer &Initializer) {
313 if (FT != Initializer.FT) {
316 IntInfo.~IntFieldInfo();
319 RealInfo.~RealFieldInfo();
322 StructInfo.~StructFieldInfo();
329 IntInfo = Initializer.IntInfo;
332 RealInfo = Initializer.RealInfo;
335 StructInfo = Initializer.StructInfo;
341FieldInitializer &FieldInitializer::operator=(FieldInitializer &&Initializer) {
342 if (FT != Initializer.FT) {
345 IntInfo.~IntFieldInfo();
348 RealInfo.~RealFieldInfo();
351 StructInfo.~StructFieldInfo();
358 IntInfo = Initializer.IntInfo;
361 RealInfo = Initializer.RealInfo;
364 StructInfo = Initializer.StructInfo;
376 void *SavedDiagContext;
377 std::unique_ptr<MCAsmParserExtension> PlatformParser;
389 std::vector<AsmCond> TheCondStack;
398 enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE };
401 RedefinableKind Redefinable = REDEFINABLE;
403 std::string TextValue;
417 std::vector<MacroInstantiation*> ActiveMacros;
420 std::deque<MCAsmMacro> MacroLikeBodies;
423 unsigned NumOfMacroInstantiations;
426 struct CppHashInfoTy {
431 CppHashInfoTy() : LineNumber(0), Buf(0) {}
433 CppHashInfoTy CppHashInfo;
443 unsigned AssemblerDialect = 1U;
446 bool ParsingMSInlineAsm =
false;
449 unsigned AngleBracketDepth = 0
U;
456 const MCAsmInfo &MAI,
struct tm TM,
unsigned CB = 0);
457 MasmParser(
const MasmParser &) =
delete;
458 MasmParser &
operator=(
const MasmParser &) =
delete;
459 ~MasmParser()
override;
461 bool Run(
bool NoInitialTextSection,
bool NoFinalize =
false)
override;
464 ExtensionDirectiveHandler Handler)
override {
465 ExtensionDirectiveMap[
Directive] = Handler;
470 DirectiveKindMap[
Directive] = DirectiveKindMap[Alias];
477 if (AssemblerDialect == ~0U)
478 return MAI.getAssemblerDialect();
480 return AssemblerDialect;
483 AssemblerDialect = i;
492 enum ExpandKind { ExpandMacros, DoNotExpandMacros };
497 ParsingMSInlineAsm =
V;
500 Lexer.setLexMasmIntegers(V);
535 enum IdentifierPositionKind { StandardPosition, StartOfStatement };
548 const AsmToken peekTok(
bool ShouldSkipSpace =
true);
550 bool parseStatement(ParseStatementInfo &Info,
553 bool parseCppHashLineFilenameComment(
SMLoc L);
558 const std::vector<std::string> &Locals,
SMLoc L);
561 bool isInsideMacroInstantiation() {
return !ActiveMacros.empty();}
567 bool handleMacroEntry(
578 void handleMacroExit();
587 parseMacroArguments(
const MCAsmMacro *M, MCAsmMacroArguments &
A,
590 void printMacroInstantiations();
592 bool expandStatement(
SMLoc Loc);
605 bool enterIncludeFile(
const std::string &Filename);
613 void jumpToLoc(
SMLoc Loc,
unsigned InBuffer = 0,
614 bool EndStatementAtEOF =
true);
628 bool parseTextItem(std::string &Data);
633 bool parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
SMLoc &EndLoc);
634 bool parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
635 bool parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
640 DK_HANDLER_DIRECTIVE,
732 bool isMacroLikeDirective();
760 const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol,
SMLoc StartLoc);
762 std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
766 enum BuiltinFunction {
779 bool parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated);
783 bool parseScalarInitializer(
unsigned Size,
785 unsigned StringPadLength = 0);
786 bool parseScalarInstList(
789 bool emitIntegralValues(
unsigned Size,
unsigned *Count =
nullptr);
792 bool parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
796 bool emitRealValues(
const fltSemantics &Semantics,
unsigned *Count =
nullptr);
800 bool parseRealInstList(
803 bool parseDirectiveNamedRealValue(
StringRef TypeName,
808 bool parseOptionalAngleBracketOpen();
809 bool parseAngleBracketClose(
const Twine &Msg =
"expected '>'");
811 bool parseFieldInitializer(
const FieldInfo &
Field,
812 FieldInitializer &Initializer);
813 bool parseFieldInitializer(
const FieldInfo &
Field,
814 const IntFieldInfo &Contents,
815 FieldInitializer &Initializer);
816 bool parseFieldInitializer(
const FieldInfo &
Field,
817 const RealFieldInfo &Contents,
818 FieldInitializer &Initializer);
819 bool parseFieldInitializer(
const FieldInfo &
Field,
820 const StructFieldInfo &Contents,
821 FieldInitializer &Initializer);
823 bool parseStructInitializer(
const StructInfo &Structure,
824 StructInitializer &Initializer);
825 bool parseStructInstList(
826 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
829 bool emitFieldValue(
const FieldInfo &
Field);
830 bool emitFieldValue(
const FieldInfo &
Field,
const IntFieldInfo &Contents);
831 bool emitFieldValue(
const FieldInfo &
Field,
const RealFieldInfo &Contents);
832 bool emitFieldValue(
const FieldInfo &
Field,
const StructFieldInfo &Contents);
834 bool emitFieldInitializer(
const FieldInfo &
Field,
835 const FieldInitializer &Initializer);
836 bool emitFieldInitializer(
const FieldInfo &
Field,
837 const IntFieldInfo &Contents,
838 const IntFieldInfo &Initializer);
839 bool emitFieldInitializer(
const FieldInfo &
Field,
840 const RealFieldInfo &Contents,
841 const RealFieldInfo &Initializer);
842 bool emitFieldInitializer(
const FieldInfo &
Field,
843 const StructFieldInfo &Contents,
844 const StructFieldInfo &Initializer);
846 bool emitStructInitializer(
const StructInfo &Structure,
847 const StructInitializer &Initializer);
850 bool emitStructValues(
const StructInfo &Structure,
unsigned *Count =
nullptr);
851 bool addStructField(
StringRef Name,
const StructInfo &Structure);
852 bool parseDirectiveStructValue(
const StructInfo &Structure,
854 bool parseDirectiveNamedStructValue(
const StructInfo &Structure,
860 DirectiveKind DirKind,
SMLoc NameLoc);
862 bool parseDirectiveOrg();
864 bool emitAlignTo(int64_t Alignment);
865 bool parseDirectiveAlign();
866 bool parseDirectiveEven();
869 bool parseDirectivePurgeMacro(
SMLoc DirectiveLoc);
879 bool parseDirectiveNestedEnds();
881 bool parseDirectiveExtern();
887 bool parseDirectiveComm(
bool IsLocal);
889 bool parseDirectiveComment(
SMLoc DirectiveLoc);
891 bool parseDirectiveInclude();
894 bool parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
896 bool parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
899 bool parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
900 bool CaseInsensitive);
902 bool parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
904 bool parseDirectiveElseIf(
SMLoc DirectiveLoc, DirectiveKind DirKind);
906 bool parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
908 bool parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
bool expect_defined);
911 bool parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
912 bool CaseInsensitive);
913 bool parseDirectiveElse(
SMLoc DirectiveLoc);
914 bool parseDirectiveEndIf(
SMLoc DirectiveLoc);
927 bool parseDirectiveWhile(
SMLoc DirectiveLoc);
930 bool parseDirectiveMSEmit(
SMLoc DirectiveLoc, ParseStatementInfo &Info,
934 bool parseDirectiveMSAlign(
SMLoc DirectiveLoc, ParseStatementInfo &Info);
937 bool parseDirectiveEnd(
SMLoc DirectiveLoc);
940 bool parseDirectiveError(
SMLoc DirectiveLoc);
942 bool parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank);
944 bool parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
bool ExpectDefined);
947 bool parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
948 bool CaseInsensitive);
950 bool parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero);
953 bool parseDirectiveRadix(
SMLoc DirectiveLoc);
956 bool parseDirectiveEcho(
SMLoc DirectiveLoc);
958 void initializeDirectiveKindMap();
959 void initializeBuiltinSymbolMaps();
975 const MCAsmInfo &MAI,
struct tm TM,
unsigned CB)
976 :
MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),
985 EndStatementAtEOFStack.push_back(
true);
997 initializeDirectiveKindMap();
998 PlatformParser->Initialize(*
this);
999 initializeBuiltinSymbolMaps();
1001 NumOfMacroInstantiations = 0;
1004MasmParser::~MasmParser() {
1005 assert((HadError || ActiveMacros.empty()) &&
1006 "Unexpected active macro instantiation!");
1013void MasmParser::printMacroInstantiations() {
1015 for (std::vector<MacroInstantiation *>::const_reverse_iterator
1016 it = ActiveMacros.rbegin(),
1017 ie = ActiveMacros.rend();
1020 "while in macro instantiation");
1024 printPendingErrors();
1026 printMacroInstantiations();
1030 if (getTargetParser().getTargetOptions().MCNoWarn)
1032 if (getTargetParser().getTargetOptions().MCFatalWarnings)
1035 printMacroInstantiations();
1042 printMacroInstantiations();
1046bool MasmParser::enterIncludeFile(
const std::string &Filename) {
1047 std::string IncludedFile;
1055 EndStatementAtEOFStack.push_back(
true);
1059void MasmParser::jumpToLoc(
SMLoc Loc,
unsigned InBuffer,
1060 bool EndStatementAtEOF) {
1066bool MasmParser::expandMacros() {
1076 if (handleMacroInvocation(M, MacroLoc)) {
1083 std::optional<std::string> ExpandedValue;
1085 if (
auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1086 BuiltinIt != BuiltinSymbolMap.end()) {
1088 evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.
getLoc());
1089 }
else if (
auto BuiltinFuncIt = BuiltinFunctionMap.find(IDLower);
1090 BuiltinFuncIt != BuiltinFunctionMap.end()) {
1092 if (parseIdentifier(
Name)) {
1096 if (evaluateBuiltinMacroFunction(BuiltinFuncIt->getValue(),
Name, Res)) {
1099 ExpandedValue = Res;
1100 }
else if (
auto VarIt = Variables.
find(IDLower);
1101 VarIt != Variables.
end() && VarIt->getValue().IsText) {
1102 ExpandedValue = VarIt->getValue().TextValue;
1107 std::unique_ptr<MemoryBuffer> Instantiation =
1115 EndStatementAtEOFStack.push_back(
false);
1120const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {
1122 Error(Lexer.getErrLoc(), Lexer.getErr());
1123 bool StartOfStatement =
false;
1128 if (!getTok().getString().empty() && getTok().getString().front() !=
'\n' &&
1131 StartOfStatement =
true;
1134 const AsmToken *tok = &Lexer.Lex();
1137 if (StartOfStatement) {
1140 size_t ReadCount = Lexer.peekTokens(Buf);
1172 if (ParentIncludeLoc !=
SMLoc()) {
1173 EndStatementAtEOFStack.pop_back();
1174 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1177 EndStatementAtEOFStack.pop_back();
1178 assert(EndStatementAtEOFStack.empty());
1184const AsmToken MasmParser::peekTok(
bool ShouldSkipSpace) {
1188 size_t ReadCount = Lexer.peekTokens(Buf, ShouldSkipSpace);
1190 if (ReadCount == 0) {
1194 if (ParentIncludeLoc !=
SMLoc()) {
1195 EndStatementAtEOFStack.pop_back();
1196 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1197 return peekTok(ShouldSkipSpace);
1199 EndStatementAtEOFStack.pop_back();
1200 assert(EndStatementAtEOFStack.empty());
1207bool MasmParser::Run(
bool NoInitialTextSection,
bool NoFinalize) {
1209 if (!NoInitialTextSection)
1216 AsmCond StartingCondState = TheCondState;
1226 ParseStatementInfo
Info(&AsmStrRewrites);
1227 bool HasError = parseStatement(Info,
nullptr);
1232 if (HasError && !hasPendingError() && Lexer.getTok().is(
AsmToken::Error))
1236 printPendingErrors();
1239 if (HasError && !getLexer().justConsumedEOL())
1240 eatToEndOfStatement();
1243 printPendingErrors();
1246 assert(!hasPendingError() &&
"unexpected error from parseStatement");
1250 printError(getTok().getLoc(),
"unmatched .ifs or .elses");
1259 for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1260 if (std::get<2>(LocSym)->isUndefined()) {
1263 CppHashInfo = std::get<1>(LocSym);
1264 printError(std::get<0>(LocSym),
"directional label undefined");
1271 if (!HadError && !NoFinalize)
1272 Out.
finish(Lexer.getLoc());
1274 return HadError || getContext().hadError();
1277bool MasmParser::checkForValidSection() {
1278 if (!ParsingMSInlineAsm && !(getStreamer().getCurrentFragment() &&
1279 getStreamer().getCurrentSectionOnly())) {
1281 return Error(getTok().getLoc(),
1282 "expected section directive before assembly directive");
1288void MasmParser::eatToEndOfStatement() {
1292 if (ParentIncludeLoc ==
SMLoc()) {
1296 EndStatementAtEOFStack.pop_back();
1297 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1311 const char *Start = getTok().getLoc().getPointer();
1312 while (Lexer.isNot(EndTok)) {
1315 if (ParentIncludeLoc ==
SMLoc()) {
1318 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1320 EndStatementAtEOFStack.pop_back();
1321 jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1323 Start = getTok().getLoc().getPointer();
1328 Refs.
emplace_back(Start, getTok().getLoc().getPointer() - Start);
1336 Str.append(S.str());
1341StringRef MasmParser::parseStringToEndOfStatement() {
1342 const char *Start = getTok().getLoc().getPointer();
1347 const char *
End = getTok().getLoc().getPointer();
1356bool MasmParser::parseParenExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1357 if (parseExpression(Res))
1359 EndLoc = Lexer.getTok().getEndLoc();
1360 return parseRParen();
1368bool MasmParser::parseBracketExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
1369 if (parseExpression(Res))
1371 EndLoc = getTok().getEndLoc();
1372 if (parseToken(
AsmToken::RBrac,
"expected ']' in brackets expression"))
1385bool MasmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc,
1387 SMLoc FirstTokenLoc = getLexer().getLoc();
1389 switch (FirstTokenKind) {
1391 return TokError(
"unknown token in expression");
1397 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1405 if (parseIdentifier(Identifier)) {
1408 if (Lexer.getMAI().getDollarIsPC()) {
1415 EndLoc = FirstTokenLoc;
1418 return Error(FirstTokenLoc,
"invalid token in expression");
1423 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1431 bool Before =
Identifier.equals_insensitive(
"@b");
1432 MCSymbol *
Sym = getContext().getDirectionalLocalSymbol(0, Before);
1433 if (Before &&
Sym->isUndefined())
1434 return Error(FirstTokenLoc,
"Expected @@ label before @B reference");
1444 return Error(getLexer().getLoc(),
"expected a symbol reference");
1449 if (
Split.second.empty()) {
1452 if (lookUpField(SymbolName,
Split.second, Info)) {
1453 std::pair<StringRef, StringRef> BaseMember =
Split.second.split(
'.');
1455 lookUpField(
Base, Member, Info);
1463 MCSymbol *
Sym = getContext().getInlineAsmLabel(SymbolName);
1466 auto BuiltinIt = BuiltinSymbolMap.find(
SymbolName.lower());
1467 const BuiltinSymbol
Symbol = (BuiltinIt == BuiltinSymbolMap.end())
1469 : BuiltinIt->getValue();
1470 if (Symbol != BI_NO_SYMBOL) {
1471 const MCExpr *
Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
1481 if (VarIt != Variables.
end())
1483 Sym = getContext().getOrCreateSymbol(SymbolName);
1488 if (
Sym->isVariable()) {
1489 auto V =
Sym->getVariableValue();
1490 bool DoInline = isa<MCConstantExpr>(V);
1491 if (
auto TV = dyn_cast<MCTargetExpr>(V))
1492 DoInline = TV->inlineAssignedExpr();
1494 Res =
Sym->getVariableValue();
1510 if (
Info.Type.Name.empty()) {
1512 if (TypeIt != KnownType.
end()) {
1513 Info.Type = TypeIt->second;
1517 *TypeInfo =
Info.Type;
1522 return TokError(
"literal value out of range for directive");
1524 int64_t
IntVal = getTok().getIntVal();
1526 EndLoc = Lexer.getTok().getEndLoc();
1532 SMLoc ValueLoc = getTok().getLoc();
1534 if (parseEscapedString(
Value))
1536 if (
Value.size() > 8)
1537 return Error(ValueLoc,
"literal value out of range");
1539 for (
const unsigned char CharVal :
Value)
1540 IntValue = (IntValue << 8) | CharVal;
1545 APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1548 EndLoc = Lexer.getTok().getEndLoc();
1558 EndLoc = Lexer.getTok().getEndLoc();
1564 return parseParenExpr(Res, EndLoc);
1566 if (!PlatformParser->HasBracketExpressions())
1567 return TokError(
"brackets expression not supported on this target");
1569 return parseBracketExpr(Res, EndLoc);
1572 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1578 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1584 if (parsePrimaryExpr(Res, EndLoc,
nullptr))
1591bool MasmParser::parseExpression(
const MCExpr *&Res) {
1593 return parseExpression(Res, EndLoc);
1604 "Argument to the function cannot be a NULL value");
1606 while ((*CharPtr !=
'>') && (*CharPtr !=
'\n') && (*CharPtr !=
'\r') &&
1607 (*CharPtr !=
'\0')) {
1608 if (*CharPtr ==
'!')
1612 if (*CharPtr ==
'>') {
1622 for (
size_t Pos = 0; Pos < BracketContents.
size(); Pos++) {
1623 if (BracketContents[Pos] ==
'!')
1625 Res += BracketContents[Pos];
1640bool MasmParser::parseExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1643 if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1644 parseBinOpRHS(1, Res, EndLoc))
1650 if (Res->evaluateAsAbsolute(
Value))
1656bool MasmParser::parseParenExpression(
const MCExpr *&Res,
SMLoc &EndLoc) {
1658 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1661bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1664 SMLoc StartLoc = Lexer.getLoc();
1665 if (parseExpression(Expr))
1668 if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1669 return Error(StartLoc,
"expected absolute expression");
1676 bool ShouldUseLogicalShr,
1677 bool EndExpressionAtGreater) {
1705 if (EndExpressionAtGreater)
1746 if (EndExpressionAtGreater)
1757 AngleBracketDepth > 0);
1762bool MasmParser::parseBinOpRHS(
unsigned Precedence,
const MCExpr *&Res,
1764 SMLoc StartLoc = Lexer.getLoc();
1784 unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
1788 if (TokPrec < Precedence)
1795 if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1801 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1802 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1815bool MasmParser::parseStatement(ParseStatementInfo &Info,
1817 assert(!hasPendingError() &&
"parseStatement started with pending error");
1823 if (getTok().getString().empty() || getTok().getString().front() ==
'\r' ||
1824 getTok().getString().front() ==
'\n')
1833 SMLoc ExpansionLoc = getTok().getLoc();
1844 return parseCppHashLineFilenameComment(IDLoc);
1851 IDVal = getTok().getString();
1854 return Error(IDLoc,
"unexpected token at start of statement");
1855 }
else if (parseIdentifier(IDVal, StartOfStatement)) {
1856 if (!TheCondState.
Ignore) {
1858 return Error(IDLoc,
"unexpected token at start of statement");
1867 DirectiveKindMap.find(IDVal.
lower());
1868 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1870 : DirKindIt->getValue();
1876 return parseDirectiveIf(IDLoc, DirKind);
1878 return parseDirectiveIfb(IDLoc,
true);
1880 return parseDirectiveIfb(IDLoc,
false);
1882 return parseDirectiveIfdef(IDLoc,
true);
1884 return parseDirectiveIfdef(IDLoc,
false);
1886 return parseDirectiveIfidn(IDLoc,
false,
1889 return parseDirectiveIfidn(IDLoc,
false,
1892 return parseDirectiveIfidn(IDLoc,
true,
1895 return parseDirectiveIfidn(IDLoc,
true,
1899 return parseDirectiveElseIf(IDLoc, DirKind);
1901 return parseDirectiveElseIfb(IDLoc,
true);
1903 return parseDirectiveElseIfb(IDLoc,
false);
1905 return parseDirectiveElseIfdef(IDLoc,
true);
1907 return parseDirectiveElseIfdef(IDLoc,
false);
1909 return parseDirectiveElseIfidn(IDLoc,
false,
1912 return parseDirectiveElseIfidn(IDLoc,
false,
1915 return parseDirectiveElseIfidn(IDLoc,
true,
1918 return parseDirectiveElseIfidn(IDLoc,
true,
1921 return parseDirectiveElse(IDLoc);
1923 return parseDirectiveEndIf(IDLoc);
1928 if (TheCondState.
Ignore) {
1929 eatToEndOfStatement();
1939 if (checkForValidSection())
1947 return Error(IDLoc,
"invalid use of pseudo-symbol '.' as a label");
1955 if (ParsingMSInlineAsm && SI) {
1957 SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc,
true);
1959 "We should have an internal name here.");
1962 IDVal = RewrittenLabel;
1965 if (IDVal ==
"@@") {
1968 Sym = getContext().getOrCreateSymbol(IDVal);
1988 if (!getTargetParser().isParsingMSInlineAsm())
1998 return handleMacroEntry(M, IDLoc, ArgumentEndTok);
2003 if (DirKind != DK_NO_DIRECTIVE) {
2019 return parseDirectiveNestedEnds();
2024 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2027 return (*Handler.second)(Handler.first, IDVal, IDLoc);
2033 ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(
ID);
2035 "Should only return Failure iff there was an error");
2047 return parseDirectiveAscii(IDVal,
false);
2050 return parseDirectiveAscii(IDVal,
true);
2054 return parseDirectiveValue(IDVal, 1);
2058 return parseDirectiveValue(IDVal, 2);
2062 return parseDirectiveValue(IDVal, 4);
2065 return parseDirectiveValue(IDVal, 6);
2069 return parseDirectiveValue(IDVal, 8);
2071 return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2073 return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2075 return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2078 return parseDirectiveNestedStruct(IDVal, DirKind);
2080 return parseDirectiveNestedEnds();
2082 return parseDirectiveAlign();
2084 return parseDirectiveEven();
2086 return parseDirectiveOrg();
2088 return parseDirectiveExtern();
2090 return parseDirectiveSymbolAttribute(
MCSA_Global);
2092 return parseDirectiveComm(
false);
2094 return parseDirectiveComment(IDLoc);
2096 return parseDirectiveInclude();
2098 return parseDirectiveRepeat(IDLoc, IDVal);
2100 return parseDirectiveWhile(IDLoc);
2102 return parseDirectiveFor(IDLoc, IDVal);
2104 return parseDirectiveForc(IDLoc, IDVal);
2106 Info.ExitValue =
"";
2107 return parseDirectiveExitMacro(IDLoc, IDVal, *
Info.ExitValue);
2109 Info.ExitValue =
"";
2110 return parseDirectiveEndMacro(IDVal);
2112 return parseDirectivePurgeMacro(IDLoc);
2114 return parseDirectiveEnd(IDLoc);
2116 return parseDirectiveError(IDLoc);
2118 return parseDirectiveErrorIfb(IDLoc,
true);
2120 return parseDirectiveErrorIfb(IDLoc,
false);
2122 return parseDirectiveErrorIfdef(IDLoc,
true);
2124 return parseDirectiveErrorIfdef(IDLoc,
false);
2126 return parseDirectiveErrorIfidn(IDLoc,
false,
2129 return parseDirectiveErrorIfidn(IDLoc,
false,
2132 return parseDirectiveErrorIfidn(IDLoc,
true,
2135 return parseDirectiveErrorIfidn(IDLoc,
true,
2138 return parseDirectiveErrorIfe(IDLoc,
true);
2140 return parseDirectiveErrorIfe(IDLoc,
false);
2142 return parseDirectiveRadix(IDLoc);
2144 return parseDirectiveEcho(IDLoc);
2147 return Error(IDLoc,
"unknown directive");
2151 auto IDIt = Structs.
find(IDVal.
lower());
2152 if (IDIt != Structs.
end())
2153 return parseDirectiveStructValue(IDIt->getValue(), IDVal,
2161 const AsmToken afterNextTok = peekTok();
2172 getTargetParser().flushPendingInstructions(getStreamer());
2178 return parseDirectiveEnds(IDVal, IDLoc);
2183 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2185 if (Handler.first) {
2188 return (*Handler.second)(Handler.first, nextVal, nextLoc);
2193 DirKindIt = DirectiveKindMap.find(nextVal.
lower());
2194 DirKind = (DirKindIt == DirectiveKindMap.end())
2196 : DirKindIt->getValue();
2204 return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
2215 return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2226 return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2237 return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2247 return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2258 return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2261 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2265 return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2269 return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2274 return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2277 return parseDirectiveEnds(IDVal, IDLoc);
2280 return parseDirectiveMacro(IDVal, IDLoc);
2284 auto NextIt = Structs.
find(nextVal.
lower());
2285 if (NextIt != Structs.
end()) {
2287 return parseDirectiveNamedStructValue(NextIt->getValue(),
2288 nextVal, nextLoc, IDVal);
2292 if (ParsingMSInlineAsm && (IDVal ==
"_emit" || IDVal ==
"__emit" ||
2293 IDVal ==
"_EMIT" || IDVal ==
"__EMIT"))
2294 return parseDirectiveMSEmit(IDLoc, Info, IDVal.
size());
2297 if (ParsingMSInlineAsm && (IDVal ==
"align" || IDVal ==
"ALIGN"))
2298 return parseDirectiveMSAlign(IDLoc, Info);
2300 if (ParsingMSInlineAsm && (IDVal ==
"even" || IDVal ==
"EVEN"))
2302 if (checkForValidSection())
2306 std::string OpcodeStr = IDVal.
lower();
2308 bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr,
ID,
2309 Info.ParsedOperands);
2310 Info.ParseError = ParseHadError;
2313 if (getShowParsedOperands()) {
2316 OS <<
"parsed instruction: [";
2317 for (
unsigned i = 0; i !=
Info.ParsedOperands.size(); ++i) {
2320 Info.ParsedOperands[i]->print(
OS, MAI);
2328 if (hasPendingError() || ParseHadError)
2332 if (!ParseHadError) {
2334 if (getTargetParser().matchAndEmitInstruction(
2336 getTargetParser().isParsingMSInlineAsm()))
2343bool MasmParser::parseCurlyBlockScope(
2349 SMLoc StartLoc = Lexer.getLoc();
2362bool MasmParser::parseCppHashLineFilenameComment(
SMLoc L) {
2367 "Lexing Cpp line comment: Expected Integer");
2368 int64_t LineNumber = getTok().getIntVal();
2371 "Lexing Cpp line comment: Expected String");
2380 CppHashInfo.Loc =
L;
2382 CppHashInfo.LineNumber = LineNumber;
2383 CppHashInfo.Buf = CurBuffer;
2384 if (FirstCppHashFilename.
empty())
2391void MasmParser::DiagHandler(
const SMDiagnostic &Diag,
void *Context) {
2392 const MasmParser *Parser =
static_cast<const MasmParser *
>(
Context);
2398 unsigned CppHashBuf =
2399 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2404 if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2413 if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2414 DiagBuf != CppHashBuf) {
2415 if (Parser->SavedDiagHandler)
2416 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2425 const std::string &
Filename = std::string(Parser->CppHashInfo.Filename);
2428 int CppHashLocLineNo =
2429 Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2431 Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2437 if (Parser->SavedDiagHandler)
2438 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2440 NewDiag.print(
nullptr,
OS);
2446 return isAlnum(
C) ||
C ==
'_' ||
C ==
'$' ||
C ==
'@' ||
C ==
'?';
2452 const std::vector<std::string> &Locals,
SMLoc L) {
2454 if (NParameters !=
A.size())
2455 return Error(L,
"Wrong number of arguments");
2467 std::optional<char> CurrentQuote;
2468 while (!Body.
empty()) {
2470 std::size_t
End = Body.
size(), Pos = 0;
2471 std::size_t IdentifierPos =
End;
2472 for (; Pos !=
End; ++Pos) {
2475 if (Body[Pos] ==
'&')
2480 if (IdentifierPos ==
End)
2481 IdentifierPos = Pos;
2483 IdentifierPos =
End;
2487 if (!CurrentQuote) {
2488 if (Body[Pos] ==
'\'' || Body[Pos] ==
'"')
2489 CurrentQuote = Body[Pos];
2490 }
else if (Body[Pos] == CurrentQuote) {
2491 if (Pos + 1 !=
End && Body[Pos + 1] == CurrentQuote) {
2496 CurrentQuote.reset();
2500 if (IdentifierPos !=
End) {
2503 Pos = IdentifierPos;
2504 IdentifierPos =
End;
2515 bool InitialAmpersand = (Body[
I] ==
'&');
2516 if (InitialAmpersand) {
2523 const char *Begin = Body.
data() + Pos;
2525 const std::string ArgumentLower =
Argument.lower();
2529 if (Parameters[Index].
Name.equals_insensitive(ArgumentLower))
2532 if (Index == NParameters) {
2533 if (InitialAmpersand)
2535 auto it = LocalSymbols.
find(ArgumentLower);
2536 if (it != LocalSymbols.
end())
2542 for (
const AsmToken &Token :
A[Index]) {
2552 OS << Token.getIntVal();
2554 OS << Token.getString();
2558 if (Pos <
End && Body[Pos] ==
'&') {
2570 MCAsmMacroArgument &MA,
2573 if (Lexer.isNot(EndTok)) {
2582 SMLoc StrLoc = Lexer.getLoc(), EndLoc;
2584 const char *StrChar = StrLoc.
getPointer() + 1;
2585 const char *EndChar = EndLoc.
getPointer() - 1;
2586 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
2593 unsigned ParenLevel = 0;
2597 return TokError(
"unexpected token");
2614 MA.push_back(getTok());
2618 if (ParenLevel != 0)
2619 return TokError(
"unbalanced parentheses in argument");
2621 if (MA.empty() && MP) {
2623 return TokError(
"missing value for required parameter '" + MP->
Name +
2633bool MasmParser::parseMacroArguments(
const MCAsmMacro *M,
2634 MCAsmMacroArguments &
A,
2636 const unsigned NParameters =
M ?
M->Parameters.size() : 0;
2637 bool NamedParametersFound =
false;
2640 A.resize(NParameters);
2641 FALocs.
resize(NParameters);
2646 for (
unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2648 SMLoc IDLoc = Lexer.getLoc();
2652 if (parseIdentifier(FA.
Name))
2653 return Error(IDLoc,
"invalid argument identifier for formal argument");
2656 return TokError(
"expected '=' after formal parameter identifier");
2660 NamedParametersFound =
true;
2663 if (NamedParametersFound && FA.
Name.
empty())
2664 return Error(IDLoc,
"cannot mix positional and keyword arguments");
2666 unsigned PI = Parameter;
2668 assert(M &&
"expected macro to be defined");
2670 for (FAI = 0; FAI < NParameters; ++FAI)
2671 if (
M->Parameters[FAI].Name == FA.
Name)
2674 if (FAI >= NParameters) {
2675 return Error(IDLoc,
"parameter named '" + FA.
Name +
2676 "' does not exist for macro '" +
M->Name +
"'");
2681 if (M && PI < NParameters)
2682 MP = &
M->Parameters[PI];
2684 SMLoc StrLoc = Lexer.getLoc();
2687 const MCExpr *AbsoluteExp;
2691 if (parseExpression(AbsoluteExp, EndLoc))
2693 if (!AbsoluteExp->evaluateAsAbsolute(
Value,
2694 getStreamer().getAssemblerPtr()))
2695 return Error(StrLoc,
"expected absolute expression");
2700 FA.
Value.push_back(newToken);
2701 }
else if (parseMacroArgument(MP, FA.
Value, EndTok)) {
2703 return addErrorSuffix(
" in '" +
M->Name +
"' macro");
2708 if (!FA.
Value.empty()) {
2713 if (FALocs.
size() <= PI)
2716 FALocs[PI] = Lexer.getLoc();
2722 if (Lexer.is(EndTok)) {
2724 for (
unsigned FAI = 0; FAI < NParameters; ++FAI) {
2725 if (
A[FAI].empty()) {
2726 if (
M->Parameters[FAI].Required) {
2727 Error(FALocs[FAI].
isValid() ? FALocs[FAI] : Lexer.getLoc(),
2728 "missing value for required parameter "
2730 M->Parameters[FAI].Name +
"' in macro '" +
M->Name +
"'");
2734 if (!
M->Parameters[FAI].Value.empty())
2735 A[FAI] =
M->Parameters[FAI].Value;
2745 return TokError(
"too many positional arguments");
2753 if (ActiveMacros.size() == MaxNestingDepth) {
2754 std::ostringstream MaxNestingDepthError;
2755 MaxNestingDepthError <<
"macros cannot be nested more than "
2756 << MaxNestingDepth <<
" levels deep."
2757 <<
" Use -asm-macro-max-nesting-depth to increase "
2759 return TokError(MaxNestingDepthError.str());
2762 MCAsmMacroArguments
A;
2763 if (parseMacroArguments(M,
A, ArgumentEndTok) || parseToken(ArgumentEndTok))
2772 if (expandMacro(
OS, Body,
M->Parameters,
A,
M->Locals, getTok().getLoc()))
2779 std::unique_ptr<MemoryBuffer> Instantiation =
2784 MacroInstantiation *
MI =
new MacroInstantiation{
2785 NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
2786 ActiveMacros.push_back(
MI);
2788 ++NumOfMacroInstantiations;
2793 EndStatementAtEOFStack.push_back(
true);
2799void MasmParser::handleMacroExit() {
2801 EndStatementAtEOFStack.pop_back();
2802 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
2803 EndStatementAtEOFStack.back());
2807 delete ActiveMacros.back();
2808 ActiveMacros.pop_back();
2811bool MasmParser::handleMacroInvocation(
const MCAsmMacro *M,
SMLoc NameLoc) {
2813 return Error(NameLoc,
"cannot invoke macro procedure as function");
2816 "' requires arguments in parentheses") ||
2821 std::string ExitValue;
2824 ParseStatementInfo
Info(&AsmStrRewrites);
2825 bool HasError = parseStatement(Info,
nullptr);
2827 if (!HasError &&
Info.ExitValue) {
2828 ExitValue = std::move(*
Info.ExitValue);
2835 if (HasError && !hasPendingError() && Lexer.getTok().is(
AsmToken::Error))
2839 printPendingErrors();
2842 if (HasError && !getLexer().justConsumedEOL())
2843 eatToEndOfStatement();
2848 std::unique_ptr<MemoryBuffer> MacroValue =
2856 EndStatementAtEOFStack.push_back(
false);
2865bool MasmParser::parseIdentifier(
StringRef &Res,
2866 IdentifierPositionKind Position) {
2873 SMLoc PrefixLoc = getLexer().getLoc();
2898 Res = getTok().getIdentifier();
2902 ExpandKind ExpandNextToken = ExpandMacros;
2903 if (Position == StartOfStatement &&
2905 .CaseLower(
"echo",
true)
2906 .CasesLower(
"ifdef",
"ifndef",
"elseifdef",
"elseifndef",
true)
2908 ExpandNextToken = DoNotExpandMacros;
2910 Lex(ExpandNextToken);
2921 DirectiveKind DirKind,
SMLoc NameLoc) {
2922 auto BuiltinIt = BuiltinSymbolMap.find(
Name.lower());
2923 if (BuiltinIt != BuiltinSymbolMap.end())
2924 return Error(NameLoc,
"cannot redefine a built-in symbol");
2926 Variable &Var = Variables[
Name.lower()];
2927 if (Var.Name.empty()) {
2931 SMLoc StartLoc = Lexer.getLoc();
2932 if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
2935 std::string TextItem;
2936 if (!parseTextItem(TextItem)) {
2940 auto parseItem = [&]() ->
bool {
2941 if (parseTextItem(TextItem))
2942 return TokError(
"expected text item");
2947 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
2949 if (!Var.IsText || Var.TextValue !=
Value) {
2950 switch (Var.Redefinable) {
2951 case Variable::NOT_REDEFINABLE:
2952 return Error(getTok().getLoc(),
"invalid variable redefinition");
2953 case Variable::WARN_ON_REDEFINITION:
2955 "', already defined on the command line")) {
2964 Var.TextValue =
Value;
2965 Var.Redefinable = Variable::REDEFINABLE;
2970 if (DirKind == DK_TEXTEQU)
2971 return TokError(
"expected <text> in '" +
Twine(IDVal) +
"' directive");
2976 if (parseExpression(Expr, EndLoc))
2977 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
2982 if (!Expr->evaluateAsAbsolute(
Value, getStreamer().getAssemblerPtr())) {
2983 if (DirKind == DK_ASSIGN)
2986 "expected absolute expression; not all symbols have known values",
2987 {StartLoc, EndLoc});
2990 if (!Var.IsText || Var.TextValue != ExprAsString) {
2991 switch (Var.Redefinable) {
2992 case Variable::NOT_REDEFINABLE:
2993 return Error(getTok().getLoc(),
"invalid variable redefinition");
2994 case Variable::WARN_ON_REDEFINITION:
2996 "', already defined on the command line")) {
3006 Var.TextValue = ExprAsString.
str();
3007 Var.Redefinable = Variable::REDEFINABLE;
3013 static_cast<MCSymbolCOFF *
>(getContext().getOrCreateSymbol(Var.Name));
3016 ? dyn_cast_or_null<MCConstantExpr>(
Sym->getVariableValue())
3018 if (Var.IsText || !PrevValue || PrevValue->
getValue() !=
Value) {
3019 switch (Var.Redefinable) {
3020 case Variable::NOT_REDEFINABLE:
3021 return Error(getTok().getLoc(),
"invalid variable redefinition");
3022 case Variable::WARN_ON_REDEFINITION:
3024 "', already defined on the command line")) {
3034 Var.TextValue.clear();
3035 Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
3036 : Variable::NOT_REDEFINABLE;
3038 Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
3039 Sym->setVariableValue(Expr);
3040 Sym->setExternal(
false);
3045bool MasmParser::parseEscapedString(std::string &Data) {
3050 char Quote = getTok().getString().front();
3051 StringRef Str = getTok().getStringContents();
3052 Data.reserve(Str.size());
3053 for (
size_t i = 0, e = Str.size(); i != e; ++i) {
3054 Data.push_back(Str[i]);
3055 if (Str[i] == Quote) {
3059 if (i + 1 == Str.size())
3060 return Error(getTok().getLoc(),
"missing quotation mark in string");
3061 if (Str[i + 1] == Quote)
3070bool MasmParser::parseAngleBracketString(std::string &Data) {
3071 SMLoc EndLoc, StartLoc = getTok().getLoc();
3073 const char *StartChar = StartLoc.
getPointer() + 1;
3074 const char *EndChar = EndLoc.
getPointer() - 1;
3075 jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3086bool MasmParser::parseTextItem(std::string &Data) {
3087 switch (getTok().getKind()) {
3094 Data = std::to_string(Res);
3101 return parseAngleBracketString(Data);
3105 SMLoc StartLoc = getTok().getLoc();
3106 if (parseIdentifier(
ID))
3110 bool Expanded =
false;
3113 auto BuiltinIt = BuiltinSymbolMap.find(
ID.lower());
3114 if (BuiltinIt != BuiltinSymbolMap.end()) {
3115 std::optional<std::string> BuiltinText =
3116 evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
3121 Data = std::move(*BuiltinText);
3128 auto BuiltinFuncIt = BuiltinFunctionMap.find(
ID.lower());
3129 if (BuiltinFuncIt != BuiltinFunctionMap.end()) {
3131 if (evaluateBuiltinMacroFunction(BuiltinFuncIt->getValue(),
ID, Data)) {
3140 auto VarIt = Variables.
find(
ID.lower());
3141 if (VarIt != Variables.
end()) {
3142 const Variable &Var = VarIt->getValue();
3147 Data = Var.TextValue;
3170bool MasmParser::parseDirectiveAscii(
StringRef IDVal,
bool ZeroTerminated) {
3171 auto parseOp = [&]() ->
bool {
3173 if (checkForValidSection() || parseEscapedString(Data))
3175 getStreamer().emitBytes(Data);
3177 getStreamer().emitBytes(
StringRef(
"\0", 1));
3181 if (parseMany(parseOp))
3182 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3190 int64_t IntValue = MCE->getValue();
3192 return Error(MCE->getLoc(),
"out of range literal value");
3193 getStreamer().emitIntValue(IntValue,
Size);
3198 getStreamer().emitIntValue(0,
Size);
3206bool MasmParser::parseScalarInitializer(
unsigned Size,
3208 unsigned StringPadLength) {
3211 if (parseEscapedString(
Value))
3214 for (
const unsigned char CharVal :
Value)
3218 for (
size_t i =
Value.size(); i < StringPadLength; ++i)
3222 if (parseExpression(
Value))
3225 getTok().getString().equals_insensitive(
"dup")) {
3230 "cannot repeat value a non-constant number of times");
3231 const int64_t Repetitions = MCE->
getValue();
3232 if (Repetitions < 0)
3234 "cannot repeat value a negative number of times");
3238 "parentheses required for 'dup' contents") ||
3239 parseScalarInstList(
Size, DuplicatedValues) || parseRParen())
3242 for (
int i = 0; i < Repetitions; ++i)
3251bool MasmParser::parseScalarInstList(
unsigned Size,
3254 while (getTok().
isNot(EndToken) &&
3257 parseScalarInitializer(
Size, Values);
3267bool MasmParser::emitIntegralValues(
unsigned Size,
unsigned *Count) {
3269 if (checkForValidSection() || parseScalarInstList(
Size, Values))
3272 for (
const auto *
Value : Values) {
3276 *Count = Values.size();
3282 StructInfo &
Struct = StructInProgress.
back();
3284 IntFieldInfo &IntInfo =
Field.Contents.IntInfo;
3288 if (parseScalarInstList(
Size, IntInfo.Values))
3291 Field.SizeOf =
Field.Type * IntInfo.Values.size();
3292 Field.LengthOf = IntInfo.Values.size();
3295 Struct.NextOffset = FieldEnd;
3303bool MasmParser::parseDirectiveValue(
StringRef IDVal,
unsigned Size) {
3304 if (StructInProgress.
empty()) {
3306 if (emitIntegralValues(
Size))
3307 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3308 }
else if (addIntegralField(
"",
Size)) {
3309 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3317bool MasmParser::parseDirectiveNamedValue(
StringRef TypeName,
unsigned Size,
3319 if (StructInProgress.
empty()) {
3322 getStreamer().emitLabel(
Sym);
3324 if (emitIntegralValues(
Size, &Count))
3325 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3331 Type.Length = Count;
3333 }
else if (addIntegralField(
Name,
Size)) {
3334 return addErrorSuffix(
" in '" +
Twine(TypeName) +
"' directive");
3346 SignLoc = getLexer().getLoc();
3350 SignLoc = getLexer().getLoc();
3355 return TokError(Lexer.getErr());
3358 return TokError(
"unexpected token in directive");
3371 return TokError(
"invalid floating point literal");
3375 unsigned SizeInBits =
Value.getSizeInBits(Semantics);
3376 if (SizeInBits != (IDVal.
size() << 2))
3377 return TokError(
"invalid floating point literal");
3382 Res =
APInt(SizeInBits, IDVal, 16);
3384 return Warning(SignLoc,
"MASM-style hex floats ignore explicit sign");
3387 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3389 return TokError(
"invalid floating point literal");
3397 Res =
Value.bitcastToAPInt();
3402bool MasmParser::parseRealInstList(
const fltSemantics &Semantics,
3405 while (getTok().
isNot(EndToken) ||
3408 const AsmToken NextTok = peekTok();
3417 "cannot repeat value a non-constant number of times");
3418 const int64_t Repetitions = MCE->
getValue();
3419 if (Repetitions < 0)
3421 "cannot repeat value a negative number of times");
3425 "parentheses required for 'dup' contents") ||
3426 parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
3429 for (
int i = 0; i < Repetitions; ++i)
3430 ValuesAsInt.
append(DuplicatedValues.
begin(), DuplicatedValues.
end());
3433 if (parseRealValue(Semantics, AsInt))
3448bool MasmParser::emitRealValues(
const fltSemantics &Semantics,
3450 if (checkForValidSection())
3454 if (parseRealInstList(Semantics, ValuesAsInt))
3457 for (
const APInt &AsInt : ValuesAsInt) {
3458 getStreamer().emitIntValue(AsInt);
3461 *Count = ValuesAsInt.size();
3468 StructInfo &
Struct = StructInProgress.
back();
3470 RealFieldInfo &RealInfo =
Field.Contents.RealInfo;
3474 if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3477 Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3478 Field.LengthOf = RealInfo.AsIntValues.size();
3483 Struct.NextOffset = FieldEnd;
3491bool MasmParser::parseDirectiveRealValue(
StringRef IDVal,
3494 if (StructInProgress.
empty()) {
3496 if (emitRealValues(Semantics))
3497 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3498 }
else if (addRealField(
"", Semantics,
Size)) {
3499 return addErrorSuffix(
" in '" +
Twine(IDVal) +
"' directive");
3506bool MasmParser::parseDirectiveNamedRealValue(
StringRef TypeName,
3510 if (StructInProgress.
empty()) {
3513 getStreamer().emitLabel(
Sym);
3515 if (emitRealValues(Semantics, &Count))
3516 return addErrorSuffix(
" in '" + TypeName +
"' directive");
3522 Type.Length = Count;
3524 }
else if (addRealField(
Name, Semantics,
Size)) {
3525 return addErrorSuffix(
" in '" + TypeName +
"' directive");
3530bool MasmParser::parseOptionalAngleBracketOpen() {
3533 AngleBracketDepth++;
3537 AngleBracketDepth++;
3541 AngleBracketDepth++;
3548bool MasmParser::parseAngleBracketClose(
const Twine &Msg) {
3555 AngleBracketDepth--;
3559bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
3560 const IntFieldInfo &Contents,
3561 FieldInitializer &Initializer) {
3562 SMLoc Loc = getTok().getLoc();
3567 return Error(Loc,
"Cannot initialize scalar field with array value");
3571 }
else if (parseOptionalAngleBracketOpen()) {
3573 return Error(Loc,
"Cannot initialize scalar field with array value");
3575 parseAngleBracketClose())
3577 }
else if (
Field.LengthOf > 1 &&
Field.Type > 1) {
3578 return Error(Loc,
"Cannot initialize array field with scalar value");
3579 }
else if (parseScalarInitializer(
Field.Type, Values,
3585 return Error(Loc,
"Initializer too long for field; expected at most " +
3586 std::to_string(
Field.LengthOf) +
" elements, got " +
3587 std::to_string(Values.
size()));
3590 Values.
append(Contents.Values.begin() + Values.
size(), Contents.Values.end());
3592 Initializer = FieldInitializer(std::move(Values));
3596bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
3597 const RealFieldInfo &Contents,
3598 FieldInitializer &Initializer) {
3600 switch (
Field.Type) {
3602 Semantics = &APFloat::IEEEsingle();
3605 Semantics = &APFloat::IEEEdouble();
3608 Semantics = &APFloat::x87DoubleExtended();
3614 SMLoc Loc = getTok().getLoc();
3618 if (
Field.LengthOf == 1)
3619 return Error(Loc,
"Cannot initialize scalar field with array value");
3623 }
else if (parseOptionalAngleBracketOpen()) {
3624 if (
Field.LengthOf == 1)
3625 return Error(Loc,
"Cannot initialize scalar field with array value");
3627 parseAngleBracketClose())
3629 }
else if (
Field.LengthOf > 1) {
3630 return Error(Loc,
"Cannot initialize array field with scalar value");
3633 if (parseRealValue(*Semantics, AsIntValues.
back()))
3637 if (AsIntValues.
size() >
Field.LengthOf) {
3638 return Error(Loc,
"Initializer too long for field; expected at most " +
3639 std::to_string(
Field.LengthOf) +
" elements, got " +
3640 std::to_string(AsIntValues.
size()));
3643 AsIntValues.
append(Contents.AsIntValues.begin() + AsIntValues.
size(),
3644 Contents.AsIntValues.end());
3646 Initializer = FieldInitializer(std::move(AsIntValues));
3650bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
3651 const StructFieldInfo &Contents,
3652 FieldInitializer &Initializer) {
3653 SMLoc Loc = getTok().getLoc();
3655 std::vector<StructInitializer> Initializers;
3656 if (
Field.LengthOf > 1) {
3658 if (parseStructInstList(Contents.Structure, Initializers,
3662 }
else if (parseOptionalAngleBracketOpen()) {
3663 if (parseStructInstList(Contents.Structure, Initializers,
3665 parseAngleBracketClose())
3668 return Error(Loc,
"Cannot initialize array field with scalar value");
3671 Initializers.emplace_back();
3672 if (parseStructInitializer(Contents.Structure, Initializers.back()))
3676 if (Initializers.size() >
Field.LengthOf) {
3677 return Error(Loc,
"Initializer too long for field; expected at most " +
3678 std::to_string(
Field.LengthOf) +
" elements, got " +
3679 std::to_string(Initializers.size()));
3683 Initializers.size()));
3685 Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
3689bool MasmParser::parseFieldInitializer(
const FieldInfo &
Field,
3690 FieldInitializer &Initializer) {
3691 switch (
Field.Contents.FT) {
3693 return parseFieldInitializer(
Field,
Field.Contents.IntInfo, Initializer);
3695 return parseFieldInitializer(
Field,
Field.Contents.RealInfo, Initializer);
3697 return parseFieldInitializer(
Field,
Field.Contents.StructInfo, Initializer);
3702bool MasmParser::parseStructInitializer(
const StructInfo &Structure,
3703 StructInitializer &Initializer) {
3704 const AsmToken FirstToken = getTok();
3706 std::optional<AsmToken::TokenKind> EndToken;
3709 }
else if (parseOptionalAngleBracketOpen()) {
3711 AngleBracketDepth++;
3718 return Error(FirstToken.
getLoc(),
"Expected struct initializer");
3721 auto &FieldInitializers = Initializer.FieldInitializers;
3722 size_t FieldIndex = 0;
3725 while (getTok().
isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
3726 const FieldInfo &
Field = Structure.Fields[FieldIndex++];
3730 FieldInitializers.push_back(
Field.Contents);
3734 FieldInitializers.emplace_back(
Field.Contents.FT);
3735 if (parseFieldInitializer(
Field, FieldInitializers.back()))
3739 SMLoc CommaLoc = getTok().getLoc();
3742 if (FieldIndex == Structure.Fields.size())
3743 return Error(CommaLoc,
"'" + Structure.Name +
3744 "' initializer initializes too many fields");
3750 FieldInitializers.push_back(
Field.Contents);
3754 return parseAngleBracketClose();
3756 return parseToken(*EndToken);
3762bool MasmParser::parseStructInstList(
3763 const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
3765 while (getTok().
isNot(EndToken) ||
3768 const AsmToken NextTok = peekTok();
3777 "cannot repeat value a non-constant number of times");
3778 const int64_t Repetitions = MCE->
getValue();
3779 if (Repetitions < 0)
3781 "cannot repeat value a negative number of times");
3783 std::vector<StructInitializer> DuplicatedValues;
3785 "parentheses required for 'dup' contents") ||
3786 parseStructInstList(Structure, DuplicatedValues) || parseRParen())
3789 for (
int i = 0; i < Repetitions; ++i)
3792 Initializers.emplace_back();
3793 if (parseStructInitializer(Structure, Initializers.back()))
3806bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
3807 const IntFieldInfo &Contents) {
3816bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
3817 const RealFieldInfo &Contents) {
3818 for (
const APInt &AsInt : Contents.AsIntValues) {
3825bool MasmParser::emitFieldValue(
const FieldInfo &
Field,
3826 const StructFieldInfo &Contents) {
3827 for (
const auto &Initializer : Contents.Initializers) {
3829 for (
const auto &SubField : Contents.Structure.Fields) {
3830 getStreamer().emitZeros(SubField.Offset -
Offset);
3831 Offset = SubField.Offset + SubField.SizeOf;
3832 emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);
3838bool MasmParser::emitFieldValue(
const FieldInfo &
Field) {
3839 switch (
Field.Contents.FT) {
3841 return emitFieldValue(
Field,
Field.Contents.IntInfo);
3843 return emitFieldValue(
Field,
Field.Contents.RealInfo);
3845 return emitFieldValue(
Field,
Field.Contents.StructInfo);
3850bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
3851 const IntFieldInfo &Contents,
3852 const IntFieldInfo &Initializer) {
3853 for (
const auto &
Value : Initializer.Values) {
3858 for (
const auto &
Value :
3866bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
3867 const RealFieldInfo &Contents,
3868 const RealFieldInfo &Initializer) {
3869 for (
const auto &AsInt : Initializer.AsIntValues) {
3874 for (
const auto &AsInt :
3882bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
3883 const StructFieldInfo &Contents,
3884 const StructFieldInfo &Initializer) {
3885 for (
const auto &
Init : Initializer.Initializers) {
3886 if (emitStructInitializer(Contents.Structure,
Init))
3891 Initializer.Initializers.size())) {
3892 if (emitStructInitializer(Contents.Structure,
Init))
3898bool MasmParser::emitFieldInitializer(
const FieldInfo &
Field,
3899 const FieldInitializer &Initializer) {
3900 switch (
Field.Contents.FT) {
3902 return emitFieldInitializer(
Field,
Field.Contents.IntInfo,
3903 Initializer.IntInfo);
3905 return emitFieldInitializer(
Field,
Field.Contents.RealInfo,
3906 Initializer.RealInfo);
3908 return emitFieldInitializer(
Field,
Field.Contents.StructInfo,
3909 Initializer.StructInfo);
3914bool MasmParser::emitStructInitializer(
const StructInfo &Structure,
3915 const StructInitializer &Initializer) {
3916 if (!Structure.Initializable)
3917 return Error(getLexer().getLoc(),
3918 "cannot initialize a value of type '" + Structure.Name +
3919 "'; 'org' was used in the type's declaration");
3921 for (
const auto &
Init : Initializer.FieldInitializers) {
3922 const auto &
Field = Structure.Fields[
Index++];
3930 Structure.Fields, Initializer.FieldInitializers.size())) {
3933 if (emitFieldValue(
Field))
3937 if (
Offset != Structure.Size)
3938 getStreamer().emitZeros(Structure.Size -
Offset);
3943bool MasmParser::emitStructValues(
const StructInfo &Structure,
3945 std::vector<StructInitializer> Initializers;
3946 if (parseStructInstList(Structure, Initializers))
3949 for (
const auto &Initializer : Initializers) {
3950 if (emitStructInitializer(Structure, Initializer))
3955 *Count = Initializers.size();
3960bool MasmParser::addStructField(
StringRef Name,
const StructInfo &Structure) {
3961 StructInfo &OwningStruct = StructInProgress.
back();
3963 OwningStruct.addField(
Name, FT_STRUCT, Structure.AlignmentSize);
3964 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
3966 StructInfo.Structure = Structure;
3969 if (parseStructInstList(Structure, StructInfo.Initializers))
3972 Field.LengthOf = StructInfo.Initializers.size();
3976 if (!OwningStruct.IsUnion) {
3977 OwningStruct.NextOffset = FieldEnd;
3979 OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
3987bool MasmParser::parseDirectiveStructValue(
const StructInfo &Structure,
3989 if (StructInProgress.
empty()) {
3990 if (emitStructValues(Structure))
3992 }
else if (addStructField(
"", Structure)) {
3993 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4001bool MasmParser::parseDirectiveNamedStructValue(
const StructInfo &Structure,
4004 if (StructInProgress.
empty()) {
4007 getStreamer().emitLabel(
Sym);
4009 if (emitStructValues(Structure, &Count))
4012 Type.Name = Structure.Name;
4013 Type.Size = Structure.Size * Count;
4014 Type.ElementSize = Structure.Size;
4015 Type.Length = Count;
4017 }
else if (addStructField(
Name, Structure)) {
4018 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4036 int64_t AlignmentValue = 1;
4039 parseAbsoluteExpression(AlignmentValue)) {
4040 return addErrorSuffix(
" in alignment value for '" +
Twine(
Directive) +
4044 return Error(NextTok.
getLoc(),
"alignment must be a power of two; was " +
4045 std::to_string(AlignmentValue));
4051 QualifierLoc = getTok().getLoc();
4052 if (parseIdentifier(Qualifier))
4053 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4054 if (!
Qualifier.equals_insensitive(
"nonunique"))
4055 return Error(QualifierLoc,
"Unrecognized qualifier for '" +
4057 "' directive; expected none or NONUNIQUE");
4061 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4072 DirectiveKind DirKind) {
4073 if (StructInProgress.
empty())
4074 return TokError(
"missing name in top-level '" +
Twine(
Directive) +
4079 Name = getTok().getIdentifier();
4083 return addErrorSuffix(
" in '" +
Twine(
Directive) +
"' directive");
4087 StructInProgress.
reserve(StructInProgress.
size() + 1);
4089 StructInProgress.
back().Alignment);
4094 if (StructInProgress.
empty())
4095 return Error(NameLoc,
"ENDS directive without matching STRUC/STRUCT/UNION");
4096 if (StructInProgress.
size() > 1)
4097 return Error(NameLoc,
"unexpected name in nested ENDS directive");
4098 if (StructInProgress.
back().Name.compare_insensitive(
Name))
4099 return Error(NameLoc,
"mismatched name in ENDS directive; expected '" +
4100 StructInProgress.
back().Name +
"'");
4101 StructInfo Structure = StructInProgress.
pop_back_val();
4105 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4106 Structs[
Name.lower()] = Structure;
4109 return addErrorSuffix(
" in ENDS directive");
4114bool MasmParser::parseDirectiveNestedEnds() {
4115 if (StructInProgress.
empty())
4116 return TokError(
"ENDS directive without matching STRUC/STRUCT/UNION");
4117 if (StructInProgress.
size() == 1)
4118 return TokError(
"missing name in top-level ENDS directive");
4121 return addErrorSuffix(
" in nested ENDS directive");
4123 StructInfo Structure = StructInProgress.
pop_back_val();
4125 Structure.Size =
llvm::alignTo(Structure.Size, Structure.Alignment);
4127 StructInfo &ParentStruct = StructInProgress.
back();
4128 if (Structure.Name.empty()) {
4131 const size_t OldFields = ParentStruct.Fields.size();
4132 ParentStruct.Fields.insert(
4133 ParentStruct.Fields.end(),
4134 std::make_move_iterator(Structure.Fields.begin()),
4135 std::make_move_iterator(Structure.Fields.end()));
4136 for (
const auto &FieldByName : Structure.FieldsByName) {
4137 ParentStruct.FieldsByName[FieldByName.getKey()] =
4138 FieldByName.getValue() + OldFields;
4141 unsigned FirstFieldOffset = 0;
4142 if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
4144 ParentStruct.NextOffset,
4145 std::min(ParentStruct.Alignment, Structure.AlignmentSize));
4148 if (ParentStruct.IsUnion) {
4149 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4154 const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
4155 if (!ParentStruct.IsUnion) {
4156 ParentStruct.NextOffset = StructureEnd;
4158 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4161 FieldInfo &
Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4162 Structure.AlignmentSize);
4163 StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
4169 if (!ParentStruct.IsUnion) {
4170 ParentStruct.NextOffset = StructureEnd;
4172 ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4174 StructInfo.Structure = Structure;
4175 StructInfo.Initializers.emplace_back();
4176 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4177 for (
const auto &SubField : Structure.Fields) {
4178 FieldInitializers.push_back(SubField.Contents);
4187bool MasmParser::parseDirectiveOrg() {
4189 SMLoc OffsetLoc = Lexer.getLoc();
4190 if (checkForValidSection() || parseExpression(
Offset))
4193 return addErrorSuffix(
" in 'org' directive");
4195 if (StructInProgress.
empty()) {
4197 if (checkForValidSection())
4198 return addErrorSuffix(
" in 'org' directive");
4200 getStreamer().emitValueToOffset(
Offset, 0, OffsetLoc);
4203 StructInfo &Structure = StructInProgress.
back();
4205 if (!
Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
4206 return Error(OffsetLoc,
4207 "expected absolute expression in 'org' directive");
4211 "expected non-negative value in struct's 'org' directive; was " +
4212 std::to_string(OffsetRes));
4213 Structure.NextOffset =
static_cast<unsigned>(OffsetRes);
4216 Structure.Initializable =
false;
4222bool MasmParser::emitAlignTo(int64_t Alignment) {
4223 if (StructInProgress.
empty()) {
4225 if (checkForValidSection())
4232 getStreamer().emitCodeAlignment(
Align(Alignment),
4233 &getTargetParser().getSTI(),
4237 getStreamer().emitValueToAlignment(
Align(Alignment), 0,
4243 StructInfo &Structure = StructInProgress.
back();
4244 Structure.NextOffset =
llvm::alignTo(Structure.NextOffset, Alignment);
4252bool MasmParser::parseDirectiveAlign() {
4253 SMLoc AlignmentLoc = getLexer().getLoc();
4259 "align directive with no operand is ignored") &&
4262 if (parseAbsoluteExpression(Alignment) || parseEOL())
4263 return addErrorSuffix(
" in align directive");
4266 bool ReturnVal =
false;
4273 ReturnVal |=
Error(AlignmentLoc,
"alignment must be a power of 2; was " +
4274 std::to_string(Alignment));
4276 if (emitAlignTo(Alignment))
4277 ReturnVal |= addErrorSuffix(
" in align directive");
4284bool MasmParser::parseDirectiveEven() {
4285 if (parseEOL() || emitAlignTo(2))
4286 return addErrorSuffix(
" in even directive");
4301 return Error(Lexer.getLoc(),
4302 "Vararg parameter '" +
Parameters.back().Name +
4303 "' should be last in the list of parameters");
4306 if (parseIdentifier(Parameter.
Name))
4307 return TokError(
"expected identifier in 'macro' directive");
4311 if (CurrParam.Name.equals_insensitive(Parameter.
Name))
4312 return TokError(
"macro '" +
Name +
"' has multiple parameters"
4313 " named '" + Parameter.
Name +
"'");
4322 ParamLoc = Lexer.getLoc();
4323 if (parseMacroArgument(
nullptr, Parameter.
Value))
4329 QualLoc = Lexer.getLoc();
4330 if (parseIdentifier(Qualifier))
4331 return Error(QualLoc,
"missing parameter qualifier for "
4333 Parameter.
Name +
"' in macro '" +
Name +
4336 if (
Qualifier.equals_insensitive(
"req"))
4338 else if (
Qualifier.equals_insensitive(
"vararg"))
4341 return Error(QualLoc,
4342 Qualifier +
" is not a valid parameter qualifier for '" +
4343 Parameter.
Name +
"' in macro '" +
Name +
"'");
4356 std::vector<std::string>
Locals;
4358 getTok().getIdentifier().equals_insensitive(
"local")) {
4363 if (parseIdentifier(
ID))
4375 AsmToken EndToken, StartToken = getTok();
4376 unsigned MacroDepth = 0;
4377 bool IsMacroFunction =
false;
4387 return Error(NameLoc,
"no matching 'endm' in definition");
4392 if (getTok().getIdentifier().equals_insensitive(
"endm")) {
4393 if (MacroDepth == 0) {
4394 EndToken = getTok();
4397 return TokError(
"unexpected token in '" + EndToken.
getIdentifier() +
4404 }
else if (getTok().getIdentifier().equals_insensitive(
"exitm")) {
4406 IsMacroFunction =
true;
4408 }
else if (isMacroLikeDirective()) {
4416 eatToEndOfStatement();
4419 if (getContext().lookupMacro(
Name.lower())) {
4420 return Error(NameLoc,
"macro '" +
Name +
"' is already defined");
4430 getContext().defineMacro(
Name.lower(), std::move(
Macro));
4436bool MasmParser::parseDirectiveExitMacro(
SMLoc DirectiveLoc,
4438 std::string &
Value) {
4439 SMLoc EndLoc = getTok().getLoc();
4441 return Error(EndLoc,
4442 "unable to parse text item in '" +
Directive +
"' directive");
4443 eatToEndOfStatement();
4445 if (!isInsideMacroInstantiation())
4446 return TokError(
"unexpected '" +
Directive +
"' in file, "
4447 "no current macro definition");
4450 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4451 TheCondState = TheCondStack.back();
4452 TheCondStack.pop_back();
4463 return TokError(
"unexpected token in '" +
Directive +
"' directive");
4467 if (isInsideMacroInstantiation()) {
4474 return TokError(
"unexpected '" +
Directive +
"' in file, "
4475 "no current macro definition");
4480bool MasmParser::parseDirectivePurgeMacro(
SMLoc DirectiveLoc) {
4484 if (parseTokenLoc(NameLoc) ||
4485 check(parseIdentifier(
Name), NameLoc,
4486 "expected identifier in 'purge' directive"))
4490 <<
"Un-defining macro: " <<
Name <<
"\n");
4491 if (!getContext().lookupMacro(
Name.lower()))
4492 return Error(NameLoc,
"macro '" +
Name +
"' is not defined");
4493 getContext().undefineMacro(
Name.lower());
4503bool MasmParser::parseDirectiveExtern() {
4505 auto parseOp = [&]() ->
bool {
4507 SMLoc NameLoc = getTok().getLoc();
4508 if (parseIdentifier(
Name))
4509 return Error(NameLoc,
"expected name");
4514 SMLoc TypeLoc = getTok().getLoc();
4515 if (parseIdentifier(TypeName))
4516 return Error(TypeLoc,
"expected type");
4517 if (!
TypeName.equals_insensitive(
"proc")) {
4519 if (lookUpType(TypeName,
Type))
4520 return Error(TypeLoc,
"unrecognized type");
4526 Sym->setExternal(
true);
4532 if (parseMany(parseOp))
4533 return addErrorSuffix(
" in directive 'extern'");
4539bool MasmParser::parseDirectiveSymbolAttribute(
MCSymbolAttr Attr) {
4540 auto parseOp = [&]() ->
bool {
4542 SMLoc Loc = getTok().getLoc();
4543 if (parseIdentifier(
Name))
4544 return Error(Loc,
"expected identifier");
4548 if (
Sym->isTemporary())
4549 return Error(Loc,
"non-local symbol required");
4551 if (!getStreamer().emitSymbolAttribute(
Sym, Attr))
4552 return Error(Loc,
"unable to emit symbol attribute");
4556 if (parseMany(parseOp))
4557 return addErrorSuffix(
" in directive");
4563bool MasmParser::parseDirectiveComm(
bool IsLocal) {
4564 if (checkForValidSection())
4567 SMLoc IDLoc = getLexer().getLoc();
4569 if (parseIdentifier(
Name))
4570 return TokError(
"expected identifier in directive");
4576 return TokError(
"unexpected token in directive");
4580 SMLoc SizeLoc = getLexer().getLoc();
4581 if (parseAbsoluteExpression(
Size))
4584 int64_t Pow2Alignment = 0;
4585 SMLoc Pow2AlignmentLoc;
4588 Pow2AlignmentLoc = getLexer().getLoc();
4589 if (parseAbsoluteExpression(Pow2Alignment))
4594 return Error(Pow2AlignmentLoc,
"alignment not supported on this target");
4597 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
4600 return Error(Pow2AlignmentLoc,
"alignment must be a power of 2");
4601 Pow2Alignment =
Log2_64(Pow2Alignment);
4611 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
4612 "be less than zero");
4617 if (Pow2Alignment < 0)
4618 return Error(Pow2AlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
4619 "alignment, can't be less than zero");
4621 Sym->redefineIfPossible();
4622 if (!
Sym->isUndefined())
4623 return Error(IDLoc,
"invalid symbol redefinition");
4627 getStreamer().emitLocalCommonSymbol(
Sym,
Size,
4628 Align(1ULL << Pow2Alignment));
4632 getStreamer().emitCommonSymbol(
Sym,
Size,
Align(1ULL << Pow2Alignment));
4640bool MasmParser::parseDirectiveComment(
SMLoc DirectiveLoc) {
4642 size_t DelimiterEnd = FirstLine.find_first_of(
"\b\t\v\f\r\x1A ");
4643 assert(DelimiterEnd != std::string::npos);
4645 if (Delimiter.
empty())
4646 return Error(DirectiveLoc,
"no delimiter in 'comment' directive");
4649 return Error(DirectiveLoc,
"unmatched delimiter in 'comment' directive");
4659bool MasmParser::parseDirectiveInclude() {
4662 SMLoc IncludeLoc = getTok().getLoc();
4664 if (parseAngleBracketString(Filename))
4666 if (check(
Filename.empty(),
"missing filename in 'include' directive") ||
4668 "unexpected token in 'include' directive") ||
4671 check(enterIncludeFile(Filename), IncludeLoc,
4672 "Could not find include file '" + Filename +
"'"))
4680bool MasmParser::parseDirectiveIf(
SMLoc DirectiveLoc, DirectiveKind DirKind) {
4681 TheCondStack.push_back(TheCondState);
4683 if (TheCondState.
Ignore) {
4684 eatToEndOfStatement();
4687 if (parseAbsoluteExpression(ExprValue) || parseEOL())
4696 ExprValue = ExprValue == 0;
4700 TheCondState.
CondMet = ExprValue;
4709bool MasmParser::parseDirectiveIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
4710 TheCondStack.push_back(TheCondState);
4713 if (TheCondState.
Ignore) {
4714 eatToEndOfStatement();
4717 if (parseTextItem(Str))
4718 return TokError(
"expected text item parameter for 'ifb' directive");
4723 TheCondState.
CondMet = ExpectBlank == Str.empty();
4732bool MasmParser::parseDirectiveIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
4733 bool CaseInsensitive) {
4734 std::string String1, String2;
4736 if (parseTextItem(String1)) {
4738 return TokError(
"expected text item parameter for 'ifidn' directive");
4739 return TokError(
"expected text item parameter for 'ifdif' directive");
4745 "expected comma after first string for 'ifidn' directive");
4746 return TokError(
"expected comma after first string for 'ifdif' directive");
4750 if (parseTextItem(String2)) {
4752 return TokError(
"expected text item parameter for 'ifidn' directive");
4753 return TokError(
"expected text item parameter for 'ifdif' directive");
4756 TheCondStack.push_back(TheCondState);
4758 if (CaseInsensitive)
4762 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
4771bool MasmParser::parseDirectiveIfdef(
SMLoc DirectiveLoc,
bool expect_defined) {
4772 TheCondStack.push_back(TheCondState);
4775 if (TheCondState.
Ignore) {
4776 eatToEndOfStatement();
4778 bool is_defined =
false;
4780 SMLoc StartLoc, EndLoc;
4782 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
4785 if (check(parseIdentifier(
Name),
"expected identifier after 'ifdef'") ||
4789 if (BuiltinSymbolMap.contains(
Name.lower())) {
4795 is_defined = (
Sym && !
Sym->isUndefined());
4799 TheCondState.
CondMet = (is_defined == expect_defined);
4808bool MasmParser::parseDirectiveElseIf(
SMLoc DirectiveLoc,
4809 DirectiveKind DirKind) {
4812 return Error(DirectiveLoc,
"Encountered a .elseif that doesn't follow an"
4813 " .if or an .elseif");
4816 bool LastIgnoreState =
false;
4817 if (!TheCondStack.empty())
4818 LastIgnoreState = TheCondStack.back().Ignore;
4819 if (LastIgnoreState || TheCondState.
CondMet) {
4820 TheCondState.
Ignore =
true;
4821 eatToEndOfStatement();
4824 if (parseAbsoluteExpression(ExprValue))
4836 ExprValue = ExprValue == 0;
4840 TheCondState.
CondMet = ExprValue;
4849bool MasmParser::parseDirectiveElseIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
4852 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
4853 " if or an elseif");
4856 bool LastIgnoreState =
false;
4857 if (!TheCondStack.empty())
4858 LastIgnoreState = TheCondStack.back().Ignore;
4859 if (LastIgnoreState || TheCondState.
CondMet) {
4860 TheCondState.
Ignore =
true;
4861 eatToEndOfStatement();
4864 if (parseTextItem(Str)) {
4866 return TokError(
"expected text item parameter for 'elseifb' directive");
4867 return TokError(
"expected text item parameter for 'elseifnb' directive");
4873 TheCondState.
CondMet = ExpectBlank == Str.empty();
4883bool MasmParser::parseDirectiveElseIfdef(
SMLoc DirectiveLoc,
4884 bool expect_defined) {
4887 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
4888 " if or an elseif");
4891 bool LastIgnoreState =
false;
4892 if (!TheCondStack.empty())
4893 LastIgnoreState = TheCondStack.back().Ignore;
4894 if (LastIgnoreState || TheCondState.
CondMet) {
4895 TheCondState.
Ignore =
true;
4896 eatToEndOfStatement();
4898 bool is_defined =
false;
4900 SMLoc StartLoc, EndLoc;
4902 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
4905 if (check(parseIdentifier(
Name),
4906 "expected identifier after 'elseifdef'") ||
4910 if (BuiltinSymbolMap.contains(
Name.lower())) {
4916 is_defined = (
Sym && !
Sym->isUndefined());
4920 TheCondState.
CondMet = (is_defined == expect_defined);
4929bool MasmParser::parseDirectiveElseIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
4930 bool CaseInsensitive) {
4933 return Error(DirectiveLoc,
"Encountered an elseif that doesn't follow an"
4934 " if or an elseif");
4937 bool LastIgnoreState =
false;
4938 if (!TheCondStack.empty())
4939 LastIgnoreState = TheCondStack.back().Ignore;
4940 if (LastIgnoreState || TheCondState.
CondMet) {
4941 TheCondState.
Ignore =
true;
4942 eatToEndOfStatement();
4944 std::string String1, String2;
4946 if (parseTextItem(String1)) {
4949 "expected text item parameter for 'elseifidn' directive");
4950 return TokError(
"expected text item parameter for 'elseifdif' directive");
4956 "expected comma after first string for 'elseifidn' directive");
4958 "expected comma after first string for 'elseifdif' directive");
4962 if (parseTextItem(String2)) {
4965 "expected text item parameter for 'elseifidn' directive");
4966 return TokError(
"expected text item parameter for 'elseifdif' directive");
4969 if (CaseInsensitive)
4973 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
4982bool MasmParser::parseDirectiveElse(
SMLoc DirectiveLoc) {
4988 return Error(DirectiveLoc,
"Encountered an else that doesn't follow an if"
4991 bool LastIgnoreState =
false;
4992 if (!TheCondStack.empty())
4993 LastIgnoreState = TheCondStack.back().Ignore;
4994 if (LastIgnoreState || TheCondState.
CondMet)
4995 TheCondState.
Ignore =
true;
4997 TheCondState.
Ignore =
false;
5004bool MasmParser::parseDirectiveEnd(
SMLoc DirectiveLoc) {
5016bool MasmParser::parseDirectiveError(
SMLoc DirectiveLoc) {
5017 if (!TheCondStack.empty()) {
5018 if (TheCondStack.back().Ignore) {
5019 eatToEndOfStatement();
5024 std::string Message =
".err directive invoked in source file";
5029 return Error(DirectiveLoc, Message);
5034bool MasmParser::parseDirectiveErrorIfb(
SMLoc DirectiveLoc,
bool ExpectBlank) {
5035 if (!TheCondStack.empty()) {
5036 if (TheCondStack.back().Ignore) {
5037 eatToEndOfStatement();
5043 if (parseTextItem(Text))
5044 return Error(getTok().getLoc(),
"missing text item in '.errb' directive");
5046 std::string Message =
".errb directive invoked in source file";
5049 return addErrorSuffix(
" in '.errb' directive");
5054 if (
Text.empty() == ExpectBlank)
5055 return Error(DirectiveLoc, Message);
5061bool MasmParser::parseDirectiveErrorIfdef(
SMLoc DirectiveLoc,
5062 bool ExpectDefined) {
5063 if (!TheCondStack.empty()) {
5064 if (TheCondStack.back().Ignore) {
5065 eatToEndOfStatement();
5070 bool IsDefined =
false;
5072 SMLoc StartLoc, EndLoc;
5074 getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
5077 if (check(parseIdentifier(
Name),
"expected identifier after '.errdef'"))
5080 if (BuiltinSymbolMap.contains(
Name.lower())) {
5086 IsDefined = (
Sym && !
Sym->isUndefined());
5090 std::string Message =
".errdef directive invoked in source file";
5093 return addErrorSuffix(
" in '.errdef' directive");
5098 if (IsDefined == ExpectDefined)
5099 return Error(DirectiveLoc, Message);
5105bool MasmParser::parseDirectiveErrorIfidn(
SMLoc DirectiveLoc,
bool ExpectEqual,
5106 bool CaseInsensitive) {
5107 if (!TheCondStack.empty()) {
5108 if (TheCondStack.back().Ignore) {
5109 eatToEndOfStatement();
5114 std::string String1, String2;
5116 if (parseTextItem(String1)) {
5118 return TokError(
"expected string parameter for '.erridn' directive");
5119 return TokError(
"expected string parameter for '.errdif' directive");
5125 "expected comma after first string for '.erridn' directive");
5127 "expected comma after first string for '.errdif' directive");
5131 if (parseTextItem(String2)) {
5133 return TokError(
"expected string parameter for '.erridn' directive");
5134 return TokError(
"expected string parameter for '.errdif' directive");
5137 std::string Message;
5139 Message =
".erridn directive invoked in source file";
5141 Message =
".errdif directive invoked in source file";
5144 return addErrorSuffix(
" in '.erridn' directive");
5149 if (CaseInsensitive)
5153 TheCondState.
CondMet = ExpectEqual == (String1 == String2);
5156 if ((CaseInsensitive &&
5158 (ExpectEqual == (String1 == String2)))
5159 return Error(DirectiveLoc, Message);
5165bool MasmParser::parseDirectiveErrorIfe(
SMLoc DirectiveLoc,
bool ExpectZero) {
5166 if (!TheCondStack.empty()) {
5167 if (TheCondStack.back().Ignore) {
5168 eatToEndOfStatement();
5174 if (parseAbsoluteExpression(ExprValue))
5175 return addErrorSuffix(
" in '.erre' directive");
5177 std::string Message =
".erre directive invoked in source file";
5180 return addErrorSuffix(
" in '.erre' directive");
5185 if ((ExprValue == 0) == ExpectZero)
5186 return Error(DirectiveLoc, Message);
5192bool MasmParser::parseDirectiveEndIf(
SMLoc DirectiveLoc) {
5197 return Error(DirectiveLoc,
"Encountered a .endif that doesn't follow "
5199 if (!TheCondStack.empty()) {
5200 TheCondState = TheCondStack.back();
5201 TheCondStack.pop_back();
5207void MasmParser::initializeDirectiveKindMap() {
5208 DirectiveKindMap[
"="] = DK_ASSIGN;
5209 DirectiveKindMap[
"equ"] = DK_EQU;
5210 DirectiveKindMap[
"textequ"] = DK_TEXTEQU;
5214 DirectiveKindMap[
"byte"] = DK_BYTE;
5215 DirectiveKindMap[
"sbyte"] = DK_SBYTE;
5216 DirectiveKindMap[
"word"] = DK_WORD;
5217 DirectiveKindMap[
"sword"] = DK_SWORD;
5218 DirectiveKindMap[
"dword"] = DK_DWORD;
5219 DirectiveKindMap[
"sdword"] = DK_SDWORD;
5220 DirectiveKindMap[
"fword"] = DK_FWORD;
5221 DirectiveKindMap[
"qword"] = DK_QWORD;
5222 DirectiveKindMap[
"sqword"] = DK_SQWORD;
5223 DirectiveKindMap[
"real4"] = DK_REAL4;
5224 DirectiveKindMap[
"real8"] = DK_REAL8;
5225 DirectiveKindMap[
"real10"] = DK_REAL10;
5226 DirectiveKindMap[
"align"] = DK_ALIGN;
5227 DirectiveKindMap[
"even"] = DK_EVEN;
5228 DirectiveKindMap[
"org"] = DK_ORG;
5229 DirectiveKindMap[
"extern"] = DK_EXTERN;
5230 DirectiveKindMap[
"extrn"] = DK_EXTERN;
5231 DirectiveKindMap[
"public"] = DK_PUBLIC;
5233 DirectiveKindMap[
"comment"] = DK_COMMENT;
5234 DirectiveKindMap[
"include"] = DK_INCLUDE;
5235 DirectiveKindMap[
"repeat"] = DK_REPEAT;
5236 DirectiveKindMap[
"rept"] = DK_REPEAT;
5237 DirectiveKindMap[
"while"] = DK_WHILE;
5238 DirectiveKindMap[
"for"] = DK_FOR;
5239 DirectiveKindMap[
"irp"] = DK_FOR;
5240 DirectiveKindMap[
"forc"] = DK_FORC;
5241 DirectiveKindMap[
"irpc"] = DK_FORC;
5242 DirectiveKindMap[
"if"] = DK_IF;
5243 DirectiveKindMap[
"ife"] = DK_IFE;
5244 DirectiveKindMap[
"ifb"] = DK_IFB;
5245 DirectiveKindMap[
"ifnb"] = DK_IFNB;
5246 DirectiveKindMap[
"ifdef"] = DK_IFDEF;
5247 DirectiveKindMap[
"ifndef"] = DK_IFNDEF;
5248 DirectiveKindMap[
"ifdif"] = DK_IFDIF;
5249 DirectiveKindMap[
"ifdifi"] = DK_IFDIFI;
5250 DirectiveKindMap[
"ifidn"] = DK_IFIDN;
5251 DirectiveKindMap[
"ifidni"] = DK_IFIDNI;
5252 DirectiveKindMap[
"elseif"] = DK_ELSEIF;
5253 DirectiveKindMap[
"elseifdef"] = DK_ELSEIFDEF;
5254 DirectiveKindMap[
"elseifndef"] = DK_ELSEIFNDEF;
5255 DirectiveKindMap[
"elseifdif"] = DK_ELSEIFDIF;
5256 DirectiveKindMap[
"elseifidn"] = DK_ELSEIFIDN;
5257 DirectiveKindMap[
"else"] = DK_ELSE;
5258 DirectiveKindMap[
"end"] = DK_END;
5259 DirectiveKindMap[
"endif"] = DK_ENDIF;
5299 DirectiveKindMap[
"macro"] = DK_MACRO;
5300 DirectiveKindMap[
"exitm"] = DK_EXITM;
5301 DirectiveKindMap[
"endm"] = DK_ENDM;
5302 DirectiveKindMap[
"purge"] = DK_PURGE;
5303 DirectiveKindMap[
".err"] = DK_ERR;
5304 DirectiveKindMap[
".errb"] = DK_ERRB;
5305 DirectiveKindMap[
".errnb"] = DK_ERRNB;
5306 DirectiveKindMap[
".errdef"] = DK_ERRDEF;
5307 DirectiveKindMap[
".errndef"] = DK_ERRNDEF;
5308 DirectiveKindMap[
".errdif"] = DK_ERRDIF;
5309 DirectiveKindMap[
".errdifi"] = DK_ERRDIFI;
5310 DirectiveKindMap[
".erridn"] = DK_ERRIDN;
5311 DirectiveKindMap[
".erridni"] = DK_ERRIDNI;
5312 DirectiveKindMap[
".erre"] = DK_ERRE;
5313 DirectiveKindMap[
".errnz"] = DK_ERRNZ;
5314 DirectiveKindMap[
".pushframe"] = DK_PUSHFRAME;
5315 DirectiveKindMap[
".pushreg"] = DK_PUSHREG;
5316 DirectiveKindMap[
".savereg"] = DK_SAVEREG;
5317 DirectiveKindMap[
".savexmm128"] = DK_SAVEXMM128;
5318 DirectiveKindMap[
".setframe"] = DK_SETFRAME;
5319 DirectiveKindMap[
".radix"] = DK_RADIX;
5320 DirectiveKindMap[
"db"] = DK_DB;
5321 DirectiveKindMap[
"dd"] = DK_DD;
5322 DirectiveKindMap[
"df"] = DK_DF;
5323 DirectiveKindMap[
"dq"] = DK_DQ;
5324 DirectiveKindMap[
"dw"] = DK_DW;
5325 DirectiveKindMap[
"echo"] = DK_ECHO;
5326 DirectiveKindMap[
"struc"] = DK_STRUCT;
5327 DirectiveKindMap[
"struct"] = DK_STRUCT;
5328 DirectiveKindMap[
"union"] = DK_UNION;
5329 DirectiveKindMap[
"ends"] = DK_ENDS;
5332bool MasmParser::isMacroLikeDirective() {
5344 peekTok().getIdentifier().equals_insensitive(
"macro"))
5351 AsmToken EndToken, StartToken = getTok();
5353 unsigned NestLevel = 0;
5357 printError(DirectiveLoc,
"no matching 'endm' in definition");
5361 if (isMacroLikeDirective())
5366 getTok().getIdentifier().equals_insensitive(
"endm")) {
5367 if (NestLevel == 0) {
5368 EndToken = getTok();
5371 printError(getTok().getLoc(),
"unexpected token in 'endm' directive");
5380 eatToEndOfStatement();
5389 return &MacroLikeBodies.back();
5392bool MasmParser::expandStatement(
SMLoc Loc) {
5394 SMLoc EndLoc = getTok().getLoc();
5400 for (
const auto &S : BuiltinSymbolMap) {
5401 const BuiltinSymbol &
Sym = S.getValue();
5402 if (std::optional<std::string> Text = evaluateBuiltinTextMacro(
Sym, Loc)) {
5403 BuiltinValues[S.getKey().lower()] = std::move(*Text);
5406 for (
const auto &
B : BuiltinValues) {
5408 MCAsmMacroArgument
A;
5409 P.Name =
B.getKey();
5417 for (
const auto &V : Variables) {
5418 const Variable &Var =
V.getValue();
5421 MCAsmMacroArgument
A;
5430 MacroLikeBodies.emplace_back(
StringRef(), Body, Parameters);
5436 if (expandMacro(
OS,
M.Body,
M.Parameters,
Arguments,
M.Locals, EndLoc))
5438 std::unique_ptr<MemoryBuffer>
Expansion =
5444 EndStatementAtEOFStack.push_back(
false);
5449void MasmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
5451 instantiateMacroLikeBody(M, DirectiveLoc, getTok().getLoc(),
OS);
5453void MasmParser::instantiateMacroLikeBody(
MCAsmMacro *M,
SMLoc DirectiveLoc,
5458 std::unique_ptr<MemoryBuffer> Instantiation =
5463 MacroInstantiation *
MI =
new MacroInstantiation{DirectiveLoc, CurBuffer,
5464 ExitLoc, TheCondStack.size()};
5465 ActiveMacros.push_back(
MI);
5470 EndStatementAtEOFStack.push_back(
true);
5478bool MasmParser::parseDirectiveRepeat(
SMLoc DirectiveLoc,
StringRef Dir) {
5480 SMLoc CountLoc = getTok().getLoc();
5481 if (parseExpression(CountExpr))
5485 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5486 return Error(CountLoc,
"unexpected token in '" + Dir +
"' directive");
5489 if (check(Count < 0, CountLoc,
"Count is negative") || parseEOL())
5502 if (expandMacro(
OS,
M->Body, {}, {},
M->Locals, getTok().getLoc()))
5505 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5514bool MasmParser::parseDirectiveWhile(
SMLoc DirectiveLoc) {
5516 SMLoc CondLoc = getTok().getLoc();
5517 if (parseExpression(CondExpr))
5530 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
5531 return Error(CondLoc,
"expected absolute expression in 'while' directive");
5535 if (expandMacro(
OS,
M->Body, {}, {},
M->Locals, getTok().getLoc()))
5537 instantiateMacroLikeBody(M, DirectiveLoc, DirectiveLoc,
OS);
5547bool MasmParser::parseDirectiveFor(
SMLoc DirectiveLoc,
StringRef Dir) {
5549 MCAsmMacroArguments
A;
5550 if (check(parseIdentifier(Parameter.
Name),
5551 "expected identifier in '" + Dir +
"' directive"))
5560 ParamLoc = Lexer.getLoc();
5561 if (parseMacroArgument(
nullptr, Parameter.
Value))
5567 QualLoc = Lexer.getLoc();
5568 if (parseIdentifier(Qualifier))
5569 return Error(QualLoc,
"missing parameter qualifier for "
5571 Parameter.
Name +
"' in '" + Dir +
5574 if (
Qualifier.equals_insensitive(
"req"))
5577 return Error(QualLoc,
5578 Qualifier +
" is not a valid parameter qualifier for '" +
5579 Parameter.
Name +
"' in '" + Dir +
"' directive");
5584 "expected comma in '" + Dir +
"' directive") ||
5586 "values in '" + Dir +
5587 "' directive must be enclosed in angle brackets"))
5593 return addErrorSuffix(
" in arguments for '" + Dir +
"' directive");
5602 "values in '" + Dir +
5603 "' directive must be enclosed in angle brackets") ||
5617 for (
const MCAsmMacroArgument &Arg :
A) {
5618 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
5622 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5635 if (check(parseIdentifier(Parameter.
Name),
5636 "expected identifier in '" +
Directive +
"' directive") ||
5638 "expected comma in '" +
Directive +
"' directive"))
5640 if (parseAngleBracketString(
Argument)) {
5668 for (std::size_t
I = 0,
End = Values.
size();
I !=
End; ++
I) {
5669 MCAsmMacroArgument Arg;
5672 if (expandMacro(
OS,
M->Body, Parameter, Arg,
M->Locals, getTok().getLoc()))
5676 instantiateMacroLikeBody(M, DirectiveLoc,
OS);
5681bool MasmParser::parseDirectiveMSEmit(
SMLoc IDLoc, ParseStatementInfo &Info,
5684 SMLoc ExprLoc = getLexer().getLoc();
5685 if (parseExpression(
Value))
5689 return Error(ExprLoc,
"unexpected expression in _emit");
5691 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5692 return Error(ExprLoc,
"literal value out of range for directive");
5698bool MasmParser::parseDirectiveMSAlign(
SMLoc IDLoc, ParseStatementInfo &Info) {
5700 SMLoc ExprLoc = getLexer().getLoc();
5701 if (parseExpression(
Value))
5705 return Error(ExprLoc,
"unexpected expression in align");
5708 return Error(ExprLoc,
"literal value not a power of two greater then zero");
5714bool MasmParser::parseDirectiveRadix(
SMLoc DirectiveLoc) {
5715 const SMLoc Loc = getLexer().getLoc();
5721 "radix must be a decimal number in the range 2 to 16; was " +
5724 if (Radix < 2 || Radix > 16)
5725 return Error(Loc,
"radix must be in the range 2 to 16; was " +
5726 std::to_string(Radix));
5727 getLexer().setMasmDefaultRadix(Radix);
5733bool MasmParser::parseDirectiveEcho(
SMLoc DirectiveLoc) {
5736 if (!
StringRef(Message).ends_with(
"\n"))
5765 Variable &Var = Variables[
Name.lower()];
5766 if (Var.Name.empty()) {
5768 }
else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {
5769 return Error(
SMLoc(),
"invalid variable redefinition");
5770 }
else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&
5772 "', already defined on the command line")) {
5775 Var.Redefinable = Variable::WARN_ON_REDEFINITION;
5777 Var.TextValue =
Value.str();
5782 const std::pair<StringRef, StringRef> BaseMember =
Name.split(
'.');
5784 return lookUpField(
Base, Member, Info);
5793 if (
Base.contains(
'.') && !lookUpField(
Base, BaseInfo))
5796 auto StructIt = Structs.
find(
Base.lower());
5797 auto TypeIt = KnownType.
find(
Base.lower());
5798 if (TypeIt != KnownType.
end()) {
5799 StructIt = Structs.
find(TypeIt->second.Name.lower());
5801 if (StructIt != Structs.
end())
5802 return lookUpField(StructIt->second, Member, Info);
5807bool MasmParser::lookUpField(
const StructInfo &Structure,
StringRef Member,
5810 Info.Type.Name = Structure.Name;
5811 Info.Type.Size = Structure.Size;
5812 Info.Type.ElementSize = Structure.Size;
5813 Info.Type.Length = 1;
5817 std::pair<StringRef, StringRef>
Split =
Member.split(
'.');
5820 auto StructIt = Structs.
find(FieldName.
lower());
5821 if (StructIt != Structs.
end())
5822 return lookUpField(StructIt->second, FieldMember, Info);
5824 auto FieldIt = Structure.FieldsByName.find(FieldName.
lower());
5825 if (FieldIt == Structure.FieldsByName.end())
5828 const FieldInfo &
Field = Structure.Fields[FieldIt->second];
5829 if (FieldMember.empty()) {
5834 if (
Field.Contents.FT == FT_STRUCT)
5835 Info.Type.Name =
Field.Contents.StructInfo.Structure.Name;
5837 Info.Type.Name =
"";
5841 if (
Field.Contents.FT != FT_STRUCT)
5843 const StructFieldInfo &StructInfo =
Field.Contents.StructInfo;
5845 if (lookUpField(StructInfo.Structure, FieldMember, Info))
5871 auto StructIt = Structs.
find(
Name.lower());
5872 if (StructIt != Structs.
end()) {
5873 const StructInfo &Structure = StructIt->second;
5875 Info.ElementSize = Structure.Size;
5877 Info.Size = Structure.Size;
5884bool MasmParser::parseMSInlineAsm(
5885 std::string &AsmString,
unsigned &NumOutputs,
unsigned &NumInputs,
5904 unsigned InputIdx = 0;
5905 unsigned OutputIdx = 0;
5908 if (parseCurlyBlockScope(AsmStrRewrites))
5911 ParseStatementInfo
Info(&AsmStrRewrites);
5912 bool StatementErr = parseStatement(Info, &SI);
5914 if (StatementErr ||
Info.ParseError) {
5916 printPendingErrors();
5921 assert(!hasPendingError() &&
"unexpected error from parseStatement");
5923 if (
Info.Opcode == ~0U)
5929 for (
unsigned i = 1, e =
Info.ParsedOperands.size(); i != e; ++i) {
5934 !getTargetParser().omitRegisterFromClobberLists(Operand.
getReg())) {
5935 unsigned NumDefs =
Desc.getNumDefs();
5944 if (SymName.
empty())
5952 if (Operand.
isImm()) {
5960 bool isOutput = (i == 1) &&
Desc.mayStore();
5966 OutputConstraints.
push_back((
"=" + Constraint).str());
5972 if (
Desc.operands()[i - 1].isBranchTarget())
5984 NumOutputs = OutputDecls.
size();
5985 NumInputs = InputDecls.
size();
5990 Clobbers.
assign(ClobberRegs.
size(), std::string());
5991 for (
unsigned I = 0, E = ClobberRegs.
size();
I != E; ++
I) {
5997 if (NumOutputs || NumInputs) {
5998 unsigned NumExprs = NumOutputs + NumInputs;
5999 OpDecls.resize(NumExprs);
6000 Constraints.
resize(NumExprs);
6001 for (
unsigned i = 0; i < NumOutputs; ++i) {
6002 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6003 Constraints[i] = OutputConstraints[i];
6005 for (
unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++
j) {
6006 OpDecls[
j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6007 Constraints[
j] = InputConstraints[i];
6012 std::string AsmStringIR;
6016 const char *AsmStart = ASMString.
begin();
6017 const char *AsmEnd = ASMString.
end();
6019 for (
auto I = AsmStrRewrites.
begin(), E = AsmStrRewrites.
end();
I != E; ++
I) {
6027 assert(Loc >= AsmStart &&
"Expected Loc to be at or after Start!");
6030 if (
unsigned Len = Loc - AsmStart)
6035 AsmStart = Loc + AR.
Len;
6039 unsigned AdditionalSkip = 0;
6061 size_t OffsetLen = OffsetName.
size();
6062 auto rewrite_it = std::find_if(
6064 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
6065 (FusingAR.Kind == AOK_Input ||
6066 FusingAR.Kind == AOK_CallInput);
6068 if (rewrite_it == AsmStrRewrites.
end()) {
6069 OS <<
"offset " << OffsetName;
6071 OS <<
"${" << InputIdx++ <<
":P}";
6072 rewrite_it->Done =
true;
6074 OS <<
'$' << InputIdx++;
6075 rewrite_it->Done =
true;
6087 OS <<
'$' << InputIdx++;
6090 OS <<
"${" << InputIdx++ <<
":P}";
6093 OS <<
'$' << OutputIdx++;
6098 case 8:
OS <<
"byte ptr ";
break;
6099 case 16:
OS <<
"word ptr ";
break;
6100 case 32:
OS <<
"dword ptr ";
break;
6101 case 64:
OS <<
"qword ptr ";
break;
6102 case 80:
OS <<
"xword ptr ";
break;
6103 case 128:
OS <<
"xmmword ptr ";
break;
6104 case 256:
OS <<
"ymmword ptr ";
break;
6114 if (getContext().getAsmInfo()->getAlignmentIsInBytes())
6119 unsigned Val = AR.
Val;
6121 assert(Val < 10 &&
"Expected alignment less then 2^10.");
6122 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
6134 AsmStart = Loc + AR.
Len + AdditionalSkip;
6138 if (AsmStart != AsmEnd)
6141 AsmString =
OS.str();
6145void MasmParser::initializeBuiltinSymbolMaps() {
6147 BuiltinSymbolMap[
"@version"] = BI_VERSION;
6148 BuiltinSymbolMap[
"@line"] = BI_LINE;
6151 BuiltinSymbolMap[
"@date"] = BI_DATE;
6152 BuiltinSymbolMap[
"@time"] = BI_TIME;
6153 BuiltinSymbolMap[
"@filecur"] = BI_FILECUR;
6154 BuiltinSymbolMap[
"@filename"] = BI_FILENAME;
6155 BuiltinSymbolMap[
"@curseg"] = BI_CURSEG;
6158 BuiltinFunctionMap[
"@catstr"] = BI_CATSTR;
6161 if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
6179const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,
6189 if (ActiveMacros.empty())
6193 ActiveMacros.front()->ExitBuffer);
6200std::optional<std::string>
6201MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
SMLoc StartLoc) {
6207 char TmpBuffer[
sizeof(
"mm/dd/yy")];
6208 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%D", &TM);
6209 return std::string(TmpBuffer, Len);
6213 char TmpBuffer[
sizeof(
"hh:mm:ss")];
6214 const size_t Len = strftime(TmpBuffer,
sizeof(TmpBuffer),
"%T", &TM);
6215 return std::string(TmpBuffer, Len);
6220 ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)
6228 return getStreamer().getCurrentSectionOnly()->getName().str();
6233bool MasmParser::evaluateBuiltinMacroFunction(BuiltinFunction
Function,
6237 "' requires arguments in parentheses")) {
6250 MCAsmMacroArguments
A;
6259 for (
const MCAsmMacroArgument &Arg :
A) {
6278 struct tm TM,
unsigned CB) {
6279 return new MasmParser(SM,
C, Out, MAI, TM, CB);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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...
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 bool isMacroParameterChar(char C)
static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc)
This function checks if the next token is <string> type or arithmetic.
static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind, bool ShouldUseLogicalShr, bool EndExpressionAtGreater)
static int rewritesSort(const AsmRewrite *AsmRewriteA, const AsmRewrite *AsmRewriteB)
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_>.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)
Factory for NaN values.
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
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.
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
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool preserveAsmComments() const
Return true if assembly (inline or otherwise) should be parsed.
StringRef getPrivateLabelPrefix() const
bool shouldUseLogicalShr() const
virtual bool useCodeAlign(const MCSection &Sec) const
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 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 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 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual unsigned getAssemblerDialect()
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAngleBracketString(std::string &Data)=0
Parse an angle-bracket delimited string at the current position if one is present,...
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
virtual void setAssemblerDialect(unsigned i)
virtual void setParsingMSInlineAsm(bool V)=0
virtual bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl< std::pair< void *, bool > > &OpDecls, SmallVectorImpl< std::string > &Constraints, SmallVectorImpl< std::string > &Clobbers, const MCInstrInfo *MII, MCInstPrinter *IP, MCAsmParserSemaCallback &SI)=0
Parse MS-style inline assembly.
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
static LLVM_ABI 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 LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Environment getObjectFileType() const
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * createDirectionalLocalSymbol(unsigned LocalLabelVal)
Create the definition of a directional local symbol for numbered label (used for "1:" definitions).
const MCAsmInfo * getAsmInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printRegName(raw_ostream &OS, MCRegister Reg)
Print the assembler register name.
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool needAddressOf() const
needAddressOf - Do we need to emit code to get the address of the variable/label? Only valid when par...
virtual MCRegister getReg() const =0
virtual bool isOffsetOfLocal() const
isOffsetOfLocal - Do we need to emit code to get the offset of the local variable,...
virtual StringRef getSymName()
virtual bool isImm() const =0
isImm - Is this an immediate operand?
unsigned getMCOperandNum()
StringRef getConstraint()
virtual void * getOpDecl()
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
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 const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
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
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
LLVM_ABI 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
LLVM_ABI 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
LLVM_ABI void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
LLVM_ABI 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.
LLVM_ABI unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
LLVM_ABI 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.
LLVM_ABI 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.
#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.
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.
LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, 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.
LLVM_ABI 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.
LLVM_ABI MCAsmParser * createMCMasmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, struct tm, unsigned CB=0)
Create an MCAsmParser instance for parsing Microsoft MASM-style assembly.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
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[]
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
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
uint64_t Offset
The offset of this field in the final layout.
uint64_t Size
The required size of this field in bytes.