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