xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp (revision 5b56413d04e608379c9a306373554a8e4d321bc0)
1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class implements the parser for assembly files.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/ADT/APFloat.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/StringSwitch.h"
24 #include "llvm/ADT/Twine.h"
25 #include "llvm/BinaryFormat/Dwarf.h"
26 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCCodeView.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCDirectives.h"
31 #include "llvm/MC/MCDwarf.h"
32 #include "llvm/MC/MCExpr.h"
33 #include "llvm/MC/MCInstPrinter.h"
34 #include "llvm/MC/MCInstrDesc.h"
35 #include "llvm/MC/MCInstrInfo.h"
36 #include "llvm/MC/MCParser/AsmCond.h"
37 #include "llvm/MC/MCParser/AsmLexer.h"
38 #include "llvm/MC/MCParser/MCAsmLexer.h"
39 #include "llvm/MC/MCParser/MCAsmParser.h"
40 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
41 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
42 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
43 #include "llvm/MC/MCRegisterInfo.h"
44 #include "llvm/MC/MCSection.h"
45 #include "llvm/MC/MCStreamer.h"
46 #include "llvm/MC/MCSubtargetInfo.h"
47 #include "llvm/MC/MCSymbol.h"
48 #include "llvm/MC/MCTargetOptions.h"
49 #include "llvm/Support/Casting.h"
50 #include "llvm/Support/CommandLine.h"
51 #include "llvm/Support/ErrorHandling.h"
52 #include "llvm/Support/Format.h"
53 #include "llvm/Support/MD5.h"
54 #include "llvm/Support/MathExtras.h"
55 #include "llvm/Support/MemoryBuffer.h"
56 #include "llvm/Support/Path.h"
57 #include "llvm/Support/SMLoc.h"
58 #include "llvm/Support/SourceMgr.h"
59 #include "llvm/Support/raw_ostream.h"
60 #include <algorithm>
61 #include <cassert>
62 #include <climits>
63 #include <cstddef>
64 #include <cstdint>
65 #include <ctime>
66 #include <deque>
67 #include <memory>
68 #include <optional>
69 #include <sstream>
70 #include <string>
71 #include <tuple>
72 #include <utility>
73 #include <vector>
74 
75 using namespace llvm;
76 
77 namespace {
78 
79 /// Helper types for tracking macro definitions.
80 typedef std::vector<AsmToken> MCAsmMacroArgument;
81 typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
82 
83 /// Helper class for storing information about an active macro instantiation.
84 struct MacroInstantiation {
85   /// The location of the instantiation.
86   SMLoc InstantiationLoc;
87 
88   /// The buffer where parsing should resume upon instantiation completion.
89   unsigned ExitBuffer;
90 
91   /// The location where parsing should resume upon instantiation completion.
92   SMLoc ExitLoc;
93 
94   /// The depth of TheCondStack at the start of the instantiation.
95   size_t CondStackDepth;
96 };
97 
98 struct ParseStatementInfo {
99   /// The parsed operands from the last parsed statement.
100   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
101 
102   /// The opcode from the last parsed instruction.
103   unsigned Opcode = ~0U;
104 
105   /// Was there an error parsing the inline assembly?
106   bool ParseError = false;
107 
108   /// The value associated with a macro exit.
109   std::optional<std::string> ExitValue;
110 
111   SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
112 
113   ParseStatementInfo() = delete;
114   ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
115       : AsmRewrites(rewrites) {}
116 };
117 
118 enum FieldType {
119   FT_INTEGRAL, // Initializer: integer expression, stored as an MCExpr.
120   FT_REAL,     // Initializer: real number, stored as an APInt.
121   FT_STRUCT    // Initializer: struct initializer, stored recursively.
122 };
123 
124 struct FieldInfo;
125 struct StructInfo {
126   StringRef Name;
127   bool IsUnion = false;
128   bool Initializable = true;
129   unsigned Alignment = 0;
130   unsigned AlignmentSize = 0;
131   unsigned NextOffset = 0;
132   unsigned Size = 0;
133   std::vector<FieldInfo> Fields;
134   StringMap<size_t> FieldsByName;
135 
136   FieldInfo &addField(StringRef FieldName, FieldType FT,
137                       unsigned FieldAlignmentSize);
138 
139   StructInfo() = default;
140   StructInfo(StringRef StructName, bool Union, unsigned AlignmentValue);
141 };
142 
143 // FIXME: This should probably use a class hierarchy, raw pointers between the
144 // objects, and dynamic type resolution instead of a union. On the other hand,
145 // ownership then becomes much more complicated; the obvious thing would be to
146 // use BumpPtrAllocator, but the lack of a destructor makes that messy.
147 
148 struct StructInitializer;
149 struct IntFieldInfo {
150   SmallVector<const MCExpr *, 1> Values;
151 
152   IntFieldInfo() = default;
153   IntFieldInfo(const SmallVector<const MCExpr *, 1> &V) { Values = V; }
154   IntFieldInfo(SmallVector<const MCExpr *, 1> &&V) { Values = std::move(V); }
155 };
156 struct RealFieldInfo {
157   SmallVector<APInt, 1> AsIntValues;
158 
159   RealFieldInfo() = default;
160   RealFieldInfo(const SmallVector<APInt, 1> &V) { AsIntValues = V; }
161   RealFieldInfo(SmallVector<APInt, 1> &&V) { AsIntValues = std::move(V); }
162 };
163 struct StructFieldInfo {
164   std::vector<StructInitializer> Initializers;
165   StructInfo Structure;
166 
167   StructFieldInfo() = default;
168   StructFieldInfo(std::vector<StructInitializer> V, StructInfo S);
169 };
170 
171 class FieldInitializer {
172 public:
173   FieldType FT;
174   union {
175     IntFieldInfo IntInfo;
176     RealFieldInfo RealInfo;
177     StructFieldInfo StructInfo;
178   };
179 
180   ~FieldInitializer();
181   FieldInitializer(FieldType FT);
182 
183   FieldInitializer(SmallVector<const MCExpr *, 1> &&Values);
184   FieldInitializer(SmallVector<APInt, 1> &&AsIntValues);
185   FieldInitializer(std::vector<StructInitializer> &&Initializers,
186                    struct StructInfo Structure);
187 
188   FieldInitializer(const FieldInitializer &Initializer);
189   FieldInitializer(FieldInitializer &&Initializer);
190 
191   FieldInitializer &operator=(const FieldInitializer &Initializer);
192   FieldInitializer &operator=(FieldInitializer &&Initializer);
193 };
194 
195 struct StructInitializer {
196   std::vector<FieldInitializer> FieldInitializers;
197 };
198 
199 struct FieldInfo {
200   // Offset of the field within the containing STRUCT.
201   unsigned Offset = 0;
202 
203   // Total size of the field (= LengthOf * Type).
204   unsigned SizeOf = 0;
205 
206   // Number of elements in the field (1 if scalar, >1 if an array).
207   unsigned LengthOf = 0;
208 
209   // Size of a single entry in this field, in bytes ("type" in MASM standards).
210   unsigned Type = 0;
211 
212   FieldInitializer Contents;
213 
214   FieldInfo(FieldType FT) : Contents(FT) {}
215 };
216 
217 StructFieldInfo::StructFieldInfo(std::vector<StructInitializer> V,
218                                  StructInfo S) {
219   Initializers = std::move(V);
220   Structure = S;
221 }
222 
223 StructInfo::StructInfo(StringRef StructName, bool Union,
224                        unsigned AlignmentValue)
225     : Name(StructName), IsUnion(Union), Alignment(AlignmentValue) {}
226 
227 FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT,
228                                 unsigned FieldAlignmentSize) {
229   if (!FieldName.empty())
230     FieldsByName[FieldName.lower()] = Fields.size();
231   Fields.emplace_back(FT);
232   FieldInfo &Field = Fields.back();
233   Field.Offset =
234       llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize));
235   if (!IsUnion) {
236     NextOffset = std::max(NextOffset, Field.Offset);
237   }
238   AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
239   return Field;
240 }
241 
242 FieldInitializer::~FieldInitializer() {
243   switch (FT) {
244   case FT_INTEGRAL:
245     IntInfo.~IntFieldInfo();
246     break;
247   case FT_REAL:
248     RealInfo.~RealFieldInfo();
249     break;
250   case FT_STRUCT:
251     StructInfo.~StructFieldInfo();
252     break;
253   }
254 }
255 
256 FieldInitializer::FieldInitializer(FieldType FT) : FT(FT) {
257   switch (FT) {
258   case FT_INTEGRAL:
259     new (&IntInfo) IntFieldInfo();
260     break;
261   case FT_REAL:
262     new (&RealInfo) RealFieldInfo();
263     break;
264   case FT_STRUCT:
265     new (&StructInfo) StructFieldInfo();
266     break;
267   }
268 }
269 
270 FieldInitializer::FieldInitializer(SmallVector<const MCExpr *, 1> &&Values)
271     : FT(FT_INTEGRAL) {
272   new (&IntInfo) IntFieldInfo(std::move(Values));
273 }
274 
275 FieldInitializer::FieldInitializer(SmallVector<APInt, 1> &&AsIntValues)
276     : FT(FT_REAL) {
277   new (&RealInfo) RealFieldInfo(std::move(AsIntValues));
278 }
279 
280 FieldInitializer::FieldInitializer(
281     std::vector<StructInitializer> &&Initializers, struct StructInfo Structure)
282     : FT(FT_STRUCT) {
283   new (&StructInfo) StructFieldInfo(std::move(Initializers), Structure);
284 }
285 
286 FieldInitializer::FieldInitializer(const FieldInitializer &Initializer)
287     : FT(Initializer.FT) {
288   switch (FT) {
289   case FT_INTEGRAL:
290     new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
291     break;
292   case FT_REAL:
293     new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
294     break;
295   case FT_STRUCT:
296     new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
297     break;
298   }
299 }
300 
301 FieldInitializer::FieldInitializer(FieldInitializer &&Initializer)
302     : FT(Initializer.FT) {
303   switch (FT) {
304   case FT_INTEGRAL:
305     new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
306     break;
307   case FT_REAL:
308     new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
309     break;
310   case FT_STRUCT:
311     new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
312     break;
313   }
314 }
315 
316 FieldInitializer &
317 FieldInitializer::operator=(const FieldInitializer &Initializer) {
318   if (FT != Initializer.FT) {
319     switch (FT) {
320     case FT_INTEGRAL:
321       IntInfo.~IntFieldInfo();
322       break;
323     case FT_REAL:
324       RealInfo.~RealFieldInfo();
325       break;
326     case FT_STRUCT:
327       StructInfo.~StructFieldInfo();
328       break;
329     }
330   }
331   FT = Initializer.FT;
332   switch (FT) {
333   case FT_INTEGRAL:
334     IntInfo = Initializer.IntInfo;
335     break;
336   case FT_REAL:
337     RealInfo = Initializer.RealInfo;
338     break;
339   case FT_STRUCT:
340     StructInfo = Initializer.StructInfo;
341     break;
342   }
343   return *this;
344 }
345 
346 FieldInitializer &FieldInitializer::operator=(FieldInitializer &&Initializer) {
347   if (FT != Initializer.FT) {
348     switch (FT) {
349     case FT_INTEGRAL:
350       IntInfo.~IntFieldInfo();
351       break;
352     case FT_REAL:
353       RealInfo.~RealFieldInfo();
354       break;
355     case FT_STRUCT:
356       StructInfo.~StructFieldInfo();
357       break;
358     }
359   }
360   FT = Initializer.FT;
361   switch (FT) {
362   case FT_INTEGRAL:
363     IntInfo = Initializer.IntInfo;
364     break;
365   case FT_REAL:
366     RealInfo = Initializer.RealInfo;
367     break;
368   case FT_STRUCT:
369     StructInfo = Initializer.StructInfo;
370     break;
371   }
372   return *this;
373 }
374 
375 /// The concrete assembly parser instance.
376 // Note that this is a full MCAsmParser, not an MCAsmParserExtension!
377 // It's a peer of AsmParser, not of COFFAsmParser, WasmAsmParser, etc.
378 class MasmParser : public MCAsmParser {
379 private:
380   AsmLexer Lexer;
381   MCContext &Ctx;
382   MCStreamer &Out;
383   const MCAsmInfo &MAI;
384   SourceMgr &SrcMgr;
385   SourceMgr::DiagHandlerTy SavedDiagHandler;
386   void *SavedDiagContext;
387   std::unique_ptr<MCAsmParserExtension> PlatformParser;
388 
389   /// This is the current buffer index we're lexing from as managed by the
390   /// SourceMgr object.
391   unsigned CurBuffer;
392 
393   /// time of assembly
394   struct tm TM;
395 
396   BitVector EndStatementAtEOFStack;
397 
398   AsmCond TheCondState;
399   std::vector<AsmCond> TheCondStack;
400 
401   /// maps directive names to handler methods in parser
402   /// extensions. Extensions register themselves in this map by calling
403   /// addDirectiveHandler.
404   StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
405 
406   /// maps assembly-time variable names to variables.
407   struct Variable {
408     enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE };
409 
410     StringRef Name;
411     RedefinableKind Redefinable = REDEFINABLE;
412     bool IsText = false;
413     std::string TextValue;
414   };
415   StringMap<Variable> Variables;
416 
417   /// Stack of active struct definitions.
418   SmallVector<StructInfo, 1> StructInProgress;
419 
420   /// Maps struct tags to struct definitions.
421   StringMap<StructInfo> Structs;
422 
423   /// Maps data location names to types.
424   StringMap<AsmTypeInfo> KnownType;
425 
426   /// Stack of active macro instantiations.
427   std::vector<MacroInstantiation*> ActiveMacros;
428 
429   /// List of bodies of anonymous macros.
430   std::deque<MCAsmMacro> MacroLikeBodies;
431 
432   /// Keeps track of how many .macro's have been instantiated.
433   unsigned NumOfMacroInstantiations;
434 
435   /// The values from the last parsed cpp hash file line comment if any.
436   struct CppHashInfoTy {
437     StringRef Filename;
438     int64_t LineNumber;
439     SMLoc Loc;
440     unsigned Buf;
441     CppHashInfoTy() : LineNumber(0), Buf(0) {}
442   };
443   CppHashInfoTy CppHashInfo;
444 
445   /// The filename from the first cpp hash file line comment, if any.
446   StringRef FirstCppHashFilename;
447 
448   /// List of forward directional labels for diagnosis at the end.
449   SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
450 
451   /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
452   /// Defaults to 1U, meaning Intel.
453   unsigned AssemblerDialect = 1U;
454 
455   /// is Darwin compatibility enabled?
456   bool IsDarwin = false;
457 
458   /// Are we parsing ms-style inline assembly?
459   bool ParsingMSInlineAsm = false;
460 
461   /// Did we already inform the user about inconsistent MD5 usage?
462   bool ReportedInconsistentMD5 = false;
463 
464   // Current <...> expression depth.
465   unsigned AngleBracketDepth = 0U;
466 
467   // Number of locals defined.
468   uint16_t LocalCounter = 0;
469 
470 public:
471   MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
472              const MCAsmInfo &MAI, struct tm TM, unsigned CB = 0);
473   MasmParser(const MasmParser &) = delete;
474   MasmParser &operator=(const MasmParser &) = delete;
475   ~MasmParser() override;
476 
477   bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
478 
479   void addDirectiveHandler(StringRef Directive,
480                            ExtensionDirectiveHandler Handler) override {
481     ExtensionDirectiveMap[Directive] = Handler;
482     if (!DirectiveKindMap.contains(Directive)) {
483       DirectiveKindMap[Directive] = DK_HANDLER_DIRECTIVE;
484     }
485   }
486 
487   void addAliasForDirective(StringRef Directive, StringRef Alias) override {
488     DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
489   }
490 
491   /// @name MCAsmParser Interface
492   /// {
493 
494   SourceMgr &getSourceManager() override { return SrcMgr; }
495   MCAsmLexer &getLexer() override { return Lexer; }
496   MCContext &getContext() override { return Ctx; }
497   MCStreamer &getStreamer() override { return Out; }
498 
499   CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
500 
501   unsigned getAssemblerDialect() override {
502     if (AssemblerDialect == ~0U)
503       return MAI.getAssemblerDialect();
504     else
505       return AssemblerDialect;
506   }
507   void setAssemblerDialect(unsigned i) override {
508     AssemblerDialect = i;
509   }
510 
511   void Note(SMLoc L, const Twine &Msg, SMRange Range = std::nullopt) override;
512   bool Warning(SMLoc L, const Twine &Msg,
513                SMRange Range = std::nullopt) override;
514   bool printError(SMLoc L, const Twine &Msg,
515                   SMRange Range = std::nullopt) override;
516 
517   enum ExpandKind { ExpandMacros, DoNotExpandMacros };
518   const AsmToken &Lex(ExpandKind ExpandNextToken);
519   const AsmToken &Lex() override { return Lex(ExpandMacros); }
520 
521   void setParsingMSInlineAsm(bool V) override {
522     ParsingMSInlineAsm = V;
523     // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and
524     // hex integer literals.
525     Lexer.setLexMasmIntegers(V);
526   }
527   bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
528 
529   bool isParsingMasm() const override { return true; }
530 
531   bool defineMacro(StringRef Name, StringRef Value) override;
532 
533   bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override;
534   bool lookUpField(StringRef Base, StringRef Member,
535                    AsmFieldInfo &Info) const override;
536 
537   bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override;
538 
539   bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs,
540                         unsigned &NumInputs,
541                         SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
542                         SmallVectorImpl<std::string> &Constraints,
543                         SmallVectorImpl<std::string> &Clobbers,
544                         const MCInstrInfo *MII, const MCInstPrinter *IP,
545                         MCAsmParserSemaCallback &SI) override;
546 
547   bool parseExpression(const MCExpr *&Res);
548   bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
549   bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
550                         AsmTypeInfo *TypeInfo) override;
551   bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
552   bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
553                              SMLoc &EndLoc) override;
554   bool parseAbsoluteExpression(int64_t &Res) override;
555 
556   /// Parse a floating point expression using the float \p Semantics
557   /// and set \p Res to the value.
558   bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
559 
560   /// Parse an identifier or string (as a quoted identifier)
561   /// and set \p Res to the identifier contents.
562   enum IdentifierPositionKind { StandardPosition, StartOfStatement };
563   bool parseIdentifier(StringRef &Res, IdentifierPositionKind Position);
564   bool parseIdentifier(StringRef &Res) override {
565     return parseIdentifier(Res, StandardPosition);
566   }
567   void eatToEndOfStatement() override;
568 
569   bool checkForValidSection() override;
570 
571   /// }
572 
573 private:
574   bool expandMacros();
575   const AsmToken peekTok(bool ShouldSkipSpace = true);
576 
577   bool parseStatement(ParseStatementInfo &Info,
578                       MCAsmParserSemaCallback *SI);
579   bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
580   bool parseCppHashLineFilenameComment(SMLoc L);
581 
582   bool expandMacro(raw_svector_ostream &OS, StringRef Body,
583                    ArrayRef<MCAsmMacroParameter> Parameters,
584                    ArrayRef<MCAsmMacroArgument> A,
585                    const std::vector<std::string> &Locals, SMLoc L);
586 
587   /// Are we inside a macro instantiation?
588   bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
589 
590   /// Handle entry to macro instantiation.
591   ///
592   /// \param M The macro.
593   /// \param NameLoc Instantiation location.
594   bool handleMacroEntry(
595       const MCAsmMacro *M, SMLoc NameLoc,
596       AsmToken::TokenKind ArgumentEndTok = AsmToken::EndOfStatement);
597 
598   /// Handle invocation of macro function.
599   ///
600   /// \param M The macro.
601   /// \param NameLoc Invocation location.
602   bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc);
603 
604   /// Handle exit from macro instantiation.
605   void handleMacroExit();
606 
607   /// Extract AsmTokens for a macro argument.
608   bool
609   parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA,
610                      AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
611 
612   /// Parse all macro arguments for a given macro.
613   bool
614   parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A,
615                       AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
616 
617   void printMacroInstantiations();
618 
619   bool expandStatement(SMLoc Loc);
620 
621   void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
622                     SMRange Range = std::nullopt) const {
623     ArrayRef<SMRange> Ranges(Range);
624     SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
625   }
626   static void DiagHandler(const SMDiagnostic &Diag, void *Context);
627 
628   bool lookUpField(const StructInfo &Structure, StringRef Member,
629                    AsmFieldInfo &Info) const;
630 
631   /// Should we emit DWARF describing this assembler source?  (Returns false if
632   /// the source has .file directives, which means we don't want to generate
633   /// info describing the assembler source itself.)
634   bool enabledGenDwarfForAssembly();
635 
636   /// Enter the specified file. This returns true on failure.
637   bool enterIncludeFile(const std::string &Filename);
638 
639   /// Reset the current lexer position to that given by \p Loc. The
640   /// current token is not set; clients should ensure Lex() is called
641   /// subsequently.
642   ///
643   /// \param InBuffer If not 0, should be the known buffer id that contains the
644   /// location.
645   void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0,
646                  bool EndStatementAtEOF = true);
647 
648   /// Parse up to a token of kind \p EndTok and return the contents from the
649   /// current token up to (but not including) this token; the current token on
650   /// exit will be either this kind or EOF. Reads through instantiated macro
651   /// functions and text macros.
652   SmallVector<StringRef, 1> parseStringRefsTo(AsmToken::TokenKind EndTok);
653   std::string parseStringTo(AsmToken::TokenKind EndTok);
654 
655   /// Parse up to the end of statement and return the contents from the current
656   /// token until the end of the statement; the current token on exit will be
657   /// either the EndOfStatement or EOF.
658   StringRef parseStringToEndOfStatement() override;
659 
660   bool parseTextItem(std::string &Data);
661 
662   unsigned getBinOpPrecedence(AsmToken::TokenKind K,
663                               MCBinaryExpr::Opcode &Kind);
664 
665   bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
666   bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
667   bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
668 
669   bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
670 
671   bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
672   bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
673 
674   // Generic (target and platform independent) directive parsing.
675   enum DirectiveKind {
676     DK_NO_DIRECTIVE, // Placeholder
677     DK_HANDLER_DIRECTIVE,
678     DK_ASSIGN,
679     DK_EQU,
680     DK_TEXTEQU,
681     DK_ASCII,
682     DK_ASCIZ,
683     DK_STRING,
684     DK_BYTE,
685     DK_SBYTE,
686     DK_WORD,
687     DK_SWORD,
688     DK_DWORD,
689     DK_SDWORD,
690     DK_FWORD,
691     DK_QWORD,
692     DK_SQWORD,
693     DK_DB,
694     DK_DD,
695     DK_DF,
696     DK_DQ,
697     DK_DW,
698     DK_REAL4,
699     DK_REAL8,
700     DK_REAL10,
701     DK_ALIGN,
702     DK_EVEN,
703     DK_ORG,
704     DK_ENDR,
705     DK_EXTERN,
706     DK_PUBLIC,
707     DK_COMM,
708     DK_COMMENT,
709     DK_INCLUDE,
710     DK_REPEAT,
711     DK_WHILE,
712     DK_FOR,
713     DK_FORC,
714     DK_IF,
715     DK_IFE,
716     DK_IFB,
717     DK_IFNB,
718     DK_IFDEF,
719     DK_IFNDEF,
720     DK_IFDIF,
721     DK_IFDIFI,
722     DK_IFIDN,
723     DK_IFIDNI,
724     DK_ELSEIF,
725     DK_ELSEIFE,
726     DK_ELSEIFB,
727     DK_ELSEIFNB,
728     DK_ELSEIFDEF,
729     DK_ELSEIFNDEF,
730     DK_ELSEIFDIF,
731     DK_ELSEIFDIFI,
732     DK_ELSEIFIDN,
733     DK_ELSEIFIDNI,
734     DK_ELSE,
735     DK_ENDIF,
736     DK_FILE,
737     DK_LINE,
738     DK_LOC,
739     DK_STABS,
740     DK_CV_FILE,
741     DK_CV_FUNC_ID,
742     DK_CV_INLINE_SITE_ID,
743     DK_CV_LOC,
744     DK_CV_LINETABLE,
745     DK_CV_INLINE_LINETABLE,
746     DK_CV_DEF_RANGE,
747     DK_CV_STRINGTABLE,
748     DK_CV_STRING,
749     DK_CV_FILECHECKSUMS,
750     DK_CV_FILECHECKSUM_OFFSET,
751     DK_CV_FPO_DATA,
752     DK_CFI_SECTIONS,
753     DK_CFI_STARTPROC,
754     DK_CFI_ENDPROC,
755     DK_CFI_DEF_CFA,
756     DK_CFI_DEF_CFA_OFFSET,
757     DK_CFI_ADJUST_CFA_OFFSET,
758     DK_CFI_DEF_CFA_REGISTER,
759     DK_CFI_OFFSET,
760     DK_CFI_REL_OFFSET,
761     DK_CFI_PERSONALITY,
762     DK_CFI_LSDA,
763     DK_CFI_REMEMBER_STATE,
764     DK_CFI_RESTORE_STATE,
765     DK_CFI_SAME_VALUE,
766     DK_CFI_RESTORE,
767     DK_CFI_ESCAPE,
768     DK_CFI_RETURN_COLUMN,
769     DK_CFI_SIGNAL_FRAME,
770     DK_CFI_UNDEFINED,
771     DK_CFI_REGISTER,
772     DK_CFI_WINDOW_SAVE,
773     DK_CFI_B_KEY_FRAME,
774     DK_MACRO,
775     DK_EXITM,
776     DK_ENDM,
777     DK_PURGE,
778     DK_ERR,
779     DK_ERRB,
780     DK_ERRNB,
781     DK_ERRDEF,
782     DK_ERRNDEF,
783     DK_ERRDIF,
784     DK_ERRDIFI,
785     DK_ERRIDN,
786     DK_ERRIDNI,
787     DK_ERRE,
788     DK_ERRNZ,
789     DK_ECHO,
790     DK_STRUCT,
791     DK_UNION,
792     DK_ENDS,
793     DK_END,
794     DK_PUSHFRAME,
795     DK_PUSHREG,
796     DK_SAVEREG,
797     DK_SAVEXMM128,
798     DK_SETFRAME,
799     DK_RADIX,
800   };
801 
802   /// Maps directive name --> DirectiveKind enum, for directives parsed by this
803   /// class.
804   StringMap<DirectiveKind> DirectiveKindMap;
805 
806   bool isMacroLikeDirective();
807 
808   // Codeview def_range type parsing.
809   enum CVDefRangeType {
810     CVDR_DEFRANGE = 0, // Placeholder
811     CVDR_DEFRANGE_REGISTER,
812     CVDR_DEFRANGE_FRAMEPOINTER_REL,
813     CVDR_DEFRANGE_SUBFIELD_REGISTER,
814     CVDR_DEFRANGE_REGISTER_REL
815   };
816 
817   /// Maps Codeview def_range types --> CVDefRangeType enum, for Codeview
818   /// def_range types parsed by this class.
819   StringMap<CVDefRangeType> CVDefRangeTypeMap;
820 
821   // Generic (target and platform independent) directive parsing.
822   enum BuiltinSymbol {
823     BI_NO_SYMBOL, // Placeholder
824     BI_DATE,
825     BI_TIME,
826     BI_VERSION,
827     BI_FILECUR,
828     BI_FILENAME,
829     BI_LINE,
830     BI_CURSEG,
831     BI_CPU,
832     BI_INTERFACE,
833     BI_CODE,
834     BI_DATA,
835     BI_FARDATA,
836     BI_WORDSIZE,
837     BI_CODESIZE,
838     BI_DATASIZE,
839     BI_MODEL,
840     BI_STACK,
841   };
842 
843   /// Maps builtin name --> BuiltinSymbol enum, for builtins handled by this
844   /// class.
845   StringMap<BuiltinSymbol> BuiltinSymbolMap;
846 
847   const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol, SMLoc StartLoc);
848 
849   std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
850                                                       SMLoc StartLoc);
851 
852   // ".ascii", ".asciz", ".string"
853   bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
854 
855   // "byte", "word", ...
856   bool emitIntValue(const MCExpr *Value, unsigned Size);
857   bool parseScalarInitializer(unsigned Size,
858                               SmallVectorImpl<const MCExpr *> &Values,
859                               unsigned StringPadLength = 0);
860   bool parseScalarInstList(
861       unsigned Size, SmallVectorImpl<const MCExpr *> &Values,
862       const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
863   bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr);
864   bool addIntegralField(StringRef Name, unsigned Size);
865   bool parseDirectiveValue(StringRef IDVal, unsigned Size);
866   bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
867                                 StringRef Name, SMLoc NameLoc);
868 
869   // "real4", "real8", "real10"
870   bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);
871   bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);
872   bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,
873                                size_t Size);
874   bool parseRealInstList(
875       const fltSemantics &Semantics, SmallVectorImpl<APInt> &Values,
876       const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
877   bool parseDirectiveNamedRealValue(StringRef TypeName,
878                                     const fltSemantics &Semantics,
879                                     unsigned Size, StringRef Name,
880                                     SMLoc NameLoc);
881 
882   bool parseOptionalAngleBracketOpen();
883   bool parseAngleBracketClose(const Twine &Msg = "expected '>'");
884 
885   bool parseFieldInitializer(const FieldInfo &Field,
886                              FieldInitializer &Initializer);
887   bool parseFieldInitializer(const FieldInfo &Field,
888                              const IntFieldInfo &Contents,
889                              FieldInitializer &Initializer);
890   bool parseFieldInitializer(const FieldInfo &Field,
891                              const RealFieldInfo &Contents,
892                              FieldInitializer &Initializer);
893   bool parseFieldInitializer(const FieldInfo &Field,
894                              const StructFieldInfo &Contents,
895                              FieldInitializer &Initializer);
896 
897   bool parseStructInitializer(const StructInfo &Structure,
898                               StructInitializer &Initializer);
899   bool parseStructInstList(
900       const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
901       const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
902 
903   bool emitFieldValue(const FieldInfo &Field);
904   bool emitFieldValue(const FieldInfo &Field, const IntFieldInfo &Contents);
905   bool emitFieldValue(const FieldInfo &Field, const RealFieldInfo &Contents);
906   bool emitFieldValue(const FieldInfo &Field, const StructFieldInfo &Contents);
907 
908   bool emitFieldInitializer(const FieldInfo &Field,
909                             const FieldInitializer &Initializer);
910   bool emitFieldInitializer(const FieldInfo &Field,
911                             const IntFieldInfo &Contents,
912                             const IntFieldInfo &Initializer);
913   bool emitFieldInitializer(const FieldInfo &Field,
914                             const RealFieldInfo &Contents,
915                             const RealFieldInfo &Initializer);
916   bool emitFieldInitializer(const FieldInfo &Field,
917                             const StructFieldInfo &Contents,
918                             const StructFieldInfo &Initializer);
919 
920   bool emitStructInitializer(const StructInfo &Structure,
921                              const StructInitializer &Initializer);
922 
923   // User-defined types (structs, unions):
924   bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr);
925   bool addStructField(StringRef Name, const StructInfo &Structure);
926   bool parseDirectiveStructValue(const StructInfo &Structure,
927                                  StringRef Directive, SMLoc DirLoc);
928   bool parseDirectiveNamedStructValue(const StructInfo &Structure,
929                                       StringRef Directive, SMLoc DirLoc,
930                                       StringRef Name);
931 
932   // "=", "equ", "textequ"
933   bool parseDirectiveEquate(StringRef IDVal, StringRef Name,
934                             DirectiveKind DirKind, SMLoc NameLoc);
935 
936   bool parseDirectiveOrg(); // "org"
937 
938   bool emitAlignTo(int64_t Alignment);
939   bool parseDirectiveAlign();  // "align"
940   bool parseDirectiveEven();   // "even"
941 
942   // ".file", ".line", ".loc", ".stabs"
943   bool parseDirectiveFile(SMLoc DirectiveLoc);
944   bool parseDirectiveLine();
945   bool parseDirectiveLoc();
946   bool parseDirectiveStabs();
947 
948   // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
949   // ".cv_inline_linetable", ".cv_def_range", ".cv_string"
950   bool parseDirectiveCVFile();
951   bool parseDirectiveCVFuncId();
952   bool parseDirectiveCVInlineSiteId();
953   bool parseDirectiveCVLoc();
954   bool parseDirectiveCVLinetable();
955   bool parseDirectiveCVInlineLinetable();
956   bool parseDirectiveCVDefRange();
957   bool parseDirectiveCVString();
958   bool parseDirectiveCVStringTable();
959   bool parseDirectiveCVFileChecksums();
960   bool parseDirectiveCVFileChecksumOffset();
961   bool parseDirectiveCVFPOData();
962 
963   // .cfi directives
964   bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
965   bool parseDirectiveCFIWindowSave(SMLoc DirectiveLoc);
966   bool parseDirectiveCFISections();
967   bool parseDirectiveCFIStartProc();
968   bool parseDirectiveCFIEndProc();
969   bool parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc);
970   bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
971   bool parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc);
972   bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
973   bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
974   bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
975   bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
976   bool parseDirectiveCFIRememberState(SMLoc DirectiveLoc);
977   bool parseDirectiveCFIRestoreState(SMLoc DirectiveLoc);
978   bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
979   bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
980   bool parseDirectiveCFIEscape(SMLoc DirectiveLoc);
981   bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
982   bool parseDirectiveCFISignalFrame();
983   bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
984 
985   // macro directives
986   bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
987   bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,
988                                std::string &Value);
989   bool parseDirectiveEndMacro(StringRef Directive);
990   bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);
991 
992   bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind,
993                             StringRef Name, SMLoc NameLoc);
994   bool parseDirectiveNestedStruct(StringRef Directive, DirectiveKind DirKind);
995   bool parseDirectiveEnds(StringRef Name, SMLoc NameLoc);
996   bool parseDirectiveNestedEnds();
997 
998   bool parseDirectiveExtern();
999 
1000   /// Parse a directive like ".globl" which accepts a single symbol (which
1001   /// should be a label or an external).
1002   bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
1003 
1004   bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
1005 
1006   bool parseDirectiveComment(SMLoc DirectiveLoc); // "comment"
1007 
1008   bool parseDirectiveInclude(); // "include"
1009 
1010   // "if" or "ife"
1011   bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
1012   // "ifb" or "ifnb", depending on ExpectBlank.
1013   bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
1014   // "ifidn", "ifdif", "ifidni", or "ifdifi", depending on ExpectEqual and
1015   // CaseInsensitive.
1016   bool parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
1017                            bool CaseInsensitive);
1018   // "ifdef" or "ifndef", depending on expect_defined
1019   bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
1020   // "elseif" or "elseife"
1021   bool parseDirectiveElseIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
1022   // "elseifb" or "elseifnb", depending on ExpectBlank.
1023   bool parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank);
1024   // ".elseifdef" or ".elseifndef", depending on expect_defined
1025   bool parseDirectiveElseIfdef(SMLoc DirectiveLoc, bool expect_defined);
1026   // "elseifidn", "elseifdif", "elseifidni", or "elseifdifi", depending on
1027   // ExpectEqual and CaseInsensitive.
1028   bool parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
1029                                bool CaseInsensitive);
1030   bool parseDirectiveElse(SMLoc DirectiveLoc);   // "else"
1031   bool parseDirectiveEndIf(SMLoc DirectiveLoc);  // "endif"
1032   bool parseEscapedString(std::string &Data) override;
1033   bool parseAngleBracketString(std::string &Data) override;
1034 
1035   // Macro-like directives
1036   MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
1037   void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
1038                                 raw_svector_ostream &OS);
1039   void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
1040                                 SMLoc ExitLoc, raw_svector_ostream &OS);
1041   bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive);
1042   bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive);
1043   bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive);
1044   bool parseDirectiveWhile(SMLoc DirectiveLoc);
1045 
1046   // "_emit" or "__emit"
1047   bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
1048                             size_t Len);
1049 
1050   // "align"
1051   bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
1052 
1053   // "end"
1054   bool parseDirectiveEnd(SMLoc DirectiveLoc);
1055 
1056   // ".err"
1057   bool parseDirectiveError(SMLoc DirectiveLoc);
1058   // ".errb" or ".errnb", depending on ExpectBlank.
1059   bool parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank);
1060   // ".errdef" or ".errndef", depending on ExpectBlank.
1061   bool parseDirectiveErrorIfdef(SMLoc DirectiveLoc, bool ExpectDefined);
1062   // ".erridn", ".errdif", ".erridni", or ".errdifi", depending on ExpectEqual
1063   // and CaseInsensitive.
1064   bool parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
1065                                 bool CaseInsensitive);
1066   // ".erre" or ".errnz", depending on ExpectZero.
1067   bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero);
1068 
1069   // ".radix"
1070   bool parseDirectiveRadix(SMLoc DirectiveLoc);
1071 
1072   // "echo"
1073   bool parseDirectiveEcho(SMLoc DirectiveLoc);
1074 
1075   void initializeDirectiveKindMap();
1076   void initializeCVDefRangeTypeMap();
1077   void initializeBuiltinSymbolMap();
1078 };
1079 
1080 } // end anonymous namespace
1081 
1082 namespace llvm {
1083 
1084 extern cl::opt<unsigned> AsmMacroMaxNestingDepth;
1085 
1086 extern MCAsmParserExtension *createCOFFMasmParser();
1087 
1088 } // end namespace llvm
1089 
1090 enum { DEFAULT_ADDRSPACE = 0 };
1091 
1092 MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
1093                        const MCAsmInfo &MAI, struct tm TM, unsigned CB)
1094     : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
1095       CurBuffer(CB ? CB : SM.getMainFileID()), TM(TM) {
1096   HadError = false;
1097   // Save the old handler.
1098   SavedDiagHandler = SrcMgr.getDiagHandler();
1099   SavedDiagContext = SrcMgr.getDiagContext();
1100   // Set our own handler which calls the saved handler.
1101   SrcMgr.setDiagHandler(DiagHandler, this);
1102   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
1103   EndStatementAtEOFStack.push_back(true);
1104 
1105   // Initialize the platform / file format parser.
1106   switch (Ctx.getObjectFileType()) {
1107   case MCContext::IsCOFF:
1108     PlatformParser.reset(createCOFFMasmParser());
1109     break;
1110   default:
1111     report_fatal_error("llvm-ml currently supports only COFF output.");
1112     break;
1113   }
1114 
1115   initializeDirectiveKindMap();
1116   PlatformParser->Initialize(*this);
1117   initializeCVDefRangeTypeMap();
1118   initializeBuiltinSymbolMap();
1119 
1120   NumOfMacroInstantiations = 0;
1121 }
1122 
1123 MasmParser::~MasmParser() {
1124   assert((HadError || ActiveMacros.empty()) &&
1125          "Unexpected active macro instantiation!");
1126 
1127   // Restore the saved diagnostics handler and context for use during
1128   // finalization.
1129   SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
1130 }
1131 
1132 void MasmParser::printMacroInstantiations() {
1133   // Print the active macro instantiation stack.
1134   for (std::vector<MacroInstantiation *>::const_reverse_iterator
1135            it = ActiveMacros.rbegin(),
1136            ie = ActiveMacros.rend();
1137        it != ie; ++it)
1138     printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
1139                  "while in macro instantiation");
1140 }
1141 
1142 void MasmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
1143   printPendingErrors();
1144   printMessage(L, SourceMgr::DK_Note, Msg, Range);
1145   printMacroInstantiations();
1146 }
1147 
1148 bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
1149   if (getTargetParser().getTargetOptions().MCNoWarn)
1150     return false;
1151   if (getTargetParser().getTargetOptions().MCFatalWarnings)
1152     return Error(L, Msg, Range);
1153   printMessage(L, SourceMgr::DK_Warning, Msg, Range);
1154   printMacroInstantiations();
1155   return false;
1156 }
1157 
1158 bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
1159   HadError = true;
1160   printMessage(L, SourceMgr::DK_Error, Msg, Range);
1161   printMacroInstantiations();
1162   return true;
1163 }
1164 
1165 bool MasmParser::enterIncludeFile(const std::string &Filename) {
1166   std::string IncludedFile;
1167   unsigned NewBuf =
1168       SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
1169   if (!NewBuf)
1170     return true;
1171 
1172   CurBuffer = NewBuf;
1173   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
1174   EndStatementAtEOFStack.push_back(true);
1175   return false;
1176 }
1177 
1178 void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer,
1179                            bool EndStatementAtEOF) {
1180   CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
1181   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
1182                   Loc.getPointer(), EndStatementAtEOF);
1183 }
1184 
1185 bool MasmParser::expandMacros() {
1186   const AsmToken &Tok = getTok();
1187   const std::string IDLower = Tok.getIdentifier().lower();
1188 
1189   const llvm::MCAsmMacro *M = getContext().lookupMacro(IDLower);
1190   if (M && M->IsFunction && peekTok().is(AsmToken::LParen)) {
1191     // This is a macro function invocation; expand it in place.
1192     const SMLoc MacroLoc = Tok.getLoc();
1193     const StringRef MacroId = Tok.getIdentifier();
1194     Lexer.Lex();
1195     if (handleMacroInvocation(M, MacroLoc)) {
1196       Lexer.UnLex(AsmToken(AsmToken::Error, MacroId));
1197       Lexer.Lex();
1198     }
1199     return false;
1200   }
1201 
1202   std::optional<std::string> ExpandedValue;
1203   auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1204   if (BuiltinIt != BuiltinSymbolMap.end()) {
1205     ExpandedValue =
1206         evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.getLoc());
1207   } else {
1208     auto VarIt = Variables.find(IDLower);
1209     if (VarIt != Variables.end() && VarIt->getValue().IsText) {
1210       ExpandedValue = VarIt->getValue().TextValue;
1211     }
1212   }
1213 
1214   if (!ExpandedValue)
1215     return true;
1216   std::unique_ptr<MemoryBuffer> Instantiation =
1217       MemoryBuffer::getMemBufferCopy(*ExpandedValue, "<instantiation>");
1218 
1219   // Jump to the macro instantiation and prime the lexer.
1220   CurBuffer =
1221       SrcMgr.AddNewSourceBuffer(std::move(Instantiation), Tok.getEndLoc());
1222   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
1223                   /*EndStatementAtEOF=*/false);
1224   EndStatementAtEOFStack.push_back(false);
1225   Lexer.Lex();
1226   return false;
1227 }
1228 
1229 const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {
1230   if (Lexer.getTok().is(AsmToken::Error))
1231     Error(Lexer.getErrLoc(), Lexer.getErr());
1232 
1233   // if it's a end of statement with a comment in it
1234   if (getTok().is(AsmToken::EndOfStatement)) {
1235     // if this is a line comment output it.
1236     if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
1237         getTok().getString().front() != '\r' && MAI.preserveAsmComments())
1238       Out.addExplicitComment(Twine(getTok().getString()));
1239   }
1240 
1241   const AsmToken *tok = &Lexer.Lex();
1242   bool StartOfStatement = Lexer.isAtStartOfStatement();
1243 
1244   while (ExpandNextToken == ExpandMacros && tok->is(AsmToken::Identifier)) {
1245     if (StartOfStatement) {
1246       AsmToken NextTok;
1247       MutableArrayRef<AsmToken> Buf(NextTok);
1248       size_t ReadCount = Lexer.peekTokens(Buf);
1249       if (ReadCount && NextTok.is(AsmToken::Identifier) &&
1250           (NextTok.getString().equals_insensitive("equ") ||
1251            NextTok.getString().equals_insensitive("textequ"))) {
1252         // This looks like an EQU or TEXTEQU directive; don't expand the
1253         // identifier, allowing for redefinitions.
1254         break;
1255       }
1256     }
1257     if (expandMacros())
1258       break;
1259   }
1260 
1261   // Parse comments here to be deferred until end of next statement.
1262   while (tok->is(AsmToken::Comment)) {
1263     if (MAI.preserveAsmComments())
1264       Out.addExplicitComment(Twine(tok->getString()));
1265     tok = &Lexer.Lex();
1266   }
1267 
1268   // Recognize and bypass line continuations.
1269   while (tok->is(AsmToken::BackSlash) &&
1270          peekTok().is(AsmToken::EndOfStatement)) {
1271     // Eat both the backslash and the end of statement.
1272     Lexer.Lex();
1273     tok = &Lexer.Lex();
1274   }
1275 
1276   if (tok->is(AsmToken::Eof)) {
1277     // If this is the end of an included file, pop the parent file off the
1278     // include stack.
1279     SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1280     if (ParentIncludeLoc != SMLoc()) {
1281       EndStatementAtEOFStack.pop_back();
1282       jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1283       return Lex();
1284     }
1285     EndStatementAtEOFStack.pop_back();
1286     assert(EndStatementAtEOFStack.empty());
1287   }
1288 
1289   return *tok;
1290 }
1291 
1292 const AsmToken MasmParser::peekTok(bool ShouldSkipSpace) {
1293   AsmToken Tok;
1294 
1295   MutableArrayRef<AsmToken> Buf(Tok);
1296   size_t ReadCount = Lexer.peekTokens(Buf, ShouldSkipSpace);
1297 
1298   if (ReadCount == 0) {
1299     // If this is the end of an included file, pop the parent file off the
1300     // include stack.
1301     SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1302     if (ParentIncludeLoc != SMLoc()) {
1303       EndStatementAtEOFStack.pop_back();
1304       jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1305       return peekTok(ShouldSkipSpace);
1306     }
1307     EndStatementAtEOFStack.pop_back();
1308     assert(EndStatementAtEOFStack.empty());
1309   }
1310 
1311   assert(ReadCount == 1);
1312   return Tok;
1313 }
1314 
1315 bool MasmParser::enabledGenDwarfForAssembly() {
1316   // Check whether the user specified -g.
1317   if (!getContext().getGenDwarfForAssembly())
1318     return false;
1319   // If we haven't encountered any .file directives (which would imply that
1320   // the assembler source was produced with debug info already) then emit one
1321   // describing the assembler source file itself.
1322   if (getContext().getGenDwarfFileNumber() == 0) {
1323     // Use the first #line directive for this, if any. It's preprocessed, so
1324     // there is no checksum, and of course no source directive.
1325     if (!FirstCppHashFilename.empty())
1326       getContext().setMCLineTableRootFile(
1327           /*CUID=*/0, getContext().getCompilationDir(), FirstCppHashFilename,
1328           /*Cksum=*/std::nullopt, /*Source=*/std::nullopt);
1329     const MCDwarfFile &RootFile =
1330         getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
1331     getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
1332         /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name,
1333         RootFile.Checksum, RootFile.Source));
1334   }
1335   return true;
1336 }
1337 
1338 bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
1339   // Create the initial section, if requested.
1340   if (!NoInitialTextSection)
1341     Out.initSections(false, getTargetParser().getSTI());
1342 
1343   // Prime the lexer.
1344   Lex();
1345 
1346   HadError = false;
1347   AsmCond StartingCondState = TheCondState;
1348   SmallVector<AsmRewrite, 4> AsmStrRewrites;
1349 
1350   // If we are generating dwarf for assembly source files save the initial text
1351   // section.  (Don't use enabledGenDwarfForAssembly() here, as we aren't
1352   // emitting any actual debug info yet and haven't had a chance to parse any
1353   // embedded .file directives.)
1354   if (getContext().getGenDwarfForAssembly()) {
1355     MCSection *Sec = getStreamer().getCurrentSectionOnly();
1356     if (!Sec->getBeginSymbol()) {
1357       MCSymbol *SectionStartSym = getContext().createTempSymbol();
1358       getStreamer().emitLabel(SectionStartSym);
1359       Sec->setBeginSymbol(SectionStartSym);
1360     }
1361     bool InsertResult = getContext().addGenDwarfSection(Sec);
1362     assert(InsertResult && ".text section should not have debug info yet");
1363     (void)InsertResult;
1364   }
1365 
1366   getTargetParser().onBeginOfFile();
1367 
1368   // While we have input, parse each statement.
1369   while (Lexer.isNot(AsmToken::Eof) ||
1370          SrcMgr.getParentIncludeLoc(CurBuffer) != SMLoc()) {
1371     // Skip through the EOF at the end of an inclusion.
1372     if (Lexer.is(AsmToken::Eof))
1373       Lex();
1374 
1375     ParseStatementInfo Info(&AsmStrRewrites);
1376     bool Parsed = parseStatement(Info, nullptr);
1377 
1378     // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
1379     // for printing ErrMsg via Lex() only if no (presumably better) parser error
1380     // exists.
1381     if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
1382       Lex();
1383     }
1384 
1385     // parseStatement returned true so may need to emit an error.
1386     printPendingErrors();
1387 
1388     // Skipping to the next line if needed.
1389     if (Parsed && !getLexer().isAtStartOfStatement())
1390       eatToEndOfStatement();
1391   }
1392 
1393   getTargetParser().onEndOfFile();
1394   printPendingErrors();
1395 
1396   // All errors should have been emitted.
1397   assert(!hasPendingError() && "unexpected error from parseStatement");
1398 
1399   getTargetParser().flushPendingInstructions(getStreamer());
1400 
1401   if (TheCondState.TheCond != StartingCondState.TheCond ||
1402       TheCondState.Ignore != StartingCondState.Ignore)
1403     printError(getTok().getLoc(), "unmatched .ifs or .elses");
1404   // Check to see there are no empty DwarfFile slots.
1405   const auto &LineTables = getContext().getMCDwarfLineTables();
1406   if (!LineTables.empty()) {
1407     unsigned Index = 0;
1408     for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1409       if (File.Name.empty() && Index != 0)
1410         printError(getTok().getLoc(), "unassigned file number: " +
1411                                           Twine(Index) +
1412                                           " for .file directives");
1413       ++Index;
1414     }
1415   }
1416 
1417   // Check to see that all assembler local symbols were actually defined.
1418   // Targets that don't do subsections via symbols may not want this, though,
1419   // so conservatively exclude them. Only do this if we're finalizing, though,
1420   // as otherwise we won't necessarilly have seen everything yet.
1421   if (!NoFinalize) {
1422     if (MAI.hasSubsectionsViaSymbols()) {
1423       for (const auto &TableEntry : getContext().getSymbols()) {
1424         MCSymbol *Sym = TableEntry.getValue();
1425         // Variable symbols may not be marked as defined, so check those
1426         // explicitly. If we know it's a variable, we have a definition for
1427         // the purposes of this check.
1428         if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
1429           // FIXME: We would really like to refer back to where the symbol was
1430           // first referenced for a source location. We need to add something
1431           // to track that. Currently, we just point to the end of the file.
1432           printError(getTok().getLoc(), "assembler local symbol '" +
1433                                             Sym->getName() + "' not defined");
1434       }
1435     }
1436 
1437     // Temporary symbols like the ones for directional jumps don't go in the
1438     // symbol table. They also need to be diagnosed in all (final) cases.
1439     for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1440       if (std::get<2>(LocSym)->isUndefined()) {
1441         // Reset the state of any "# line file" directives we've seen to the
1442         // context as it was at the diagnostic site.
1443         CppHashInfo = std::get<1>(LocSym);
1444         printError(std::get<0>(LocSym), "directional label undefined");
1445       }
1446     }
1447   }
1448 
1449   // Finalize the output stream if there are no errors and if the client wants
1450   // us to.
1451   if (!HadError && !NoFinalize)
1452     Out.finish(Lexer.getLoc());
1453 
1454   return HadError || getContext().hadError();
1455 }
1456 
1457 bool MasmParser::checkForValidSection() {
1458   if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1459     Out.initSections(false, getTargetParser().getSTI());
1460     return Error(getTok().getLoc(),
1461                  "expected section directive before assembly directive");
1462   }
1463   return false;
1464 }
1465 
1466 /// Throw away the rest of the line for testing purposes.
1467 void MasmParser::eatToEndOfStatement() {
1468   while (Lexer.isNot(AsmToken::EndOfStatement)) {
1469     if (Lexer.is(AsmToken::Eof)) {
1470       SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1471       if (ParentIncludeLoc == SMLoc()) {
1472         break;
1473       }
1474 
1475       EndStatementAtEOFStack.pop_back();
1476       jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1477     }
1478 
1479     Lexer.Lex();
1480   }
1481 
1482   // Eat EOL.
1483   if (Lexer.is(AsmToken::EndOfStatement))
1484     Lexer.Lex();
1485 }
1486 
1487 SmallVector<StringRef, 1>
1488 MasmParser::parseStringRefsTo(AsmToken::TokenKind EndTok) {
1489   SmallVector<StringRef, 1> Refs;
1490   const char *Start = getTok().getLoc().getPointer();
1491   while (Lexer.isNot(EndTok)) {
1492     if (Lexer.is(AsmToken::Eof)) {
1493       SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1494       if (ParentIncludeLoc == SMLoc()) {
1495         break;
1496       }
1497       Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
1498 
1499       EndStatementAtEOFStack.pop_back();
1500       jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1501       Lexer.Lex();
1502       Start = getTok().getLoc().getPointer();
1503     } else {
1504       Lexer.Lex();
1505     }
1506   }
1507   Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
1508   return Refs;
1509 }
1510 
1511 std::string MasmParser::parseStringTo(AsmToken::TokenKind EndTok) {
1512   SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok);
1513   std::string Str;
1514   for (StringRef S : Refs) {
1515     Str.append(S.str());
1516   }
1517   return Str;
1518 }
1519 
1520 StringRef MasmParser::parseStringToEndOfStatement() {
1521   const char *Start = getTok().getLoc().getPointer();
1522 
1523   while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
1524     Lexer.Lex();
1525 
1526   const char *End = getTok().getLoc().getPointer();
1527   return StringRef(Start, End - Start);
1528 }
1529 
1530 /// Parse a paren expression and return it.
1531 /// NOTE: This assumes the leading '(' has already been consumed.
1532 ///
1533 /// parenexpr ::= expr)
1534 ///
1535 bool MasmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1536   if (parseExpression(Res))
1537     return true;
1538   EndLoc = Lexer.getTok().getEndLoc();
1539   return parseRParen();
1540 }
1541 
1542 /// Parse a bracket expression and return it.
1543 /// NOTE: This assumes the leading '[' has already been consumed.
1544 ///
1545 /// bracketexpr ::= expr]
1546 ///
1547 bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1548   if (parseExpression(Res))
1549     return true;
1550   EndLoc = getTok().getEndLoc();
1551   if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1552     return true;
1553   return false;
1554 }
1555 
1556 /// Parse a primary expression and return it.
1557 ///  primaryexpr ::= (parenexpr
1558 ///  primaryexpr ::= symbol
1559 ///  primaryexpr ::= number
1560 ///  primaryexpr ::= '.'
1561 ///  primaryexpr ::= ~,+,-,'not' primaryexpr
1562 ///  primaryexpr ::= string
1563 ///          (a string is interpreted as a 64-bit number in big-endian base-256)
1564 bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
1565                                   AsmTypeInfo *TypeInfo) {
1566   SMLoc FirstTokenLoc = getLexer().getLoc();
1567   AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
1568   switch (FirstTokenKind) {
1569   default:
1570     return TokError("unknown token in expression");
1571   // If we have an error assume that we've already handled it.
1572   case AsmToken::Error:
1573     return true;
1574   case AsmToken::Exclaim:
1575     Lex(); // Eat the operator.
1576     if (parsePrimaryExpr(Res, EndLoc, nullptr))
1577       return true;
1578     Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
1579     return false;
1580   case AsmToken::Dollar:
1581   case AsmToken::At:
1582   case AsmToken::Identifier: {
1583     StringRef Identifier;
1584     if (parseIdentifier(Identifier)) {
1585       // We may have failed but $ may be a valid token.
1586       if (getTok().is(AsmToken::Dollar)) {
1587         if (Lexer.getMAI().getDollarIsPC()) {
1588           Lex();
1589           // This is a '$' reference, which references the current PC.  Emit a
1590           // temporary label to the streamer and refer to it.
1591           MCSymbol *Sym = Ctx.createTempSymbol();
1592           Out.emitLabel(Sym);
1593           Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
1594                                         getContext());
1595           EndLoc = FirstTokenLoc;
1596           return false;
1597         }
1598         return Error(FirstTokenLoc, "invalid token in expression");
1599       }
1600     }
1601     // Parse named bitwise negation.
1602     if (Identifier.equals_insensitive("not")) {
1603       if (parsePrimaryExpr(Res, EndLoc, nullptr))
1604         return true;
1605       Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1606       return false;
1607     }
1608     // Parse directional local label references.
1609     if (Identifier.equals_insensitive("@b") ||
1610         Identifier.equals_insensitive("@f")) {
1611       bool Before = Identifier.equals_insensitive("@b");
1612       MCSymbol *Sym = getContext().getDirectionalLocalSymbol(0, Before);
1613       if (Before && Sym->isUndefined())
1614         return Error(FirstTokenLoc, "Expected @@ label before @B reference");
1615       Res = MCSymbolRefExpr::create(Sym, getContext());
1616       return false;
1617     }
1618     // Parse symbol variant.
1619     std::pair<StringRef, StringRef> Split;
1620     if (!MAI.useParensForSymbolVariant()) {
1621       Split = Identifier.split('@');
1622     } else if (Lexer.is(AsmToken::LParen)) {
1623       Lex(); // eat '('.
1624       StringRef VName;
1625       parseIdentifier(VName);
1626       // eat ')'.
1627       if (parseToken(AsmToken::RParen,
1628                      "unexpected token in variant, expected ')'"))
1629         return true;
1630       Split = std::make_pair(Identifier, VName);
1631     }
1632 
1633     EndLoc = SMLoc::getFromPointer(Identifier.end());
1634 
1635     // This is a symbol reference.
1636     StringRef SymbolName = Identifier;
1637     if (SymbolName.empty())
1638       return Error(getLexer().getLoc(), "expected a symbol reference");
1639 
1640     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1641 
1642     // Look up the symbol variant if used.
1643     if (!Split.second.empty()) {
1644       Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1645       if (Variant != MCSymbolRefExpr::VK_Invalid) {
1646         SymbolName = Split.first;
1647       } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
1648         Variant = MCSymbolRefExpr::VK_None;
1649       } else {
1650         return Error(SMLoc::getFromPointer(Split.second.begin()),
1651                      "invalid variant '" + Split.second + "'");
1652       }
1653     }
1654 
1655     // Find the field offset if used.
1656     AsmFieldInfo Info;
1657     Split = SymbolName.split('.');
1658     if (Split.second.empty()) {
1659     } else {
1660       SymbolName = Split.first;
1661       if (lookUpField(SymbolName, Split.second, Info)) {
1662         std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');
1663         StringRef Base = BaseMember.first, Member = BaseMember.second;
1664         lookUpField(Base, Member, Info);
1665       } else if (Structs.count(SymbolName.lower())) {
1666         // This is actually a reference to a field offset.
1667         Res = MCConstantExpr::create(Info.Offset, getContext());
1668         return false;
1669       }
1670     }
1671 
1672     MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
1673     if (!Sym) {
1674       // If this is a built-in numeric value, treat it as a constant.
1675       auto BuiltinIt = BuiltinSymbolMap.find(SymbolName.lower());
1676       const BuiltinSymbol Symbol = (BuiltinIt == BuiltinSymbolMap.end())
1677                                        ? BI_NO_SYMBOL
1678                                        : BuiltinIt->getValue();
1679       if (Symbol != BI_NO_SYMBOL) {
1680         const MCExpr *Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
1681         if (Value) {
1682           Res = Value;
1683           return false;
1684         }
1685       }
1686 
1687       // Variables use case-insensitive symbol names; if this is a variable, we
1688       // find the symbol using its canonical name.
1689       auto VarIt = Variables.find(SymbolName.lower());
1690       if (VarIt != Variables.end())
1691         SymbolName = VarIt->second.Name;
1692       Sym = getContext().getOrCreateSymbol(SymbolName);
1693     }
1694 
1695     // If this is an absolute variable reference, substitute it now to preserve
1696     // semantics in the face of reassignment.
1697     if (Sym->isVariable()) {
1698       auto V = Sym->getVariableValue(/*SetUsed=*/false);
1699       bool DoInline = isa<MCConstantExpr>(V) && !Variant;
1700       if (auto TV = dyn_cast<MCTargetExpr>(V))
1701         DoInline = TV->inlineAssignedExpr();
1702       if (DoInline) {
1703         if (Variant)
1704           return Error(EndLoc, "unexpected modifier on variable reference");
1705         Res = Sym->getVariableValue(/*SetUsed=*/false);
1706         return false;
1707       }
1708     }
1709 
1710     // Otherwise create a symbol ref.
1711     const MCExpr *SymRef =
1712         MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
1713     if (Info.Offset) {
1714       Res = MCBinaryExpr::create(
1715           MCBinaryExpr::Add, SymRef,
1716           MCConstantExpr::create(Info.Offset, getContext()), getContext());
1717     } else {
1718       Res = SymRef;
1719     }
1720     if (TypeInfo) {
1721       if (Info.Type.Name.empty()) {
1722         auto TypeIt = KnownType.find(Identifier.lower());
1723         if (TypeIt != KnownType.end()) {
1724           Info.Type = TypeIt->second;
1725         }
1726       }
1727 
1728       *TypeInfo = Info.Type;
1729     }
1730     return false;
1731   }
1732   case AsmToken::BigNum:
1733     return TokError("literal value out of range for directive");
1734   case AsmToken::Integer: {
1735     int64_t IntVal = getTok().getIntVal();
1736     Res = MCConstantExpr::create(IntVal, getContext());
1737     EndLoc = Lexer.getTok().getEndLoc();
1738     Lex(); // Eat token.
1739     return false;
1740   }
1741   case AsmToken::String: {
1742     // MASM strings (used as constants) are interpreted as big-endian base-256.
1743     SMLoc ValueLoc = getTok().getLoc();
1744     std::string Value;
1745     if (parseEscapedString(Value))
1746       return true;
1747     if (Value.size() > 8)
1748       return Error(ValueLoc, "literal value out of range");
1749     uint64_t IntValue = 0;
1750     for (const unsigned char CharVal : Value)
1751       IntValue = (IntValue << 8) | CharVal;
1752     Res = MCConstantExpr::create(IntValue, getContext());
1753     return false;
1754   }
1755   case AsmToken::Real: {
1756     APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1757     uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1758     Res = MCConstantExpr::create(IntVal, getContext());
1759     EndLoc = Lexer.getTok().getEndLoc();
1760     Lex(); // Eat token.
1761     return false;
1762   }
1763   case AsmToken::Dot: {
1764     // This is a '.' reference, which references the current PC.  Emit a
1765     // temporary label to the streamer and refer to it.
1766     MCSymbol *Sym = Ctx.createTempSymbol();
1767     Out.emitLabel(Sym);
1768     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1769     EndLoc = Lexer.getTok().getEndLoc();
1770     Lex(); // Eat identifier.
1771     return false;
1772   }
1773   case AsmToken::LParen:
1774     Lex(); // Eat the '('.
1775     return parseParenExpr(Res, EndLoc);
1776   case AsmToken::LBrac:
1777     if (!PlatformParser->HasBracketExpressions())
1778       return TokError("brackets expression not supported on this target");
1779     Lex(); // Eat the '['.
1780     return parseBracketExpr(Res, EndLoc);
1781   case AsmToken::Minus:
1782     Lex(); // Eat the operator.
1783     if (parsePrimaryExpr(Res, EndLoc, nullptr))
1784       return true;
1785     Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
1786     return false;
1787   case AsmToken::Plus:
1788     Lex(); // Eat the operator.
1789     if (parsePrimaryExpr(Res, EndLoc, nullptr))
1790       return true;
1791     Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
1792     return false;
1793   case AsmToken::Tilde:
1794     Lex(); // Eat the operator.
1795     if (parsePrimaryExpr(Res, EndLoc, nullptr))
1796       return true;
1797     Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1798     return false;
1799   // MIPS unary expression operators. The lexer won't generate these tokens if
1800   // MCAsmInfo::HasMipsExpressions is false for the target.
1801   case AsmToken::PercentCall16:
1802   case AsmToken::PercentCall_Hi:
1803   case AsmToken::PercentCall_Lo:
1804   case AsmToken::PercentDtprel_Hi:
1805   case AsmToken::PercentDtprel_Lo:
1806   case AsmToken::PercentGot:
1807   case AsmToken::PercentGot_Disp:
1808   case AsmToken::PercentGot_Hi:
1809   case AsmToken::PercentGot_Lo:
1810   case AsmToken::PercentGot_Ofst:
1811   case AsmToken::PercentGot_Page:
1812   case AsmToken::PercentGottprel:
1813   case AsmToken::PercentGp_Rel:
1814   case AsmToken::PercentHi:
1815   case AsmToken::PercentHigher:
1816   case AsmToken::PercentHighest:
1817   case AsmToken::PercentLo:
1818   case AsmToken::PercentNeg:
1819   case AsmToken::PercentPcrel_Hi:
1820   case AsmToken::PercentPcrel_Lo:
1821   case AsmToken::PercentTlsgd:
1822   case AsmToken::PercentTlsldm:
1823   case AsmToken::PercentTprel_Hi:
1824   case AsmToken::PercentTprel_Lo:
1825     Lex(); // Eat the operator.
1826     if (Lexer.isNot(AsmToken::LParen))
1827       return TokError("expected '(' after operator");
1828     Lex(); // Eat the operator.
1829     if (parseExpression(Res, EndLoc))
1830       return true;
1831     if (parseRParen())
1832       return true;
1833     Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1834     return !Res;
1835   }
1836 }
1837 
1838 bool MasmParser::parseExpression(const MCExpr *&Res) {
1839   SMLoc EndLoc;
1840   return parseExpression(Res, EndLoc);
1841 }
1842 
1843 /// This function checks if the next token is <string> type or arithmetic.
1844 /// string that begin with character '<' must end with character '>'.
1845 /// otherwise it is arithmetics.
1846 /// If the function returns a 'true' value,
1847 /// the End argument will be filled with the last location pointed to the '>'
1848 /// character.
1849 static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc) {
1850   assert((StrLoc.getPointer() != nullptr) &&
1851          "Argument to the function cannot be a NULL value");
1852   const char *CharPtr = StrLoc.getPointer();
1853   while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1854          (*CharPtr != '\0')) {
1855     if (*CharPtr == '!')
1856       CharPtr++;
1857     CharPtr++;
1858   }
1859   if (*CharPtr == '>') {
1860     EndLoc = StrLoc.getFromPointer(CharPtr + 1);
1861     return true;
1862   }
1863   return false;
1864 }
1865 
1866 /// creating a string without the escape characters '!'.
1867 static std::string angleBracketString(StringRef BracketContents) {
1868   std::string Res;
1869   for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) {
1870     if (BracketContents[Pos] == '!')
1871       Pos++;
1872     Res += BracketContents[Pos];
1873   }
1874   return Res;
1875 }
1876 
1877 /// Parse an expression and return it.
1878 ///
1879 ///  expr ::= expr &&,|| expr               -> lowest.
1880 ///  expr ::= expr |,^,&,! expr
1881 ///  expr ::= expr ==,!=,<>,<,<=,>,>= expr
1882 ///  expr ::= expr <<,>> expr
1883 ///  expr ::= expr +,- expr
1884 ///  expr ::= expr *,/,% expr               -> highest.
1885 ///  expr ::= primaryexpr
1886 ///
1887 bool MasmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1888   // Parse the expression.
1889   Res = nullptr;
1890   if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1891       parseBinOpRHS(1, Res, EndLoc))
1892     return true;
1893 
1894   // Try to constant fold it up front, if possible. Do not exploit
1895   // assembler here.
1896   int64_t Value;
1897   if (Res->evaluateAsAbsolute(Value))
1898     Res = MCConstantExpr::create(Value, getContext());
1899 
1900   return false;
1901 }
1902 
1903 bool MasmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1904   Res = nullptr;
1905   return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1906 }
1907 
1908 bool MasmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
1909                                        SMLoc &EndLoc) {
1910   if (parseParenExpr(Res, EndLoc))
1911     return true;
1912 
1913   for (; ParenDepth > 0; --ParenDepth) {
1914     if (parseBinOpRHS(1, Res, EndLoc))
1915       return true;
1916 
1917     // We don't Lex() the last RParen.
1918     // This is the same behavior as parseParenExpression().
1919     if (ParenDepth - 1 > 0) {
1920       EndLoc = getTok().getEndLoc();
1921       if (parseRParen())
1922         return true;
1923     }
1924   }
1925   return false;
1926 }
1927 
1928 bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1929   const MCExpr *Expr;
1930 
1931   SMLoc StartLoc = Lexer.getLoc();
1932   if (parseExpression(Expr))
1933     return true;
1934 
1935   if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1936     return Error(StartLoc, "expected absolute expression");
1937 
1938   return false;
1939 }
1940 
1941 static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K,
1942                                       MCBinaryExpr::Opcode &Kind,
1943                                       bool ShouldUseLogicalShr,
1944                                       bool EndExpressionAtGreater) {
1945   switch (K) {
1946   default:
1947     return 0; // not a binop.
1948 
1949   // Lowest Precedence: &&, ||
1950   case AsmToken::AmpAmp:
1951     Kind = MCBinaryExpr::LAnd;
1952     return 2;
1953   case AsmToken::PipePipe:
1954     Kind = MCBinaryExpr::LOr;
1955     return 1;
1956 
1957   // Low Precedence: ==, !=, <>, <, <=, >, >=
1958   case AsmToken::EqualEqual:
1959     Kind = MCBinaryExpr::EQ;
1960     return 3;
1961   case AsmToken::ExclaimEqual:
1962   case AsmToken::LessGreater:
1963     Kind = MCBinaryExpr::NE;
1964     return 3;
1965   case AsmToken::Less:
1966     Kind = MCBinaryExpr::LT;
1967     return 3;
1968   case AsmToken::LessEqual:
1969     Kind = MCBinaryExpr::LTE;
1970     return 3;
1971   case AsmToken::Greater:
1972     if (EndExpressionAtGreater)
1973       return 0;
1974     Kind = MCBinaryExpr::GT;
1975     return 3;
1976   case AsmToken::GreaterEqual:
1977     Kind = MCBinaryExpr::GTE;
1978     return 3;
1979 
1980   // Low Intermediate Precedence: +, -
1981   case AsmToken::Plus:
1982     Kind = MCBinaryExpr::Add;
1983     return 4;
1984   case AsmToken::Minus:
1985     Kind = MCBinaryExpr::Sub;
1986     return 4;
1987 
1988   // High Intermediate Precedence: |, &, ^
1989   case AsmToken::Pipe:
1990     Kind = MCBinaryExpr::Or;
1991     return 5;
1992   case AsmToken::Caret:
1993     Kind = MCBinaryExpr::Xor;
1994     return 5;
1995   case AsmToken::Amp:
1996     Kind = MCBinaryExpr::And;
1997     return 5;
1998 
1999   // Highest Precedence: *, /, %, <<, >>
2000   case AsmToken::Star:
2001     Kind = MCBinaryExpr::Mul;
2002     return 6;
2003   case AsmToken::Slash:
2004     Kind = MCBinaryExpr::Div;
2005     return 6;
2006   case AsmToken::Percent:
2007     Kind = MCBinaryExpr::Mod;
2008     return 6;
2009   case AsmToken::LessLess:
2010     Kind = MCBinaryExpr::Shl;
2011     return 6;
2012   case AsmToken::GreaterGreater:
2013     if (EndExpressionAtGreater)
2014       return 0;
2015     Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
2016     return 6;
2017   }
2018 }
2019 
2020 unsigned MasmParser::getBinOpPrecedence(AsmToken::TokenKind K,
2021                                         MCBinaryExpr::Opcode &Kind) {
2022   bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
2023   return getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr,
2024                                AngleBracketDepth > 0);
2025 }
2026 
2027 /// Parse all binary operators with precedence >= 'Precedence'.
2028 /// Res contains the LHS of the expression on input.
2029 bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
2030                                SMLoc &EndLoc) {
2031   SMLoc StartLoc = Lexer.getLoc();
2032   while (true) {
2033     AsmToken::TokenKind TokKind = Lexer.getKind();
2034     if (Lexer.getKind() == AsmToken::Identifier) {
2035       TokKind = StringSwitch<AsmToken::TokenKind>(Lexer.getTok().getString())
2036                     .CaseLower("and", AsmToken::Amp)
2037                     .CaseLower("not", AsmToken::Exclaim)
2038                     .CaseLower("or", AsmToken::Pipe)
2039                     .CaseLower("xor", AsmToken::Caret)
2040                     .CaseLower("shl", AsmToken::LessLess)
2041                     .CaseLower("shr", AsmToken::GreaterGreater)
2042                     .CaseLower("eq", AsmToken::EqualEqual)
2043                     .CaseLower("ne", AsmToken::ExclaimEqual)
2044                     .CaseLower("lt", AsmToken::Less)
2045                     .CaseLower("le", AsmToken::LessEqual)
2046                     .CaseLower("gt", AsmToken::Greater)
2047                     .CaseLower("ge", AsmToken::GreaterEqual)
2048                     .Default(TokKind);
2049     }
2050     MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
2051     unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
2052 
2053     // If the next token is lower precedence than we are allowed to eat, return
2054     // successfully with what we ate already.
2055     if (TokPrec < Precedence)
2056       return false;
2057 
2058     Lex();
2059 
2060     // Eat the next primary expression.
2061     const MCExpr *RHS;
2062     if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
2063       return true;
2064 
2065     // If BinOp binds less tightly with RHS than the operator after RHS, let
2066     // the pending operator take RHS as its LHS.
2067     MCBinaryExpr::Opcode Dummy;
2068     unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
2069     if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
2070       return true;
2071 
2072     // Merge LHS and RHS according to operator.
2073     Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
2074   }
2075 }
2076 
2077 /// ParseStatement:
2078 ///   ::= % statement
2079 ///   ::= EndOfStatement
2080 ///   ::= Label* Directive ...Operands... EndOfStatement
2081 ///   ::= Label* Identifier OperandList* EndOfStatement
2082 bool MasmParser::parseStatement(ParseStatementInfo &Info,
2083                                 MCAsmParserSemaCallback *SI) {
2084   assert(!hasPendingError() && "parseStatement started with pending error");
2085   // Eat initial spaces and comments.
2086   while (Lexer.is(AsmToken::Space))
2087     Lex();
2088   if (Lexer.is(AsmToken::EndOfStatement)) {
2089     // If this is a line comment we can drop it safely.
2090     if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
2091         getTok().getString().front() == '\n')
2092       Out.addBlankLine();
2093     Lex();
2094     return false;
2095   }
2096 
2097   // If preceded by an expansion operator, first expand all text macros and
2098   // macro functions.
2099   if (getTok().is(AsmToken::Percent)) {
2100     SMLoc ExpansionLoc = getTok().getLoc();
2101     if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc))
2102       return true;
2103   }
2104 
2105   // Statements always start with an identifier, unless we're dealing with a
2106   // processor directive (.386, .686, etc.) that lexes as a real.
2107   AsmToken ID = getTok();
2108   SMLoc IDLoc = ID.getLoc();
2109   StringRef IDVal;
2110   if (Lexer.is(AsmToken::HashDirective))
2111     return parseCppHashLineFilenameComment(IDLoc);
2112   if (Lexer.is(AsmToken::Dot)) {
2113     // Treat '.' as a valid identifier in this context.
2114     Lex();
2115     IDVal = ".";
2116   } else if (Lexer.is(AsmToken::Real)) {
2117     // Treat ".<number>" as a valid identifier in this context.
2118     IDVal = getTok().getString();
2119     Lex(); // always eat a token
2120     if (!IDVal.starts_with("."))
2121       return Error(IDLoc, "unexpected token at start of statement");
2122   } else if (parseIdentifier(IDVal, StartOfStatement)) {
2123     if (!TheCondState.Ignore) {
2124       Lex(); // always eat a token
2125       return Error(IDLoc, "unexpected token at start of statement");
2126     }
2127     IDVal = "";
2128   }
2129 
2130   // Handle conditional assembly here before checking for skipping.  We
2131   // have to do this so that .endif isn't skipped in a ".if 0" block for
2132   // example.
2133   StringMap<DirectiveKind>::const_iterator DirKindIt =
2134       DirectiveKindMap.find(IDVal.lower());
2135   DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
2136                               ? DK_NO_DIRECTIVE
2137                               : DirKindIt->getValue();
2138   switch (DirKind) {
2139   default:
2140     break;
2141   case DK_IF:
2142   case DK_IFE:
2143     return parseDirectiveIf(IDLoc, DirKind);
2144   case DK_IFB:
2145     return parseDirectiveIfb(IDLoc, true);
2146   case DK_IFNB:
2147     return parseDirectiveIfb(IDLoc, false);
2148   case DK_IFDEF:
2149     return parseDirectiveIfdef(IDLoc, true);
2150   case DK_IFNDEF:
2151     return parseDirectiveIfdef(IDLoc, false);
2152   case DK_IFDIF:
2153     return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
2154                                /*CaseInsensitive=*/false);
2155   case DK_IFDIFI:
2156     return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
2157                                /*CaseInsensitive=*/true);
2158   case DK_IFIDN:
2159     return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
2160                                /*CaseInsensitive=*/false);
2161   case DK_IFIDNI:
2162     return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
2163                                /*CaseInsensitive=*/true);
2164   case DK_ELSEIF:
2165   case DK_ELSEIFE:
2166     return parseDirectiveElseIf(IDLoc, DirKind);
2167   case DK_ELSEIFB:
2168     return parseDirectiveElseIfb(IDLoc, true);
2169   case DK_ELSEIFNB:
2170     return parseDirectiveElseIfb(IDLoc, false);
2171   case DK_ELSEIFDEF:
2172     return parseDirectiveElseIfdef(IDLoc, true);
2173   case DK_ELSEIFNDEF:
2174     return parseDirectiveElseIfdef(IDLoc, false);
2175   case DK_ELSEIFDIF:
2176     return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
2177                                    /*CaseInsensitive=*/false);
2178   case DK_ELSEIFDIFI:
2179     return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
2180                                    /*CaseInsensitive=*/true);
2181   case DK_ELSEIFIDN:
2182     return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
2183                                    /*CaseInsensitive=*/false);
2184   case DK_ELSEIFIDNI:
2185     return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
2186                                    /*CaseInsensitive=*/true);
2187   case DK_ELSE:
2188     return parseDirectiveElse(IDLoc);
2189   case DK_ENDIF:
2190     return parseDirectiveEndIf(IDLoc);
2191   }
2192 
2193   // Ignore the statement if in the middle of inactive conditional
2194   // (e.g. ".if 0").
2195   if (TheCondState.Ignore) {
2196     eatToEndOfStatement();
2197     return false;
2198   }
2199 
2200   // FIXME: Recurse on local labels?
2201 
2202   // Check for a label.
2203   //   ::= identifier ':'
2204   //   ::= number ':'
2205   if (Lexer.is(AsmToken::Colon) && getTargetParser().isLabel(ID)) {
2206     if (checkForValidSection())
2207       return true;
2208 
2209     // identifier ':'   -> Label.
2210     Lex();
2211 
2212     // Diagnose attempt to use '.' as a label.
2213     if (IDVal == ".")
2214       return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
2215 
2216     // Diagnose attempt to use a variable as a label.
2217     //
2218     // FIXME: Diagnostics. Note the location of the definition as a label.
2219     // FIXME: This doesn't diagnose assignment to a symbol which has been
2220     // implicitly marked as external.
2221     MCSymbol *Sym;
2222     if (ParsingMSInlineAsm && SI) {
2223       StringRef RewrittenLabel =
2224           SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
2225       assert(!RewrittenLabel.empty() &&
2226              "We should have an internal name here.");
2227       Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
2228                                      RewrittenLabel);
2229       IDVal = RewrittenLabel;
2230     }
2231     // Handle directional local labels
2232     if (IDVal == "@@") {
2233       Sym = Ctx.createDirectionalLocalSymbol(0);
2234     } else {
2235       Sym = getContext().getOrCreateSymbol(IDVal);
2236     }
2237 
2238     // End of Labels should be treated as end of line for lexing
2239     // purposes but that information is not available to the Lexer who
2240     // does not understand Labels. This may cause us to see a Hash
2241     // here instead of a preprocessor line comment.
2242     if (getTok().is(AsmToken::Hash)) {
2243       std::string CommentStr = parseStringTo(AsmToken::EndOfStatement);
2244       Lexer.Lex();
2245       Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
2246     }
2247 
2248     // Consume any end of statement token, if present, to avoid spurious
2249     // addBlankLine calls().
2250     if (getTok().is(AsmToken::EndOfStatement)) {
2251       Lex();
2252     }
2253 
2254     getTargetParser().doBeforeLabelEmit(Sym, IDLoc);
2255 
2256     // Emit the label.
2257     if (!getTargetParser().isParsingMSInlineAsm())
2258       Out.emitLabel(Sym, IDLoc);
2259 
2260     // If we are generating dwarf for assembly source files then gather the
2261     // info to make a dwarf label entry for this label if needed.
2262     if (enabledGenDwarfForAssembly())
2263       MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
2264                                  IDLoc);
2265 
2266     getTargetParser().onLabelParsed(Sym);
2267 
2268     return false;
2269   }
2270 
2271   // If macros are enabled, check to see if this is a macro instantiation.
2272   if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) {
2273     return handleMacroEntry(M, IDLoc);
2274   }
2275 
2276   // Otherwise, we have a normal instruction or directive.
2277 
2278   if (DirKind != DK_NO_DIRECTIVE) {
2279     // There are several entities interested in parsing directives:
2280     //
2281     // 1. Asm parser extensions. For example, platform-specific parsers
2282     //    (like the ELF parser) register themselves as extensions.
2283     // 2. The target-specific assembly parser. Some directives are target
2284     //    specific or may potentially behave differently on certain targets.
2285     // 3. The generic directive parser implemented by this class. These are
2286     //    all the directives that behave in a target and platform independent
2287     //    manner, or at least have a default behavior that's shared between
2288     //    all targets and platforms.
2289 
2290     getTargetParser().flushPendingInstructions(getStreamer());
2291 
2292     // Special-case handling of structure-end directives at higher priority,
2293     // since ENDS is overloaded as a segment-end directive.
2294     if (IDVal.equals_insensitive("ends") && StructInProgress.size() > 1 &&
2295         getTok().is(AsmToken::EndOfStatement)) {
2296       return parseDirectiveNestedEnds();
2297     }
2298 
2299     // First, check the extension directive map to see if any extension has
2300     // registered itself to parse this directive.
2301     std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2302         ExtensionDirectiveMap.lookup(IDVal.lower());
2303     if (Handler.first)
2304       return (*Handler.second)(Handler.first, IDVal, IDLoc);
2305 
2306     // Next, let the target-specific assembly parser try.
2307     if (ID.isNot(AsmToken::Identifier))
2308       return false;
2309 
2310     ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);
2311     assert(TPDirectiveReturn.isFailure() == hasPendingError() &&
2312            "Should only return Failure iff there was an error");
2313     if (TPDirectiveReturn.isFailure())
2314       return true;
2315     if (TPDirectiveReturn.isSuccess())
2316       return false;
2317 
2318     // Finally, if no one else is interested in this directive, it must be
2319     // generic and familiar to this class.
2320     switch (DirKind) {
2321     default:
2322       break;
2323     case DK_ASCII:
2324       return parseDirectiveAscii(IDVal, false);
2325     case DK_ASCIZ:
2326     case DK_STRING:
2327       return parseDirectiveAscii(IDVal, true);
2328     case DK_BYTE:
2329     case DK_SBYTE:
2330     case DK_DB:
2331       return parseDirectiveValue(IDVal, 1);
2332     case DK_WORD:
2333     case DK_SWORD:
2334     case DK_DW:
2335       return parseDirectiveValue(IDVal, 2);
2336     case DK_DWORD:
2337     case DK_SDWORD:
2338     case DK_DD:
2339       return parseDirectiveValue(IDVal, 4);
2340     case DK_FWORD:
2341     case DK_DF:
2342       return parseDirectiveValue(IDVal, 6);
2343     case DK_QWORD:
2344     case DK_SQWORD:
2345     case DK_DQ:
2346       return parseDirectiveValue(IDVal, 8);
2347     case DK_REAL4:
2348       return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2349     case DK_REAL8:
2350       return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2351     case DK_REAL10:
2352       return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2353     case DK_STRUCT:
2354     case DK_UNION:
2355       return parseDirectiveNestedStruct(IDVal, DirKind);
2356     case DK_ENDS:
2357       return parseDirectiveNestedEnds();
2358     case DK_ALIGN:
2359       return parseDirectiveAlign();
2360     case DK_EVEN:
2361       return parseDirectiveEven();
2362     case DK_ORG:
2363       return parseDirectiveOrg();
2364     case DK_EXTERN:
2365       return parseDirectiveExtern();
2366     case DK_PUBLIC:
2367       return parseDirectiveSymbolAttribute(MCSA_Global);
2368     case DK_COMM:
2369       return parseDirectiveComm(/*IsLocal=*/false);
2370     case DK_COMMENT:
2371       return parseDirectiveComment(IDLoc);
2372     case DK_INCLUDE:
2373       return parseDirectiveInclude();
2374     case DK_REPEAT:
2375       return parseDirectiveRepeat(IDLoc, IDVal);
2376     case DK_WHILE:
2377       return parseDirectiveWhile(IDLoc);
2378     case DK_FOR:
2379       return parseDirectiveFor(IDLoc, IDVal);
2380     case DK_FORC:
2381       return parseDirectiveForc(IDLoc, IDVal);
2382     case DK_FILE:
2383       return parseDirectiveFile(IDLoc);
2384     case DK_LINE:
2385       return parseDirectiveLine();
2386     case DK_LOC:
2387       return parseDirectiveLoc();
2388     case DK_STABS:
2389       return parseDirectiveStabs();
2390     case DK_CV_FILE:
2391       return parseDirectiveCVFile();
2392     case DK_CV_FUNC_ID:
2393       return parseDirectiveCVFuncId();
2394     case DK_CV_INLINE_SITE_ID:
2395       return parseDirectiveCVInlineSiteId();
2396     case DK_CV_LOC:
2397       return parseDirectiveCVLoc();
2398     case DK_CV_LINETABLE:
2399       return parseDirectiveCVLinetable();
2400     case DK_CV_INLINE_LINETABLE:
2401       return parseDirectiveCVInlineLinetable();
2402     case DK_CV_DEF_RANGE:
2403       return parseDirectiveCVDefRange();
2404     case DK_CV_STRING:
2405       return parseDirectiveCVString();
2406     case DK_CV_STRINGTABLE:
2407       return parseDirectiveCVStringTable();
2408     case DK_CV_FILECHECKSUMS:
2409       return parseDirectiveCVFileChecksums();
2410     case DK_CV_FILECHECKSUM_OFFSET:
2411       return parseDirectiveCVFileChecksumOffset();
2412     case DK_CV_FPO_DATA:
2413       return parseDirectiveCVFPOData();
2414     case DK_CFI_SECTIONS:
2415       return parseDirectiveCFISections();
2416     case DK_CFI_STARTPROC:
2417       return parseDirectiveCFIStartProc();
2418     case DK_CFI_ENDPROC:
2419       return parseDirectiveCFIEndProc();
2420     case DK_CFI_DEF_CFA:
2421       return parseDirectiveCFIDefCfa(IDLoc);
2422     case DK_CFI_DEF_CFA_OFFSET:
2423       return parseDirectiveCFIDefCfaOffset(IDLoc);
2424     case DK_CFI_ADJUST_CFA_OFFSET:
2425       return parseDirectiveCFIAdjustCfaOffset(IDLoc);
2426     case DK_CFI_DEF_CFA_REGISTER:
2427       return parseDirectiveCFIDefCfaRegister(IDLoc);
2428     case DK_CFI_OFFSET:
2429       return parseDirectiveCFIOffset(IDLoc);
2430     case DK_CFI_REL_OFFSET:
2431       return parseDirectiveCFIRelOffset(IDLoc);
2432     case DK_CFI_PERSONALITY:
2433       return parseDirectiveCFIPersonalityOrLsda(true);
2434     case DK_CFI_LSDA:
2435       return parseDirectiveCFIPersonalityOrLsda(false);
2436     case DK_CFI_REMEMBER_STATE:
2437       return parseDirectiveCFIRememberState(IDLoc);
2438     case DK_CFI_RESTORE_STATE:
2439       return parseDirectiveCFIRestoreState(IDLoc);
2440     case DK_CFI_SAME_VALUE:
2441       return parseDirectiveCFISameValue(IDLoc);
2442     case DK_CFI_RESTORE:
2443       return parseDirectiveCFIRestore(IDLoc);
2444     case DK_CFI_ESCAPE:
2445       return parseDirectiveCFIEscape(IDLoc);
2446     case DK_CFI_RETURN_COLUMN:
2447       return parseDirectiveCFIReturnColumn(IDLoc);
2448     case DK_CFI_SIGNAL_FRAME:
2449       return parseDirectiveCFISignalFrame();
2450     case DK_CFI_UNDEFINED:
2451       return parseDirectiveCFIUndefined(IDLoc);
2452     case DK_CFI_REGISTER:
2453       return parseDirectiveCFIRegister(IDLoc);
2454     case DK_CFI_WINDOW_SAVE:
2455       return parseDirectiveCFIWindowSave(IDLoc);
2456     case DK_EXITM:
2457       Info.ExitValue = "";
2458       return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);
2459     case DK_ENDM:
2460       Info.ExitValue = "";
2461       return parseDirectiveEndMacro(IDVal);
2462     case DK_PURGE:
2463       return parseDirectivePurgeMacro(IDLoc);
2464     case DK_END:
2465       return parseDirectiveEnd(IDLoc);
2466     case DK_ERR:
2467       return parseDirectiveError(IDLoc);
2468     case DK_ERRB:
2469       return parseDirectiveErrorIfb(IDLoc, true);
2470     case DK_ERRNB:
2471       return parseDirectiveErrorIfb(IDLoc, false);
2472     case DK_ERRDEF:
2473       return parseDirectiveErrorIfdef(IDLoc, true);
2474     case DK_ERRNDEF:
2475       return parseDirectiveErrorIfdef(IDLoc, false);
2476     case DK_ERRDIF:
2477       return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
2478                                       /*CaseInsensitive=*/false);
2479     case DK_ERRDIFI:
2480       return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
2481                                       /*CaseInsensitive=*/true);
2482     case DK_ERRIDN:
2483       return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
2484                                       /*CaseInsensitive=*/false);
2485     case DK_ERRIDNI:
2486       return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
2487                                       /*CaseInsensitive=*/true);
2488     case DK_ERRE:
2489       return parseDirectiveErrorIfe(IDLoc, true);
2490     case DK_ERRNZ:
2491       return parseDirectiveErrorIfe(IDLoc, false);
2492     case DK_RADIX:
2493       return parseDirectiveRadix(IDLoc);
2494     case DK_ECHO:
2495       return parseDirectiveEcho(IDLoc);
2496     }
2497 
2498     return Error(IDLoc, "unknown directive");
2499   }
2500 
2501   // We also check if this is allocating memory with user-defined type.
2502   auto IDIt = Structs.find(IDVal.lower());
2503   if (IDIt != Structs.end())
2504     return parseDirectiveStructValue(/*Structure=*/IDIt->getValue(), IDVal,
2505                                      IDLoc);
2506 
2507   // Non-conditional Microsoft directives sometimes follow their first argument.
2508   const AsmToken nextTok = getTok();
2509   const StringRef nextVal = nextTok.getString();
2510   const SMLoc nextLoc = nextTok.getLoc();
2511 
2512   const AsmToken afterNextTok = peekTok();
2513 
2514   // There are several entities interested in parsing infix directives:
2515   //
2516   // 1. Asm parser extensions. For example, platform-specific parsers
2517   //    (like the ELF parser) register themselves as extensions.
2518   // 2. The generic directive parser implemented by this class. These are
2519   //    all the directives that behave in a target and platform independent
2520   //    manner, or at least have a default behavior that's shared between
2521   //    all targets and platforms.
2522 
2523   getTargetParser().flushPendingInstructions(getStreamer());
2524 
2525   // Special-case handling of structure-end directives at higher priority, since
2526   // ENDS is overloaded as a segment-end directive.
2527   if (nextVal.equals_insensitive("ends") && StructInProgress.size() == 1) {
2528     Lex();
2529     return parseDirectiveEnds(IDVal, IDLoc);
2530   }
2531 
2532   // First, check the extension directive map to see if any extension has
2533   // registered itself to parse this directive.
2534   std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2535       ExtensionDirectiveMap.lookup(nextVal.lower());
2536   if (Handler.first) {
2537     Lex();
2538     Lexer.UnLex(ID);
2539     return (*Handler.second)(Handler.first, nextVal, nextLoc);
2540   }
2541 
2542   // If no one else is interested in this directive, it must be
2543   // generic and familiar to this class.
2544   DirKindIt = DirectiveKindMap.find(nextVal.lower());
2545   DirKind = (DirKindIt == DirectiveKindMap.end())
2546                 ? DK_NO_DIRECTIVE
2547                 : DirKindIt->getValue();
2548   switch (DirKind) {
2549   default:
2550     break;
2551   case DK_ASSIGN:
2552   case DK_EQU:
2553   case DK_TEXTEQU:
2554     Lex();
2555     return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
2556   case DK_BYTE:
2557     if (afterNextTok.is(AsmToken::Identifier) &&
2558         afterNextTok.getString().equals_insensitive("ptr")) {
2559       // Size directive; part of an instruction.
2560       break;
2561     }
2562     [[fallthrough]];
2563   case DK_SBYTE:
2564   case DK_DB:
2565     Lex();
2566     return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2567   case DK_WORD:
2568     if (afterNextTok.is(AsmToken::Identifier) &&
2569         afterNextTok.getString().equals_insensitive("ptr")) {
2570       // Size directive; part of an instruction.
2571       break;
2572     }
2573     [[fallthrough]];
2574   case DK_SWORD:
2575   case DK_DW:
2576     Lex();
2577     return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2578   case DK_DWORD:
2579     if (afterNextTok.is(AsmToken::Identifier) &&
2580         afterNextTok.getString().equals_insensitive("ptr")) {
2581       // Size directive; part of an instruction.
2582       break;
2583     }
2584     [[fallthrough]];
2585   case DK_SDWORD:
2586   case DK_DD:
2587     Lex();
2588     return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2589   case DK_FWORD:
2590     if (afterNextTok.is(AsmToken::Identifier) &&
2591         afterNextTok.getString().equals_insensitive("ptr")) {
2592       // Size directive; part of an instruction.
2593       break;
2594     }
2595     [[fallthrough]];
2596   case DK_DF:
2597     Lex();
2598     return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2599   case DK_QWORD:
2600     if (afterNextTok.is(AsmToken::Identifier) &&
2601         afterNextTok.getString().equals_insensitive("ptr")) {
2602       // Size directive; part of an instruction.
2603       break;
2604     }
2605     [[fallthrough]];
2606   case DK_SQWORD:
2607   case DK_DQ:
2608     Lex();
2609     return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2610   case DK_REAL4:
2611     Lex();
2612     return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2613                                         IDVal, IDLoc);
2614   case DK_REAL8:
2615     Lex();
2616     return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2617                                         IDVal, IDLoc);
2618   case DK_REAL10:
2619     Lex();
2620     return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2621                                         10, IDVal, IDLoc);
2622   case DK_STRUCT:
2623   case DK_UNION:
2624     Lex();
2625     return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2626   case DK_ENDS:
2627     Lex();
2628     return parseDirectiveEnds(IDVal, IDLoc);
2629   case DK_MACRO:
2630     Lex();
2631     return parseDirectiveMacro(IDVal, IDLoc);
2632   }
2633 
2634   // Finally, we check if this is allocating a variable with user-defined type.
2635   auto NextIt = Structs.find(nextVal.lower());
2636   if (NextIt != Structs.end()) {
2637     Lex();
2638     return parseDirectiveNamedStructValue(/*Structure=*/NextIt->getValue(),
2639                                           nextVal, nextLoc, IDVal);
2640   }
2641 
2642   // __asm _emit or __asm __emit
2643   if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2644                              IDVal == "_EMIT" || IDVal == "__EMIT"))
2645     return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2646 
2647   // __asm align
2648   if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2649     return parseDirectiveMSAlign(IDLoc, Info);
2650 
2651   if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2652     Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2653   if (checkForValidSection())
2654     return true;
2655 
2656   // Canonicalize the opcode to lower case.
2657   std::string OpcodeStr = IDVal.lower();
2658   ParseInstructionInfo IInfo(Info.AsmRewrites);
2659   bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
2660                                                           Info.ParsedOperands);
2661   Info.ParseError = ParseHadError;
2662 
2663   // Dump the parsed representation, if requested.
2664   if (getShowParsedOperands()) {
2665     SmallString<256> Str;
2666     raw_svector_ostream OS(Str);
2667     OS << "parsed instruction: [";
2668     for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2669       if (i != 0)
2670         OS << ", ";
2671       Info.ParsedOperands[i]->print(OS);
2672     }
2673     OS << "]";
2674 
2675     printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
2676   }
2677 
2678   // Fail even if ParseInstruction erroneously returns false.
2679   if (hasPendingError() || ParseHadError)
2680     return true;
2681 
2682   // If we are generating dwarf for the current section then generate a .loc
2683   // directive for the instruction.
2684   if (!ParseHadError && enabledGenDwarfForAssembly() &&
2685       getContext().getGenDwarfSectionSyms().count(
2686           getStreamer().getCurrentSectionOnly())) {
2687     unsigned Line;
2688     if (ActiveMacros.empty())
2689       Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
2690     else
2691       Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
2692                                    ActiveMacros.front()->ExitBuffer);
2693 
2694     // If we previously parsed a cpp hash file line comment then make sure the
2695     // current Dwarf File is for the CppHashFilename if not then emit the
2696     // Dwarf File table for it and adjust the line number for the .loc.
2697     if (!CppHashInfo.Filename.empty()) {
2698       unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2699           0, StringRef(), CppHashInfo.Filename);
2700       getContext().setGenDwarfFileNumber(FileNumber);
2701 
2702       unsigned CppHashLocLineNo =
2703         SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
2704       Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2705     }
2706 
2707     getStreamer().emitDwarfLocDirective(
2708         getContext().getGenDwarfFileNumber(), Line, 0,
2709         DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0,
2710         StringRef());
2711   }
2712 
2713   // If parsing succeeded, match the instruction.
2714   if (!ParseHadError) {
2715     uint64_t ErrorInfo;
2716     if (getTargetParser().MatchAndEmitInstruction(
2717             IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
2718             getTargetParser().isParsingMSInlineAsm()))
2719       return true;
2720   }
2721   return false;
2722 }
2723 
2724 // Parse and erase curly braces marking block start/end.
2725 bool MasmParser::parseCurlyBlockScope(
2726     SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
2727   // Identify curly brace marking block start/end.
2728   if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
2729     return false;
2730 
2731   SMLoc StartLoc = Lexer.getLoc();
2732   Lex(); // Eat the brace.
2733   if (Lexer.is(AsmToken::EndOfStatement))
2734     Lex(); // Eat EndOfStatement following the brace.
2735 
2736   // Erase the block start/end brace from the output asm string.
2737   AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
2738                                                   StartLoc.getPointer());
2739   return true;
2740 }
2741 
2742 /// parseCppHashLineFilenameComment as this:
2743 ///   ::= # number "filename"
2744 bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) {
2745   Lex(); // Eat the hash token.
2746   // Lexer only ever emits HashDirective if it fully formed if it's
2747   // done the checking already so this is an internal error.
2748   assert(getTok().is(AsmToken::Integer) &&
2749          "Lexing Cpp line comment: Expected Integer");
2750   int64_t LineNumber = getTok().getIntVal();
2751   Lex();
2752   assert(getTok().is(AsmToken::String) &&
2753          "Lexing Cpp line comment: Expected String");
2754   StringRef Filename = getTok().getString();
2755   Lex();
2756 
2757   // Get rid of the enclosing quotes.
2758   Filename = Filename.substr(1, Filename.size() - 2);
2759 
2760   // Save the SMLoc, Filename and LineNumber for later use by diagnostics
2761   // and possibly DWARF file info.
2762   CppHashInfo.Loc = L;
2763   CppHashInfo.Filename = Filename;
2764   CppHashInfo.LineNumber = LineNumber;
2765   CppHashInfo.Buf = CurBuffer;
2766   if (FirstCppHashFilename.empty())
2767     FirstCppHashFilename = Filename;
2768   return false;
2769 }
2770 
2771 /// will use the last parsed cpp hash line filename comment
2772 /// for the Filename and LineNo if any in the diagnostic.
2773 void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2774   const MasmParser *Parser = static_cast<const MasmParser *>(Context);
2775   raw_ostream &OS = errs();
2776 
2777   const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
2778   SMLoc DiagLoc = Diag.getLoc();
2779   unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2780   unsigned CppHashBuf =
2781       Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2782 
2783   // Like SourceMgr::printMessage() we need to print the include stack if any
2784   // before printing the message.
2785   unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2786   if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2787       DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
2788     SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
2789     DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
2790   }
2791 
2792   // If we have not parsed a cpp hash line filename comment or the source
2793   // manager changed or buffer changed (like in a nested include) then just
2794   // print the normal diagnostic using its Filename and LineNo.
2795   if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2796       DiagBuf != CppHashBuf) {
2797     if (Parser->SavedDiagHandler)
2798       Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2799     else
2800       Diag.print(nullptr, OS);
2801     return;
2802   }
2803 
2804   // Use the CppHashFilename and calculate a line number based on the
2805   // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
2806   // for the diagnostic.
2807   const std::string &Filename = std::string(Parser->CppHashInfo.Filename);
2808 
2809   int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2810   int CppHashLocLineNo =
2811       Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2812   int LineNo =
2813       Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2814 
2815   SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
2816                        Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
2817                        Diag.getLineContents(), Diag.getRanges());
2818 
2819   if (Parser->SavedDiagHandler)
2820     Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2821   else
2822     NewDiag.print(nullptr, OS);
2823 }
2824 
2825 // This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does
2826 // not accept '.'.
2827 static bool isMacroParameterChar(char C) {
2828   return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?';
2829 }
2830 
2831 bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
2832                              ArrayRef<MCAsmMacroParameter> Parameters,
2833                              ArrayRef<MCAsmMacroArgument> A,
2834                              const std::vector<std::string> &Locals, SMLoc L) {
2835   unsigned NParameters = Parameters.size();
2836   if (NParameters != A.size())
2837     return Error(L, "Wrong number of arguments");
2838   StringMap<std::string> LocalSymbols;
2839   std::string Name;
2840   Name.reserve(6);
2841   for (StringRef Local : Locals) {
2842     raw_string_ostream LocalName(Name);
2843     LocalName << "??"
2844               << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true);
2845     LocalSymbols.insert({Local, LocalName.str()});
2846     Name.clear();
2847   }
2848 
2849   std::optional<char> CurrentQuote;
2850   while (!Body.empty()) {
2851     // Scan for the next substitution.
2852     std::size_t End = Body.size(), Pos = 0;
2853     std::size_t IdentifierPos = End;
2854     for (; Pos != End; ++Pos) {
2855       // Find the next possible macro parameter, including preceding a '&'
2856       // inside quotes.
2857       if (Body[Pos] == '&')
2858         break;
2859       if (isMacroParameterChar(Body[Pos])) {
2860         if (!CurrentQuote)
2861           break;
2862         if (IdentifierPos == End)
2863           IdentifierPos = Pos;
2864       } else {
2865         IdentifierPos = End;
2866       }
2867 
2868       // Track quotation status
2869       if (!CurrentQuote) {
2870         if (Body[Pos] == '\'' || Body[Pos] == '"')
2871           CurrentQuote = Body[Pos];
2872       } else if (Body[Pos] == CurrentQuote) {
2873         if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {
2874           // Escaped quote, and quotes aren't identifier chars; skip
2875           ++Pos;
2876           continue;
2877         } else {
2878           CurrentQuote.reset();
2879         }
2880       }
2881     }
2882     if (IdentifierPos != End) {
2883       // We've recognized an identifier before an apostrophe inside quotes;
2884       // check once to see if we can expand it.
2885       Pos = IdentifierPos;
2886       IdentifierPos = End;
2887     }
2888 
2889     // Add the prefix.
2890     OS << Body.slice(0, Pos);
2891 
2892     // Check if we reached the end.
2893     if (Pos == End)
2894       break;
2895 
2896     unsigned I = Pos;
2897     bool InitialAmpersand = (Body[I] == '&');
2898     if (InitialAmpersand) {
2899       ++I;
2900       ++Pos;
2901     }
2902     while (I < End && isMacroParameterChar(Body[I]))
2903       ++I;
2904 
2905     const char *Begin = Body.data() + Pos;
2906     StringRef Argument(Begin, I - Pos);
2907     const std::string ArgumentLower = Argument.lower();
2908     unsigned Index = 0;
2909 
2910     for (; Index < NParameters; ++Index)
2911       if (Parameters[Index].Name.equals_insensitive(ArgumentLower))
2912         break;
2913 
2914     if (Index == NParameters) {
2915       if (InitialAmpersand)
2916         OS << '&';
2917       auto it = LocalSymbols.find(ArgumentLower);
2918       if (it != LocalSymbols.end())
2919         OS << it->second;
2920       else
2921         OS << Argument;
2922       Pos = I;
2923     } else {
2924       for (const AsmToken &Token : A[Index]) {
2925         // In MASM, you can write '%expr'.
2926         // The prefix '%' evaluates the expression 'expr'
2927         // and uses the result as a string (e.g. replace %(1+2) with the
2928         // string "3").
2929         // Here, we identify the integer token which is the result of the
2930         // absolute expression evaluation and replace it with its string
2931         // representation.
2932         if (Token.getString().front() == '%' && Token.is(AsmToken::Integer))
2933           // Emit an integer value to the buffer.
2934           OS << Token.getIntVal();
2935         else
2936           OS << Token.getString();
2937       }
2938 
2939       Pos += Argument.size();
2940       if (Pos < End && Body[Pos] == '&') {
2941         ++Pos;
2942       }
2943     }
2944     // Update the scan point.
2945     Body = Body.substr(Pos);
2946   }
2947 
2948   return false;
2949 }
2950 
2951 static bool isOperator(AsmToken::TokenKind kind) {
2952   switch (kind) {
2953   default:
2954     return false;
2955   case AsmToken::Plus:
2956   case AsmToken::Minus:
2957   case AsmToken::Tilde:
2958   case AsmToken::Slash:
2959   case AsmToken::Star:
2960   case AsmToken::Dot:
2961   case AsmToken::Equal:
2962   case AsmToken::EqualEqual:
2963   case AsmToken::Pipe:
2964   case AsmToken::PipePipe:
2965   case AsmToken::Caret:
2966   case AsmToken::Amp:
2967   case AsmToken::AmpAmp:
2968   case AsmToken::Exclaim:
2969   case AsmToken::ExclaimEqual:
2970   case AsmToken::Less:
2971   case AsmToken::LessEqual:
2972   case AsmToken::LessLess:
2973   case AsmToken::LessGreater:
2974   case AsmToken::Greater:
2975   case AsmToken::GreaterEqual:
2976   case AsmToken::GreaterGreater:
2977     return true;
2978   }
2979 }
2980 
2981 namespace {
2982 
2983 class AsmLexerSkipSpaceRAII {
2984 public:
2985   AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2986     Lexer.setSkipSpace(SkipSpace);
2987   }
2988 
2989   ~AsmLexerSkipSpaceRAII() {
2990     Lexer.setSkipSpace(true);
2991   }
2992 
2993 private:
2994   AsmLexer &Lexer;
2995 };
2996 
2997 } // end anonymous namespace
2998 
2999 bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
3000                                     MCAsmMacroArgument &MA,
3001                                     AsmToken::TokenKind EndTok) {
3002   if (MP && MP->Vararg) {
3003     if (Lexer.isNot(EndTok)) {
3004       SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok);
3005       for (StringRef S : Str) {
3006         MA.emplace_back(AsmToken::String, S);
3007       }
3008     }
3009     return false;
3010   }
3011 
3012   SMLoc StrLoc = Lexer.getLoc(), EndLoc;
3013   if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) {
3014     const char *StrChar = StrLoc.getPointer() + 1;
3015     const char *EndChar = EndLoc.getPointer() - 1;
3016     jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3017     /// Eat from '<' to '>'.
3018     Lex();
3019     MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
3020     return false;
3021   }
3022 
3023   unsigned ParenLevel = 0;
3024 
3025   // Darwin doesn't use spaces to delmit arguments.
3026   AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
3027 
3028   bool SpaceEaten;
3029 
3030   while (true) {
3031     SpaceEaten = false;
3032     if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
3033       return TokError("unexpected token");
3034 
3035     if (ParenLevel == 0) {
3036       if (Lexer.is(AsmToken::Comma))
3037         break;
3038 
3039       if (Lexer.is(AsmToken::Space)) {
3040         SpaceEaten = true;
3041         Lex(); // Eat spaces.
3042       }
3043 
3044       // Spaces can delimit parameters, but could also be part an expression.
3045       // If the token after a space is an operator, add the token and the next
3046       // one into this argument
3047       if (!IsDarwin) {
3048         if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) {
3049           MA.push_back(getTok());
3050           Lex();
3051 
3052           // Whitespace after an operator can be ignored.
3053           if (Lexer.is(AsmToken::Space))
3054             Lex();
3055 
3056           continue;
3057         }
3058       }
3059       if (SpaceEaten)
3060         break;
3061     }
3062 
3063     // handleMacroEntry relies on not advancing the lexer here
3064     // to be able to fill in the remaining default parameter values
3065     if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0))
3066       break;
3067 
3068     // Adjust the current parentheses level.
3069     if (Lexer.is(AsmToken::LParen))
3070       ++ParenLevel;
3071     else if (Lexer.is(AsmToken::RParen) && ParenLevel)
3072       --ParenLevel;
3073 
3074     // Append the token to the current argument list.
3075     MA.push_back(getTok());
3076     Lex();
3077   }
3078 
3079   if (ParenLevel != 0)
3080     return TokError("unbalanced parentheses in argument");
3081 
3082   if (MA.empty() && MP) {
3083     if (MP->Required) {
3084       return TokError("missing value for required parameter '" + MP->Name +
3085                       "'");
3086     } else {
3087       MA = MP->Value;
3088     }
3089   }
3090   return false;
3091 }
3092 
3093 // Parse the macro instantiation arguments.
3094 bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
3095                                      MCAsmMacroArguments &A,
3096                                      AsmToken::TokenKind EndTok) {
3097   const unsigned NParameters = M ? M->Parameters.size() : 0;
3098   bool NamedParametersFound = false;
3099   SmallVector<SMLoc, 4> FALocs;
3100 
3101   A.resize(NParameters);
3102   FALocs.resize(NParameters);
3103 
3104   // Parse two kinds of macro invocations:
3105   // - macros defined without any parameters accept an arbitrary number of them
3106   // - macros defined with parameters accept at most that many of them
3107   for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
3108        ++Parameter) {
3109     SMLoc IDLoc = Lexer.getLoc();
3110     MCAsmMacroParameter FA;
3111 
3112     if (Lexer.is(AsmToken::Identifier) && peekTok().is(AsmToken::Equal)) {
3113       if (parseIdentifier(FA.Name))
3114         return Error(IDLoc, "invalid argument identifier for formal argument");
3115 
3116       if (Lexer.isNot(AsmToken::Equal))
3117         return TokError("expected '=' after formal parameter identifier");
3118 
3119       Lex();
3120 
3121       NamedParametersFound = true;
3122     }
3123 
3124     if (NamedParametersFound && FA.Name.empty())
3125       return Error(IDLoc, "cannot mix positional and keyword arguments");
3126 
3127     unsigned PI = Parameter;
3128     if (!FA.Name.empty()) {
3129       assert(M && "expected macro to be defined");
3130       unsigned FAI = 0;
3131       for (FAI = 0; FAI < NParameters; ++FAI)
3132         if (M->Parameters[FAI].Name == FA.Name)
3133           break;
3134 
3135       if (FAI >= NParameters) {
3136         return Error(IDLoc, "parameter named '" + FA.Name +
3137                                 "' does not exist for macro '" + M->Name + "'");
3138       }
3139       PI = FAI;
3140     }
3141     const MCAsmMacroParameter *MP = nullptr;
3142     if (M && PI < NParameters)
3143       MP = &M->Parameters[PI];
3144 
3145     SMLoc StrLoc = Lexer.getLoc();
3146     SMLoc EndLoc;
3147     if (Lexer.is(AsmToken::Percent)) {
3148       const MCExpr *AbsoluteExp;
3149       int64_t Value;
3150       /// Eat '%'.
3151       Lex();
3152       if (parseExpression(AbsoluteExp, EndLoc))
3153         return false;
3154       if (!AbsoluteExp->evaluateAsAbsolute(Value,
3155                                            getStreamer().getAssemblerPtr()))
3156         return Error(StrLoc, "expected absolute expression");
3157       const char *StrChar = StrLoc.getPointer();
3158       const char *EndChar = EndLoc.getPointer();
3159       AsmToken newToken(AsmToken::Integer,
3160                         StringRef(StrChar, EndChar - StrChar), Value);
3161       FA.Value.push_back(newToken);
3162     } else if (parseMacroArgument(MP, FA.Value, EndTok)) {
3163       if (M)
3164         return addErrorSuffix(" in '" + M->Name + "' macro");
3165       else
3166         return true;
3167     }
3168 
3169     if (!FA.Value.empty()) {
3170       if (A.size() <= PI)
3171         A.resize(PI + 1);
3172       A[PI] = FA.Value;
3173 
3174       if (FALocs.size() <= PI)
3175         FALocs.resize(PI + 1);
3176 
3177       FALocs[PI] = Lexer.getLoc();
3178     }
3179 
3180     // At the end of the statement, fill in remaining arguments that have
3181     // default values. If there aren't any, then the next argument is
3182     // required but missing
3183     if (Lexer.is(EndTok)) {
3184       bool Failure = false;
3185       for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
3186         if (A[FAI].empty()) {
3187           if (M->Parameters[FAI].Required) {
3188             Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
3189                   "missing value for required parameter "
3190                   "'" +
3191                       M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
3192             Failure = true;
3193           }
3194 
3195           if (!M->Parameters[FAI].Value.empty())
3196             A[FAI] = M->Parameters[FAI].Value;
3197         }
3198       }
3199       return Failure;
3200     }
3201 
3202     if (Lexer.is(AsmToken::Comma))
3203       Lex();
3204   }
3205 
3206   return TokError("too many positional arguments");
3207 }
3208 
3209 bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
3210                                   AsmToken::TokenKind ArgumentEndTok) {
3211   // Arbitrarily limit macro nesting depth (default matches 'as'). We can
3212   // eliminate this, although we should protect against infinite loops.
3213   unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
3214   if (ActiveMacros.size() == MaxNestingDepth) {
3215     std::ostringstream MaxNestingDepthError;
3216     MaxNestingDepthError << "macros cannot be nested more than "
3217                          << MaxNestingDepth << " levels deep."
3218                          << " Use -asm-macro-max-nesting-depth to increase "
3219                             "this limit.";
3220     return TokError(MaxNestingDepthError.str());
3221   }
3222 
3223   MCAsmMacroArguments A;
3224   if (parseMacroArguments(M, A, ArgumentEndTok))
3225     return true;
3226 
3227   // Macro instantiation is lexical, unfortunately. We construct a new buffer
3228   // to hold the macro body with substitutions.
3229   SmallString<256> Buf;
3230   StringRef Body = M->Body;
3231   raw_svector_ostream OS(Buf);
3232 
3233   if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc()))
3234     return true;
3235 
3236   // We include the endm in the buffer as our cue to exit the macro
3237   // instantiation.
3238   OS << "endm\n";
3239 
3240   std::unique_ptr<MemoryBuffer> Instantiation =
3241       MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
3242 
3243   // Create the macro instantiation object and add to the current macro
3244   // instantiation stack.
3245   MacroInstantiation *MI = new MacroInstantiation{
3246       NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
3247   ActiveMacros.push_back(MI);
3248 
3249   ++NumOfMacroInstantiations;
3250 
3251   // Jump to the macro instantiation and prime the lexer.
3252   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
3253   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
3254   EndStatementAtEOFStack.push_back(true);
3255   Lex();
3256 
3257   return false;
3258 }
3259 
3260 void MasmParser::handleMacroExit() {
3261   // Jump to the token we should return to, and consume it.
3262   EndStatementAtEOFStack.pop_back();
3263   jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
3264             EndStatementAtEOFStack.back());
3265   Lex();
3266 
3267   // Pop the instantiation entry.
3268   delete ActiveMacros.back();
3269   ActiveMacros.pop_back();
3270 }
3271 
3272 bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) {
3273   if (!M->IsFunction)
3274     return Error(NameLoc, "cannot invoke macro procedure as function");
3275 
3276   if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name +
3277                                        "' requires arguments in parentheses") ||
3278       handleMacroEntry(M, NameLoc, AsmToken::RParen))
3279     return true;
3280 
3281   // Parse all statements in the macro, retrieving the exit value when it ends.
3282   std::string ExitValue;
3283   SmallVector<AsmRewrite, 4> AsmStrRewrites;
3284   while (Lexer.isNot(AsmToken::Eof)) {
3285     ParseStatementInfo Info(&AsmStrRewrites);
3286     bool Parsed = parseStatement(Info, nullptr);
3287 
3288     if (!Parsed && Info.ExitValue) {
3289       ExitValue = std::move(*Info.ExitValue);
3290       break;
3291     }
3292 
3293     // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
3294     // for printing ErrMsg via Lex() only if no (presumably better) parser error
3295     // exists.
3296     if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
3297       Lex();
3298     }
3299 
3300     // parseStatement returned true so may need to emit an error.
3301     printPendingErrors();
3302 
3303     // Skipping to the next line if needed.
3304     if (Parsed && !getLexer().isAtStartOfStatement())
3305       eatToEndOfStatement();
3306   }
3307 
3308   // Consume the right-parenthesis on the other side of the arguments.
3309   if (parseRParen())
3310     return true;
3311 
3312   // Exit values may require lexing, unfortunately. We construct a new buffer to
3313   // hold the exit value.
3314   std::unique_ptr<MemoryBuffer> MacroValue =
3315       MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>");
3316 
3317   // Jump from this location to the instantiated exit value, and prime the
3318   // lexer.
3319   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc());
3320   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
3321                   /*EndStatementAtEOF=*/false);
3322   EndStatementAtEOFStack.push_back(false);
3323   Lex();
3324 
3325   return false;
3326 }
3327 
3328 /// parseIdentifier:
3329 ///   ::= identifier
3330 ///   ::= string
3331 bool MasmParser::parseIdentifier(StringRef &Res,
3332                                  IdentifierPositionKind Position) {
3333   // The assembler has relaxed rules for accepting identifiers, in particular we
3334   // allow things like '.globl $foo' and '.def @feat.00', which would normally
3335   // be separate tokens. At this level, we have already lexed so we cannot
3336   // (currently) handle this as a context dependent token, instead we detect
3337   // adjacent tokens and return the combined identifier.
3338   if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
3339     SMLoc PrefixLoc = getLexer().getLoc();
3340 
3341     // Consume the prefix character, and check for a following identifier.
3342 
3343     AsmToken nextTok = peekTok(false);
3344 
3345     if (nextTok.isNot(AsmToken::Identifier))
3346       return true;
3347 
3348     // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
3349     if (PrefixLoc.getPointer() + 1 != nextTok.getLoc().getPointer())
3350       return true;
3351 
3352     // eat $ or @
3353     Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
3354     // Construct the joined identifier and consume the token.
3355     Res =
3356         StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
3357     Lex(); // Parser Lex to maintain invariants.
3358     return false;
3359   }
3360 
3361   if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
3362     return true;
3363 
3364   Res = getTok().getIdentifier();
3365 
3366   // Consume the identifier token - but if parsing certain directives, avoid
3367   // lexical expansion of the next token.
3368   ExpandKind ExpandNextToken = ExpandMacros;
3369   if (Position == StartOfStatement &&
3370       StringSwitch<bool>(Res)
3371           .CaseLower("echo", true)
3372           .CasesLower("ifdef", "ifndef", "elseifdef", "elseifndef", true)
3373           .Default(false)) {
3374     ExpandNextToken = DoNotExpandMacros;
3375   }
3376   Lex(ExpandNextToken);
3377 
3378   return false;
3379 }
3380 
3381 /// parseDirectiveEquate:
3382 ///  ::= name "=" expression
3383 ///    | name "equ" expression    (not redefinable)
3384 ///    | name "equ" text-list
3385 ///    | name "textequ" text-list (redefinability unspecified)
3386 bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
3387                                       DirectiveKind DirKind, SMLoc NameLoc) {
3388   auto BuiltinIt = BuiltinSymbolMap.find(Name.lower());
3389   if (BuiltinIt != BuiltinSymbolMap.end())
3390     return Error(NameLoc, "cannot redefine a built-in symbol");
3391 
3392   Variable &Var = Variables[Name.lower()];
3393   if (Var.Name.empty()) {
3394     Var.Name = Name;
3395   }
3396 
3397   SMLoc StartLoc = Lexer.getLoc();
3398   if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3399     // "equ" and "textequ" both allow text expressions.
3400     std::string Value;
3401     std::string TextItem;
3402     if (!parseTextItem(TextItem)) {
3403       Value += TextItem;
3404 
3405       // Accept a text-list, not just one text-item.
3406       auto parseItem = [&]() -> bool {
3407         if (parseTextItem(TextItem))
3408           return TokError("expected text item");
3409         Value += TextItem;
3410         return false;
3411       };
3412       if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem))
3413         return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3414 
3415       if (!Var.IsText || Var.TextValue != Value) {
3416         switch (Var.Redefinable) {
3417         case Variable::NOT_REDEFINABLE:
3418           return Error(getTok().getLoc(), "invalid variable redefinition");
3419         case Variable::WARN_ON_REDEFINITION:
3420           if (Warning(NameLoc, "redefining '" + Name +
3421                                    "', already defined on the command line")) {
3422             return true;
3423           }
3424           break;
3425         default:
3426           break;
3427         }
3428       }
3429       Var.IsText = true;
3430       Var.TextValue = Value;
3431       Var.Redefinable = Variable::REDEFINABLE;
3432 
3433       return false;
3434     }
3435   }
3436   if (DirKind == DK_TEXTEQU)
3437     return TokError("expected <text> in '" + Twine(IDVal) + "' directive");
3438 
3439   // Parse as expression assignment.
3440   const MCExpr *Expr;
3441   SMLoc EndLoc;
3442   if (parseExpression(Expr, EndLoc))
3443     return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3444   StringRef ExprAsString = StringRef(
3445       StartLoc.getPointer(), EndLoc.getPointer() - StartLoc.getPointer());
3446 
3447   int64_t Value;
3448   if (!Expr->evaluateAsAbsolute(Value, getStreamer().getAssemblerPtr())) {
3449     if (DirKind == DK_ASSIGN)
3450       return Error(
3451           StartLoc,
3452           "expected absolute expression; not all symbols have known values",
3453           {StartLoc, EndLoc});
3454 
3455     // Not an absolute expression; define as a text replacement.
3456     if (!Var.IsText || Var.TextValue != ExprAsString) {
3457       switch (Var.Redefinable) {
3458       case Variable::NOT_REDEFINABLE:
3459         return Error(getTok().getLoc(), "invalid variable redefinition");
3460       case Variable::WARN_ON_REDEFINITION:
3461         if (Warning(NameLoc, "redefining '" + Name +
3462                                  "', already defined on the command line")) {
3463           return true;
3464         }
3465         break;
3466       default:
3467         break;
3468       }
3469     }
3470 
3471     Var.IsText = true;
3472     Var.TextValue = ExprAsString.str();
3473     Var.Redefinable = Variable::REDEFINABLE;
3474 
3475     return false;
3476   }
3477 
3478   MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
3479 
3480   const MCConstantExpr *PrevValue =
3481       Sym->isVariable() ? dyn_cast_or_null<MCConstantExpr>(
3482                               Sym->getVariableValue(/*SetUsed=*/false))
3483                         : nullptr;
3484   if (Var.IsText || !PrevValue || PrevValue->getValue() != Value) {
3485     switch (Var.Redefinable) {
3486     case Variable::NOT_REDEFINABLE:
3487       return Error(getTok().getLoc(), "invalid variable redefinition");
3488     case Variable::WARN_ON_REDEFINITION:
3489       if (Warning(NameLoc, "redefining '" + Name +
3490                                "', already defined on the command line")) {
3491         return true;
3492       }
3493       break;
3494     default:
3495       break;
3496     }
3497   }
3498 
3499   Var.IsText = false;
3500   Var.TextValue.clear();
3501   Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
3502                                            : Variable::NOT_REDEFINABLE;
3503 
3504   Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
3505   Sym->setVariableValue(Expr);
3506   Sym->setExternal(false);
3507 
3508   return false;
3509 }
3510 
3511 bool MasmParser::parseEscapedString(std::string &Data) {
3512   if (check(getTok().isNot(AsmToken::String), "expected string"))
3513     return true;
3514 
3515   Data = "";
3516   char Quote = getTok().getString().front();
3517   StringRef Str = getTok().getStringContents();
3518   Data.reserve(Str.size());
3519   for (size_t i = 0, e = Str.size(); i != e; ++i) {
3520     Data.push_back(Str[i]);
3521     if (Str[i] == Quote) {
3522       // MASM treats doubled delimiting quotes as an escaped delimiting quote.
3523       // If we're escaping the string's trailing delimiter, we're definitely
3524       // missing a quotation mark.
3525       if (i + 1 == Str.size())
3526         return Error(getTok().getLoc(), "missing quotation mark in string");
3527       if (Str[i + 1] == Quote)
3528         ++i;
3529     }
3530   }
3531 
3532   Lex();
3533   return false;
3534 }
3535 
3536 bool MasmParser::parseAngleBracketString(std::string &Data) {
3537   SMLoc EndLoc, StartLoc = getTok().getLoc();
3538   if (isAngleBracketString(StartLoc, EndLoc)) {
3539     const char *StartChar = StartLoc.getPointer() + 1;
3540     const char *EndChar = EndLoc.getPointer() - 1;
3541     jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3542     // Eat from '<' to '>'.
3543     Lex();
3544 
3545     Data = angleBracketString(StringRef(StartChar, EndChar - StartChar));
3546     return false;
3547   }
3548   return true;
3549 }
3550 
3551 /// textItem ::= textLiteral | textMacroID | % constExpr
3552 bool MasmParser::parseTextItem(std::string &Data) {
3553   switch (getTok().getKind()) {
3554   default:
3555     return true;
3556   case AsmToken::Percent: {
3557     int64_t Res;
3558     if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))
3559       return true;
3560     Data = std::to_string(Res);
3561     return false;
3562   }
3563   case AsmToken::Less:
3564   case AsmToken::LessEqual:
3565   case AsmToken::LessLess:
3566   case AsmToken::LessGreater:
3567     return parseAngleBracketString(Data);
3568   case AsmToken::Identifier: {
3569     // This must be a text macro; we need to expand it accordingly.
3570     StringRef ID;
3571     SMLoc StartLoc = getTok().getLoc();
3572     if (parseIdentifier(ID))
3573       return true;
3574     Data = ID.str();
3575 
3576     bool Expanded = false;
3577     while (true) {
3578       // Try to resolve as a built-in text macro
3579       auto BuiltinIt = BuiltinSymbolMap.find(ID.lower());
3580       if (BuiltinIt != BuiltinSymbolMap.end()) {
3581         std::optional<std::string> BuiltinText =
3582             evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
3583         if (!BuiltinText) {
3584           // Not a text macro; break without substituting
3585           break;
3586         }
3587         Data = std::move(*BuiltinText);
3588         ID = StringRef(Data);
3589         Expanded = true;
3590         continue;
3591       }
3592 
3593       // Try to resolve as a variable text macro
3594       auto VarIt = Variables.find(ID.lower());
3595       if (VarIt != Variables.end()) {
3596         const Variable &Var = VarIt->getValue();
3597         if (!Var.IsText) {
3598           // Not a text macro; break without substituting
3599           break;
3600         }
3601         Data = Var.TextValue;
3602         ID = StringRef(Data);
3603         Expanded = true;
3604         continue;
3605       }
3606 
3607       break;
3608     }
3609 
3610     if (!Expanded) {
3611       // Not a text macro; not usable in TextItem context. Since we haven't used
3612       // the token, put it back for better error recovery.
3613       getLexer().UnLex(AsmToken(AsmToken::Identifier, ID));
3614       return true;
3615     }
3616     return false;
3617   }
3618   }
3619   llvm_unreachable("unhandled token kind");
3620 }
3621 
3622 /// parseDirectiveAscii:
3623 ///   ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
3624 bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
3625   auto parseOp = [&]() -> bool {
3626     std::string Data;
3627     if (checkForValidSection() || parseEscapedString(Data))
3628       return true;
3629     getStreamer().emitBytes(Data);
3630     if (ZeroTerminated)
3631       getStreamer().emitBytes(StringRef("\0", 1));
3632     return false;
3633   };
3634 
3635   if (parseMany(parseOp))
3636     return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3637   return false;
3638 }
3639 
3640 bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) {
3641   // Special case constant expressions to match code generator.
3642   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3643     assert(Size <= 8 && "Invalid size");
3644     int64_t IntValue = MCE->getValue();
3645     if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3646       return Error(MCE->getLoc(), "out of range literal value");
3647     getStreamer().emitIntValue(IntValue, Size);
3648   } else {
3649     const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value);
3650     if (MSE && MSE->getSymbol().getName() == "?") {
3651       // ? initializer; treat as 0.
3652       getStreamer().emitIntValue(0, Size);
3653     } else {
3654       getStreamer().emitValue(Value, Size, Value->getLoc());
3655     }
3656   }
3657   return false;
3658 }
3659 
3660 bool MasmParser::parseScalarInitializer(unsigned Size,
3661                                         SmallVectorImpl<const MCExpr *> &Values,
3662                                         unsigned StringPadLength) {
3663   if (Size == 1 && getTok().is(AsmToken::String)) {
3664     std::string Value;
3665     if (parseEscapedString(Value))
3666       return true;
3667     // Treat each character as an initializer.
3668     for (const unsigned char CharVal : Value)
3669       Values.push_back(MCConstantExpr::create(CharVal, getContext()));
3670 
3671     // Pad the string with spaces to the specified length.
3672     for (size_t i = Value.size(); i < StringPadLength; ++i)
3673       Values.push_back(MCConstantExpr::create(' ', getContext()));
3674   } else {
3675     const MCExpr *Value;
3676     if (parseExpression(Value))
3677       return true;
3678     if (getTok().is(AsmToken::Identifier) &&
3679         getTok().getString().equals_insensitive("dup")) {
3680       Lex(); // Eat 'dup'.
3681       const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3682       if (!MCE)
3683         return Error(Value->getLoc(),
3684                      "cannot repeat value a non-constant number of times");
3685       const int64_t Repetitions = MCE->getValue();
3686       if (Repetitions < 0)
3687         return Error(Value->getLoc(),
3688                      "cannot repeat value a negative number of times");
3689 
3690       SmallVector<const MCExpr *, 1> DuplicatedValues;
3691       if (parseToken(AsmToken::LParen,
3692                      "parentheses required for 'dup' contents") ||
3693           parseScalarInstList(Size, DuplicatedValues) || parseRParen())
3694         return true;
3695 
3696       for (int i = 0; i < Repetitions; ++i)
3697         Values.append(DuplicatedValues.begin(), DuplicatedValues.end());
3698     } else {
3699       Values.push_back(Value);
3700     }
3701   }
3702   return false;
3703 }
3704 
3705 bool MasmParser::parseScalarInstList(unsigned Size,
3706                                      SmallVectorImpl<const MCExpr *> &Values,
3707                                      const AsmToken::TokenKind EndToken) {
3708   while (getTok().isNot(EndToken) &&
3709          (EndToken != AsmToken::Greater ||
3710           getTok().isNot(AsmToken::GreaterGreater))) {
3711     parseScalarInitializer(Size, Values);
3712 
3713     // If we see a comma, continue, and allow line continuation.
3714     if (!parseOptionalToken(AsmToken::Comma))
3715       break;
3716     parseOptionalToken(AsmToken::EndOfStatement);
3717   }
3718   return false;
3719 }
3720 
3721 bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {
3722   SmallVector<const MCExpr *, 1> Values;
3723   if (checkForValidSection() || parseScalarInstList(Size, Values))
3724     return true;
3725 
3726   for (const auto *Value : Values) {
3727     emitIntValue(Value, Size);
3728   }
3729   if (Count)
3730     *Count = Values.size();
3731   return false;
3732 }
3733 
3734 // Add a field to the current structure.
3735 bool MasmParser::addIntegralField(StringRef Name, unsigned Size) {
3736   StructInfo &Struct = StructInProgress.back();
3737   FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size);
3738   IntFieldInfo &IntInfo = Field.Contents.IntInfo;
3739 
3740   Field.Type = Size;
3741 
3742   if (parseScalarInstList(Size, IntInfo.Values))
3743     return true;
3744 
3745   Field.SizeOf = Field.Type * IntInfo.Values.size();
3746   Field.LengthOf = IntInfo.Values.size();
3747   const unsigned FieldEnd = Field.Offset + Field.SizeOf;
3748   if (!Struct.IsUnion) {
3749     Struct.NextOffset = FieldEnd;
3750   }
3751   Struct.Size = std::max(Struct.Size, FieldEnd);
3752   return false;
3753 }
3754 
3755 /// parseDirectiveValue
3756 ///  ::= (byte | word | ... ) [ expression (, expression)* ]
3757 bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
3758   if (StructInProgress.empty()) {
3759     // Initialize data value.
3760     if (emitIntegralValues(Size))
3761       return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3762   } else if (addIntegralField("", Size)) {
3763     return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3764   }
3765 
3766   return false;
3767 }
3768 
3769 /// parseDirectiveNamedValue
3770 ///  ::= name (byte | word | ... ) [ expression (, expression)* ]
3771 bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
3772                                           StringRef Name, SMLoc NameLoc) {
3773   if (StructInProgress.empty()) {
3774     // Initialize named data value.
3775     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3776     getStreamer().emitLabel(Sym);
3777     unsigned Count;
3778     if (emitIntegralValues(Size, &Count))
3779       return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
3780 
3781     AsmTypeInfo Type;
3782     Type.Name = TypeName;
3783     Type.Size = Size * Count;
3784     Type.ElementSize = Size;
3785     Type.Length = Count;
3786     KnownType[Name.lower()] = Type;
3787   } else if (addIntegralField(Name, Size)) {
3788     return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
3789   }
3790 
3791   return false;
3792 }
3793 
3794 static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo) {
3795   if (Asm.getTok().isNot(AsmToken::Integer) &&
3796       Asm.getTok().isNot(AsmToken::BigNum))
3797     return Asm.TokError("unknown token in expression");
3798   SMLoc ExprLoc = Asm.getTok().getLoc();
3799   APInt IntValue = Asm.getTok().getAPIntVal();
3800   Asm.Lex();
3801   if (!IntValue.isIntN(128))
3802     return Asm.Error(ExprLoc, "out of range literal value");
3803   if (!IntValue.isIntN(64)) {
3804     hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
3805     lo = IntValue.getLoBits(64).getZExtValue();
3806   } else {
3807     hi = 0;
3808     lo = IntValue.getZExtValue();
3809   }
3810   return false;
3811 }
3812 
3813 bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3814   // We don't truly support arithmetic on floating point expressions, so we
3815   // have to manually parse unary prefixes.
3816   bool IsNeg = false;
3817   SMLoc SignLoc;
3818   if (getLexer().is(AsmToken::Minus)) {
3819     SignLoc = getLexer().getLoc();
3820     Lexer.Lex();
3821     IsNeg = true;
3822   } else if (getLexer().is(AsmToken::Plus)) {
3823     SignLoc = getLexer().getLoc();
3824     Lexer.Lex();
3825   }
3826 
3827   if (Lexer.is(AsmToken::Error))
3828     return TokError(Lexer.getErr());
3829   if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
3830       Lexer.isNot(AsmToken::Identifier))
3831     return TokError("unexpected token in directive");
3832 
3833   // Convert to an APFloat.
3834   APFloat Value(Semantics);
3835   StringRef IDVal = getTok().getString();
3836   if (getLexer().is(AsmToken::Identifier)) {
3837     if (IDVal.equals_insensitive("infinity") || IDVal.equals_insensitive("inf"))
3838       Value = APFloat::getInf(Semantics);
3839     else if (IDVal.equals_insensitive("nan"))
3840       Value = APFloat::getNaN(Semantics, false, ~0);
3841     else if (IDVal.equals_insensitive("?"))
3842       Value = APFloat::getZero(Semantics);
3843     else
3844       return TokError("invalid floating point literal");
3845   } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) {
3846     // MASM hexadecimal floating-point literal; no APFloat conversion needed.
3847     // To match ML64.exe, ignore the initial sign.
3848     unsigned SizeInBits = Value.getSizeInBits(Semantics);
3849     if (SizeInBits != (IDVal.size() << 2))
3850       return TokError("invalid floating point literal");
3851 
3852     // Consume the numeric token.
3853     Lex();
3854 
3855     Res = APInt(SizeInBits, IDVal, 16);
3856     if (SignLoc.isValid())
3857       return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");
3858     return false;
3859   } else if (errorToBool(
3860                  Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3861                      .takeError())) {
3862     return TokError("invalid floating point literal");
3863   }
3864   if (IsNeg)
3865     Value.changeSign();
3866 
3867   // Consume the numeric token.
3868   Lex();
3869 
3870   Res = Value.bitcastToAPInt();
3871 
3872   return false;
3873 }
3874 
3875 bool MasmParser::parseRealInstList(const fltSemantics &Semantics,
3876                                    SmallVectorImpl<APInt> &ValuesAsInt,
3877                                    const AsmToken::TokenKind EndToken) {
3878   while (getTok().isNot(EndToken) ||
3879          (EndToken == AsmToken::Greater &&
3880           getTok().isNot(AsmToken::GreaterGreater))) {
3881     const AsmToken NextTok = peekTok();
3882     if (NextTok.is(AsmToken::Identifier) &&
3883         NextTok.getString().equals_insensitive("dup")) {
3884       const MCExpr *Value;
3885       if (parseExpression(Value) || parseToken(AsmToken::Identifier))
3886         return true;
3887       const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3888       if (!MCE)
3889         return Error(Value->getLoc(),
3890                      "cannot repeat value a non-constant number of times");
3891       const int64_t Repetitions = MCE->getValue();
3892       if (Repetitions < 0)
3893         return Error(Value->getLoc(),
3894                      "cannot repeat value a negative number of times");
3895 
3896       SmallVector<APInt, 1> DuplicatedValues;
3897       if (parseToken(AsmToken::LParen,
3898                      "parentheses required for 'dup' contents") ||
3899           parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
3900         return true;
3901 
3902       for (int i = 0; i < Repetitions; ++i)
3903         ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end());
3904     } else {
3905       APInt AsInt;
3906       if (parseRealValue(Semantics, AsInt))
3907         return true;
3908       ValuesAsInt.push_back(AsInt);
3909     }
3910 
3911     // Continue if we see a comma. (Also, allow line continuation.)
3912     if (!parseOptionalToken(AsmToken::Comma))
3913       break;
3914     parseOptionalToken(AsmToken::EndOfStatement);
3915   }
3916 
3917   return false;
3918 }
3919 
3920 // Initialize real data values.
3921 bool MasmParser::emitRealValues(const fltSemantics &Semantics,
3922                                 unsigned *Count) {
3923   if (checkForValidSection())
3924     return true;
3925 
3926   SmallVector<APInt, 1> ValuesAsInt;
3927   if (parseRealInstList(Semantics, ValuesAsInt))
3928     return true;
3929 
3930   for (const APInt &AsInt : ValuesAsInt) {
3931     getStreamer().emitIntValue(AsInt);
3932   }
3933   if (Count)
3934     *Count = ValuesAsInt.size();
3935   return false;
3936 }
3937 
3938 // Add a real field to the current struct.
3939 bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
3940                               size_t Size) {
3941   StructInfo &Struct = StructInProgress.back();
3942   FieldInfo &Field = Struct.addField(Name, FT_REAL, Size);
3943   RealFieldInfo &RealInfo = Field.Contents.RealInfo;
3944 
3945   Field.SizeOf = 0;
3946 
3947   if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3948     return true;
3949 
3950   Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3951   Field.LengthOf = RealInfo.AsIntValues.size();
3952   Field.SizeOf = Field.Type * Field.LengthOf;
3953 
3954   const unsigned FieldEnd = Field.Offset + Field.SizeOf;
3955   if (!Struct.IsUnion) {
3956     Struct.NextOffset = FieldEnd;
3957   }
3958   Struct.Size = std::max(Struct.Size, FieldEnd);
3959   return false;
3960 }
3961 
3962 /// parseDirectiveRealValue
3963 ///  ::= (real4 | real8 | real10) [ expression (, expression)* ]
3964 bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
3965                                          const fltSemantics &Semantics,
3966                                          size_t Size) {
3967   if (StructInProgress.empty()) {
3968     // Initialize data value.
3969     if (emitRealValues(Semantics))
3970       return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3971   } else if (addRealField("", Semantics, Size)) {
3972     return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3973   }
3974   return false;
3975 }
3976 
3977 /// parseDirectiveNamedRealValue
3978 ///  ::= name (real4 | real8 | real10) [ expression (, expression)* ]
3979 bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,
3980                                               const fltSemantics &Semantics,
3981                                               unsigned Size, StringRef Name,
3982                                               SMLoc NameLoc) {
3983   if (StructInProgress.empty()) {
3984     // Initialize named data value.
3985     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3986     getStreamer().emitLabel(Sym);
3987     unsigned Count;
3988     if (emitRealValues(Semantics, &Count))
3989       return addErrorSuffix(" in '" + TypeName + "' directive");
3990 
3991     AsmTypeInfo Type;
3992     Type.Name = TypeName;
3993     Type.Size = Size * Count;
3994     Type.ElementSize = Size;
3995     Type.Length = Count;
3996     KnownType[Name.lower()] = Type;
3997   } else if (addRealField(Name, Semantics, Size)) {
3998     return addErrorSuffix(" in '" + TypeName + "' directive");
3999   }
4000   return false;
4001 }
4002 
4003 bool MasmParser::parseOptionalAngleBracketOpen() {
4004   const AsmToken Tok = getTok();
4005   if (parseOptionalToken(AsmToken::LessLess)) {
4006     AngleBracketDepth++;
4007     Lexer.UnLex(AsmToken(AsmToken::Less, Tok.getString().substr(1)));
4008     return true;
4009   } else if (parseOptionalToken(AsmToken::LessGreater)) {
4010     AngleBracketDepth++;
4011     Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
4012     return true;
4013   } else if (parseOptionalToken(AsmToken::Less)) {
4014     AngleBracketDepth++;
4015     return true;
4016   }
4017 
4018   return false;
4019 }
4020 
4021 bool MasmParser::parseAngleBracketClose(const Twine &Msg) {
4022   const AsmToken Tok = getTok();
4023   if (parseOptionalToken(AsmToken::GreaterGreater)) {
4024     Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
4025   } else if (parseToken(AsmToken::Greater, Msg)) {
4026     return true;
4027   }
4028   AngleBracketDepth--;
4029   return false;
4030 }
4031 
4032 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
4033                                        const IntFieldInfo &Contents,
4034                                        FieldInitializer &Initializer) {
4035   SMLoc Loc = getTok().getLoc();
4036 
4037   SmallVector<const MCExpr *, 1> Values;
4038   if (parseOptionalToken(AsmToken::LCurly)) {
4039     if (Field.LengthOf == 1 && Field.Type > 1)
4040       return Error(Loc, "Cannot initialize scalar field with array value");
4041     if (parseScalarInstList(Field.Type, Values, AsmToken::RCurly) ||
4042         parseToken(AsmToken::RCurly))
4043       return true;
4044   } else if (parseOptionalAngleBracketOpen()) {
4045     if (Field.LengthOf == 1 && Field.Type > 1)
4046       return Error(Loc, "Cannot initialize scalar field with array value");
4047     if (parseScalarInstList(Field.Type, Values, AsmToken::Greater) ||
4048         parseAngleBracketClose())
4049       return true;
4050   } else if (Field.LengthOf > 1 && Field.Type > 1) {
4051     return Error(Loc, "Cannot initialize array field with scalar value");
4052   } else if (parseScalarInitializer(Field.Type, Values,
4053                                     /*StringPadLength=*/Field.LengthOf)) {
4054     return true;
4055   }
4056 
4057   if (Values.size() > Field.LengthOf) {
4058     return Error(Loc, "Initializer too long for field; expected at most " +
4059                           std::to_string(Field.LengthOf) + " elements, got " +
4060                           std::to_string(Values.size()));
4061   }
4062   // Default-initialize all remaining values.
4063   Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end());
4064 
4065   Initializer = FieldInitializer(std::move(Values));
4066   return false;
4067 }
4068 
4069 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
4070                                        const RealFieldInfo &Contents,
4071                                        FieldInitializer &Initializer) {
4072   const fltSemantics *Semantics;
4073   switch (Field.Type) {
4074   case 4:
4075     Semantics = &APFloat::IEEEsingle();
4076     break;
4077   case 8:
4078     Semantics = &APFloat::IEEEdouble();
4079     break;
4080   case 10:
4081     Semantics = &APFloat::x87DoubleExtended();
4082     break;
4083   default:
4084     llvm_unreachable("unknown real field type");
4085   }
4086 
4087   SMLoc Loc = getTok().getLoc();
4088 
4089   SmallVector<APInt, 1> AsIntValues;
4090   if (parseOptionalToken(AsmToken::LCurly)) {
4091     if (Field.LengthOf == 1)
4092       return Error(Loc, "Cannot initialize scalar field with array value");
4093     if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||
4094         parseToken(AsmToken::RCurly))
4095       return true;
4096   } else if (parseOptionalAngleBracketOpen()) {
4097     if (Field.LengthOf == 1)
4098       return Error(Loc, "Cannot initialize scalar field with array value");
4099     if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||
4100         parseAngleBracketClose())
4101       return true;
4102   } else if (Field.LengthOf > 1) {
4103     return Error(Loc, "Cannot initialize array field with scalar value");
4104   } else {
4105     AsIntValues.emplace_back();
4106     if (parseRealValue(*Semantics, AsIntValues.back()))
4107       return true;
4108   }
4109 
4110   if (AsIntValues.size() > Field.LengthOf) {
4111     return Error(Loc, "Initializer too long for field; expected at most " +
4112                           std::to_string(Field.LengthOf) + " elements, got " +
4113                           std::to_string(AsIntValues.size()));
4114   }
4115   // Default-initialize all remaining values.
4116   AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(),
4117                      Contents.AsIntValues.end());
4118 
4119   Initializer = FieldInitializer(std::move(AsIntValues));
4120   return false;
4121 }
4122 
4123 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
4124                                        const StructFieldInfo &Contents,
4125                                        FieldInitializer &Initializer) {
4126   SMLoc Loc = getTok().getLoc();
4127 
4128   std::vector<StructInitializer> Initializers;
4129   if (Field.LengthOf > 1) {
4130     if (parseOptionalToken(AsmToken::LCurly)) {
4131       if (parseStructInstList(Contents.Structure, Initializers,
4132                               AsmToken::RCurly) ||
4133           parseToken(AsmToken::RCurly))
4134         return true;
4135     } else if (parseOptionalAngleBracketOpen()) {
4136       if (parseStructInstList(Contents.Structure, Initializers,
4137                               AsmToken::Greater) ||
4138           parseAngleBracketClose())
4139         return true;
4140     } else {
4141       return Error(Loc, "Cannot initialize array field with scalar value");
4142     }
4143   } else {
4144     Initializers.emplace_back();
4145     if (parseStructInitializer(Contents.Structure, Initializers.back()))
4146       return true;
4147   }
4148 
4149   if (Initializers.size() > Field.LengthOf) {
4150     return Error(Loc, "Initializer too long for field; expected at most " +
4151                           std::to_string(Field.LengthOf) + " elements, got " +
4152                           std::to_string(Initializers.size()));
4153   }
4154   // Default-initialize all remaining values.
4155   Initializers.insert(Initializers.end(),
4156                       Contents.Initializers.begin() + Initializers.size(),
4157                       Contents.Initializers.end());
4158 
4159   Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
4160   return false;
4161 }
4162 
4163 bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
4164                                        FieldInitializer &Initializer) {
4165   switch (Field.Contents.FT) {
4166   case FT_INTEGRAL:
4167     return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer);
4168   case FT_REAL:
4169     return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer);
4170   case FT_STRUCT:
4171     return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer);
4172   }
4173   llvm_unreachable("Unhandled FieldType enum");
4174 }
4175 
4176 bool MasmParser::parseStructInitializer(const StructInfo &Structure,
4177                                         StructInitializer &Initializer) {
4178   const AsmToken FirstToken = getTok();
4179 
4180   std::optional<AsmToken::TokenKind> EndToken;
4181   if (parseOptionalToken(AsmToken::LCurly)) {
4182     EndToken = AsmToken::RCurly;
4183   } else if (parseOptionalAngleBracketOpen()) {
4184     EndToken = AsmToken::Greater;
4185     AngleBracketDepth++;
4186   } else if (FirstToken.is(AsmToken::Identifier) &&
4187              FirstToken.getString() == "?") {
4188     // ? initializer; leave EndToken uninitialized to treat as empty.
4189     if (parseToken(AsmToken::Identifier))
4190       return true;
4191   } else {
4192     return Error(FirstToken.getLoc(), "Expected struct initializer");
4193   }
4194 
4195   auto &FieldInitializers = Initializer.FieldInitializers;
4196   size_t FieldIndex = 0;
4197   if (EndToken) {
4198     // Initialize all fields with given initializers.
4199     while (getTok().isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
4200       const FieldInfo &Field = Structure.Fields[FieldIndex++];
4201       if (parseOptionalToken(AsmToken::Comma)) {
4202         // Empty initializer; use the default and continue. (Also, allow line
4203         // continuation.)
4204         FieldInitializers.push_back(Field.Contents);
4205         parseOptionalToken(AsmToken::EndOfStatement);
4206         continue;
4207       }
4208       FieldInitializers.emplace_back(Field.Contents.FT);
4209       if (parseFieldInitializer(Field, FieldInitializers.back()))
4210         return true;
4211 
4212       // Continue if we see a comma. (Also, allow line continuation.)
4213       SMLoc CommaLoc = getTok().getLoc();
4214       if (!parseOptionalToken(AsmToken::Comma))
4215         break;
4216       if (FieldIndex == Structure.Fields.size())
4217         return Error(CommaLoc, "'" + Structure.Name +
4218                                    "' initializer initializes too many fields");
4219       parseOptionalToken(AsmToken::EndOfStatement);
4220     }
4221   }
4222   // Default-initialize all remaining fields.
4223   for (const FieldInfo &Field : llvm::drop_begin(Structure.Fields, FieldIndex))
4224     FieldInitializers.push_back(Field.Contents);
4225 
4226   if (EndToken) {
4227     if (*EndToken == AsmToken::Greater)
4228       return parseAngleBracketClose();
4229 
4230     return parseToken(*EndToken);
4231   }
4232 
4233   return false;
4234 }
4235 
4236 bool MasmParser::parseStructInstList(
4237     const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
4238     const AsmToken::TokenKind EndToken) {
4239   while (getTok().isNot(EndToken) ||
4240          (EndToken == AsmToken::Greater &&
4241           getTok().isNot(AsmToken::GreaterGreater))) {
4242     const AsmToken NextTok = peekTok();
4243     if (NextTok.is(AsmToken::Identifier) &&
4244         NextTok.getString().equals_insensitive("dup")) {
4245       const MCExpr *Value;
4246       if (parseExpression(Value) || parseToken(AsmToken::Identifier))
4247         return true;
4248       const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
4249       if (!MCE)
4250         return Error(Value->getLoc(),
4251                      "cannot repeat value a non-constant number of times");
4252       const int64_t Repetitions = MCE->getValue();
4253       if (Repetitions < 0)
4254         return Error(Value->getLoc(),
4255                      "cannot repeat value a negative number of times");
4256 
4257       std::vector<StructInitializer> DuplicatedValues;
4258       if (parseToken(AsmToken::LParen,
4259                      "parentheses required for 'dup' contents") ||
4260           parseStructInstList(Structure, DuplicatedValues) || parseRParen())
4261         return true;
4262 
4263       for (int i = 0; i < Repetitions; ++i)
4264         llvm::append_range(Initializers, DuplicatedValues);
4265     } else {
4266       Initializers.emplace_back();
4267       if (parseStructInitializer(Structure, Initializers.back()))
4268         return true;
4269     }
4270 
4271     // Continue if we see a comma. (Also, allow line continuation.)
4272     if (!parseOptionalToken(AsmToken::Comma))
4273       break;
4274     parseOptionalToken(AsmToken::EndOfStatement);
4275   }
4276 
4277   return false;
4278 }
4279 
4280 bool MasmParser::emitFieldValue(const FieldInfo &Field,
4281                                 const IntFieldInfo &Contents) {
4282   // Default-initialize all values.
4283   for (const MCExpr *Value : Contents.Values) {
4284     if (emitIntValue(Value, Field.Type))
4285       return true;
4286   }
4287   return false;
4288 }
4289 
4290 bool MasmParser::emitFieldValue(const FieldInfo &Field,
4291                                 const RealFieldInfo &Contents) {
4292   for (const APInt &AsInt : Contents.AsIntValues) {
4293     getStreamer().emitIntValue(AsInt.getLimitedValue(),
4294                                AsInt.getBitWidth() / 8);
4295   }
4296   return false;
4297 }
4298 
4299 bool MasmParser::emitFieldValue(const FieldInfo &Field,
4300                                 const StructFieldInfo &Contents) {
4301   for (const auto &Initializer : Contents.Initializers) {
4302     size_t Index = 0, Offset = 0;
4303     for (const auto &SubField : Contents.Structure.Fields) {
4304       getStreamer().emitZeros(SubField.Offset - Offset);
4305       Offset = SubField.Offset + SubField.SizeOf;
4306       emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);
4307     }
4308   }
4309   return false;
4310 }
4311 
4312 bool MasmParser::emitFieldValue(const FieldInfo &Field) {
4313   switch (Field.Contents.FT) {
4314   case FT_INTEGRAL:
4315     return emitFieldValue(Field, Field.Contents.IntInfo);
4316   case FT_REAL:
4317     return emitFieldValue(Field, Field.Contents.RealInfo);
4318   case FT_STRUCT:
4319     return emitFieldValue(Field, Field.Contents.StructInfo);
4320   }
4321   llvm_unreachable("Unhandled FieldType enum");
4322 }
4323 
4324 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4325                                       const IntFieldInfo &Contents,
4326                                       const IntFieldInfo &Initializer) {
4327   for (const auto &Value : Initializer.Values) {
4328     if (emitIntValue(Value, Field.Type))
4329       return true;
4330   }
4331   // Default-initialize all remaining values.
4332   for (const auto &Value :
4333            llvm::drop_begin(Contents.Values, Initializer.Values.size())) {
4334     if (emitIntValue(Value, Field.Type))
4335       return true;
4336   }
4337   return false;
4338 }
4339 
4340 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4341                                       const RealFieldInfo &Contents,
4342                                       const RealFieldInfo &Initializer) {
4343   for (const auto &AsInt : Initializer.AsIntValues) {
4344     getStreamer().emitIntValue(AsInt.getLimitedValue(),
4345                                AsInt.getBitWidth() / 8);
4346   }
4347   // Default-initialize all remaining values.
4348   for (const auto &AsInt :
4349        llvm::drop_begin(Contents.AsIntValues, Initializer.AsIntValues.size())) {
4350     getStreamer().emitIntValue(AsInt.getLimitedValue(),
4351                                AsInt.getBitWidth() / 8);
4352   }
4353   return false;
4354 }
4355 
4356 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4357                                       const StructFieldInfo &Contents,
4358                                       const StructFieldInfo &Initializer) {
4359   for (const auto &Init : Initializer.Initializers) {
4360     if (emitStructInitializer(Contents.Structure, Init))
4361       return true;
4362   }
4363   // Default-initialize all remaining values.
4364   for (const auto &Init : llvm::drop_begin(Contents.Initializers,
4365                                            Initializer.Initializers.size())) {
4366     if (emitStructInitializer(Contents.Structure, Init))
4367       return true;
4368   }
4369   return false;
4370 }
4371 
4372 bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4373                                       const FieldInitializer &Initializer) {
4374   switch (Field.Contents.FT) {
4375   case FT_INTEGRAL:
4376     return emitFieldInitializer(Field, Field.Contents.IntInfo,
4377                                 Initializer.IntInfo);
4378   case FT_REAL:
4379     return emitFieldInitializer(Field, Field.Contents.RealInfo,
4380                                 Initializer.RealInfo);
4381   case FT_STRUCT:
4382     return emitFieldInitializer(Field, Field.Contents.StructInfo,
4383                                 Initializer.StructInfo);
4384   }
4385   llvm_unreachable("Unhandled FieldType enum");
4386 }
4387 
4388 bool MasmParser::emitStructInitializer(const StructInfo &Structure,
4389                                        const StructInitializer &Initializer) {
4390   if (!Structure.Initializable)
4391     return Error(getLexer().getLoc(),
4392                  "cannot initialize a value of type '" + Structure.Name +
4393                      "'; 'org' was used in the type's declaration");
4394   size_t Index = 0, Offset = 0;
4395   for (const auto &Init : Initializer.FieldInitializers) {
4396     const auto &Field = Structure.Fields[Index++];
4397     getStreamer().emitZeros(Field.Offset - Offset);
4398     Offset = Field.Offset + Field.SizeOf;
4399     if (emitFieldInitializer(Field, Init))
4400       return true;
4401   }
4402   // Default-initialize all remaining fields.
4403   for (const auto &Field : llvm::drop_begin(
4404            Structure.Fields, Initializer.FieldInitializers.size())) {
4405     getStreamer().emitZeros(Field.Offset - Offset);
4406     Offset = Field.Offset + Field.SizeOf;
4407     if (emitFieldValue(Field))
4408       return true;
4409   }
4410   // Add final padding.
4411   if (Offset != Structure.Size)
4412     getStreamer().emitZeros(Structure.Size - Offset);
4413   return false;
4414 }
4415 
4416 // Set data values from initializers.
4417 bool MasmParser::emitStructValues(const StructInfo &Structure,
4418                                   unsigned *Count) {
4419   std::vector<StructInitializer> Initializers;
4420   if (parseStructInstList(Structure, Initializers))
4421     return true;
4422 
4423   for (const auto &Initializer : Initializers) {
4424     if (emitStructInitializer(Structure, Initializer))
4425       return true;
4426   }
4427 
4428   if (Count)
4429     *Count = Initializers.size();
4430   return false;
4431 }
4432 
4433 // Declare a field in the current struct.
4434 bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) {
4435   StructInfo &OwningStruct = StructInProgress.back();
4436   FieldInfo &Field =
4437       OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize);
4438   StructFieldInfo &StructInfo = Field.Contents.StructInfo;
4439 
4440   StructInfo.Structure = Structure;
4441   Field.Type = Structure.Size;
4442 
4443   if (parseStructInstList(Structure, StructInfo.Initializers))
4444     return true;
4445 
4446   Field.LengthOf = StructInfo.Initializers.size();
4447   Field.SizeOf = Field.Type * Field.LengthOf;
4448 
4449   const unsigned FieldEnd = Field.Offset + Field.SizeOf;
4450   if (!OwningStruct.IsUnion) {
4451     OwningStruct.NextOffset = FieldEnd;
4452   }
4453   OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
4454 
4455   return false;
4456 }
4457 
4458 /// parseDirectiveStructValue
4459 ///  ::= struct-id (<struct-initializer> | {struct-initializer})
4460 ///                [, (<struct-initializer> | {struct-initializer})]*
4461 bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure,
4462                                            StringRef Directive, SMLoc DirLoc) {
4463   if (StructInProgress.empty()) {
4464     if (emitStructValues(Structure))
4465       return true;
4466   } else if (addStructField("", Structure)) {
4467     return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4468   }
4469 
4470   return false;
4471 }
4472 
4473 /// parseDirectiveNamedValue
4474 ///  ::= name (byte | word | ... ) [ expression (, expression)* ]
4475 bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure,
4476                                                 StringRef Directive,
4477                                                 SMLoc DirLoc, StringRef Name) {
4478   if (StructInProgress.empty()) {
4479     // Initialize named data value.
4480     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4481     getStreamer().emitLabel(Sym);
4482     unsigned Count;
4483     if (emitStructValues(Structure, &Count))
4484       return true;
4485     AsmTypeInfo Type;
4486     Type.Name = Structure.Name;
4487     Type.Size = Structure.Size * Count;
4488     Type.ElementSize = Structure.Size;
4489     Type.Length = Count;
4490     KnownType[Name.lower()] = Type;
4491   } else if (addStructField(Name, Structure)) {
4492     return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4493   }
4494 
4495   return false;
4496 }
4497 
4498 /// parseDirectiveStruct
4499 ///  ::= <name> (STRUC | STRUCT | UNION) [fieldAlign] [, NONUNIQUE]
4500 ///      (dataDir | generalDir | offsetDir | nestedStruct)+
4501 ///      <name> ENDS
4502 ////// dataDir = data declaration
4503 ////// offsetDir = EVEN, ORG, ALIGN
4504 bool MasmParser::parseDirectiveStruct(StringRef Directive,
4505                                       DirectiveKind DirKind, StringRef Name,
4506                                       SMLoc NameLoc) {
4507   // We ignore NONUNIQUE; we do not support OPTION M510 or OPTION OLDSTRUCTS
4508   // anyway, so all field accesses must be qualified.
4509   AsmToken NextTok = getTok();
4510   int64_t AlignmentValue = 1;
4511   if (NextTok.isNot(AsmToken::Comma) &&
4512       NextTok.isNot(AsmToken::EndOfStatement) &&
4513       parseAbsoluteExpression(AlignmentValue)) {
4514     return addErrorSuffix(" in alignment value for '" + Twine(Directive) +
4515                           "' directive");
4516   }
4517   if (!isPowerOf2_64(AlignmentValue)) {
4518     return Error(NextTok.getLoc(), "alignment must be a power of two; was " +
4519                                        std::to_string(AlignmentValue));
4520   }
4521 
4522   StringRef Qualifier;
4523   SMLoc QualifierLoc;
4524   if (parseOptionalToken(AsmToken::Comma)) {
4525     QualifierLoc = getTok().getLoc();
4526     if (parseIdentifier(Qualifier))
4527       return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4528     if (!Qualifier.equals_insensitive("nonunique"))
4529       return Error(QualifierLoc, "Unrecognized qualifier for '" +
4530                                      Twine(Directive) +
4531                                      "' directive; expected none or NONUNIQUE");
4532   }
4533 
4534   if (parseEOL())
4535     return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4536 
4537   StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue);
4538   return false;
4539 }
4540 
4541 /// parseDirectiveNestedStruct
4542 ///  ::= (STRUC | STRUCT | UNION) [name]
4543 ///      (dataDir | generalDir | offsetDir | nestedStruct)+
4544 ///      ENDS
4545 bool MasmParser::parseDirectiveNestedStruct(StringRef Directive,
4546                                             DirectiveKind DirKind) {
4547   if (StructInProgress.empty())
4548     return TokError("missing name in top-level '" + Twine(Directive) +
4549                     "' directive");
4550 
4551   StringRef Name;
4552   if (getTok().is(AsmToken::Identifier)) {
4553     Name = getTok().getIdentifier();
4554     parseToken(AsmToken::Identifier);
4555   }
4556   if (parseEOL())
4557     return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4558 
4559   // Reserve space to ensure Alignment doesn't get invalidated when
4560   // StructInProgress grows.
4561   StructInProgress.reserve(StructInProgress.size() + 1);
4562   StructInProgress.emplace_back(Name, DirKind == DK_UNION,
4563                                 StructInProgress.back().Alignment);
4564   return false;
4565 }
4566 
4567 bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
4568   if (StructInProgress.empty())
4569     return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION");
4570   if (StructInProgress.size() > 1)
4571     return Error(NameLoc, "unexpected name in nested ENDS directive");
4572   if (StructInProgress.back().Name.compare_insensitive(Name))
4573     return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
4574                               StructInProgress.back().Name + "'");
4575   StructInfo Structure = StructInProgress.pop_back_val();
4576   // Pad to make the structure's size divisible by the smaller of its alignment
4577   // and the size of its largest field.
4578   Structure.Size = llvm::alignTo(
4579       Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4580   Structs[Name.lower()] = Structure;
4581 
4582   if (parseEOL())
4583     return addErrorSuffix(" in ENDS directive");
4584 
4585   return false;
4586 }
4587 
4588 bool MasmParser::parseDirectiveNestedEnds() {
4589   if (StructInProgress.empty())
4590     return TokError("ENDS directive without matching STRUC/STRUCT/UNION");
4591   if (StructInProgress.size() == 1)
4592     return TokError("missing name in top-level ENDS directive");
4593 
4594   if (parseEOL())
4595     return addErrorSuffix(" in nested ENDS directive");
4596 
4597   StructInfo Structure = StructInProgress.pop_back_val();
4598   // Pad to make the structure's size divisible by its alignment.
4599   Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
4600 
4601   StructInfo &ParentStruct = StructInProgress.back();
4602   if (Structure.Name.empty()) {
4603     // Anonymous substructures' fields are addressed as if they belong to the
4604     // parent structure - so we transfer them to the parent here.
4605     const size_t OldFields = ParentStruct.Fields.size();
4606     ParentStruct.Fields.insert(
4607         ParentStruct.Fields.end(),
4608         std::make_move_iterator(Structure.Fields.begin()),
4609         std::make_move_iterator(Structure.Fields.end()));
4610     for (const auto &FieldByName : Structure.FieldsByName) {
4611       ParentStruct.FieldsByName[FieldByName.getKey()] =
4612           FieldByName.getValue() + OldFields;
4613     }
4614 
4615     unsigned FirstFieldOffset = 0;
4616     if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
4617       FirstFieldOffset = llvm::alignTo(
4618           ParentStruct.NextOffset,
4619           std::min(ParentStruct.Alignment, Structure.AlignmentSize));
4620     }
4621 
4622     if (ParentStruct.IsUnion) {
4623       ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4624     } else {
4625       for (auto &Field : llvm::drop_begin(ParentStruct.Fields, OldFields))
4626         Field.Offset += FirstFieldOffset;
4627 
4628       const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
4629       if (!ParentStruct.IsUnion) {
4630         ParentStruct.NextOffset = StructureEnd;
4631       }
4632       ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4633     }
4634   } else {
4635     FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4636                                              Structure.AlignmentSize);
4637     StructFieldInfo &StructInfo = Field.Contents.StructInfo;
4638     Field.Type = Structure.Size;
4639     Field.LengthOf = 1;
4640     Field.SizeOf = Structure.Size;
4641 
4642     const unsigned StructureEnd = Field.Offset + Field.SizeOf;
4643     if (!ParentStruct.IsUnion) {
4644       ParentStruct.NextOffset = StructureEnd;
4645     }
4646     ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
4647 
4648     StructInfo.Structure = Structure;
4649     StructInfo.Initializers.emplace_back();
4650     auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4651     for (const auto &SubField : Structure.Fields) {
4652       FieldInitializers.push_back(SubField.Contents);
4653     }
4654   }
4655 
4656   return false;
4657 }
4658 
4659 /// parseDirectiveOrg
4660 ///  ::= org expression
4661 bool MasmParser::parseDirectiveOrg() {
4662   const MCExpr *Offset;
4663   SMLoc OffsetLoc = Lexer.getLoc();
4664   if (checkForValidSection() || parseExpression(Offset))
4665     return true;
4666   if (parseEOL())
4667     return addErrorSuffix(" in 'org' directive");
4668 
4669   if (StructInProgress.empty()) {
4670     // Not in a struct; change the offset for the next instruction or data
4671     if (checkForValidSection())
4672       return addErrorSuffix(" in 'org' directive");
4673 
4674     getStreamer().emitValueToOffset(Offset, 0, OffsetLoc);
4675   } else {
4676     // Offset the next field of this struct
4677     StructInfo &Structure = StructInProgress.back();
4678     int64_t OffsetRes;
4679     if (!Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
4680       return Error(OffsetLoc,
4681                    "expected absolute expression in 'org' directive");
4682     if (OffsetRes < 0)
4683       return Error(
4684           OffsetLoc,
4685           "expected non-negative value in struct's 'org' directive; was " +
4686               std::to_string(OffsetRes));
4687     Structure.NextOffset = static_cast<unsigned>(OffsetRes);
4688 
4689     // ORG-affected structures cannot be initialized
4690     Structure.Initializable = false;
4691   }
4692 
4693   return false;
4694 }
4695 
4696 bool MasmParser::emitAlignTo(int64_t Alignment) {
4697   if (StructInProgress.empty()) {
4698     // Not in a struct; align the next instruction or data
4699     if (checkForValidSection())
4700       return true;
4701 
4702     // Check whether we should use optimal code alignment for this align
4703     // directive.
4704     const MCSection *Section = getStreamer().getCurrentSectionOnly();
4705     assert(Section && "must have section to emit alignment");
4706     if (Section->useCodeAlign()) {
4707       getStreamer().emitCodeAlignment(Align(Alignment),
4708                                       &getTargetParser().getSTI(),
4709                                       /*MaxBytesToEmit=*/0);
4710     } else {
4711       // FIXME: Target specific behavior about how the "extra" bytes are filled.
4712       getStreamer().emitValueToAlignment(Align(Alignment), /*Value=*/0,
4713                                          /*ValueSize=*/1,
4714                                          /*MaxBytesToEmit=*/0);
4715     }
4716   } else {
4717     // Align the next field of this struct
4718     StructInfo &Structure = StructInProgress.back();
4719     Structure.NextOffset = llvm::alignTo(Structure.NextOffset, Alignment);
4720   }
4721 
4722   return false;
4723 }
4724 
4725 /// parseDirectiveAlign
4726 ///  ::= align expression
4727 bool MasmParser::parseDirectiveAlign() {
4728   SMLoc AlignmentLoc = getLexer().getLoc();
4729   int64_t Alignment;
4730 
4731   // Ignore empty 'align' directives.
4732   if (getTok().is(AsmToken::EndOfStatement)) {
4733     return Warning(AlignmentLoc,
4734                    "align directive with no operand is ignored") &&
4735            parseEOL();
4736   }
4737   if (parseAbsoluteExpression(Alignment) || parseEOL())
4738     return addErrorSuffix(" in align directive");
4739 
4740   // Always emit an alignment here even if we throw an error.
4741   bool ReturnVal = false;
4742 
4743   // Reject alignments that aren't either a power of two or zero, for ML.exe
4744   // compatibility. Alignment of zero is silently rounded up to one.
4745   if (Alignment == 0)
4746     Alignment = 1;
4747   if (!isPowerOf2_64(Alignment))
4748     ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2; was " +
4749                                          std::to_string(Alignment));
4750 
4751   if (emitAlignTo(Alignment))
4752     ReturnVal |= addErrorSuffix(" in align directive");
4753 
4754   return ReturnVal;
4755 }
4756 
4757 /// parseDirectiveEven
4758 ///  ::= even
4759 bool MasmParser::parseDirectiveEven() {
4760   if (parseEOL() || emitAlignTo(2))
4761     return addErrorSuffix(" in even directive");
4762 
4763   return false;
4764 }
4765 
4766 /// parseDirectiveFile
4767 /// ::= .file filename
4768 /// ::= .file number [directory] filename [md5 checksum] [source source-text]
4769 bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
4770   // FIXME: I'm not sure what this is.
4771   int64_t FileNumber = -1;
4772   if (getLexer().is(AsmToken::Integer)) {
4773     FileNumber = getTok().getIntVal();
4774     Lex();
4775 
4776     if (FileNumber < 0)
4777       return TokError("negative file number");
4778   }
4779 
4780   std::string Path;
4781 
4782   // Usually the directory and filename together, otherwise just the directory.
4783   // Allow the strings to have escaped octal character sequence.
4784   if (check(getTok().isNot(AsmToken::String),
4785             "unexpected token in '.file' directive") ||
4786       parseEscapedString(Path))
4787     return true;
4788 
4789   StringRef Directory;
4790   StringRef Filename;
4791   std::string FilenameData;
4792   if (getLexer().is(AsmToken::String)) {
4793     if (check(FileNumber == -1,
4794               "explicit path specified, but no file number") ||
4795         parseEscapedString(FilenameData))
4796       return true;
4797     Filename = FilenameData;
4798     Directory = Path;
4799   } else {
4800     Filename = Path;
4801   }
4802 
4803   uint64_t MD5Hi, MD5Lo;
4804   bool HasMD5 = false;
4805 
4806   std::optional<StringRef> Source;
4807   bool HasSource = false;
4808   std::string SourceString;
4809 
4810   while (!parseOptionalToken(AsmToken::EndOfStatement)) {
4811     StringRef Keyword;
4812     if (check(getTok().isNot(AsmToken::Identifier),
4813               "unexpected token in '.file' directive") ||
4814         parseIdentifier(Keyword))
4815       return true;
4816     if (Keyword == "md5") {
4817       HasMD5 = true;
4818       if (check(FileNumber == -1,
4819                 "MD5 checksum specified, but no file number") ||
4820           parseHexOcta(*this, MD5Hi, MD5Lo))
4821         return true;
4822     } else if (Keyword == "source") {
4823       HasSource = true;
4824       if (check(FileNumber == -1,
4825                 "source specified, but no file number") ||
4826           check(getTok().isNot(AsmToken::String),
4827                 "unexpected token in '.file' directive") ||
4828           parseEscapedString(SourceString))
4829         return true;
4830     } else {
4831       return TokError("unexpected token in '.file' directive");
4832     }
4833   }
4834 
4835   if (FileNumber == -1) {
4836     // Ignore the directive if there is no number and the target doesn't support
4837     // numberless .file directives. This allows some portability of assembler
4838     // between different object file formats.
4839     if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4840       getStreamer().emitFileDirective(Filename);
4841   } else {
4842     // In case there is a -g option as well as debug info from directive .file,
4843     // we turn off the -g option, directly use the existing debug info instead.
4844     // Throw away any implicit file table for the assembler source.
4845     if (Ctx.getGenDwarfForAssembly()) {
4846       Ctx.getMCDwarfLineTable(0).resetFileTable();
4847       Ctx.setGenDwarfForAssembly(false);
4848     }
4849 
4850     std::optional<MD5::MD5Result> CKMem;
4851     if (HasMD5) {
4852       MD5::MD5Result Sum;
4853       for (unsigned i = 0; i != 8; ++i) {
4854         Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4855         Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4856       }
4857       CKMem = Sum;
4858     }
4859     if (HasSource) {
4860       char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
4861       memcpy(SourceBuf, SourceString.data(), SourceString.size());
4862       Source = StringRef(SourceBuf, SourceString.size());
4863     }
4864     if (FileNumber == 0) {
4865       if (Ctx.getDwarfVersion() < 5)
4866         return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
4867       getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4868     } else {
4869       Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
4870           FileNumber, Directory, Filename, CKMem, Source);
4871       if (!FileNumOrErr)
4872         return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
4873     }
4874     // Alert the user if there are some .file directives with MD5 and some not.
4875     // But only do that once.
4876     if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
4877       ReportedInconsistentMD5 = true;
4878       return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
4879     }
4880   }
4881 
4882   return false;
4883 }
4884 
4885 /// parseDirectiveLine
4886 /// ::= .line [number]
4887 bool MasmParser::parseDirectiveLine() {
4888   int64_t LineNumber;
4889   if (getLexer().is(AsmToken::Integer)) {
4890     if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
4891       return true;
4892     (void)LineNumber;
4893     // FIXME: Do something with the .line.
4894   }
4895   if (parseEOL())
4896     return true;
4897 
4898   return false;
4899 }
4900 
4901 /// parseDirectiveLoc
4902 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
4903 ///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
4904 /// The first number is a file number, must have been previously assigned with
4905 /// a .file directive, the second number is the line number and optionally the
4906 /// third number is a column position (zero if not specified).  The remaining
4907 /// optional items are .loc sub-directives.
4908 bool MasmParser::parseDirectiveLoc() {
4909   int64_t FileNumber = 0, LineNumber = 0;
4910   SMLoc Loc = getTok().getLoc();
4911   if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
4912       check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
4913             "file number less than one in '.loc' directive") ||
4914       check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4915             "unassigned file number in '.loc' directive"))
4916     return true;
4917 
4918   // optional
4919   if (getLexer().is(AsmToken::Integer)) {
4920     LineNumber = getTok().getIntVal();
4921     if (LineNumber < 0)
4922       return TokError("line number less than zero in '.loc' directive");
4923     Lex();
4924   }
4925 
4926   int64_t ColumnPos = 0;
4927   if (getLexer().is(AsmToken::Integer)) {
4928     ColumnPos = getTok().getIntVal();
4929     if (ColumnPos < 0)
4930       return TokError("column position less than zero in '.loc' directive");
4931     Lex();
4932   }
4933 
4934   auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4935   unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT;
4936   unsigned Isa = 0;
4937   int64_t Discriminator = 0;
4938 
4939   auto parseLocOp = [&]() -> bool {
4940     StringRef Name;
4941     SMLoc Loc = getTok().getLoc();
4942     if (parseIdentifier(Name))
4943       return TokError("unexpected token in '.loc' directive");
4944 
4945     if (Name == "basic_block")
4946       Flags |= DWARF2_FLAG_BASIC_BLOCK;
4947     else if (Name == "prologue_end")
4948       Flags |= DWARF2_FLAG_PROLOGUE_END;
4949     else if (Name == "epilogue_begin")
4950       Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
4951     else if (Name == "is_stmt") {
4952       Loc = getTok().getLoc();
4953       const MCExpr *Value;
4954       if (parseExpression(Value))
4955         return true;
4956       // The expression must be the constant 0 or 1.
4957       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4958         int Value = MCE->getValue();
4959         if (Value == 0)
4960           Flags &= ~DWARF2_FLAG_IS_STMT;
4961         else if (Value == 1)
4962           Flags |= DWARF2_FLAG_IS_STMT;
4963         else
4964           return Error(Loc, "is_stmt value not 0 or 1");
4965       } else {
4966         return Error(Loc, "is_stmt value not the constant value of 0 or 1");
4967       }
4968     } else if (Name == "isa") {
4969       Loc = getTok().getLoc();
4970       const MCExpr *Value;
4971       if (parseExpression(Value))
4972         return true;
4973       // The expression must be a constant greater or equal to 0.
4974       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4975         int Value = MCE->getValue();
4976         if (Value < 0)
4977           return Error(Loc, "isa number less than zero");
4978         Isa = Value;
4979       } else {
4980         return Error(Loc, "isa number not a constant value");
4981       }
4982     } else if (Name == "discriminator") {
4983       if (parseAbsoluteExpression(Discriminator))
4984         return true;
4985     } else {
4986       return Error(Loc, "unknown sub-directive in '.loc' directive");
4987     }
4988     return false;
4989   };
4990 
4991   if (parseMany(parseLocOp, false /*hasComma*/))
4992     return true;
4993 
4994   getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
4995                                       Isa, Discriminator, StringRef());
4996 
4997   return false;
4998 }
4999 
5000 /// parseDirectiveStabs
5001 /// ::= .stabs string, number, number, number
5002 bool MasmParser::parseDirectiveStabs() {
5003   return TokError("unsupported directive '.stabs'");
5004 }
5005 
5006 /// parseDirectiveCVFile
5007 /// ::= .cv_file number filename [checksum] [checksumkind]
5008 bool MasmParser::parseDirectiveCVFile() {
5009   SMLoc FileNumberLoc = getTok().getLoc();
5010   int64_t FileNumber;
5011   std::string Filename;
5012   std::string Checksum;
5013   int64_t ChecksumKind = 0;
5014 
5015   if (parseIntToken(FileNumber,
5016                     "expected file number in '.cv_file' directive") ||
5017       check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
5018       check(getTok().isNot(AsmToken::String),
5019             "unexpected token in '.cv_file' directive") ||
5020       parseEscapedString(Filename))
5021     return true;
5022   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5023     if (check(getTok().isNot(AsmToken::String),
5024               "unexpected token in '.cv_file' directive") ||
5025         parseEscapedString(Checksum) ||
5026         parseIntToken(ChecksumKind,
5027                       "expected checksum kind in '.cv_file' directive") ||
5028         parseEOL())
5029       return true;
5030   }
5031 
5032   Checksum = fromHex(Checksum);
5033   void *CKMem = Ctx.allocate(Checksum.size(), 1);
5034   memcpy(CKMem, Checksum.data(), Checksum.size());
5035   ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
5036                                     Checksum.size());
5037 
5038   if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
5039                                          static_cast<uint8_t>(ChecksumKind)))
5040     return Error(FileNumberLoc, "file number already allocated");
5041 
5042   return false;
5043 }
5044 
5045 bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
5046                                    StringRef DirectiveName) {
5047   SMLoc Loc;
5048   return parseTokenLoc(Loc) ||
5049          parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
5050                                        "' directive") ||
5051          check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
5052                "expected function id within range [0, UINT_MAX)");
5053 }
5054 
5055 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
5056   SMLoc Loc;
5057   return parseTokenLoc(Loc) ||
5058          parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
5059                                        "' directive") ||
5060          check(FileNumber < 1, Loc, "file number less than one in '" +
5061                                         DirectiveName + "' directive") ||
5062          check(!getCVContext().isValidFileNumber(FileNumber), Loc,
5063                "unassigned file number in '" + DirectiveName + "' directive");
5064 }
5065 
5066 /// parseDirectiveCVFuncId
5067 /// ::= .cv_func_id FunctionId
5068 ///
5069 /// Introduces a function ID that can be used with .cv_loc.
5070 bool MasmParser::parseDirectiveCVFuncId() {
5071   SMLoc FunctionIdLoc = getTok().getLoc();
5072   int64_t FunctionId;
5073 
5074   if (parseCVFunctionId(FunctionId, ".cv_func_id") || parseEOL())
5075     return true;
5076 
5077   if (!getStreamer().emitCVFuncIdDirective(FunctionId))
5078     return Error(FunctionIdLoc, "function id already allocated");
5079 
5080   return false;
5081 }
5082 
5083 /// parseDirectiveCVInlineSiteId
5084 /// ::= .cv_inline_site_id FunctionId
5085 ///         "within" IAFunc
5086 ///         "inlined_at" IAFile IALine [IACol]
5087 ///
5088 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
5089 /// at" source location information for use in the line table of the caller,
5090 /// whether the caller is a real function or another inlined call site.
5091 bool MasmParser::parseDirectiveCVInlineSiteId() {
5092   SMLoc FunctionIdLoc = getTok().getLoc();
5093   int64_t FunctionId;
5094   int64_t IAFunc;
5095   int64_t IAFile;
5096   int64_t IALine;
5097   int64_t IACol = 0;
5098 
5099   // FunctionId
5100   if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
5101     return true;
5102 
5103   // "within"
5104   if (check((getLexer().isNot(AsmToken::Identifier) ||
5105              getTok().getIdentifier() != "within"),
5106             "expected 'within' identifier in '.cv_inline_site_id' directive"))
5107     return true;
5108   Lex();
5109 
5110   // IAFunc
5111   if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
5112     return true;
5113 
5114   // "inlined_at"
5115   if (check((getLexer().isNot(AsmToken::Identifier) ||
5116              getTok().getIdentifier() != "inlined_at"),
5117             "expected 'inlined_at' identifier in '.cv_inline_site_id' "
5118             "directive") )
5119     return true;
5120   Lex();
5121 
5122   // IAFile IALine
5123   if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
5124       parseIntToken(IALine, "expected line number after 'inlined_at'"))
5125     return true;
5126 
5127   // [IACol]
5128   if (getLexer().is(AsmToken::Integer)) {
5129     IACol = getTok().getIntVal();
5130     Lex();
5131   }
5132 
5133   if (parseEOL())
5134     return true;
5135 
5136   if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
5137                                                  IALine, IACol, FunctionIdLoc))
5138     return Error(FunctionIdLoc, "function id already allocated");
5139 
5140   return false;
5141 }
5142 
5143 /// parseDirectiveCVLoc
5144 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
5145 ///                                [is_stmt VALUE]
5146 /// The first number is a file number, must have been previously assigned with
5147 /// a .file directive, the second number is the line number and optionally the
5148 /// third number is a column position (zero if not specified).  The remaining
5149 /// optional items are .loc sub-directives.
5150 bool MasmParser::parseDirectiveCVLoc() {
5151   SMLoc DirectiveLoc = getTok().getLoc();
5152   int64_t FunctionId, FileNumber;
5153   if (parseCVFunctionId(FunctionId, ".cv_loc") ||
5154       parseCVFileId(FileNumber, ".cv_loc"))
5155     return true;
5156 
5157   int64_t LineNumber = 0;
5158   if (getLexer().is(AsmToken::Integer)) {
5159     LineNumber = getTok().getIntVal();
5160     if (LineNumber < 0)
5161       return TokError("line number less than zero in '.cv_loc' directive");
5162     Lex();
5163   }
5164 
5165   int64_t ColumnPos = 0;
5166   if (getLexer().is(AsmToken::Integer)) {
5167     ColumnPos = getTok().getIntVal();
5168     if (ColumnPos < 0)
5169       return TokError("column position less than zero in '.cv_loc' directive");
5170     Lex();
5171   }
5172 
5173   bool PrologueEnd = false;
5174   uint64_t IsStmt = 0;
5175 
5176   auto parseOp = [&]() -> bool {
5177     StringRef Name;
5178     SMLoc Loc = getTok().getLoc();
5179     if (parseIdentifier(Name))
5180       return TokError("unexpected token in '.cv_loc' directive");
5181     if (Name == "prologue_end")
5182       PrologueEnd = true;
5183     else if (Name == "is_stmt") {
5184       Loc = getTok().getLoc();
5185       const MCExpr *Value;
5186       if (parseExpression(Value))
5187         return true;
5188       // The expression must be the constant 0 or 1.
5189       IsStmt = ~0ULL;
5190       if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
5191         IsStmt = MCE->getValue();
5192 
5193       if (IsStmt > 1)
5194         return Error(Loc, "is_stmt value not 0 or 1");
5195     } else {
5196       return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
5197     }
5198     return false;
5199   };
5200 
5201   if (parseMany(parseOp, false /*hasComma*/))
5202     return true;
5203 
5204   getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
5205                                    ColumnPos, PrologueEnd, IsStmt, StringRef(),
5206                                    DirectiveLoc);
5207   return false;
5208 }
5209 
5210 /// parseDirectiveCVLinetable
5211 /// ::= .cv_linetable FunctionId, FnStart, FnEnd
5212 bool MasmParser::parseDirectiveCVLinetable() {
5213   int64_t FunctionId;
5214   StringRef FnStartName, FnEndName;
5215   SMLoc Loc = getTok().getLoc();
5216   if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
5217       parseToken(AsmToken::Comma,
5218                  "unexpected token in '.cv_linetable' directive") ||
5219       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5220                                   "expected identifier in directive") ||
5221       parseToken(AsmToken::Comma,
5222                  "unexpected token in '.cv_linetable' directive") ||
5223       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5224                                   "expected identifier in directive"))
5225     return true;
5226 
5227   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5228   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5229 
5230   getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
5231   return false;
5232 }
5233 
5234 /// parseDirectiveCVInlineLinetable
5235 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
5236 bool MasmParser::parseDirectiveCVInlineLinetable() {
5237   int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
5238   StringRef FnStartName, FnEndName;
5239   SMLoc Loc = getTok().getLoc();
5240   if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
5241       parseTokenLoc(Loc) ||
5242       parseIntToken(
5243           SourceFileId,
5244           "expected SourceField in '.cv_inline_linetable' directive") ||
5245       check(SourceFileId <= 0, Loc,
5246             "File id less than zero in '.cv_inline_linetable' directive") ||
5247       parseTokenLoc(Loc) ||
5248       parseIntToken(
5249           SourceLineNum,
5250           "expected SourceLineNum in '.cv_inline_linetable' directive") ||
5251       check(SourceLineNum < 0, Loc,
5252             "Line number less than zero in '.cv_inline_linetable' directive") ||
5253       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5254                                   "expected identifier in directive") ||
5255       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5256                                   "expected identifier in directive"))
5257     return true;
5258 
5259   if (parseEOL())
5260     return true;
5261 
5262   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5263   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5264   getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
5265                                                SourceLineNum, FnStartSym,
5266                                                FnEndSym);
5267   return false;
5268 }
5269 
5270 void MasmParser::initializeCVDefRangeTypeMap() {
5271   CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
5272   CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
5273   CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
5274   CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
5275 }
5276 
5277 /// parseDirectiveCVDefRange
5278 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
5279 bool MasmParser::parseDirectiveCVDefRange() {
5280   SMLoc Loc;
5281   std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
5282   while (getLexer().is(AsmToken::Identifier)) {
5283     Loc = getLexer().getLoc();
5284     StringRef GapStartName;
5285     if (parseIdentifier(GapStartName))
5286       return Error(Loc, "expected identifier in directive");
5287     MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
5288 
5289     Loc = getLexer().getLoc();
5290     StringRef GapEndName;
5291     if (parseIdentifier(GapEndName))
5292       return Error(Loc, "expected identifier in directive");
5293     MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
5294 
5295     Ranges.push_back({GapStartSym, GapEndSym});
5296   }
5297 
5298   StringRef CVDefRangeTypeStr;
5299   if (parseToken(
5300           AsmToken::Comma,
5301           "expected comma before def_range type in .cv_def_range directive") ||
5302       parseIdentifier(CVDefRangeTypeStr))
5303     return Error(Loc, "expected def_range type in directive");
5304 
5305   StringMap<CVDefRangeType>::const_iterator CVTypeIt =
5306       CVDefRangeTypeMap.find(CVDefRangeTypeStr);
5307   CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
5308                                 ? CVDR_DEFRANGE
5309                                 : CVTypeIt->getValue();
5310   switch (CVDRType) {
5311   case CVDR_DEFRANGE_REGISTER: {
5312     int64_t DRRegister;
5313     if (parseToken(AsmToken::Comma, "expected comma before register number in "
5314                                     ".cv_def_range directive") ||
5315         parseAbsoluteExpression(DRRegister))
5316       return Error(Loc, "expected register number");
5317 
5318     codeview::DefRangeRegisterHeader DRHdr;
5319     DRHdr.Register = DRRegister;
5320     DRHdr.MayHaveNoName = 0;
5321     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5322     break;
5323   }
5324   case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
5325     int64_t DROffset;
5326     if (parseToken(AsmToken::Comma,
5327                    "expected comma before offset in .cv_def_range directive") ||
5328         parseAbsoluteExpression(DROffset))
5329       return Error(Loc, "expected offset value");
5330 
5331     codeview::DefRangeFramePointerRelHeader DRHdr;
5332     DRHdr.Offset = DROffset;
5333     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5334     break;
5335   }
5336   case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
5337     int64_t DRRegister;
5338     int64_t DROffsetInParent;
5339     if (parseToken(AsmToken::Comma, "expected comma before register number in "
5340                                     ".cv_def_range directive") ||
5341         parseAbsoluteExpression(DRRegister))
5342       return Error(Loc, "expected register number");
5343     if (parseToken(AsmToken::Comma,
5344                    "expected comma before offset in .cv_def_range directive") ||
5345         parseAbsoluteExpression(DROffsetInParent))
5346       return Error(Loc, "expected offset value");
5347 
5348     codeview::DefRangeSubfieldRegisterHeader DRHdr;
5349     DRHdr.Register = DRRegister;
5350     DRHdr.MayHaveNoName = 0;
5351     DRHdr.OffsetInParent = DROffsetInParent;
5352     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5353     break;
5354   }
5355   case CVDR_DEFRANGE_REGISTER_REL: {
5356     int64_t DRRegister;
5357     int64_t DRFlags;
5358     int64_t DRBasePointerOffset;
5359     if (parseToken(AsmToken::Comma, "expected comma before register number in "
5360                                     ".cv_def_range directive") ||
5361         parseAbsoluteExpression(DRRegister))
5362       return Error(Loc, "expected register value");
5363     if (parseToken(
5364             AsmToken::Comma,
5365             "expected comma before flag value in .cv_def_range directive") ||
5366         parseAbsoluteExpression(DRFlags))
5367       return Error(Loc, "expected flag value");
5368     if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
5369                                     "in .cv_def_range directive") ||
5370         parseAbsoluteExpression(DRBasePointerOffset))
5371       return Error(Loc, "expected base pointer offset value");
5372 
5373     codeview::DefRangeRegisterRelHeader DRHdr;
5374     DRHdr.Register = DRRegister;
5375     DRHdr.Flags = DRFlags;
5376     DRHdr.BasePointerOffset = DRBasePointerOffset;
5377     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5378     break;
5379   }
5380   default:
5381     return Error(Loc, "unexpected def_range type in .cv_def_range directive");
5382   }
5383   return true;
5384 }
5385 
5386 /// parseDirectiveCVString
5387 /// ::= .cv_stringtable "string"
5388 bool MasmParser::parseDirectiveCVString() {
5389   std::string Data;
5390   if (checkForValidSection() || parseEscapedString(Data))
5391     return addErrorSuffix(" in '.cv_string' directive");
5392 
5393   // Put the string in the table and emit the offset.
5394   std::pair<StringRef, unsigned> Insertion =
5395       getCVContext().addToStringTable(Data);
5396   getStreamer().emitIntValue(Insertion.second, 4);
5397   return false;
5398 }
5399 
5400 /// parseDirectiveCVStringTable
5401 /// ::= .cv_stringtable
5402 bool MasmParser::parseDirectiveCVStringTable() {
5403   getStreamer().emitCVStringTableDirective();
5404   return false;
5405 }
5406 
5407 /// parseDirectiveCVFileChecksums
5408 /// ::= .cv_filechecksums
5409 bool MasmParser::parseDirectiveCVFileChecksums() {
5410   getStreamer().emitCVFileChecksumsDirective();
5411   return false;
5412 }
5413 
5414 /// parseDirectiveCVFileChecksumOffset
5415 /// ::= .cv_filechecksumoffset fileno
5416 bool MasmParser::parseDirectiveCVFileChecksumOffset() {
5417   int64_t FileNo;
5418   if (parseIntToken(FileNo, "expected identifier in directive"))
5419     return true;
5420   if (parseEOL())
5421     return true;
5422   getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
5423   return false;
5424 }
5425 
5426 /// parseDirectiveCVFPOData
5427 /// ::= .cv_fpo_data procsym
5428 bool MasmParser::parseDirectiveCVFPOData() {
5429   SMLoc DirLoc = getLexer().getLoc();
5430   StringRef ProcName;
5431   if (parseIdentifier(ProcName))
5432     return TokError("expected symbol name");
5433   if (parseEOL("unexpected tokens"))
5434     return addErrorSuffix(" in '.cv_fpo_data' directive");
5435   MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
5436   getStreamer().emitCVFPOData(ProcSym, DirLoc);
5437   return false;
5438 }
5439 
5440 /// parseDirectiveCFISections
5441 /// ::= .cfi_sections section [, section]
5442 bool MasmParser::parseDirectiveCFISections() {
5443   StringRef Name;
5444   bool EH = false;
5445   bool Debug = false;
5446 
5447   if (parseIdentifier(Name))
5448     return TokError("Expected an identifier");
5449 
5450   if (Name == ".eh_frame")
5451     EH = true;
5452   else if (Name == ".debug_frame")
5453     Debug = true;
5454 
5455   if (getLexer().is(AsmToken::Comma)) {
5456     Lex();
5457 
5458     if (parseIdentifier(Name))
5459       return TokError("Expected an identifier");
5460 
5461     if (Name == ".eh_frame")
5462       EH = true;
5463     else if (Name == ".debug_frame")
5464       Debug = true;
5465   }
5466 
5467   getStreamer().emitCFISections(EH, Debug);
5468   return false;
5469 }
5470 
5471 /// parseDirectiveCFIStartProc
5472 /// ::= .cfi_startproc [simple]
5473 bool MasmParser::parseDirectiveCFIStartProc() {
5474   StringRef Simple;
5475   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5476     if (check(parseIdentifier(Simple) || Simple != "simple",
5477               "unexpected token") ||
5478         parseEOL())
5479       return addErrorSuffix(" in '.cfi_startproc' directive");
5480   }
5481 
5482   // TODO(kristina): Deal with a corner case of incorrect diagnostic context
5483   // being produced if this directive is emitted as part of preprocessor macro
5484   // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
5485   // Tools like llvm-mc on the other hand are not affected by it, and report
5486   // correct context information.
5487   getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc());
5488   return false;
5489 }
5490 
5491 /// parseDirectiveCFIEndProc
5492 /// ::= .cfi_endproc
5493 bool MasmParser::parseDirectiveCFIEndProc() {
5494   getStreamer().emitCFIEndProc();
5495   return false;
5496 }
5497 
5498 /// parse register name or number.
5499 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register,
5500                                                SMLoc DirectiveLoc) {
5501   MCRegister RegNo;
5502 
5503   if (getLexer().isNot(AsmToken::Integer)) {
5504     if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
5505       return true;
5506     Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
5507   } else
5508     return parseAbsoluteExpression(Register);
5509 
5510   return false;
5511 }
5512 
5513 /// parseDirectiveCFIDefCfa
5514 /// ::= .cfi_def_cfa register,  offset
5515 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
5516   int64_t Register = 0, Offset = 0;
5517   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5518       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5519       parseAbsoluteExpression(Offset))
5520     return true;
5521 
5522   getStreamer().emitCFIDefCfa(Register, Offset);
5523   return false;
5524 }
5525 
5526 /// parseDirectiveCFIDefCfaOffset
5527 /// ::= .cfi_def_cfa_offset offset
5528 bool MasmParser::parseDirectiveCFIDefCfaOffset(SMLoc DirectiveLoc) {
5529   int64_t Offset = 0;
5530   if (parseAbsoluteExpression(Offset))
5531     return true;
5532 
5533   getStreamer().emitCFIDefCfaOffset(Offset, DirectiveLoc);
5534   return false;
5535 }
5536 
5537 /// parseDirectiveCFIRegister
5538 /// ::= .cfi_register register, register
5539 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
5540   int64_t Register1 = 0, Register2 = 0;
5541   if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
5542       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5543       parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
5544     return true;
5545 
5546   getStreamer().emitCFIRegister(Register1, Register2, DirectiveLoc);
5547   return false;
5548 }
5549 
5550 /// parseDirectiveCFIWindowSave
5551 /// ::= .cfi_window_save
5552 bool MasmParser::parseDirectiveCFIWindowSave(SMLoc DirectiveLoc) {
5553   getStreamer().emitCFIWindowSave(DirectiveLoc);
5554   return false;
5555 }
5556 
5557 /// parseDirectiveCFIAdjustCfaOffset
5558 /// ::= .cfi_adjust_cfa_offset adjustment
5559 bool MasmParser::parseDirectiveCFIAdjustCfaOffset(SMLoc DirectiveLoc) {
5560   int64_t Adjustment = 0;
5561   if (parseAbsoluteExpression(Adjustment))
5562     return true;
5563 
5564   getStreamer().emitCFIAdjustCfaOffset(Adjustment, DirectiveLoc);
5565   return false;
5566 }
5567 
5568 /// parseDirectiveCFIDefCfaRegister
5569 /// ::= .cfi_def_cfa_register register
5570 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
5571   int64_t Register = 0;
5572   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5573     return true;
5574 
5575   getStreamer().emitCFIDefCfaRegister(Register);
5576   return false;
5577 }
5578 
5579 /// parseDirectiveCFIOffset
5580 /// ::= .cfi_offset register, offset
5581 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
5582   int64_t Register = 0;
5583   int64_t Offset = 0;
5584 
5585   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5586       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5587       parseAbsoluteExpression(Offset))
5588     return true;
5589 
5590   getStreamer().emitCFIOffset(Register, Offset);
5591   return false;
5592 }
5593 
5594 /// parseDirectiveCFIRelOffset
5595 /// ::= .cfi_rel_offset register, offset
5596 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
5597   int64_t Register = 0, Offset = 0;
5598 
5599   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5600       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5601       parseAbsoluteExpression(Offset))
5602     return true;
5603 
5604   getStreamer().emitCFIRelOffset(Register, Offset, DirectiveLoc);
5605   return false;
5606 }
5607 
5608 static bool isValidEncoding(int64_t Encoding) {
5609   if (Encoding & ~0xff)
5610     return false;
5611 
5612   if (Encoding == dwarf::DW_EH_PE_omit)
5613     return true;
5614 
5615   const unsigned Format = Encoding & 0xf;
5616   if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
5617       Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
5618       Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
5619       Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
5620     return false;
5621 
5622   const unsigned Application = Encoding & 0x70;
5623   if (Application != dwarf::DW_EH_PE_absptr &&
5624       Application != dwarf::DW_EH_PE_pcrel)
5625     return false;
5626 
5627   return true;
5628 }
5629 
5630 /// parseDirectiveCFIPersonalityOrLsda
5631 /// IsPersonality true for cfi_personality, false for cfi_lsda
5632 /// ::= .cfi_personality encoding, [symbol_name]
5633 /// ::= .cfi_lsda encoding, [symbol_name]
5634 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
5635   int64_t Encoding = 0;
5636   if (parseAbsoluteExpression(Encoding))
5637     return true;
5638   if (Encoding == dwarf::DW_EH_PE_omit)
5639     return false;
5640 
5641   StringRef Name;
5642   if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
5643       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5644       check(parseIdentifier(Name), "expected identifier in directive"))
5645     return true;
5646 
5647   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5648 
5649   if (IsPersonality)
5650     getStreamer().emitCFIPersonality(Sym, Encoding);
5651   else
5652     getStreamer().emitCFILsda(Sym, Encoding);
5653   return false;
5654 }
5655 
5656 /// parseDirectiveCFIRememberState
5657 /// ::= .cfi_remember_state
5658 bool MasmParser::parseDirectiveCFIRememberState(SMLoc DirectiveLoc) {
5659   getStreamer().emitCFIRememberState(DirectiveLoc);
5660   return false;
5661 }
5662 
5663 /// parseDirectiveCFIRestoreState
5664 /// ::= .cfi_remember_state
5665 bool MasmParser::parseDirectiveCFIRestoreState(SMLoc DirectiveLoc) {
5666   getStreamer().emitCFIRestoreState(DirectiveLoc);
5667   return false;
5668 }
5669 
5670 /// parseDirectiveCFISameValue
5671 /// ::= .cfi_same_value register
5672 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
5673   int64_t Register = 0;
5674 
5675   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5676     return true;
5677 
5678   getStreamer().emitCFISameValue(Register, DirectiveLoc);
5679   return false;
5680 }
5681 
5682 /// parseDirectiveCFIRestore
5683 /// ::= .cfi_restore register
5684 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
5685   int64_t Register = 0;
5686   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5687     return true;
5688 
5689   getStreamer().emitCFIRestore(Register);
5690   return false;
5691 }
5692 
5693 /// parseDirectiveCFIEscape
5694 /// ::= .cfi_escape expression[,...]
5695 bool MasmParser::parseDirectiveCFIEscape(SMLoc DirectiveLoc) {
5696   std::string Values;
5697   int64_t CurrValue;
5698   if (parseAbsoluteExpression(CurrValue))
5699     return true;
5700 
5701   Values.push_back((uint8_t)CurrValue);
5702 
5703   while (getLexer().is(AsmToken::Comma)) {
5704     Lex();
5705 
5706     if (parseAbsoluteExpression(CurrValue))
5707       return true;
5708 
5709     Values.push_back((uint8_t)CurrValue);
5710   }
5711 
5712   getStreamer().emitCFIEscape(Values, DirectiveLoc);
5713   return false;
5714 }
5715 
5716 /// parseDirectiveCFIReturnColumn
5717 /// ::= .cfi_return_column register
5718 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
5719   int64_t Register = 0;
5720   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5721     return true;
5722   getStreamer().emitCFIReturnColumn(Register);
5723   return false;
5724 }
5725 
5726 /// parseDirectiveCFISignalFrame
5727 /// ::= .cfi_signal_frame
5728 bool MasmParser::parseDirectiveCFISignalFrame() {
5729   if (parseEOL())
5730     return true;
5731 
5732   getStreamer().emitCFISignalFrame();
5733   return false;
5734 }
5735 
5736 /// parseDirectiveCFIUndefined
5737 /// ::= .cfi_undefined register
5738 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
5739   int64_t Register = 0;
5740 
5741   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5742     return true;
5743 
5744   getStreamer().emitCFIUndefined(Register);
5745   return false;
5746 }
5747 
5748 /// parseDirectiveMacro
5749 /// ::= name macro [parameters]
5750 ///     ["LOCAL" identifiers]
5751 ///   parameters ::= parameter [, parameter]*
5752 ///   parameter ::= name ":" qualifier
5753 ///   qualifier ::= "req" | "vararg" | "=" macro_argument
5754 bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
5755   MCAsmMacroParameters Parameters;
5756   while (getLexer().isNot(AsmToken::EndOfStatement)) {
5757     if (!Parameters.empty() && Parameters.back().Vararg)
5758       return Error(Lexer.getLoc(),
5759                    "Vararg parameter '" + Parameters.back().Name +
5760                        "' should be last in the list of parameters");
5761 
5762     MCAsmMacroParameter Parameter;
5763     if (parseIdentifier(Parameter.Name))
5764       return TokError("expected identifier in 'macro' directive");
5765 
5766     // Emit an error if two (or more) named parameters share the same name.
5767     for (const MCAsmMacroParameter& CurrParam : Parameters)
5768       if (CurrParam.Name.equals_insensitive(Parameter.Name))
5769         return TokError("macro '" + Name + "' has multiple parameters"
5770                         " named '" + Parameter.Name + "'");
5771 
5772     if (Lexer.is(AsmToken::Colon)) {
5773       Lex();  // consume ':'
5774 
5775       if (parseOptionalToken(AsmToken::Equal)) {
5776         // Default value
5777         SMLoc ParamLoc;
5778 
5779         ParamLoc = Lexer.getLoc();
5780         if (parseMacroArgument(nullptr, Parameter.Value))
5781           return true;
5782       } else {
5783         SMLoc QualLoc;
5784         StringRef Qualifier;
5785 
5786         QualLoc = Lexer.getLoc();
5787         if (parseIdentifier(Qualifier))
5788           return Error(QualLoc, "missing parameter qualifier for "
5789                                 "'" +
5790                                     Parameter.Name + "' in macro '" + Name +
5791                                     "'");
5792 
5793         if (Qualifier.equals_insensitive("req"))
5794           Parameter.Required = true;
5795         else if (Qualifier.equals_insensitive("vararg"))
5796           Parameter.Vararg = true;
5797         else
5798           return Error(QualLoc,
5799                        Qualifier + " is not a valid parameter qualifier for '" +
5800                            Parameter.Name + "' in macro '" + Name + "'");
5801       }
5802     }
5803 
5804     Parameters.push_back(std::move(Parameter));
5805 
5806     if (getLexer().is(AsmToken::Comma))
5807       Lex();
5808   }
5809 
5810   // Eat just the end of statement.
5811   Lexer.Lex();
5812 
5813   std::vector<std::string> Locals;
5814   if (getTok().is(AsmToken::Identifier) &&
5815       getTok().getIdentifier().equals_insensitive("local")) {
5816     Lex(); // Eat the LOCAL directive.
5817 
5818     StringRef ID;
5819     while (true) {
5820       if (parseIdentifier(ID))
5821         return true;
5822       Locals.push_back(ID.lower());
5823 
5824       // If we see a comma, continue (and allow line continuation).
5825       if (!parseOptionalToken(AsmToken::Comma))
5826         break;
5827       parseOptionalToken(AsmToken::EndOfStatement);
5828     }
5829   }
5830 
5831   // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors.
5832   AsmToken EndToken, StartToken = getTok();
5833   unsigned MacroDepth = 0;
5834   bool IsMacroFunction = false;
5835   // Lex the macro definition.
5836   while (true) {
5837     // Ignore Lexing errors in macros.
5838     while (Lexer.is(AsmToken::Error)) {
5839       Lexer.Lex();
5840     }
5841 
5842     // Check whether we have reached the end of the file.
5843     if (getLexer().is(AsmToken::Eof))
5844       return Error(NameLoc, "no matching 'endm' in definition");
5845 
5846     // Otherwise, check whether we have reached the 'endm'... and determine if
5847     // this is a macro function.
5848     if (getLexer().is(AsmToken::Identifier)) {
5849       if (getTok().getIdentifier().equals_insensitive("endm")) {
5850         if (MacroDepth == 0) { // Outermost macro.
5851           EndToken = getTok();
5852           Lexer.Lex();
5853           if (getLexer().isNot(AsmToken::EndOfStatement))
5854             return TokError("unexpected token in '" + EndToken.getIdentifier() +
5855                             "' directive");
5856           break;
5857         } else {
5858           // Otherwise we just found the end of an inner macro.
5859           --MacroDepth;
5860         }
5861       } else if (getTok().getIdentifier().equals_insensitive("exitm")) {
5862         if (MacroDepth == 0 && peekTok().isNot(AsmToken::EndOfStatement)) {
5863           IsMacroFunction = true;
5864         }
5865       } else if (isMacroLikeDirective()) {
5866         // We allow nested macros. Those aren't instantiated until the
5867         // outermost macro is expanded so just ignore them for now.
5868         ++MacroDepth;
5869       }
5870     }
5871 
5872     // Otherwise, scan til the end of the statement.
5873     eatToEndOfStatement();
5874   }
5875 
5876   if (getContext().lookupMacro(Name.lower())) {
5877     return Error(NameLoc, "macro '" + Name + "' is already defined");
5878   }
5879 
5880   const char *BodyStart = StartToken.getLoc().getPointer();
5881   const char *BodyEnd = EndToken.getLoc().getPointer();
5882   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5883   MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals),
5884                    IsMacroFunction);
5885   DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
5886                   Macro.dump());
5887   getContext().defineMacro(Name.lower(), std::move(Macro));
5888   return false;
5889 }
5890 
5891 /// parseDirectiveExitMacro
5892 /// ::= "exitm" [textitem]
5893 bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
5894                                          StringRef Directive,
5895                                          std::string &Value) {
5896   SMLoc EndLoc = getTok().getLoc();
5897   if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value))
5898     return Error(EndLoc,
5899                  "unable to parse text item in '" + Directive + "' directive");
5900   eatToEndOfStatement();
5901 
5902   if (!isInsideMacroInstantiation())
5903     return TokError("unexpected '" + Directive + "' in file, "
5904                                                  "no current macro definition");
5905 
5906   // Exit all conditionals that are active in the current macro.
5907   while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5908     TheCondState = TheCondStack.back();
5909     TheCondStack.pop_back();
5910   }
5911 
5912   handleMacroExit();
5913   return false;
5914 }
5915 
5916 /// parseDirectiveEndMacro
5917 /// ::= endm
5918 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
5919   if (getLexer().isNot(AsmToken::EndOfStatement))
5920     return TokError("unexpected token in '" + Directive + "' directive");
5921 
5922   // If we are inside a macro instantiation, terminate the current
5923   // instantiation.
5924   if (isInsideMacroInstantiation()) {
5925     handleMacroExit();
5926     return false;
5927   }
5928 
5929   // Otherwise, this .endmacro is a stray entry in the file; well formed
5930   // .endmacro directives are handled during the macro definition parsing.
5931   return TokError("unexpected '" + Directive + "' in file, "
5932                                                "no current macro definition");
5933 }
5934 
5935 /// parseDirectivePurgeMacro
5936 /// ::= purge identifier ( , identifier )*
5937 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
5938   StringRef Name;
5939   while (true) {
5940     SMLoc NameLoc;
5941     if (parseTokenLoc(NameLoc) ||
5942         check(parseIdentifier(Name), NameLoc,
5943               "expected identifier in 'purge' directive"))
5944       return true;
5945 
5946     DEBUG_WITH_TYPE("asm-macros", dbgs()
5947                                       << "Un-defining macro: " << Name << "\n");
5948     if (!getContext().lookupMacro(Name.lower()))
5949       return Error(NameLoc, "macro '" + Name + "' is not defined");
5950     getContext().undefineMacro(Name.lower());
5951 
5952     if (!parseOptionalToken(AsmToken::Comma))
5953       break;
5954     parseOptionalToken(AsmToken::EndOfStatement);
5955   }
5956 
5957   return false;
5958 }
5959 
5960 bool MasmParser::parseDirectiveExtern() {
5961   // .extern is the default - but we still need to take any provided type info.
5962   auto parseOp = [&]() -> bool {
5963     StringRef Name;
5964     SMLoc NameLoc = getTok().getLoc();
5965     if (parseIdentifier(Name))
5966       return Error(NameLoc, "expected name");
5967     if (parseToken(AsmToken::Colon))
5968       return true;
5969 
5970     StringRef TypeName;
5971     SMLoc TypeLoc = getTok().getLoc();
5972     if (parseIdentifier(TypeName))
5973       return Error(TypeLoc, "expected type");
5974     if (!TypeName.equals_insensitive("proc")) {
5975       AsmTypeInfo Type;
5976       if (lookUpType(TypeName, Type))
5977         return Error(TypeLoc, "unrecognized type");
5978       KnownType[Name.lower()] = Type;
5979     }
5980 
5981     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5982     Sym->setExternal(true);
5983     getStreamer().emitSymbolAttribute(Sym, MCSA_Extern);
5984 
5985     return false;
5986   };
5987 
5988   if (parseMany(parseOp))
5989     return addErrorSuffix(" in directive 'extern'");
5990   return false;
5991 }
5992 
5993 /// parseDirectiveSymbolAttribute
5994 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
5995 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
5996   auto parseOp = [&]() -> bool {
5997     StringRef Name;
5998     SMLoc Loc = getTok().getLoc();
5999     if (parseIdentifier(Name))
6000       return Error(Loc, "expected identifier");
6001     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6002 
6003     // Assembler local symbols don't make any sense here. Complain loudly.
6004     if (Sym->isTemporary())
6005       return Error(Loc, "non-local symbol required");
6006 
6007     if (!getStreamer().emitSymbolAttribute(Sym, Attr))
6008       return Error(Loc, "unable to emit symbol attribute");
6009     return false;
6010   };
6011 
6012   if (parseMany(parseOp))
6013     return addErrorSuffix(" in directive");
6014   return false;
6015 }
6016 
6017 /// parseDirectiveComm
6018 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
6019 bool MasmParser::parseDirectiveComm(bool IsLocal) {
6020   if (checkForValidSection())
6021     return true;
6022 
6023   SMLoc IDLoc = getLexer().getLoc();
6024   StringRef Name;
6025   if (parseIdentifier(Name))
6026     return TokError("expected identifier in directive");
6027 
6028   // Handle the identifier as the key symbol.
6029   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6030 
6031   if (getLexer().isNot(AsmToken::Comma))
6032     return TokError("unexpected token in directive");
6033   Lex();
6034 
6035   int64_t Size;
6036   SMLoc SizeLoc = getLexer().getLoc();
6037   if (parseAbsoluteExpression(Size))
6038     return true;
6039 
6040   int64_t Pow2Alignment = 0;
6041   SMLoc Pow2AlignmentLoc;
6042   if (getLexer().is(AsmToken::Comma)) {
6043     Lex();
6044     Pow2AlignmentLoc = getLexer().getLoc();
6045     if (parseAbsoluteExpression(Pow2Alignment))
6046       return true;
6047 
6048     LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
6049     if (IsLocal && LCOMM == LCOMM::NoAlignment)
6050       return Error(Pow2AlignmentLoc, "alignment not supported on this target");
6051 
6052     // If this target takes alignments in bytes (not log) validate and convert.
6053     if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
6054         (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
6055       if (!isPowerOf2_64(Pow2Alignment))
6056         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
6057       Pow2Alignment = Log2_64(Pow2Alignment);
6058     }
6059   }
6060 
6061   if (parseEOL())
6062     return true;
6063 
6064   // NOTE: a size of zero for a .comm should create a undefined symbol
6065   // but a size of .lcomm creates a bss symbol of size zero.
6066   if (Size < 0)
6067     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
6068                           "be less than zero");
6069 
6070   // NOTE: The alignment in the directive is a power of 2 value, the assembler
6071   // may internally end up wanting an alignment in bytes.
6072   // FIXME: Diagnose overflow.
6073   if (Pow2Alignment < 0)
6074     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
6075                                    "alignment, can't be less than zero");
6076 
6077   Sym->redefineIfPossible();
6078   if (!Sym->isUndefined())
6079     return Error(IDLoc, "invalid symbol redefinition");
6080 
6081   // Create the Symbol as a common or local common with Size and Pow2Alignment.
6082   if (IsLocal) {
6083     getStreamer().emitLocalCommonSymbol(Sym, Size,
6084                                         Align(1ULL << Pow2Alignment));
6085     return false;
6086   }
6087 
6088   getStreamer().emitCommonSymbol(Sym, Size, Align(1ULL << Pow2Alignment));
6089   return false;
6090 }
6091 
6092 /// parseDirectiveComment
6093 ///  ::= comment delimiter [[text]]
6094 ///              [[text]]
6095 ///              [[text]] delimiter [[text]]
6096 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
6097   std::string FirstLine = parseStringTo(AsmToken::EndOfStatement);
6098   size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
6099   assert(DelimiterEnd != std::string::npos);
6100   StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd);
6101   if (Delimiter.empty())
6102     return Error(DirectiveLoc, "no delimiter in 'comment' directive");
6103   do {
6104     if (getTok().is(AsmToken::Eof))
6105       return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
6106     Lex();  // eat end of statement
6107   } while (
6108       !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter));
6109   return parseEOL();
6110 }
6111 
6112 /// parseDirectiveInclude
6113 ///  ::= include <filename>
6114 ///    | include filename
6115 bool MasmParser::parseDirectiveInclude() {
6116   // Allow the strings to have escaped octal character sequence.
6117   std::string Filename;
6118   SMLoc IncludeLoc = getTok().getLoc();
6119 
6120   if (parseAngleBracketString(Filename))
6121     Filename = parseStringTo(AsmToken::EndOfStatement);
6122   if (check(Filename.empty(), "missing filename in 'include' directive") ||
6123       check(getTok().isNot(AsmToken::EndOfStatement),
6124             "unexpected token in 'include' directive") ||
6125       // Attempt to switch the lexer to the included file before consuming the
6126       // end of statement to avoid losing it when we switch.
6127       check(enterIncludeFile(Filename), IncludeLoc,
6128             "Could not find include file '" + Filename + "'"))
6129     return true;
6130 
6131   return false;
6132 }
6133 
6134 /// parseDirectiveIf
6135 /// ::= .if{,eq,ge,gt,le,lt,ne} expression
6136 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
6137   TheCondStack.push_back(TheCondState);
6138   TheCondState.TheCond = AsmCond::IfCond;
6139   if (TheCondState.Ignore) {
6140     eatToEndOfStatement();
6141   } else {
6142     int64_t ExprValue;
6143     if (parseAbsoluteExpression(ExprValue) || parseEOL())
6144       return true;
6145 
6146     switch (DirKind) {
6147     default:
6148       llvm_unreachable("unsupported directive");
6149     case DK_IF:
6150       break;
6151     case DK_IFE:
6152       ExprValue = ExprValue == 0;
6153       break;
6154     }
6155 
6156     TheCondState.CondMet = ExprValue;
6157     TheCondState.Ignore = !TheCondState.CondMet;
6158   }
6159 
6160   return false;
6161 }
6162 
6163 /// parseDirectiveIfb
6164 /// ::= .ifb textitem
6165 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
6166   TheCondStack.push_back(TheCondState);
6167   TheCondState.TheCond = AsmCond::IfCond;
6168 
6169   if (TheCondState.Ignore) {
6170     eatToEndOfStatement();
6171   } else {
6172     std::string Str;
6173     if (parseTextItem(Str))
6174       return TokError("expected text item parameter for 'ifb' directive");
6175 
6176     if (parseEOL())
6177       return true;
6178 
6179     TheCondState.CondMet = ExpectBlank == Str.empty();
6180     TheCondState.Ignore = !TheCondState.CondMet;
6181   }
6182 
6183   return false;
6184 }
6185 
6186 /// parseDirectiveIfidn
6187 ///   ::= ifidn textitem, textitem
6188 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6189                                      bool CaseInsensitive) {
6190   std::string String1, String2;
6191 
6192   if (parseTextItem(String1)) {
6193     if (ExpectEqual)
6194       return TokError("expected text item parameter for 'ifidn' directive");
6195     return TokError("expected text item parameter for 'ifdif' directive");
6196   }
6197 
6198   if (Lexer.isNot(AsmToken::Comma)) {
6199     if (ExpectEqual)
6200       return TokError(
6201           "expected comma after first string for 'ifidn' directive");
6202     return TokError("expected comma after first string for 'ifdif' directive");
6203   }
6204   Lex();
6205 
6206   if (parseTextItem(String2)) {
6207     if (ExpectEqual)
6208       return TokError("expected text item parameter for 'ifidn' directive");
6209     return TokError("expected text item parameter for 'ifdif' directive");
6210   }
6211 
6212   TheCondStack.push_back(TheCondState);
6213   TheCondState.TheCond = AsmCond::IfCond;
6214   if (CaseInsensitive)
6215     TheCondState.CondMet =
6216         ExpectEqual == (StringRef(String1).equals_insensitive(String2));
6217   else
6218     TheCondState.CondMet = ExpectEqual == (String1 == String2);
6219   TheCondState.Ignore = !TheCondState.CondMet;
6220 
6221   return false;
6222 }
6223 
6224 /// parseDirectiveIfdef
6225 /// ::= ifdef symbol
6226 ///   | ifdef variable
6227 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
6228   TheCondStack.push_back(TheCondState);
6229   TheCondState.TheCond = AsmCond::IfCond;
6230 
6231   if (TheCondState.Ignore) {
6232     eatToEndOfStatement();
6233   } else {
6234     bool is_defined = false;
6235     MCRegister Reg;
6236     SMLoc StartLoc, EndLoc;
6237     is_defined =
6238         getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6239     if (!is_defined) {
6240       StringRef Name;
6241       if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||
6242           parseEOL())
6243         return true;
6244 
6245       if (BuiltinSymbolMap.contains(Name.lower())) {
6246         is_defined = true;
6247       } else if (Variables.contains(Name.lower())) {
6248         is_defined = true;
6249       } else {
6250         MCSymbol *Sym = getContext().lookupSymbol(Name.lower());
6251         is_defined = (Sym && !Sym->isUndefined(false));
6252       }
6253     }
6254 
6255     TheCondState.CondMet = (is_defined == expect_defined);
6256     TheCondState.Ignore = !TheCondState.CondMet;
6257   }
6258 
6259   return false;
6260 }
6261 
6262 /// parseDirectiveElseIf
6263 /// ::= elseif expression
6264 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
6265                                       DirectiveKind DirKind) {
6266   if (TheCondState.TheCond != AsmCond::IfCond &&
6267       TheCondState.TheCond != AsmCond::ElseIfCond)
6268     return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
6269                                " .if or  an .elseif");
6270   TheCondState.TheCond = AsmCond::ElseIfCond;
6271 
6272   bool LastIgnoreState = false;
6273   if (!TheCondStack.empty())
6274     LastIgnoreState = TheCondStack.back().Ignore;
6275   if (LastIgnoreState || TheCondState.CondMet) {
6276     TheCondState.Ignore = true;
6277     eatToEndOfStatement();
6278   } else {
6279     int64_t ExprValue;
6280     if (parseAbsoluteExpression(ExprValue))
6281       return true;
6282 
6283     if (parseEOL())
6284       return true;
6285 
6286     switch (DirKind) {
6287     default:
6288       llvm_unreachable("unsupported directive");
6289     case DK_ELSEIF:
6290       break;
6291     case DK_ELSEIFE:
6292       ExprValue = ExprValue == 0;
6293       break;
6294     }
6295 
6296     TheCondState.CondMet = ExprValue;
6297     TheCondState.Ignore = !TheCondState.CondMet;
6298   }
6299 
6300   return false;
6301 }
6302 
6303 /// parseDirectiveElseIfb
6304 /// ::= elseifb textitem
6305 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
6306   if (TheCondState.TheCond != AsmCond::IfCond &&
6307       TheCondState.TheCond != AsmCond::ElseIfCond)
6308     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
6309                                " if or an elseif");
6310   TheCondState.TheCond = AsmCond::ElseIfCond;
6311 
6312   bool LastIgnoreState = false;
6313   if (!TheCondStack.empty())
6314     LastIgnoreState = TheCondStack.back().Ignore;
6315   if (LastIgnoreState || TheCondState.CondMet) {
6316     TheCondState.Ignore = true;
6317     eatToEndOfStatement();
6318   } else {
6319     std::string Str;
6320     if (parseTextItem(Str)) {
6321       if (ExpectBlank)
6322         return TokError("expected text item parameter for 'elseifb' directive");
6323       return TokError("expected text item parameter for 'elseifnb' directive");
6324     }
6325 
6326     if (parseEOL())
6327       return true;
6328 
6329     TheCondState.CondMet = ExpectBlank == Str.empty();
6330     TheCondState.Ignore = !TheCondState.CondMet;
6331   }
6332 
6333   return false;
6334 }
6335 
6336 /// parseDirectiveElseIfdef
6337 /// ::= elseifdef symbol
6338 ///   | elseifdef variable
6339 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
6340                                          bool expect_defined) {
6341   if (TheCondState.TheCond != AsmCond::IfCond &&
6342       TheCondState.TheCond != AsmCond::ElseIfCond)
6343     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
6344                                " if or an elseif");
6345   TheCondState.TheCond = AsmCond::ElseIfCond;
6346 
6347   bool LastIgnoreState = false;
6348   if (!TheCondStack.empty())
6349     LastIgnoreState = TheCondStack.back().Ignore;
6350   if (LastIgnoreState || TheCondState.CondMet) {
6351     TheCondState.Ignore = true;
6352     eatToEndOfStatement();
6353   } else {
6354     bool is_defined = false;
6355     MCRegister Reg;
6356     SMLoc StartLoc, EndLoc;
6357     is_defined =
6358         getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6359     if (!is_defined) {
6360       StringRef Name;
6361       if (check(parseIdentifier(Name),
6362                 "expected identifier after 'elseifdef'") ||
6363           parseEOL())
6364         return true;
6365 
6366       if (BuiltinSymbolMap.contains(Name.lower())) {
6367         is_defined = true;
6368       } else if (Variables.contains(Name.lower())) {
6369         is_defined = true;
6370       } else {
6371         MCSymbol *Sym = getContext().lookupSymbol(Name);
6372         is_defined = (Sym && !Sym->isUndefined(false));
6373       }
6374     }
6375 
6376     TheCondState.CondMet = (is_defined == expect_defined);
6377     TheCondState.Ignore = !TheCondState.CondMet;
6378   }
6379 
6380   return false;
6381 }
6382 
6383 /// parseDirectiveElseIfidn
6384 /// ::= elseifidn textitem, textitem
6385 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6386                                          bool CaseInsensitive) {
6387   if (TheCondState.TheCond != AsmCond::IfCond &&
6388       TheCondState.TheCond != AsmCond::ElseIfCond)
6389     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
6390                                " if or an elseif");
6391   TheCondState.TheCond = AsmCond::ElseIfCond;
6392 
6393   bool LastIgnoreState = false;
6394   if (!TheCondStack.empty())
6395     LastIgnoreState = TheCondStack.back().Ignore;
6396   if (LastIgnoreState || TheCondState.CondMet) {
6397     TheCondState.Ignore = true;
6398     eatToEndOfStatement();
6399   } else {
6400     std::string String1, String2;
6401 
6402     if (parseTextItem(String1)) {
6403       if (ExpectEqual)
6404         return TokError(
6405             "expected text item parameter for 'elseifidn' directive");
6406       return TokError("expected text item parameter for 'elseifdif' directive");
6407     }
6408 
6409     if (Lexer.isNot(AsmToken::Comma)) {
6410       if (ExpectEqual)
6411         return TokError(
6412             "expected comma after first string for 'elseifidn' directive");
6413       return TokError(
6414           "expected comma after first string for 'elseifdif' directive");
6415     }
6416     Lex();
6417 
6418     if (parseTextItem(String2)) {
6419       if (ExpectEqual)
6420         return TokError(
6421             "expected text item parameter for 'elseifidn' directive");
6422       return TokError("expected text item parameter for 'elseifdif' directive");
6423     }
6424 
6425     if (CaseInsensitive)
6426       TheCondState.CondMet =
6427           ExpectEqual == (StringRef(String1).equals_insensitive(String2));
6428     else
6429       TheCondState.CondMet = ExpectEqual == (String1 == String2);
6430     TheCondState.Ignore = !TheCondState.CondMet;
6431   }
6432 
6433   return false;
6434 }
6435 
6436 /// parseDirectiveElse
6437 /// ::= else
6438 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
6439   if (parseEOL())
6440     return true;
6441 
6442   if (TheCondState.TheCond != AsmCond::IfCond &&
6443       TheCondState.TheCond != AsmCond::ElseIfCond)
6444     return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"
6445                                " or an elseif");
6446   TheCondState.TheCond = AsmCond::ElseCond;
6447   bool LastIgnoreState = false;
6448   if (!TheCondStack.empty())
6449     LastIgnoreState = TheCondStack.back().Ignore;
6450   if (LastIgnoreState || TheCondState.CondMet)
6451     TheCondState.Ignore = true;
6452   else
6453     TheCondState.Ignore = false;
6454 
6455   return false;
6456 }
6457 
6458 /// parseDirectiveEnd
6459 /// ::= end
6460 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
6461   if (parseEOL())
6462     return true;
6463 
6464   while (Lexer.isNot(AsmToken::Eof))
6465     Lexer.Lex();
6466 
6467   return false;
6468 }
6469 
6470 /// parseDirectiveError
6471 ///   ::= .err [message]
6472 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
6473   if (!TheCondStack.empty()) {
6474     if (TheCondStack.back().Ignore) {
6475       eatToEndOfStatement();
6476       return false;
6477     }
6478   }
6479 
6480   std::string Message = ".err directive invoked in source file";
6481   if (Lexer.isNot(AsmToken::EndOfStatement))
6482     Message = parseStringTo(AsmToken::EndOfStatement);
6483   Lex();
6484 
6485   return Error(DirectiveLoc, Message);
6486 }
6487 
6488 /// parseDirectiveErrorIfb
6489 ///   ::= .errb textitem[, message]
6490 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
6491   if (!TheCondStack.empty()) {
6492     if (TheCondStack.back().Ignore) {
6493       eatToEndOfStatement();
6494       return false;
6495     }
6496   }
6497 
6498   std::string Text;
6499   if (parseTextItem(Text))
6500     return Error(getTok().getLoc(), "missing text item in '.errb' directive");
6501 
6502   std::string Message = ".errb directive invoked in source file";
6503   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6504     if (parseToken(AsmToken::Comma))
6505       return addErrorSuffix(" in '.errb' directive");
6506     Message = parseStringTo(AsmToken::EndOfStatement);
6507   }
6508   Lex();
6509 
6510   if (Text.empty() == ExpectBlank)
6511     return Error(DirectiveLoc, Message);
6512   return false;
6513 }
6514 
6515 /// parseDirectiveErrorIfdef
6516 ///   ::= .errdef name[, message]
6517 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
6518                                           bool ExpectDefined) {
6519   if (!TheCondStack.empty()) {
6520     if (TheCondStack.back().Ignore) {
6521       eatToEndOfStatement();
6522       return false;
6523     }
6524   }
6525 
6526   bool IsDefined = false;
6527   MCRegister Reg;
6528   SMLoc StartLoc, EndLoc;
6529   IsDefined =
6530       getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6531   if (!IsDefined) {
6532     StringRef Name;
6533     if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))
6534       return true;
6535 
6536     if (BuiltinSymbolMap.contains(Name.lower())) {
6537       IsDefined = true;
6538     } else if (Variables.contains(Name.lower())) {
6539       IsDefined = true;
6540     } else {
6541       MCSymbol *Sym = getContext().lookupSymbol(Name);
6542       IsDefined = (Sym && !Sym->isUndefined(false));
6543     }
6544   }
6545 
6546   std::string Message = ".errdef directive invoked in source file";
6547   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6548     if (parseToken(AsmToken::Comma))
6549       return addErrorSuffix(" in '.errdef' directive");
6550     Message = parseStringTo(AsmToken::EndOfStatement);
6551   }
6552   Lex();
6553 
6554   if (IsDefined == ExpectDefined)
6555     return Error(DirectiveLoc, Message);
6556   return false;
6557 }
6558 
6559 /// parseDirectiveErrorIfidn
6560 ///   ::= .erridn textitem, textitem[, message]
6561 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6562                                           bool CaseInsensitive) {
6563   if (!TheCondStack.empty()) {
6564     if (TheCondStack.back().Ignore) {
6565       eatToEndOfStatement();
6566       return false;
6567     }
6568   }
6569 
6570   std::string String1, String2;
6571 
6572   if (parseTextItem(String1)) {
6573     if (ExpectEqual)
6574       return TokError("expected string parameter for '.erridn' directive");
6575     return TokError("expected string parameter for '.errdif' directive");
6576   }
6577 
6578   if (Lexer.isNot(AsmToken::Comma)) {
6579     if (ExpectEqual)
6580       return TokError(
6581           "expected comma after first string for '.erridn' directive");
6582     return TokError(
6583         "expected comma after first string for '.errdif' directive");
6584   }
6585   Lex();
6586 
6587   if (parseTextItem(String2)) {
6588     if (ExpectEqual)
6589       return TokError("expected string parameter for '.erridn' directive");
6590     return TokError("expected string parameter for '.errdif' directive");
6591   }
6592 
6593   std::string Message;
6594   if (ExpectEqual)
6595     Message = ".erridn directive invoked in source file";
6596   else
6597     Message = ".errdif directive invoked in source file";
6598   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6599     if (parseToken(AsmToken::Comma))
6600       return addErrorSuffix(" in '.erridn' directive");
6601     Message = parseStringTo(AsmToken::EndOfStatement);
6602   }
6603   Lex();
6604 
6605   if (CaseInsensitive)
6606     TheCondState.CondMet =
6607         ExpectEqual == (StringRef(String1).equals_insensitive(String2));
6608   else
6609     TheCondState.CondMet = ExpectEqual == (String1 == String2);
6610   TheCondState.Ignore = !TheCondState.CondMet;
6611 
6612   if ((CaseInsensitive &&
6613        ExpectEqual == StringRef(String1).equals_insensitive(String2)) ||
6614       (ExpectEqual == (String1 == String2)))
6615     return Error(DirectiveLoc, Message);
6616   return false;
6617 }
6618 
6619 /// parseDirectiveErrorIfe
6620 ///   ::= .erre expression[, message]
6621 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
6622   if (!TheCondStack.empty()) {
6623     if (TheCondStack.back().Ignore) {
6624       eatToEndOfStatement();
6625       return false;
6626     }
6627   }
6628 
6629   int64_t ExprValue;
6630   if (parseAbsoluteExpression(ExprValue))
6631     return addErrorSuffix(" in '.erre' directive");
6632 
6633   std::string Message = ".erre directive invoked in source file";
6634   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6635     if (parseToken(AsmToken::Comma))
6636       return addErrorSuffix(" in '.erre' directive");
6637     Message = parseStringTo(AsmToken::EndOfStatement);
6638   }
6639   Lex();
6640 
6641   if ((ExprValue == 0) == ExpectZero)
6642     return Error(DirectiveLoc, Message);
6643   return false;
6644 }
6645 
6646 /// parseDirectiveEndIf
6647 /// ::= .endif
6648 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
6649   if (parseEOL())
6650     return true;
6651 
6652   if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
6653     return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
6654                                "an .if or .else");
6655   if (!TheCondStack.empty()) {
6656     TheCondState = TheCondStack.back();
6657     TheCondStack.pop_back();
6658   }
6659 
6660   return false;
6661 }
6662 
6663 void MasmParser::initializeDirectiveKindMap() {
6664   DirectiveKindMap["="] = DK_ASSIGN;
6665   DirectiveKindMap["equ"] = DK_EQU;
6666   DirectiveKindMap["textequ"] = DK_TEXTEQU;
6667   // DirectiveKindMap[".ascii"] = DK_ASCII;
6668   // DirectiveKindMap[".asciz"] = DK_ASCIZ;
6669   // DirectiveKindMap[".string"] = DK_STRING;
6670   DirectiveKindMap["byte"] = DK_BYTE;
6671   DirectiveKindMap["sbyte"] = DK_SBYTE;
6672   DirectiveKindMap["word"] = DK_WORD;
6673   DirectiveKindMap["sword"] = DK_SWORD;
6674   DirectiveKindMap["dword"] = DK_DWORD;
6675   DirectiveKindMap["sdword"] = DK_SDWORD;
6676   DirectiveKindMap["fword"] = DK_FWORD;
6677   DirectiveKindMap["qword"] = DK_QWORD;
6678   DirectiveKindMap["sqword"] = DK_SQWORD;
6679   DirectiveKindMap["real4"] = DK_REAL4;
6680   DirectiveKindMap["real8"] = DK_REAL8;
6681   DirectiveKindMap["real10"] = DK_REAL10;
6682   DirectiveKindMap["align"] = DK_ALIGN;
6683   DirectiveKindMap["even"] = DK_EVEN;
6684   DirectiveKindMap["org"] = DK_ORG;
6685   DirectiveKindMap["extern"] = DK_EXTERN;
6686   DirectiveKindMap["extrn"] = DK_EXTERN;
6687   DirectiveKindMap["public"] = DK_PUBLIC;
6688   // DirectiveKindMap[".comm"] = DK_COMM;
6689   DirectiveKindMap["comment"] = DK_COMMENT;
6690   DirectiveKindMap["include"] = DK_INCLUDE;
6691   DirectiveKindMap["repeat"] = DK_REPEAT;
6692   DirectiveKindMap["rept"] = DK_REPEAT;
6693   DirectiveKindMap["while"] = DK_WHILE;
6694   DirectiveKindMap["for"] = DK_FOR;
6695   DirectiveKindMap["irp"] = DK_FOR;
6696   DirectiveKindMap["forc"] = DK_FORC;
6697   DirectiveKindMap["irpc"] = DK_FORC;
6698   DirectiveKindMap["if"] = DK_IF;
6699   DirectiveKindMap["ife"] = DK_IFE;
6700   DirectiveKindMap["ifb"] = DK_IFB;
6701   DirectiveKindMap["ifnb"] = DK_IFNB;
6702   DirectiveKindMap["ifdef"] = DK_IFDEF;
6703   DirectiveKindMap["ifndef"] = DK_IFNDEF;
6704   DirectiveKindMap["ifdif"] = DK_IFDIF;
6705   DirectiveKindMap["ifdifi"] = DK_IFDIFI;
6706   DirectiveKindMap["ifidn"] = DK_IFIDN;
6707   DirectiveKindMap["ifidni"] = DK_IFIDNI;
6708   DirectiveKindMap["elseif"] = DK_ELSEIF;
6709   DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;
6710   DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;
6711   DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;
6712   DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;
6713   DirectiveKindMap["else"] = DK_ELSE;
6714   DirectiveKindMap["end"] = DK_END;
6715   DirectiveKindMap["endif"] = DK_ENDIF;
6716   // DirectiveKindMap[".file"] = DK_FILE;
6717   // DirectiveKindMap[".line"] = DK_LINE;
6718   // DirectiveKindMap[".loc"] = DK_LOC;
6719   // DirectiveKindMap[".stabs"] = DK_STABS;
6720   // DirectiveKindMap[".cv_file"] = DK_CV_FILE;
6721   // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
6722   // DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
6723   // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
6724   // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
6725   // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
6726   // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
6727   // DirectiveKindMap[".cv_string"] = DK_CV_STRING;
6728   // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
6729   // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
6730   // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
6731   // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
6732   // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
6733   // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
6734   // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
6735   // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
6736   // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
6737   // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
6738   // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
6739   // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
6740   // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
6741   // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
6742   // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
6743   // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
6744   // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
6745   // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
6746   // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
6747   // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
6748   // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
6749   // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
6750   // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
6751   // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
6752   // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
6753   // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
6754   DirectiveKindMap["macro"] = DK_MACRO;
6755   DirectiveKindMap["exitm"] = DK_EXITM;
6756   DirectiveKindMap["endm"] = DK_ENDM;
6757   DirectiveKindMap["purge"] = DK_PURGE;
6758   DirectiveKindMap[".err"] = DK_ERR;
6759   DirectiveKindMap[".errb"] = DK_ERRB;
6760   DirectiveKindMap[".errnb"] = DK_ERRNB;
6761   DirectiveKindMap[".errdef"] = DK_ERRDEF;
6762   DirectiveKindMap[".errndef"] = DK_ERRNDEF;
6763   DirectiveKindMap[".errdif"] = DK_ERRDIF;
6764   DirectiveKindMap[".errdifi"] = DK_ERRDIFI;
6765   DirectiveKindMap[".erridn"] = DK_ERRIDN;
6766   DirectiveKindMap[".erridni"] = DK_ERRIDNI;
6767   DirectiveKindMap[".erre"] = DK_ERRE;
6768   DirectiveKindMap[".errnz"] = DK_ERRNZ;
6769   DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
6770   DirectiveKindMap[".pushreg"] = DK_PUSHREG;
6771   DirectiveKindMap[".savereg"] = DK_SAVEREG;
6772   DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
6773   DirectiveKindMap[".setframe"] = DK_SETFRAME;
6774   DirectiveKindMap[".radix"] = DK_RADIX;
6775   DirectiveKindMap["db"] = DK_DB;
6776   DirectiveKindMap["dd"] = DK_DD;
6777   DirectiveKindMap["df"] = DK_DF;
6778   DirectiveKindMap["dq"] = DK_DQ;
6779   DirectiveKindMap["dw"] = DK_DW;
6780   DirectiveKindMap["echo"] = DK_ECHO;
6781   DirectiveKindMap["struc"] = DK_STRUCT;
6782   DirectiveKindMap["struct"] = DK_STRUCT;
6783   DirectiveKindMap["union"] = DK_UNION;
6784   DirectiveKindMap["ends"] = DK_ENDS;
6785 }
6786 
6787 bool MasmParser::isMacroLikeDirective() {
6788   if (getLexer().is(AsmToken::Identifier)) {
6789     bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier())
6790                            .CasesLower("repeat", "rept", true)
6791                            .CaseLower("while", true)
6792                            .CasesLower("for", "irp", true)
6793                            .CasesLower("forc", "irpc", true)
6794                            .Default(false);
6795     if (IsMacroLike)
6796       return true;
6797   }
6798   if (peekTok().is(AsmToken::Identifier) &&
6799       peekTok().getIdentifier().equals_insensitive("macro"))
6800     return true;
6801 
6802   return false;
6803 }
6804 
6805 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
6806   AsmToken EndToken, StartToken = getTok();
6807 
6808   unsigned NestLevel = 0;
6809   while (true) {
6810     // Check whether we have reached the end of the file.
6811     if (getLexer().is(AsmToken::Eof)) {
6812       printError(DirectiveLoc, "no matching 'endm' in definition");
6813       return nullptr;
6814     }
6815 
6816     if (isMacroLikeDirective())
6817       ++NestLevel;
6818 
6819     // Otherwise, check whether we have reached the endm.
6820     if (Lexer.is(AsmToken::Identifier) &&
6821         getTok().getIdentifier().equals_insensitive("endm")) {
6822       if (NestLevel == 0) {
6823         EndToken = getTok();
6824         Lex();
6825         if (Lexer.isNot(AsmToken::EndOfStatement)) {
6826           printError(getTok().getLoc(), "unexpected token in 'endm' directive");
6827           return nullptr;
6828         }
6829         break;
6830       }
6831       --NestLevel;
6832     }
6833 
6834     // Otherwise, scan till the end of the statement.
6835     eatToEndOfStatement();
6836   }
6837 
6838   const char *BodyStart = StartToken.getLoc().getPointer();
6839   const char *BodyEnd = EndToken.getLoc().getPointer();
6840   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
6841 
6842   // We Are Anonymous.
6843   MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
6844   return &MacroLikeBodies.back();
6845 }
6846 
6847 bool MasmParser::expandStatement(SMLoc Loc) {
6848   std::string Body = parseStringTo(AsmToken::EndOfStatement);
6849   SMLoc EndLoc = getTok().getLoc();
6850 
6851   MCAsmMacroParameters Parameters;
6852   MCAsmMacroArguments Arguments;
6853 
6854   StringMap<std::string> BuiltinValues;
6855   for (const auto &S : BuiltinSymbolMap) {
6856     const BuiltinSymbol &Sym = S.getValue();
6857     if (std::optional<std::string> Text = evaluateBuiltinTextMacro(Sym, Loc)) {
6858       BuiltinValues[S.getKey().lower()] = std::move(*Text);
6859     }
6860   }
6861   for (const auto &B : BuiltinValues) {
6862     MCAsmMacroParameter P;
6863     MCAsmMacroArgument A;
6864     P.Name = B.getKey();
6865     P.Required = true;
6866     A.push_back(AsmToken(AsmToken::String, B.getValue()));
6867 
6868     Parameters.push_back(std::move(P));
6869     Arguments.push_back(std::move(A));
6870   }
6871 
6872   for (const auto &V : Variables) {
6873     const Variable &Var = V.getValue();
6874     if (Var.IsText) {
6875       MCAsmMacroParameter P;
6876       MCAsmMacroArgument A;
6877       P.Name = Var.Name;
6878       P.Required = true;
6879       A.push_back(AsmToken(AsmToken::String, Var.TextValue));
6880 
6881       Parameters.push_back(std::move(P));
6882       Arguments.push_back(std::move(A));
6883     }
6884   }
6885   MacroLikeBodies.emplace_back(StringRef(), Body, Parameters);
6886   MCAsmMacro M = MacroLikeBodies.back();
6887 
6888   // Expand the statement in a new buffer.
6889   SmallString<80> Buf;
6890   raw_svector_ostream OS(Buf);
6891   if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc))
6892     return true;
6893   std::unique_ptr<MemoryBuffer> Expansion =
6894       MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>");
6895 
6896   // Jump to the expanded statement and prime the lexer.
6897   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc);
6898   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
6899   EndStatementAtEOFStack.push_back(false);
6900   Lex();
6901   return false;
6902 }
6903 
6904 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6905                                           raw_svector_ostream &OS) {
6906   instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS);
6907 }
6908 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6909                                           SMLoc ExitLoc,
6910                                           raw_svector_ostream &OS) {
6911   OS << "endm\n";
6912 
6913   std::unique_ptr<MemoryBuffer> Instantiation =
6914       MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
6915 
6916   // Create the macro instantiation object and add to the current macro
6917   // instantiation stack.
6918   MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,
6919                                                   ExitLoc, TheCondStack.size()};
6920   ActiveMacros.push_back(MI);
6921 
6922   // Jump to the macro instantiation and prime the lexer.
6923   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
6924   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
6925   EndStatementAtEOFStack.push_back(true);
6926   Lex();
6927 }
6928 
6929 /// parseDirectiveRepeat
6930 ///   ::= ("repeat" | "rept") count
6931 ///       body
6932 ///     endm
6933 bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
6934   const MCExpr *CountExpr;
6935   SMLoc CountLoc = getTok().getLoc();
6936   if (parseExpression(CountExpr))
6937     return true;
6938 
6939   int64_t Count;
6940   if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
6941     return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
6942   }
6943 
6944   if (check(Count < 0, CountLoc, "Count is negative") || parseEOL())
6945     return true;
6946 
6947   // Lex the repeat definition.
6948   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6949   if (!M)
6950     return true;
6951 
6952   // Macro instantiation is lexical, unfortunately. We construct a new buffer
6953   // to hold the macro body with substitutions.
6954   SmallString<256> Buf;
6955   raw_svector_ostream OS(Buf);
6956   while (Count--) {
6957     if (expandMacro(OS, M->Body, std::nullopt, std::nullopt, M->Locals,
6958                     getTok().getLoc()))
6959       return true;
6960   }
6961   instantiateMacroLikeBody(M, DirectiveLoc, OS);
6962 
6963   return false;
6964 }
6965 
6966 /// parseDirectiveWhile
6967 /// ::= "while" expression
6968 ///       body
6969 ///     endm
6970 bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
6971   const MCExpr *CondExpr;
6972   SMLoc CondLoc = getTok().getLoc();
6973   if (parseExpression(CondExpr))
6974     return true;
6975 
6976   // Lex the repeat definition.
6977   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6978   if (!M)
6979     return true;
6980 
6981   // Macro instantiation is lexical, unfortunately. We construct a new buffer
6982   // to hold the macro body with substitutions.
6983   SmallString<256> Buf;
6984   raw_svector_ostream OS(Buf);
6985   int64_t Condition;
6986   if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
6987     return Error(CondLoc, "expected absolute expression in 'while' directive");
6988   if (Condition) {
6989     // Instantiate the macro, then resume at this directive to recheck the
6990     // condition.
6991     if (expandMacro(OS, M->Body, std::nullopt, std::nullopt, M->Locals,
6992                     getTok().getLoc()))
6993       return true;
6994     instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
6995   }
6996 
6997   return false;
6998 }
6999 
7000 /// parseDirectiveFor
7001 /// ::= ("for" | "irp") symbol [":" qualifier], <values>
7002 ///       body
7003 ///     endm
7004 bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
7005   MCAsmMacroParameter Parameter;
7006   MCAsmMacroArguments A;
7007   if (check(parseIdentifier(Parameter.Name),
7008             "expected identifier in '" + Dir + "' directive"))
7009     return true;
7010 
7011   // Parse optional qualifier (default value, or "req")
7012   if (parseOptionalToken(AsmToken::Colon)) {
7013     if (parseOptionalToken(AsmToken::Equal)) {
7014       // Default value
7015       SMLoc ParamLoc;
7016 
7017       ParamLoc = Lexer.getLoc();
7018       if (parseMacroArgument(nullptr, Parameter.Value))
7019         return true;
7020     } else {
7021       SMLoc QualLoc;
7022       StringRef Qualifier;
7023 
7024       QualLoc = Lexer.getLoc();
7025       if (parseIdentifier(Qualifier))
7026         return Error(QualLoc, "missing parameter qualifier for "
7027                               "'" +
7028                                   Parameter.Name + "' in '" + Dir +
7029                                   "' directive");
7030 
7031       if (Qualifier.equals_insensitive("req"))
7032         Parameter.Required = true;
7033       else
7034         return Error(QualLoc,
7035                      Qualifier + " is not a valid parameter qualifier for '" +
7036                          Parameter.Name + "' in '" + Dir + "' directive");
7037     }
7038   }
7039 
7040   if (parseToken(AsmToken::Comma,
7041                  "expected comma in '" + Dir + "' directive") ||
7042       parseToken(AsmToken::Less,
7043                  "values in '" + Dir +
7044                      "' directive must be enclosed in angle brackets"))
7045     return true;
7046 
7047   while (true) {
7048     A.emplace_back();
7049     if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater))
7050       return addErrorSuffix(" in arguments for '" + Dir + "' directive");
7051 
7052     // If we see a comma, continue, and allow line continuation.
7053     if (!parseOptionalToken(AsmToken::Comma))
7054       break;
7055     parseOptionalToken(AsmToken::EndOfStatement);
7056   }
7057 
7058   if (parseToken(AsmToken::Greater,
7059                  "values in '" + Dir +
7060                      "' directive must be enclosed in angle brackets") ||
7061       parseEOL())
7062     return true;
7063 
7064   // Lex the for definition.
7065   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
7066   if (!M)
7067     return true;
7068 
7069   // Macro instantiation is lexical, unfortunately. We construct a new buffer
7070   // to hold the macro body with substitutions.
7071   SmallString<256> Buf;
7072   raw_svector_ostream OS(Buf);
7073 
7074   for (const MCAsmMacroArgument &Arg : A) {
7075     if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
7076       return true;
7077   }
7078 
7079   instantiateMacroLikeBody(M, DirectiveLoc, OS);
7080 
7081   return false;
7082 }
7083 
7084 /// parseDirectiveForc
7085 /// ::= ("forc" | "irpc") symbol, <string>
7086 ///       body
7087 ///     endm
7088 bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
7089   MCAsmMacroParameter Parameter;
7090 
7091   std::string Argument;
7092   if (check(parseIdentifier(Parameter.Name),
7093             "expected identifier in '" + Directive + "' directive") ||
7094       parseToken(AsmToken::Comma,
7095                  "expected comma in '" + Directive + "' directive"))
7096     return true;
7097   if (parseAngleBracketString(Argument)) {
7098     // Match ml64.exe; treat all characters to end of statement as a string,
7099     // ignoring comment markers, then discard anything following a space (using
7100     // the C locale).
7101     Argument = parseStringTo(AsmToken::EndOfStatement);
7102     if (getTok().is(AsmToken::EndOfStatement))
7103       Argument += getTok().getString();
7104     size_t End = 0;
7105     for (; End < Argument.size(); ++End) {
7106       if (isSpace(Argument[End]))
7107         break;
7108     }
7109     Argument.resize(End);
7110   }
7111   if (parseEOL())
7112     return true;
7113 
7114   // Lex the irpc definition.
7115   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
7116   if (!M)
7117     return true;
7118 
7119   // Macro instantiation is lexical, unfortunately. We construct a new buffer
7120   // to hold the macro body with substitutions.
7121   SmallString<256> Buf;
7122   raw_svector_ostream OS(Buf);
7123 
7124   StringRef Values(Argument);
7125   for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
7126     MCAsmMacroArgument Arg;
7127     Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
7128 
7129     if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
7130       return true;
7131   }
7132 
7133   instantiateMacroLikeBody(M, DirectiveLoc, OS);
7134 
7135   return false;
7136 }
7137 
7138 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
7139                                       size_t Len) {
7140   const MCExpr *Value;
7141   SMLoc ExprLoc = getLexer().getLoc();
7142   if (parseExpression(Value))
7143     return true;
7144   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
7145   if (!MCE)
7146     return Error(ExprLoc, "unexpected expression in _emit");
7147   uint64_t IntValue = MCE->getValue();
7148   if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
7149     return Error(ExprLoc, "literal value out of range for directive");
7150 
7151   Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
7152   return false;
7153 }
7154 
7155 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
7156   const MCExpr *Value;
7157   SMLoc ExprLoc = getLexer().getLoc();
7158   if (parseExpression(Value))
7159     return true;
7160   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
7161   if (!MCE)
7162     return Error(ExprLoc, "unexpected expression in align");
7163   uint64_t IntValue = MCE->getValue();
7164   if (!isPowerOf2_64(IntValue))
7165     return Error(ExprLoc, "literal value not a power of two greater then zero");
7166 
7167   Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
7168   return false;
7169 }
7170 
7171 bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {
7172   const SMLoc Loc = getLexer().getLoc();
7173   std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement);
7174   StringRef RadixString = StringRef(RadixStringRaw).trim();
7175   unsigned Radix;
7176   if (RadixString.getAsInteger(10, Radix)) {
7177     return Error(Loc,
7178                  "radix must be a decimal number in the range 2 to 16; was " +
7179                      RadixString);
7180   }
7181   if (Radix < 2 || Radix > 16)
7182     return Error(Loc, "radix must be in the range 2 to 16; was " +
7183                           std::to_string(Radix));
7184   getLexer().setMasmDefaultRadix(Radix);
7185   return false;
7186 }
7187 
7188 /// parseDirectiveEcho
7189 ///   ::= "echo" message
7190 bool MasmParser::parseDirectiveEcho(SMLoc DirectiveLoc) {
7191   std::string Message = parseStringTo(AsmToken::EndOfStatement);
7192   llvm::outs() << Message;
7193   if (!StringRef(Message).ends_with("\n"))
7194     llvm::outs() << '\n';
7195   return false;
7196 }
7197 
7198 // We are comparing pointers, but the pointers are relative to a single string.
7199 // Thus, this should always be deterministic.
7200 static int rewritesSort(const AsmRewrite *AsmRewriteA,
7201                         const AsmRewrite *AsmRewriteB) {
7202   if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
7203     return -1;
7204   if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
7205     return 1;
7206 
7207   // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
7208   // rewrite to the same location.  Make sure the SizeDirective rewrite is
7209   // performed first, then the Imm/ImmPrefix and finally the Input/Output.  This
7210   // ensures the sort algorithm is stable.
7211   if (AsmRewritePrecedence[AsmRewriteA->Kind] >
7212       AsmRewritePrecedence[AsmRewriteB->Kind])
7213     return -1;
7214 
7215   if (AsmRewritePrecedence[AsmRewriteA->Kind] <
7216       AsmRewritePrecedence[AsmRewriteB->Kind])
7217     return 1;
7218   llvm_unreachable("Unstable rewrite sort.");
7219 }
7220 
7221 bool MasmParser::defineMacro(StringRef Name, StringRef Value) {
7222   Variable &Var = Variables[Name.lower()];
7223   if (Var.Name.empty()) {
7224     Var.Name = Name;
7225   } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {
7226     return Error(SMLoc(), "invalid variable redefinition");
7227   } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&
7228              Warning(SMLoc(), "redefining '" + Name +
7229                                   "', already defined on the command line")) {
7230     return true;
7231   }
7232   Var.Redefinable = Variable::WARN_ON_REDEFINITION;
7233   Var.IsText = true;
7234   Var.TextValue = Value.str();
7235   return false;
7236 }
7237 
7238 bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {
7239   const std::pair<StringRef, StringRef> BaseMember = Name.split('.');
7240   const StringRef Base = BaseMember.first, Member = BaseMember.second;
7241   return lookUpField(Base, Member, Info);
7242 }
7243 
7244 bool MasmParser::lookUpField(StringRef Base, StringRef Member,
7245                              AsmFieldInfo &Info) const {
7246   if (Base.empty())
7247     return true;
7248 
7249   AsmFieldInfo BaseInfo;
7250   if (Base.contains('.') && !lookUpField(Base, BaseInfo))
7251     Base = BaseInfo.Type.Name;
7252 
7253   auto StructIt = Structs.find(Base.lower());
7254   auto TypeIt = KnownType.find(Base.lower());
7255   if (TypeIt != KnownType.end()) {
7256     StructIt = Structs.find(TypeIt->second.Name.lower());
7257   }
7258   if (StructIt != Structs.end())
7259     return lookUpField(StructIt->second, Member, Info);
7260 
7261   return true;
7262 }
7263 
7264 bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
7265                              AsmFieldInfo &Info) const {
7266   if (Member.empty()) {
7267     Info.Type.Name = Structure.Name;
7268     Info.Type.Size = Structure.Size;
7269     Info.Type.ElementSize = Structure.Size;
7270     Info.Type.Length = 1;
7271     return false;
7272   }
7273 
7274   std::pair<StringRef, StringRef> Split = Member.split('.');
7275   const StringRef FieldName = Split.first, FieldMember = Split.second;
7276 
7277   auto StructIt = Structs.find(FieldName.lower());
7278   if (StructIt != Structs.end())
7279     return lookUpField(StructIt->second, FieldMember, Info);
7280 
7281   auto FieldIt = Structure.FieldsByName.find(FieldName.lower());
7282   if (FieldIt == Structure.FieldsByName.end())
7283     return true;
7284 
7285   const FieldInfo &Field = Structure.Fields[FieldIt->second];
7286   if (FieldMember.empty()) {
7287     Info.Offset += Field.Offset;
7288     Info.Type.Size = Field.SizeOf;
7289     Info.Type.ElementSize = Field.Type;
7290     Info.Type.Length = Field.LengthOf;
7291     if (Field.Contents.FT == FT_STRUCT)
7292       Info.Type.Name = Field.Contents.StructInfo.Structure.Name;
7293     else
7294       Info.Type.Name = "";
7295     return false;
7296   }
7297 
7298   if (Field.Contents.FT != FT_STRUCT)
7299     return true;
7300   const StructFieldInfo &StructInfo = Field.Contents.StructInfo;
7301 
7302   if (lookUpField(StructInfo.Structure, FieldMember, Info))
7303     return true;
7304 
7305   Info.Offset += Field.Offset;
7306   return false;
7307 }
7308 
7309 bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
7310   unsigned Size = StringSwitch<unsigned>(Name)
7311                       .CasesLower("byte", "db", "sbyte", 1)
7312                       .CasesLower("word", "dw", "sword", 2)
7313                       .CasesLower("dword", "dd", "sdword", 4)
7314                       .CasesLower("fword", "df", 6)
7315                       .CasesLower("qword", "dq", "sqword", 8)
7316                       .CaseLower("real4", 4)
7317                       .CaseLower("real8", 8)
7318                       .CaseLower("real10", 10)
7319                       .Default(0);
7320   if (Size) {
7321     Info.Name = Name;
7322     Info.ElementSize = Size;
7323     Info.Length = 1;
7324     Info.Size = Size;
7325     return false;
7326   }
7327 
7328   auto StructIt = Structs.find(Name.lower());
7329   if (StructIt != Structs.end()) {
7330     const StructInfo &Structure = StructIt->second;
7331     Info.Name = Name;
7332     Info.ElementSize = Structure.Size;
7333     Info.Length = 1;
7334     Info.Size = Structure.Size;
7335     return false;
7336   }
7337 
7338   return true;
7339 }
7340 
7341 bool MasmParser::parseMSInlineAsm(
7342     std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs,
7343     SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
7344     SmallVectorImpl<std::string> &Constraints,
7345     SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
7346     const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
7347   SmallVector<void *, 4> InputDecls;
7348   SmallVector<void *, 4> OutputDecls;
7349   SmallVector<bool, 4> InputDeclsAddressOf;
7350   SmallVector<bool, 4> OutputDeclsAddressOf;
7351   SmallVector<std::string, 4> InputConstraints;
7352   SmallVector<std::string, 4> OutputConstraints;
7353   SmallVector<unsigned, 4> ClobberRegs;
7354 
7355   SmallVector<AsmRewrite, 4> AsmStrRewrites;
7356 
7357   // Prime the lexer.
7358   Lex();
7359 
7360   // While we have input, parse each statement.
7361   unsigned InputIdx = 0;
7362   unsigned OutputIdx = 0;
7363   while (getLexer().isNot(AsmToken::Eof)) {
7364     // Parse curly braces marking block start/end.
7365     if (parseCurlyBlockScope(AsmStrRewrites))
7366       continue;
7367 
7368     ParseStatementInfo Info(&AsmStrRewrites);
7369     bool StatementErr = parseStatement(Info, &SI);
7370 
7371     if (StatementErr || Info.ParseError) {
7372       // Emit pending errors if any exist.
7373       printPendingErrors();
7374       return true;
7375     }
7376 
7377     // No pending error should exist here.
7378     assert(!hasPendingError() && "unexpected error from parseStatement");
7379 
7380     if (Info.Opcode == ~0U)
7381       continue;
7382 
7383     const MCInstrDesc &Desc = MII->get(Info.Opcode);
7384 
7385     // Build the list of clobbers, outputs and inputs.
7386     for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
7387       MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
7388 
7389       // Register operand.
7390       if (Operand.isReg() && !Operand.needAddressOf() &&
7391           !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
7392         unsigned NumDefs = Desc.getNumDefs();
7393         // Clobber.
7394         if (NumDefs && Operand.getMCOperandNum() < NumDefs)
7395           ClobberRegs.push_back(Operand.getReg());
7396         continue;
7397       }
7398 
7399       // Expr/Input or Output.
7400       StringRef SymName = Operand.getSymName();
7401       if (SymName.empty())
7402         continue;
7403 
7404       void *OpDecl = Operand.getOpDecl();
7405       if (!OpDecl)
7406         continue;
7407 
7408       StringRef Constraint = Operand.getConstraint();
7409       if (Operand.isImm()) {
7410         // Offset as immediate.
7411         if (Operand.isOffsetOfLocal())
7412           Constraint = "r";
7413         else
7414           Constraint = "i";
7415       }
7416 
7417       bool isOutput = (i == 1) && Desc.mayStore();
7418       SMLoc Start = SMLoc::getFromPointer(SymName.data());
7419       if (isOutput) {
7420         ++InputIdx;
7421         OutputDecls.push_back(OpDecl);
7422         OutputDeclsAddressOf.push_back(Operand.needAddressOf());
7423         OutputConstraints.push_back(("=" + Constraint).str());
7424         AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
7425       } else {
7426         InputDecls.push_back(OpDecl);
7427         InputDeclsAddressOf.push_back(Operand.needAddressOf());
7428         InputConstraints.push_back(Constraint.str());
7429         if (Desc.operands()[i - 1].isBranchTarget())
7430           AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size());
7431         else
7432           AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
7433       }
7434     }
7435 
7436     // Consider implicit defs to be clobbers.  Think of cpuid and push.
7437     llvm::append_range(ClobberRegs, Desc.implicit_defs());
7438   }
7439 
7440   // Set the number of Outputs and Inputs.
7441   NumOutputs = OutputDecls.size();
7442   NumInputs = InputDecls.size();
7443 
7444   // Set the unique clobbers.
7445   array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
7446   ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
7447                     ClobberRegs.end());
7448   Clobbers.assign(ClobberRegs.size(), std::string());
7449   for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
7450     raw_string_ostream OS(Clobbers[I]);
7451     IP->printRegName(OS, ClobberRegs[I]);
7452   }
7453 
7454   // Merge the various outputs and inputs.  Output are expected first.
7455   if (NumOutputs || NumInputs) {
7456     unsigned NumExprs = NumOutputs + NumInputs;
7457     OpDecls.resize(NumExprs);
7458     Constraints.resize(NumExprs);
7459     for (unsigned i = 0; i < NumOutputs; ++i) {
7460       OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
7461       Constraints[i] = OutputConstraints[i];
7462     }
7463     for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
7464       OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
7465       Constraints[j] = InputConstraints[i];
7466     }
7467   }
7468 
7469   // Build the IR assembly string.
7470   std::string AsmStringIR;
7471   raw_string_ostream OS(AsmStringIR);
7472   StringRef ASMString =
7473       SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
7474   const char *AsmStart = ASMString.begin();
7475   const char *AsmEnd = ASMString.end();
7476   array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
7477   for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) {
7478     const AsmRewrite &AR = *it;
7479     // Check if this has already been covered by another rewrite...
7480     if (AR.Done)
7481       continue;
7482     AsmRewriteKind Kind = AR.Kind;
7483 
7484     const char *Loc = AR.Loc.getPointer();
7485     assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
7486 
7487     // Emit everything up to the immediate/expression.
7488     if (unsigned Len = Loc - AsmStart)
7489       OS << StringRef(AsmStart, Len);
7490 
7491     // Skip the original expression.
7492     if (Kind == AOK_Skip) {
7493       AsmStart = Loc + AR.Len;
7494       continue;
7495     }
7496 
7497     unsigned AdditionalSkip = 0;
7498     // Rewrite expressions in $N notation.
7499     switch (Kind) {
7500     default:
7501       break;
7502     case AOK_IntelExpr:
7503       assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
7504       if (AR.IntelExp.NeedBracs)
7505         OS << "[";
7506       if (AR.IntelExp.hasBaseReg())
7507         OS << AR.IntelExp.BaseReg;
7508       if (AR.IntelExp.hasIndexReg())
7509         OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
7510            << AR.IntelExp.IndexReg;
7511       if (AR.IntelExp.Scale > 1)
7512         OS << " * $$" << AR.IntelExp.Scale;
7513       if (AR.IntelExp.hasOffset()) {
7514         if (AR.IntelExp.hasRegs())
7515           OS << " + ";
7516         // Fuse this rewrite with a rewrite of the offset name, if present.
7517         StringRef OffsetName = AR.IntelExp.OffsetName;
7518         SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data());
7519         size_t OffsetLen = OffsetName.size();
7520         auto rewrite_it = std::find_if(
7521             it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
7522               return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
7523                      (FusingAR.Kind == AOK_Input ||
7524                       FusingAR.Kind == AOK_CallInput);
7525             });
7526         if (rewrite_it == AsmStrRewrites.end()) {
7527           OS << "offset " << OffsetName;
7528         } else if (rewrite_it->Kind == AOK_CallInput) {
7529           OS << "${" << InputIdx++ << ":P}";
7530           rewrite_it->Done = true;
7531         } else {
7532           OS << '$' << InputIdx++;
7533           rewrite_it->Done = true;
7534         }
7535       }
7536       if (AR.IntelExp.Imm || AR.IntelExp.emitImm())
7537         OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm;
7538       if (AR.IntelExp.NeedBracs)
7539         OS << "]";
7540       break;
7541     case AOK_Label:
7542       OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
7543       break;
7544     case AOK_Input:
7545       OS << '$' << InputIdx++;
7546       break;
7547     case AOK_CallInput:
7548       OS << "${" << InputIdx++ << ":P}";
7549       break;
7550     case AOK_Output:
7551       OS << '$' << OutputIdx++;
7552       break;
7553     case AOK_SizeDirective:
7554       switch (AR.Val) {
7555       default: break;
7556       case 8:  OS << "byte ptr "; break;
7557       case 16: OS << "word ptr "; break;
7558       case 32: OS << "dword ptr "; break;
7559       case 64: OS << "qword ptr "; break;
7560       case 80: OS << "xword ptr "; break;
7561       case 128: OS << "xmmword ptr "; break;
7562       case 256: OS << "ymmword ptr "; break;
7563       }
7564       break;
7565     case AOK_Emit:
7566       OS << ".byte";
7567       break;
7568     case AOK_Align: {
7569       // MS alignment directives are measured in bytes. If the native assembler
7570       // measures alignment in bytes, we can pass it straight through.
7571       OS << ".align";
7572       if (getContext().getAsmInfo()->getAlignmentIsInBytes())
7573         break;
7574 
7575       // Alignment is in log2 form, so print that instead and skip the original
7576       // immediate.
7577       unsigned Val = AR.Val;
7578       OS << ' ' << Val;
7579       assert(Val < 10 && "Expected alignment less then 2^10.");
7580       AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
7581       break;
7582     }
7583     case AOK_EVEN:
7584       OS << ".even";
7585       break;
7586     case AOK_EndOfStatement:
7587       OS << "\n\t";
7588       break;
7589     }
7590 
7591     // Skip the original expression.
7592     AsmStart = Loc + AR.Len + AdditionalSkip;
7593   }
7594 
7595   // Emit the remainder of the asm string.
7596   if (AsmStart != AsmEnd)
7597     OS << StringRef(AsmStart, AsmEnd - AsmStart);
7598 
7599   AsmString = OS.str();
7600   return false;
7601 }
7602 
7603 void MasmParser::initializeBuiltinSymbolMap() {
7604   // Numeric built-ins (supported in all versions)
7605   BuiltinSymbolMap["@version"] = BI_VERSION;
7606   BuiltinSymbolMap["@line"] = BI_LINE;
7607 
7608   // Text built-ins (supported in all versions)
7609   BuiltinSymbolMap["@date"] = BI_DATE;
7610   BuiltinSymbolMap["@time"] = BI_TIME;
7611   BuiltinSymbolMap["@filecur"] = BI_FILECUR;
7612   BuiltinSymbolMap["@filename"] = BI_FILENAME;
7613   BuiltinSymbolMap["@curseg"] = BI_CURSEG;
7614 
7615   // Some built-ins exist only for MASM32 (32-bit x86)
7616   if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
7617       Triple::x86) {
7618     // Numeric built-ins
7619     // BuiltinSymbolMap["@cpu"] = BI_CPU;
7620     // BuiltinSymbolMap["@interface"] = BI_INTERFACE;
7621     // BuiltinSymbolMap["@wordsize"] = BI_WORDSIZE;
7622     // BuiltinSymbolMap["@codesize"] = BI_CODESIZE;
7623     // BuiltinSymbolMap["@datasize"] = BI_DATASIZE;
7624     // BuiltinSymbolMap["@model"] = BI_MODEL;
7625 
7626     // Text built-ins
7627     // BuiltinSymbolMap["@code"] = BI_CODE;
7628     // BuiltinSymbolMap["@data"] = BI_DATA;
7629     // BuiltinSymbolMap["@fardata?"] = BI_FARDATA;
7630     // BuiltinSymbolMap["@stack"] = BI_STACK;
7631   }
7632 }
7633 
7634 const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,
7635                                                SMLoc StartLoc) {
7636   switch (Symbol) {
7637   default:
7638     return nullptr;
7639   case BI_VERSION:
7640     // Match a recent version of ML.EXE.
7641     return MCConstantExpr::create(1427, getContext());
7642   case BI_LINE: {
7643     int64_t Line;
7644     if (ActiveMacros.empty())
7645       Line = SrcMgr.FindLineNumber(StartLoc, CurBuffer);
7646     else
7647       Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
7648                                    ActiveMacros.front()->ExitBuffer);
7649     return MCConstantExpr::create(Line, getContext());
7650   }
7651   }
7652   llvm_unreachable("unhandled built-in symbol");
7653 }
7654 
7655 std::optional<std::string>
7656 MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) {
7657   switch (Symbol) {
7658   default:
7659     return {};
7660   case BI_DATE: {
7661     // Current local date, formatted MM/DD/YY
7662     char TmpBuffer[sizeof("mm/dd/yy")];
7663     const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%D", &TM);
7664     return std::string(TmpBuffer, Len);
7665   }
7666   case BI_TIME: {
7667     // Current local time, formatted HH:MM:SS (24-hour clock)
7668     char TmpBuffer[sizeof("hh:mm:ss")];
7669     const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%T", &TM);
7670     return std::string(TmpBuffer, Len);
7671   }
7672   case BI_FILECUR:
7673     return SrcMgr
7674         .getMemoryBuffer(
7675             ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)
7676         ->getBufferIdentifier()
7677         .str();
7678   case BI_FILENAME:
7679     return sys::path::stem(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())
7680                                ->getBufferIdentifier())
7681         .upper();
7682   case BI_CURSEG:
7683     return getStreamer().getCurrentSectionOnly()->getName().str();
7684   }
7685   llvm_unreachable("unhandled built-in symbol");
7686 }
7687 
7688 /// Create an MCAsmParser instance.
7689 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
7690                                       MCStreamer &Out, const MCAsmInfo &MAI,
7691                                       struct tm TM, unsigned CB) {
7692   return new MasmParser(SM, C, Out, MAI, TM, CB);
7693 }
7694