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