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