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   StructInProgress.emplace_back(Name, DirKind == DK_UNION,
4149                                 StructInProgress.back().Alignment);
4150   return false;
4151 }
4152 
4153 bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
4154   if (StructInProgress.empty())
4155     return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION");
4156   if (StructInProgress.size() > 1)
4157     return Error(NameLoc, "unexpected name in nested ENDS directive");
4158   if (StructInProgress.back().Name.compare_lower(Name))
4159     return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
4160                               StructInProgress.back().Name + "'");
4161   StructInfo Structure = StructInProgress.pop_back_val();
4162   // Pad to make the structure's size divisible by the smaller of its alignment
4163   // and the size of its largest field.
4164   Structure.Size = llvm::alignTo(
4165       Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4166   Structs[Name.lower()] = Structure;
4167 
4168   if (parseToken(AsmToken::EndOfStatement))
4169     return addErrorSuffix(" in ENDS directive");
4170 
4171   return false;
4172 }
4173 
4174 bool MasmParser::parseDirectiveNestedEnds() {
4175   if (StructInProgress.empty())
4176     return TokError("ENDS directive without matching STRUC/STRUCT/UNION");
4177   if (StructInProgress.size() == 1)
4178     return TokError("missing name in top-level ENDS directive");
4179 
4180   if (parseToken(AsmToken::EndOfStatement))
4181     return addErrorSuffix(" in nested ENDS directive");
4182 
4183   StructInfo Structure = StructInProgress.pop_back_val();
4184   // Pad to make the structure's size divisible by its alignment.
4185   Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
4186 
4187   StructInfo &ParentStruct = StructInProgress.back();
4188   if (Structure.Name.empty()) {
4189     const size_t OldFields = ParentStruct.Fields.size();
4190     ParentStruct.Fields.insert(
4191         ParentStruct.Fields.end(),
4192         std::make_move_iterator(Structure.Fields.begin()),
4193         std::make_move_iterator(Structure.Fields.end()));
4194     for (const auto &FieldByName : Structure.FieldsByName) {
4195       ParentStruct.FieldsByName[FieldByName.getKey()] =
4196           FieldByName.getValue() + OldFields;
4197     }
4198     if (!ParentStruct.IsUnion) {
4199       for (auto FieldIter = ParentStruct.Fields.begin() + OldFields;
4200            FieldIter != ParentStruct.Fields.end(); ++FieldIter) {
4201         FieldIter->Offset += ParentStruct.Size;
4202       }
4203     }
4204 
4205     if (ParentStruct.IsUnion)
4206       ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4207     else
4208       ParentStruct.Size += Structure.Size;
4209   } else {
4210     FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4211                                              Structure.AlignmentSize);
4212     StructFieldInfo &StructInfo = Field.Contents.StructInfo;
4213     Field.Type = Structure.Size;
4214     Field.LengthOf = 1;
4215     Field.SizeOf = Structure.Size;
4216 
4217     if (ParentStruct.IsUnion)
4218       ParentStruct.Size = std::max(ParentStruct.Size, Field.SizeOf);
4219     else
4220       ParentStruct.Size += Field.SizeOf;
4221 
4222     StructInfo.Structure = Structure;
4223     StructInfo.Initializers.emplace_back();
4224     auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4225     for (const auto &SubField : Structure.Fields) {
4226       FieldInitializers.push_back(SubField.Contents);
4227     }
4228   }
4229 
4230   return false;
4231 }
4232 
4233 /// parseDirectiveOrg
4234 ///  ::= .org expression [ , expression ]
4235 bool MasmParser::parseDirectiveOrg() {
4236   const MCExpr *Offset;
4237   SMLoc OffsetLoc = Lexer.getLoc();
4238   if (checkForValidSection() || parseExpression(Offset))
4239     return true;
4240 
4241   // Parse optional fill expression.
4242   int64_t FillExpr = 0;
4243   if (parseOptionalToken(AsmToken::Comma))
4244     if (parseAbsoluteExpression(FillExpr))
4245       return addErrorSuffix(" in '.org' directive");
4246   if (parseToken(AsmToken::EndOfStatement))
4247     return addErrorSuffix(" in '.org' directive");
4248 
4249   getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
4250   return false;
4251 }
4252 
4253 /// parseDirectiveAlign
4254 ///  ::= align expression
4255 bool MasmParser::parseDirectiveAlign() {
4256   SMLoc AlignmentLoc = getLexer().getLoc();
4257   int64_t Alignment;
4258 
4259   if (checkForValidSection())
4260     return addErrorSuffix(" in align directive");
4261   // Ignore empty 'align' directives.
4262   if (getTok().is(AsmToken::EndOfStatement)) {
4263     Warning(AlignmentLoc, "align directive with no operand is ignored");
4264     return parseToken(AsmToken::EndOfStatement);
4265   }
4266   if (parseAbsoluteExpression(Alignment) ||
4267       parseToken(AsmToken::EndOfStatement))
4268     return addErrorSuffix(" in align directive");
4269 
4270   // Always emit an alignment here even if we thrown an error.
4271   bool ReturnVal = false;
4272 
4273   // Reject alignments that aren't either a power of two or zero, for gas
4274   // compatibility. Alignment of zero is silently rounded up to one.
4275   if (Alignment == 0)
4276     Alignment = 1;
4277   if (!isPowerOf2_64(Alignment))
4278     ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
4279 
4280   // Check whether we should use optimal code alignment for this align
4281   // directive.
4282   const MCSection *Section = getStreamer().getCurrentSectionOnly();
4283   assert(Section && "must have section to emit alignment");
4284   if (Section->UseCodeAlign()) {
4285     getStreamer().emitCodeAlignment(Alignment, /*MaxBytesToEmit=*/0);
4286   } else {
4287     // FIXME: Target specific behavior about how the "extra" bytes are filled.
4288     getStreamer().emitValueToAlignment(Alignment, /*Value=*/0, /*ValueSize=*/1,
4289                                        /*MaxBytesToEmit=*/0);
4290   }
4291 
4292   return ReturnVal;
4293 }
4294 
4295 /// parseDirectiveFile
4296 /// ::= .file filename
4297 /// ::= .file number [directory] filename [md5 checksum] [source source-text]
4298 bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
4299   // FIXME: I'm not sure what this is.
4300   int64_t FileNumber = -1;
4301   if (getLexer().is(AsmToken::Integer)) {
4302     FileNumber = getTok().getIntVal();
4303     Lex();
4304 
4305     if (FileNumber < 0)
4306       return TokError("negative file number");
4307   }
4308 
4309   std::string Path;
4310 
4311   // Usually the directory and filename together, otherwise just the directory.
4312   // Allow the strings to have escaped octal character sequence.
4313   if (check(getTok().isNot(AsmToken::String),
4314             "unexpected token in '.file' directive") ||
4315       parseEscapedString(Path))
4316     return true;
4317 
4318   StringRef Directory;
4319   StringRef Filename;
4320   std::string FilenameData;
4321   if (getLexer().is(AsmToken::String)) {
4322     if (check(FileNumber == -1,
4323               "explicit path specified, but no file number") ||
4324         parseEscapedString(FilenameData))
4325       return true;
4326     Filename = FilenameData;
4327     Directory = Path;
4328   } else {
4329     Filename = Path;
4330   }
4331 
4332   uint64_t MD5Hi, MD5Lo;
4333   bool HasMD5 = false;
4334 
4335   Optional<StringRef> Source;
4336   bool HasSource = false;
4337   std::string SourceString;
4338 
4339   while (!parseOptionalToken(AsmToken::EndOfStatement)) {
4340     StringRef Keyword;
4341     if (check(getTok().isNot(AsmToken::Identifier),
4342               "unexpected token in '.file' directive") ||
4343         parseIdentifier(Keyword))
4344       return true;
4345     if (Keyword == "md5") {
4346       HasMD5 = true;
4347       if (check(FileNumber == -1,
4348                 "MD5 checksum specified, but no file number") ||
4349           parseHexOcta(*this, MD5Hi, MD5Lo))
4350         return true;
4351     } else if (Keyword == "source") {
4352       HasSource = true;
4353       if (check(FileNumber == -1,
4354                 "source specified, but no file number") ||
4355           check(getTok().isNot(AsmToken::String),
4356                 "unexpected token in '.file' directive") ||
4357           parseEscapedString(SourceString))
4358         return true;
4359     } else {
4360       return TokError("unexpected token in '.file' directive");
4361     }
4362   }
4363 
4364   if (FileNumber == -1) {
4365     // Ignore the directive if there is no number and the target doesn't support
4366     // numberless .file directives. This allows some portability of assembler
4367     // between different object file formats.
4368     if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4369       getStreamer().emitFileDirective(Filename);
4370   } else {
4371     // In case there is a -g option as well as debug info from directive .file,
4372     // we turn off the -g option, directly use the existing debug info instead.
4373     // Throw away any implicit file table for the assembler source.
4374     if (Ctx.getGenDwarfForAssembly()) {
4375       Ctx.getMCDwarfLineTable(0).resetFileTable();
4376       Ctx.setGenDwarfForAssembly(false);
4377     }
4378 
4379     Optional<MD5::MD5Result> CKMem;
4380     if (HasMD5) {
4381       MD5::MD5Result Sum;
4382       for (unsigned i = 0; i != 8; ++i) {
4383         Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4384         Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4385       }
4386       CKMem = Sum;
4387     }
4388     if (HasSource) {
4389       char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
4390       memcpy(SourceBuf, SourceString.data(), SourceString.size());
4391       Source = StringRef(SourceBuf, SourceString.size());
4392     }
4393     if (FileNumber == 0) {
4394       if (Ctx.getDwarfVersion() < 5)
4395         return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
4396       getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4397     } else {
4398       Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
4399           FileNumber, Directory, Filename, CKMem, Source);
4400       if (!FileNumOrErr)
4401         return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
4402     }
4403     // Alert the user if there are some .file directives with MD5 and some not.
4404     // But only do that once.
4405     if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
4406       ReportedInconsistentMD5 = true;
4407       return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
4408     }
4409   }
4410 
4411   return false;
4412 }
4413 
4414 /// parseDirectiveLine
4415 /// ::= .line [number]
4416 bool MasmParser::parseDirectiveLine() {
4417   int64_t LineNumber;
4418   if (getLexer().is(AsmToken::Integer)) {
4419     if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
4420       return true;
4421     (void)LineNumber;
4422     // FIXME: Do something with the .line.
4423   }
4424   if (parseToken(AsmToken::EndOfStatement,
4425                  "unexpected token in '.line' directive"))
4426     return true;
4427 
4428   return false;
4429 }
4430 
4431 /// parseDirectiveLoc
4432 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
4433 ///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
4434 /// The first number is a file number, must have been previously assigned with
4435 /// a .file directive, the second number is the line number and optionally the
4436 /// third number is a column position (zero if not specified).  The remaining
4437 /// optional items are .loc sub-directives.
4438 bool MasmParser::parseDirectiveLoc() {
4439   int64_t FileNumber = 0, LineNumber = 0;
4440   SMLoc Loc = getTok().getLoc();
4441   if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
4442       check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
4443             "file number less than one in '.loc' directive") ||
4444       check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4445             "unassigned file number in '.loc' directive"))
4446     return true;
4447 
4448   // optional
4449   if (getLexer().is(AsmToken::Integer)) {
4450     LineNumber = getTok().getIntVal();
4451     if (LineNumber < 0)
4452       return TokError("line number less than zero in '.loc' directive");
4453     Lex();
4454   }
4455 
4456   int64_t ColumnPos = 0;
4457   if (getLexer().is(AsmToken::Integer)) {
4458     ColumnPos = getTok().getIntVal();
4459     if (ColumnPos < 0)
4460       return TokError("column position less than zero in '.loc' directive");
4461     Lex();
4462   }
4463 
4464   auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4465   unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT;
4466   unsigned Isa = 0;
4467   int64_t Discriminator = 0;
4468 
4469   auto parseLocOp = [&]() -> bool {
4470     StringRef Name;
4471     SMLoc Loc = getTok().getLoc();
4472     if (parseIdentifier(Name))
4473       return TokError("unexpected token in '.loc' directive");
4474 
4475     if (Name == "basic_block")
4476       Flags |= DWARF2_FLAG_BASIC_BLOCK;
4477     else if (Name == "prologue_end")
4478       Flags |= DWARF2_FLAG_PROLOGUE_END;
4479     else if (Name == "epilogue_begin")
4480       Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
4481     else if (Name == "is_stmt") {
4482       Loc = getTok().getLoc();
4483       const MCExpr *Value;
4484       if (parseExpression(Value))
4485         return true;
4486       // The expression must be the constant 0 or 1.
4487       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4488         int Value = MCE->getValue();
4489         if (Value == 0)
4490           Flags &= ~DWARF2_FLAG_IS_STMT;
4491         else if (Value == 1)
4492           Flags |= DWARF2_FLAG_IS_STMT;
4493         else
4494           return Error(Loc, "is_stmt value not 0 or 1");
4495       } else {
4496         return Error(Loc, "is_stmt value not the constant value of 0 or 1");
4497       }
4498     } else if (Name == "isa") {
4499       Loc = getTok().getLoc();
4500       const MCExpr *Value;
4501       if (parseExpression(Value))
4502         return true;
4503       // The expression must be a constant greater or equal to 0.
4504       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4505         int Value = MCE->getValue();
4506         if (Value < 0)
4507           return Error(Loc, "isa number less than zero");
4508         Isa = Value;
4509       } else {
4510         return Error(Loc, "isa number not a constant value");
4511       }
4512     } else if (Name == "discriminator") {
4513       if (parseAbsoluteExpression(Discriminator))
4514         return true;
4515     } else {
4516       return Error(Loc, "unknown sub-directive in '.loc' directive");
4517     }
4518     return false;
4519   };
4520 
4521   if (parseMany(parseLocOp, false /*hasComma*/))
4522     return true;
4523 
4524   getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
4525                                       Isa, Discriminator, StringRef());
4526 
4527   return false;
4528 }
4529 
4530 /// parseDirectiveStabs
4531 /// ::= .stabs string, number, number, number
4532 bool MasmParser::parseDirectiveStabs() {
4533   return TokError("unsupported directive '.stabs'");
4534 }
4535 
4536 /// parseDirectiveCVFile
4537 /// ::= .cv_file number filename [checksum] [checksumkind]
4538 bool MasmParser::parseDirectiveCVFile() {
4539   SMLoc FileNumberLoc = getTok().getLoc();
4540   int64_t FileNumber;
4541   std::string Filename;
4542   std::string Checksum;
4543   int64_t ChecksumKind = 0;
4544 
4545   if (parseIntToken(FileNumber,
4546                     "expected file number in '.cv_file' directive") ||
4547       check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
4548       check(getTok().isNot(AsmToken::String),
4549             "unexpected token in '.cv_file' directive") ||
4550       parseEscapedString(Filename))
4551     return true;
4552   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4553     if (check(getTok().isNot(AsmToken::String),
4554               "unexpected token in '.cv_file' directive") ||
4555         parseEscapedString(Checksum) ||
4556         parseIntToken(ChecksumKind,
4557                       "expected checksum kind in '.cv_file' directive") ||
4558         parseToken(AsmToken::EndOfStatement,
4559                    "unexpected token in '.cv_file' directive"))
4560       return true;
4561   }
4562 
4563   Checksum = fromHex(Checksum);
4564   void *CKMem = Ctx.allocate(Checksum.size(), 1);
4565   memcpy(CKMem, Checksum.data(), Checksum.size());
4566   ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
4567                                     Checksum.size());
4568 
4569   if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
4570                                          static_cast<uint8_t>(ChecksumKind)))
4571     return Error(FileNumberLoc, "file number already allocated");
4572 
4573   return false;
4574 }
4575 
4576 bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
4577                                    StringRef DirectiveName) {
4578   SMLoc Loc;
4579   return parseTokenLoc(Loc) ||
4580          parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
4581                                        "' directive") ||
4582          check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
4583                "expected function id within range [0, UINT_MAX)");
4584 }
4585 
4586 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
4587   SMLoc Loc;
4588   return parseTokenLoc(Loc) ||
4589          parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
4590                                        "' directive") ||
4591          check(FileNumber < 1, Loc, "file number less than one in '" +
4592                                         DirectiveName + "' directive") ||
4593          check(!getCVContext().isValidFileNumber(FileNumber), Loc,
4594                "unassigned file number in '" + DirectiveName + "' directive");
4595 }
4596 
4597 /// parseDirectiveCVFuncId
4598 /// ::= .cv_func_id FunctionId
4599 ///
4600 /// Introduces a function ID that can be used with .cv_loc.
4601 bool MasmParser::parseDirectiveCVFuncId() {
4602   SMLoc FunctionIdLoc = getTok().getLoc();
4603   int64_t FunctionId;
4604 
4605   if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
4606       parseToken(AsmToken::EndOfStatement,
4607                  "unexpected token in '.cv_func_id' directive"))
4608     return true;
4609 
4610   if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
4611     return Error(FunctionIdLoc, "function id already allocated");
4612 
4613   return false;
4614 }
4615 
4616 /// parseDirectiveCVInlineSiteId
4617 /// ::= .cv_inline_site_id FunctionId
4618 ///         "within" IAFunc
4619 ///         "inlined_at" IAFile IALine [IACol]
4620 ///
4621 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
4622 /// at" source location information for use in the line table of the caller,
4623 /// whether the caller is a real function or another inlined call site.
4624 bool MasmParser::parseDirectiveCVInlineSiteId() {
4625   SMLoc FunctionIdLoc = getTok().getLoc();
4626   int64_t FunctionId;
4627   int64_t IAFunc;
4628   int64_t IAFile;
4629   int64_t IALine;
4630   int64_t IACol = 0;
4631 
4632   // FunctionId
4633   if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
4634     return true;
4635 
4636   // "within"
4637   if (check((getLexer().isNot(AsmToken::Identifier) ||
4638              getTok().getIdentifier() != "within"),
4639             "expected 'within' identifier in '.cv_inline_site_id' directive"))
4640     return true;
4641   Lex();
4642 
4643   // IAFunc
4644   if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
4645     return true;
4646 
4647   // "inlined_at"
4648   if (check((getLexer().isNot(AsmToken::Identifier) ||
4649              getTok().getIdentifier() != "inlined_at"),
4650             "expected 'inlined_at' identifier in '.cv_inline_site_id' "
4651             "directive") )
4652     return true;
4653   Lex();
4654 
4655   // IAFile IALine
4656   if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
4657       parseIntToken(IALine, "expected line number after 'inlined_at'"))
4658     return true;
4659 
4660   // [IACol]
4661   if (getLexer().is(AsmToken::Integer)) {
4662     IACol = getTok().getIntVal();
4663     Lex();
4664   }
4665 
4666   if (parseToken(AsmToken::EndOfStatement,
4667                  "unexpected token in '.cv_inline_site_id' directive"))
4668     return true;
4669 
4670   if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
4671                                                  IALine, IACol, FunctionIdLoc))
4672     return Error(FunctionIdLoc, "function id already allocated");
4673 
4674   return false;
4675 }
4676 
4677 /// parseDirectiveCVLoc
4678 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
4679 ///                                [is_stmt VALUE]
4680 /// The first number is a file number, must have been previously assigned with
4681 /// a .file directive, the second number is the line number and optionally the
4682 /// third number is a column position (zero if not specified).  The remaining
4683 /// optional items are .loc sub-directives.
4684 bool MasmParser::parseDirectiveCVLoc() {
4685   SMLoc DirectiveLoc = getTok().getLoc();
4686   int64_t FunctionId, FileNumber;
4687   if (parseCVFunctionId(FunctionId, ".cv_loc") ||
4688       parseCVFileId(FileNumber, ".cv_loc"))
4689     return true;
4690 
4691   int64_t LineNumber = 0;
4692   if (getLexer().is(AsmToken::Integer)) {
4693     LineNumber = getTok().getIntVal();
4694     if (LineNumber < 0)
4695       return TokError("line number less than zero in '.cv_loc' directive");
4696     Lex();
4697   }
4698 
4699   int64_t ColumnPos = 0;
4700   if (getLexer().is(AsmToken::Integer)) {
4701     ColumnPos = getTok().getIntVal();
4702     if (ColumnPos < 0)
4703       return TokError("column position less than zero in '.cv_loc' directive");
4704     Lex();
4705   }
4706 
4707   bool PrologueEnd = false;
4708   uint64_t IsStmt = 0;
4709 
4710   auto parseOp = [&]() -> bool {
4711     StringRef Name;
4712     SMLoc Loc = getTok().getLoc();
4713     if (parseIdentifier(Name))
4714       return TokError("unexpected token in '.cv_loc' directive");
4715     if (Name == "prologue_end")
4716       PrologueEnd = true;
4717     else if (Name == "is_stmt") {
4718       Loc = getTok().getLoc();
4719       const MCExpr *Value;
4720       if (parseExpression(Value))
4721         return true;
4722       // The expression must be the constant 0 or 1.
4723       IsStmt = ~0ULL;
4724       if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
4725         IsStmt = MCE->getValue();
4726 
4727       if (IsStmt > 1)
4728         return Error(Loc, "is_stmt value not 0 or 1");
4729     } else {
4730       return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
4731     }
4732     return false;
4733   };
4734 
4735   if (parseMany(parseOp, false /*hasComma*/))
4736     return true;
4737 
4738   getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
4739                                    ColumnPos, PrologueEnd, IsStmt, StringRef(),
4740                                    DirectiveLoc);
4741   return false;
4742 }
4743 
4744 /// parseDirectiveCVLinetable
4745 /// ::= .cv_linetable FunctionId, FnStart, FnEnd
4746 bool MasmParser::parseDirectiveCVLinetable() {
4747   int64_t FunctionId;
4748   StringRef FnStartName, FnEndName;
4749   SMLoc Loc = getTok().getLoc();
4750   if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
4751       parseToken(AsmToken::Comma,
4752                  "unexpected token in '.cv_linetable' directive") ||
4753       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
4754                                   "expected identifier in directive") ||
4755       parseToken(AsmToken::Comma,
4756                  "unexpected token in '.cv_linetable' directive") ||
4757       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
4758                                   "expected identifier in directive"))
4759     return true;
4760 
4761   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4762   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4763 
4764   getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
4765   return false;
4766 }
4767 
4768 /// parseDirectiveCVInlineLinetable
4769 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
4770 bool MasmParser::parseDirectiveCVInlineLinetable() {
4771   int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
4772   StringRef FnStartName, FnEndName;
4773   SMLoc Loc = getTok().getLoc();
4774   if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
4775       parseTokenLoc(Loc) ||
4776       parseIntToken(
4777           SourceFileId,
4778           "expected SourceField in '.cv_inline_linetable' directive") ||
4779       check(SourceFileId <= 0, Loc,
4780             "File id less than zero in '.cv_inline_linetable' directive") ||
4781       parseTokenLoc(Loc) ||
4782       parseIntToken(
4783           SourceLineNum,
4784           "expected SourceLineNum in '.cv_inline_linetable' directive") ||
4785       check(SourceLineNum < 0, Loc,
4786             "Line number less than zero in '.cv_inline_linetable' directive") ||
4787       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
4788                                   "expected identifier in directive") ||
4789       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
4790                                   "expected identifier in directive"))
4791     return true;
4792 
4793   if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
4794     return true;
4795 
4796   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4797   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4798   getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
4799                                                SourceLineNum, FnStartSym,
4800                                                FnEndSym);
4801   return false;
4802 }
4803 
4804 void MasmParser::initializeCVDefRangeTypeMap() {
4805   CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
4806   CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
4807   CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
4808   CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
4809 }
4810 
4811 /// parseDirectiveCVDefRange
4812 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
4813 bool MasmParser::parseDirectiveCVDefRange() {
4814   SMLoc Loc;
4815   std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
4816   while (getLexer().is(AsmToken::Identifier)) {
4817     Loc = getLexer().getLoc();
4818     StringRef GapStartName;
4819     if (parseIdentifier(GapStartName))
4820       return Error(Loc, "expected identifier in directive");
4821     MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
4822 
4823     Loc = getLexer().getLoc();
4824     StringRef GapEndName;
4825     if (parseIdentifier(GapEndName))
4826       return Error(Loc, "expected identifier in directive");
4827     MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
4828 
4829     Ranges.push_back({GapStartSym, GapEndSym});
4830   }
4831 
4832   StringRef CVDefRangeTypeStr;
4833   if (parseToken(
4834           AsmToken::Comma,
4835           "expected comma before def_range type in .cv_def_range directive") ||
4836       parseIdentifier(CVDefRangeTypeStr))
4837     return Error(Loc, "expected def_range type in directive");
4838 
4839   StringMap<CVDefRangeType>::const_iterator CVTypeIt =
4840       CVDefRangeTypeMap.find(CVDefRangeTypeStr);
4841   CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
4842                                 ? CVDR_DEFRANGE
4843                                 : CVTypeIt->getValue();
4844   switch (CVDRType) {
4845   case CVDR_DEFRANGE_REGISTER: {
4846     int64_t DRRegister;
4847     if (parseToken(AsmToken::Comma, "expected comma before register number in "
4848                                     ".cv_def_range directive") ||
4849         parseAbsoluteExpression(DRRegister))
4850       return Error(Loc, "expected register number");
4851 
4852     codeview::DefRangeRegisterHeader DRHdr;
4853     DRHdr.Register = DRRegister;
4854     DRHdr.MayHaveNoName = 0;
4855     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4856     break;
4857   }
4858   case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
4859     int64_t DROffset;
4860     if (parseToken(AsmToken::Comma,
4861                    "expected comma before offset in .cv_def_range directive") ||
4862         parseAbsoluteExpression(DROffset))
4863       return Error(Loc, "expected offset value");
4864 
4865     codeview::DefRangeFramePointerRelHeader DRHdr;
4866     DRHdr.Offset = DROffset;
4867     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4868     break;
4869   }
4870   case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
4871     int64_t DRRegister;
4872     int64_t DROffsetInParent;
4873     if (parseToken(AsmToken::Comma, "expected comma before register number in "
4874                                     ".cv_def_range directive") ||
4875         parseAbsoluteExpression(DRRegister))
4876       return Error(Loc, "expected register number");
4877     if (parseToken(AsmToken::Comma,
4878                    "expected comma before offset in .cv_def_range directive") ||
4879         parseAbsoluteExpression(DROffsetInParent))
4880       return Error(Loc, "expected offset value");
4881 
4882     codeview::DefRangeSubfieldRegisterHeader DRHdr;
4883     DRHdr.Register = DRRegister;
4884     DRHdr.MayHaveNoName = 0;
4885     DRHdr.OffsetInParent = DROffsetInParent;
4886     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4887     break;
4888   }
4889   case CVDR_DEFRANGE_REGISTER_REL: {
4890     int64_t DRRegister;
4891     int64_t DRFlags;
4892     int64_t DRBasePointerOffset;
4893     if (parseToken(AsmToken::Comma, "expected comma before register number in "
4894                                     ".cv_def_range directive") ||
4895         parseAbsoluteExpression(DRRegister))
4896       return Error(Loc, "expected register value");
4897     if (parseToken(
4898             AsmToken::Comma,
4899             "expected comma before flag value in .cv_def_range directive") ||
4900         parseAbsoluteExpression(DRFlags))
4901       return Error(Loc, "expected flag value");
4902     if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
4903                                     "in .cv_def_range directive") ||
4904         parseAbsoluteExpression(DRBasePointerOffset))
4905       return Error(Loc, "expected base pointer offset value");
4906 
4907     codeview::DefRangeRegisterRelHeader DRHdr;
4908     DRHdr.Register = DRRegister;
4909     DRHdr.Flags = DRFlags;
4910     DRHdr.BasePointerOffset = DRBasePointerOffset;
4911     getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
4912     break;
4913   }
4914   default:
4915     return Error(Loc, "unexpected def_range type in .cv_def_range directive");
4916   }
4917   return true;
4918 }
4919 
4920 /// parseDirectiveCVString
4921 /// ::= .cv_stringtable "string"
4922 bool MasmParser::parseDirectiveCVString() {
4923   std::string Data;
4924   if (checkForValidSection() || parseEscapedString(Data))
4925     return addErrorSuffix(" in '.cv_string' directive");
4926 
4927   // Put the string in the table and emit the offset.
4928   std::pair<StringRef, unsigned> Insertion =
4929       getCVContext().addToStringTable(Data);
4930   getStreamer().emitIntValue(Insertion.second, 4);
4931   return false;
4932 }
4933 
4934 /// parseDirectiveCVStringTable
4935 /// ::= .cv_stringtable
4936 bool MasmParser::parseDirectiveCVStringTable() {
4937   getStreamer().emitCVStringTableDirective();
4938   return false;
4939 }
4940 
4941 /// parseDirectiveCVFileChecksums
4942 /// ::= .cv_filechecksums
4943 bool MasmParser::parseDirectiveCVFileChecksums() {
4944   getStreamer().emitCVFileChecksumsDirective();
4945   return false;
4946 }
4947 
4948 /// parseDirectiveCVFileChecksumOffset
4949 /// ::= .cv_filechecksumoffset fileno
4950 bool MasmParser::parseDirectiveCVFileChecksumOffset() {
4951   int64_t FileNo;
4952   if (parseIntToken(FileNo, "expected identifier in directive"))
4953     return true;
4954   if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
4955     return true;
4956   getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
4957   return false;
4958 }
4959 
4960 /// parseDirectiveCVFPOData
4961 /// ::= .cv_fpo_data procsym
4962 bool MasmParser::parseDirectiveCVFPOData() {
4963   SMLoc DirLoc = getLexer().getLoc();
4964   StringRef ProcName;
4965   if (parseIdentifier(ProcName))
4966     return TokError("expected symbol name");
4967   if (parseEOL("unexpected tokens"))
4968     return addErrorSuffix(" in '.cv_fpo_data' directive");
4969   MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4970   getStreamer().EmitCVFPOData(ProcSym, DirLoc);
4971   return false;
4972 }
4973 
4974 /// parseDirectiveCFISections
4975 /// ::= .cfi_sections section [, section]
4976 bool MasmParser::parseDirectiveCFISections() {
4977   StringRef Name;
4978   bool EH = false;
4979   bool Debug = false;
4980 
4981   if (parseIdentifier(Name))
4982     return TokError("Expected an identifier");
4983 
4984   if (Name == ".eh_frame")
4985     EH = true;
4986   else if (Name == ".debug_frame")
4987     Debug = true;
4988 
4989   if (getLexer().is(AsmToken::Comma)) {
4990     Lex();
4991 
4992     if (parseIdentifier(Name))
4993       return TokError("Expected an identifier");
4994 
4995     if (Name == ".eh_frame")
4996       EH = true;
4997     else if (Name == ".debug_frame")
4998       Debug = true;
4999   }
5000 
5001   getStreamer().emitCFISections(EH, Debug);
5002   return false;
5003 }
5004 
5005 /// parseDirectiveCFIStartProc
5006 /// ::= .cfi_startproc [simple]
5007 bool MasmParser::parseDirectiveCFIStartProc() {
5008   StringRef Simple;
5009   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5010     if (check(parseIdentifier(Simple) || Simple != "simple",
5011               "unexpected token") ||
5012         parseToken(AsmToken::EndOfStatement))
5013       return addErrorSuffix(" in '.cfi_startproc' directive");
5014   }
5015 
5016   // TODO(kristina): Deal with a corner case of incorrect diagnostic context
5017   // being produced if this directive is emitted as part of preprocessor macro
5018   // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
5019   // Tools like llvm-mc on the other hand are not affected by it, and report
5020   // correct context information.
5021   getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc());
5022   return false;
5023 }
5024 
5025 /// parseDirectiveCFIEndProc
5026 /// ::= .cfi_endproc
5027 bool MasmParser::parseDirectiveCFIEndProc() {
5028   getStreamer().emitCFIEndProc();
5029   return false;
5030 }
5031 
5032 /// parse register name or number.
5033 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register,
5034                                                SMLoc DirectiveLoc) {
5035   unsigned RegNo;
5036 
5037   if (getLexer().isNot(AsmToken::Integer)) {
5038     if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
5039       return true;
5040     Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
5041   } else
5042     return parseAbsoluteExpression(Register);
5043 
5044   return false;
5045 }
5046 
5047 /// parseDirectiveCFIDefCfa
5048 /// ::= .cfi_def_cfa register,  offset
5049 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
5050   int64_t Register = 0, Offset = 0;
5051   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5052       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5053       parseAbsoluteExpression(Offset))
5054     return true;
5055 
5056   getStreamer().emitCFIDefCfa(Register, Offset);
5057   return false;
5058 }
5059 
5060 /// parseDirectiveCFIDefCfaOffset
5061 /// ::= .cfi_def_cfa_offset offset
5062 bool MasmParser::parseDirectiveCFIDefCfaOffset() {
5063   int64_t Offset = 0;
5064   if (parseAbsoluteExpression(Offset))
5065     return true;
5066 
5067   getStreamer().emitCFIDefCfaOffset(Offset);
5068   return false;
5069 }
5070 
5071 /// parseDirectiveCFIRegister
5072 /// ::= .cfi_register register, register
5073 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
5074   int64_t Register1 = 0, Register2 = 0;
5075   if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
5076       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5077       parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
5078     return true;
5079 
5080   getStreamer().emitCFIRegister(Register1, Register2);
5081   return false;
5082 }
5083 
5084 /// parseDirectiveCFIWindowSave
5085 /// ::= .cfi_window_save
5086 bool MasmParser::parseDirectiveCFIWindowSave() {
5087   getStreamer().emitCFIWindowSave();
5088   return false;
5089 }
5090 
5091 /// parseDirectiveCFIAdjustCfaOffset
5092 /// ::= .cfi_adjust_cfa_offset adjustment
5093 bool MasmParser::parseDirectiveCFIAdjustCfaOffset() {
5094   int64_t Adjustment = 0;
5095   if (parseAbsoluteExpression(Adjustment))
5096     return true;
5097 
5098   getStreamer().emitCFIAdjustCfaOffset(Adjustment);
5099   return false;
5100 }
5101 
5102 /// parseDirectiveCFIDefCfaRegister
5103 /// ::= .cfi_def_cfa_register register
5104 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
5105   int64_t Register = 0;
5106   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5107     return true;
5108 
5109   getStreamer().emitCFIDefCfaRegister(Register);
5110   return false;
5111 }
5112 
5113 /// parseDirectiveCFIOffset
5114 /// ::= .cfi_offset register, offset
5115 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
5116   int64_t Register = 0;
5117   int64_t Offset = 0;
5118 
5119   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5120       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5121       parseAbsoluteExpression(Offset))
5122     return true;
5123 
5124   getStreamer().emitCFIOffset(Register, Offset);
5125   return false;
5126 }
5127 
5128 /// parseDirectiveCFIRelOffset
5129 /// ::= .cfi_rel_offset register, offset
5130 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
5131   int64_t Register = 0, Offset = 0;
5132 
5133   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5134       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5135       parseAbsoluteExpression(Offset))
5136     return true;
5137 
5138   getStreamer().emitCFIRelOffset(Register, Offset);
5139   return false;
5140 }
5141 
5142 static bool isValidEncoding(int64_t Encoding) {
5143   if (Encoding & ~0xff)
5144     return false;
5145 
5146   if (Encoding == dwarf::DW_EH_PE_omit)
5147     return true;
5148 
5149   const unsigned Format = Encoding & 0xf;
5150   if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
5151       Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
5152       Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
5153       Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
5154     return false;
5155 
5156   const unsigned Application = Encoding & 0x70;
5157   if (Application != dwarf::DW_EH_PE_absptr &&
5158       Application != dwarf::DW_EH_PE_pcrel)
5159     return false;
5160 
5161   return true;
5162 }
5163 
5164 /// parseDirectiveCFIPersonalityOrLsda
5165 /// IsPersonality true for cfi_personality, false for cfi_lsda
5166 /// ::= .cfi_personality encoding, [symbol_name]
5167 /// ::= .cfi_lsda encoding, [symbol_name]
5168 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
5169   int64_t Encoding = 0;
5170   if (parseAbsoluteExpression(Encoding))
5171     return true;
5172   if (Encoding == dwarf::DW_EH_PE_omit)
5173     return false;
5174 
5175   StringRef Name;
5176   if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
5177       parseToken(AsmToken::Comma, "unexpected token in directive") ||
5178       check(parseIdentifier(Name), "expected identifier in directive"))
5179     return true;
5180 
5181   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5182 
5183   if (IsPersonality)
5184     getStreamer().emitCFIPersonality(Sym, Encoding);
5185   else
5186     getStreamer().emitCFILsda(Sym, Encoding);
5187   return false;
5188 }
5189 
5190 /// parseDirectiveCFIRememberState
5191 /// ::= .cfi_remember_state
5192 bool MasmParser::parseDirectiveCFIRememberState() {
5193   getStreamer().emitCFIRememberState();
5194   return false;
5195 }
5196 
5197 /// parseDirectiveCFIRestoreState
5198 /// ::= .cfi_remember_state
5199 bool MasmParser::parseDirectiveCFIRestoreState() {
5200   getStreamer().emitCFIRestoreState();
5201   return false;
5202 }
5203 
5204 /// parseDirectiveCFISameValue
5205 /// ::= .cfi_same_value register
5206 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
5207   int64_t Register = 0;
5208 
5209   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5210     return true;
5211 
5212   getStreamer().emitCFISameValue(Register);
5213   return false;
5214 }
5215 
5216 /// parseDirectiveCFIRestore
5217 /// ::= .cfi_restore register
5218 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
5219   int64_t Register = 0;
5220   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5221     return true;
5222 
5223   getStreamer().emitCFIRestore(Register);
5224   return false;
5225 }
5226 
5227 /// parseDirectiveCFIEscape
5228 /// ::= .cfi_escape expression[,...]
5229 bool MasmParser::parseDirectiveCFIEscape() {
5230   std::string Values;
5231   int64_t CurrValue;
5232   if (parseAbsoluteExpression(CurrValue))
5233     return true;
5234 
5235   Values.push_back((uint8_t)CurrValue);
5236 
5237   while (getLexer().is(AsmToken::Comma)) {
5238     Lex();
5239 
5240     if (parseAbsoluteExpression(CurrValue))
5241       return true;
5242 
5243     Values.push_back((uint8_t)CurrValue);
5244   }
5245 
5246   getStreamer().emitCFIEscape(Values);
5247   return false;
5248 }
5249 
5250 /// parseDirectiveCFIReturnColumn
5251 /// ::= .cfi_return_column register
5252 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
5253   int64_t Register = 0;
5254   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5255     return true;
5256   getStreamer().emitCFIReturnColumn(Register);
5257   return false;
5258 }
5259 
5260 /// parseDirectiveCFISignalFrame
5261 /// ::= .cfi_signal_frame
5262 bool MasmParser::parseDirectiveCFISignalFrame() {
5263   if (parseToken(AsmToken::EndOfStatement,
5264                  "unexpected token in '.cfi_signal_frame'"))
5265     return true;
5266 
5267   getStreamer().emitCFISignalFrame();
5268   return false;
5269 }
5270 
5271 /// parseDirectiveCFIUndefined
5272 /// ::= .cfi_undefined register
5273 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
5274   int64_t Register = 0;
5275 
5276   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5277     return true;
5278 
5279   getStreamer().emitCFIUndefined(Register);
5280   return false;
5281 }
5282 
5283 /// parseDirectiveMacro
5284 /// ::= name macro [parameters]
5285 ///     ["LOCAL" identifiers]
5286 ///   parameters ::= parameter [, parameter]*
5287 ///   parameter ::= name ":" qualifier
5288 ///   qualifier ::= "req" | "vararg" | "=" macro_argument
5289 bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
5290   MCAsmMacroParameters Parameters;
5291   while (getLexer().isNot(AsmToken::EndOfStatement)) {
5292     if (!Parameters.empty() && Parameters.back().Vararg)
5293       return Error(Lexer.getLoc(),
5294                    "Vararg parameter '" + Parameters.back().Name +
5295                        "' should be last in the list of parameters");
5296 
5297     MCAsmMacroParameter Parameter;
5298     if (parseIdentifier(Parameter.Name))
5299       return TokError("expected identifier in 'macro' directive");
5300 
5301     // Emit an error if two (or more) named parameters share the same name.
5302     for (const MCAsmMacroParameter& CurrParam : Parameters)
5303       if (CurrParam.Name.equals_lower(Parameter.Name))
5304         return TokError("macro '" + Name + "' has multiple parameters"
5305                         " named '" + Parameter.Name + "'");
5306 
5307     if (Lexer.is(AsmToken::Colon)) {
5308       Lex();  // consume ':'
5309 
5310       if (parseOptionalToken(AsmToken::Equal)) {
5311         // Default value
5312         SMLoc ParamLoc;
5313 
5314         ParamLoc = Lexer.getLoc();
5315         if (parseMacroArgument(nullptr, Parameter.Value))
5316           return true;
5317       } else {
5318         SMLoc QualLoc;
5319         StringRef Qualifier;
5320 
5321         QualLoc = Lexer.getLoc();
5322         if (parseIdentifier(Qualifier))
5323           return Error(QualLoc, "missing parameter qualifier for "
5324                                 "'" +
5325                                     Parameter.Name + "' in macro '" + Name +
5326                                     "'");
5327 
5328         if (Qualifier.equals_lower("req"))
5329           Parameter.Required = true;
5330         else if (Qualifier.equals_lower("vararg"))
5331           Parameter.Vararg = true;
5332         else
5333           return Error(QualLoc,
5334                        Qualifier + " is not a valid parameter qualifier for '" +
5335                            Parameter.Name + "' in macro '" + Name + "'");
5336       }
5337     }
5338 
5339     Parameters.push_back(std::move(Parameter));
5340 
5341     if (getLexer().is(AsmToken::Comma))
5342       Lex();
5343   }
5344 
5345   // Eat just the end of statement.
5346   Lexer.Lex();
5347 
5348   std::vector<std::string> Locals;
5349   if (getTok().is(AsmToken::Identifier) &&
5350       getTok().getIdentifier().equals_lower("local")) {
5351     Lex(); // Eat the LOCAL directive.
5352 
5353     StringRef ID;
5354     while (true) {
5355       if (parseIdentifier(ID))
5356         return true;
5357       Locals.push_back(ID.lower());
5358 
5359       // If we see a comma, continue (and allow line continuation).
5360       if (!parseOptionalToken(AsmToken::Comma))
5361         break;
5362       parseOptionalToken(AsmToken::EndOfStatement);
5363     }
5364   }
5365 
5366   // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors.
5367   AsmToken EndToken, StartToken = getTok();
5368   unsigned MacroDepth = 0;
5369   // Lex the macro definition.
5370   while (true) {
5371     // Ignore Lexing errors in macros.
5372     while (Lexer.is(AsmToken::Error)) {
5373       Lexer.Lex();
5374     }
5375 
5376     // Check whether we have reached the end of the file.
5377     if (getLexer().is(AsmToken::Eof))
5378       return Error(NameLoc, "no matching 'endm' in definition");
5379 
5380     // Otherwise, check whether we have reach the 'endm'.
5381     if (getLexer().is(AsmToken::Identifier)) {
5382       if (getTok().getIdentifier().equals_lower("endm")) {
5383         if (MacroDepth == 0) { // Outermost macro.
5384           EndToken = getTok();
5385           Lexer.Lex();
5386           if (getLexer().isNot(AsmToken::EndOfStatement))
5387             return TokError("unexpected token in '" + EndToken.getIdentifier() +
5388                             "' directive");
5389           break;
5390         } else {
5391           // Otherwise we just found the end of an inner macro.
5392           --MacroDepth;
5393         }
5394       } else if (isMacroLikeDirective()) {
5395         // We allow nested macros. Those aren't instantiated until the
5396         // outermost macro is expanded so just ignore them for now.
5397         ++MacroDepth;
5398       }
5399     }
5400 
5401     // Otherwise, scan til the end of the statement.
5402     eatToEndOfStatement();
5403   }
5404 
5405   if (getContext().lookupMacro(Name)) {
5406     return Error(NameLoc, "macro '" + Name + "' is already defined");
5407   }
5408 
5409   const char *BodyStart = StartToken.getLoc().getPointer();
5410   const char *BodyEnd = EndToken.getLoc().getPointer();
5411   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5412   checkForBadMacro(NameLoc, Name, Body, Parameters);
5413   MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals));
5414   DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
5415                   Macro.dump());
5416   getContext().defineMacro(Name, std::move(Macro));
5417   return false;
5418 }
5419 
5420 /// checkForBadMacro
5421 ///
5422 /// With the support added for named parameters there may be code out there that
5423 /// is transitioning from positional parameters.  In versions of gas that did
5424 /// not support named parameters they would be ignored on the macro definition.
5425 /// But to support both styles of parameters this is not possible so if a macro
5426 /// definition has named parameters but does not use them and has what appears
5427 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a
5428 /// warning that the positional parameter found in body which have no effect.
5429 /// Hoping the developer will either remove the named parameters from the macro
5430 /// definition so the positional parameters get used if that was what was
5431 /// intended or change the macro to use the named parameters.  It is possible
5432 /// this warning will trigger when the none of the named parameters are used
5433 /// and the strings like $1 are infact to simply to be passed trough unchanged.
5434 void MasmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
5435                                   StringRef Body,
5436                                   ArrayRef<MCAsmMacroParameter> Parameters) {
5437   // If this macro is not defined with named parameters the warning we are
5438   // checking for here doesn't apply.
5439   unsigned NParameters = Parameters.size();
5440   if (NParameters == 0)
5441     return;
5442 
5443   bool NamedParametersFound = false;
5444   bool PositionalParametersFound = false;
5445 
5446   // Look at the body of the macro for use of both the named parameters and what
5447   // are likely to be positional parameters.  This is what expandMacro() is
5448   // doing when it finds the parameters in the body.
5449   while (!Body.empty()) {
5450     // Scan for the next possible parameter.
5451     std::size_t End = Body.size(), Pos = 0;
5452     for (; Pos != End; ++Pos) {
5453       // Check for a substitution or escape.
5454       // This macro is defined with parameters, look for \foo, \bar, etc.
5455       if (Body[Pos] == '\\' && Pos + 1 != End)
5456         break;
5457 
5458       // This macro should have parameters, but look for $0, $1, ..., $n too.
5459       if (Body[Pos] != '$' || Pos + 1 == End)
5460         continue;
5461       char Next = Body[Pos + 1];
5462       if (Next == '$' || Next == 'n' ||
5463           isdigit(static_cast<unsigned char>(Next)))
5464         break;
5465     }
5466 
5467     // Check if we reached the end.
5468     if (Pos == End)
5469       break;
5470 
5471     if (Body[Pos] == '$') {
5472       switch (Body[Pos + 1]) {
5473       // $$ => $
5474       case '$':
5475         break;
5476 
5477       // $n => number of arguments
5478       case 'n':
5479         PositionalParametersFound = true;
5480         break;
5481 
5482       // $[0-9] => argument
5483       default: {
5484         PositionalParametersFound = true;
5485         break;
5486       }
5487       }
5488       Pos += 2;
5489     } else {
5490       unsigned I = Pos + 1;
5491       while (isIdentifierChar(Body[I]) && I + 1 != End)
5492         ++I;
5493 
5494       const char *Begin = Body.data() + Pos + 1;
5495       StringRef Argument(Begin, I - (Pos + 1));
5496       unsigned Index = 0;
5497       for (; Index < NParameters; ++Index)
5498         if (Parameters[Index].Name == Argument)
5499           break;
5500 
5501       if (Index == NParameters) {
5502         if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
5503           Pos += 3;
5504         else {
5505           Pos = I;
5506         }
5507       } else {
5508         NamedParametersFound = true;
5509         Pos += 1 + Argument.size();
5510       }
5511     }
5512     // Update the scan point.
5513     Body = Body.substr(Pos);
5514   }
5515 
5516   if (!NamedParametersFound && PositionalParametersFound)
5517     Warning(DirectiveLoc, "macro defined with named parameters which are not "
5518                           "used in macro body, possible positional parameter "
5519                           "found in body which will have no effect");
5520 }
5521 
5522 /// parseDirectiveExitMacro
5523 /// ::= exitm
5524 bool MasmParser::parseDirectiveExitMacro(StringRef Directive) {
5525   if (parseToken(AsmToken::EndOfStatement,
5526                  "unexpected token in '" + Directive + "' directive"))
5527     return true;
5528 
5529   if (!isInsideMacroInstantiation())
5530     return TokError("unexpected '" + Directive + "' in file, "
5531                                                  "no current macro definition");
5532 
5533   // Exit all conditionals that are active in the current macro.
5534   while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5535     TheCondState = TheCondStack.back();
5536     TheCondStack.pop_back();
5537   }
5538 
5539   handleMacroExit();
5540   return false;
5541 }
5542 
5543 /// parseDirectiveEndMacro
5544 /// ::= endm
5545 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
5546   if (getLexer().isNot(AsmToken::EndOfStatement))
5547     return TokError("unexpected token in '" + Directive + "' directive");
5548 
5549   // If we are inside a macro instantiation, terminate the current
5550   // instantiation.
5551   if (isInsideMacroInstantiation()) {
5552     handleMacroExit();
5553     return false;
5554   }
5555 
5556   // Otherwise, this .endmacro is a stray entry in the file; well formed
5557   // .endmacro directives are handled during the macro definition parsing.
5558   return TokError("unexpected '" + Directive + "' in file, "
5559                                                "no current macro definition");
5560 }
5561 
5562 /// parseDirectivePurgeMacro
5563 /// ::= .purgem
5564 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
5565   StringRef Name;
5566   SMLoc Loc;
5567   if (parseTokenLoc(Loc) ||
5568       check(parseIdentifier(Name), Loc,
5569             "expected identifier in '.purgem' directive") ||
5570       parseToken(AsmToken::EndOfStatement,
5571                  "unexpected token in '.purgem' directive"))
5572     return true;
5573 
5574   if (!getContext().lookupMacro(Name))
5575     return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
5576 
5577   getContext().undefineMacro(Name);
5578   DEBUG_WITH_TYPE("asm-macros", dbgs()
5579                                     << "Un-defining macro: " << Name << "\n");
5580   return false;
5581 }
5582 
5583 /// parseDirectiveSymbolAttribute
5584 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
5585 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
5586   auto parseOp = [&]() -> bool {
5587     StringRef Name;
5588     SMLoc Loc = getTok().getLoc();
5589     if (parseIdentifier(Name))
5590       return Error(Loc, "expected identifier");
5591     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5592 
5593     // Assembler local symbols don't make any sense here. Complain loudly.
5594     if (Sym->isTemporary())
5595       return Error(Loc, "non-local symbol required");
5596 
5597     if (!getStreamer().emitSymbolAttribute(Sym, Attr))
5598       return Error(Loc, "unable to emit symbol attribute");
5599     return false;
5600   };
5601 
5602   if (parseMany(parseOp))
5603     return addErrorSuffix(" in directive");
5604   return false;
5605 }
5606 
5607 /// parseDirectiveComm
5608 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
5609 bool MasmParser::parseDirectiveComm(bool IsLocal) {
5610   if (checkForValidSection())
5611     return true;
5612 
5613   SMLoc IDLoc = getLexer().getLoc();
5614   StringRef Name;
5615   if (parseIdentifier(Name))
5616     return TokError("expected identifier in directive");
5617 
5618   // Handle the identifier as the key symbol.
5619   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5620 
5621   if (getLexer().isNot(AsmToken::Comma))
5622     return TokError("unexpected token in directive");
5623   Lex();
5624 
5625   int64_t Size;
5626   SMLoc SizeLoc = getLexer().getLoc();
5627   if (parseAbsoluteExpression(Size))
5628     return true;
5629 
5630   int64_t Pow2Alignment = 0;
5631   SMLoc Pow2AlignmentLoc;
5632   if (getLexer().is(AsmToken::Comma)) {
5633     Lex();
5634     Pow2AlignmentLoc = getLexer().getLoc();
5635     if (parseAbsoluteExpression(Pow2Alignment))
5636       return true;
5637 
5638     LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
5639     if (IsLocal && LCOMM == LCOMM::NoAlignment)
5640       return Error(Pow2AlignmentLoc, "alignment not supported on this target");
5641 
5642     // If this target takes alignments in bytes (not log) validate and convert.
5643     if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5644         (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
5645       if (!isPowerOf2_64(Pow2Alignment))
5646         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
5647       Pow2Alignment = Log2_64(Pow2Alignment);
5648     }
5649   }
5650 
5651   if (parseToken(AsmToken::EndOfStatement,
5652                  "unexpected token in '.comm' or '.lcomm' directive"))
5653     return true;
5654 
5655   // NOTE: a size of zero for a .comm should create a undefined symbol
5656   // but a size of .lcomm creates a bss symbol of size zero.
5657   if (Size < 0)
5658     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
5659                           "be less than zero");
5660 
5661   // NOTE: The alignment in the directive is a power of 2 value, the assembler
5662   // may internally end up wanting an alignment in bytes.
5663   // FIXME: Diagnose overflow.
5664   if (Pow2Alignment < 0)
5665     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
5666                                    "alignment, can't be less than zero");
5667 
5668   Sym->redefineIfPossible();
5669   if (!Sym->isUndefined())
5670     return Error(IDLoc, "invalid symbol redefinition");
5671 
5672   // Create the Symbol as a common or local common with Size and Pow2Alignment.
5673   if (IsLocal) {
5674     getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
5675     return false;
5676   }
5677 
5678   getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
5679   return false;
5680 }
5681 
5682 /// parseDirectiveComment
5683 ///  ::= comment delimiter [[text]]
5684 ///              [[text]]
5685 ///              [[text]] delimiter [[text]]
5686 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
5687   StringRef FirstLine = parseStringToEndOfStatement();
5688   size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
5689   StringRef Delimiter = FirstLine.take_front(DelimiterEnd);
5690   if (Delimiter.empty())
5691     return Error(DirectiveLoc, "no delimiter in 'comment' directive");
5692   do {
5693     if (getTok().is(AsmToken::Eof))
5694       return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
5695     Lex();  // eat end of statement
5696   } while (!parseStringToEndOfStatement().contains(Delimiter));
5697   return parseToken(AsmToken::EndOfStatement,
5698                     "unexpected token in 'comment' directive");
5699 }
5700 
5701 /// parseDirectiveInclude
5702 ///  ::= include <filename>
5703 ///    | include filename
5704 bool MasmParser::parseDirectiveInclude() {
5705   // Allow the strings to have escaped octal character sequence.
5706   std::string Filename;
5707   SMLoc IncludeLoc = getTok().getLoc();
5708 
5709   if (!parseAngleBracketString(Filename))
5710     Filename = parseStringToEndOfStatement().str();
5711   if (check(!Filename.empty(), "missing filename in 'include' directive") ||
5712       check(getTok().isNot(AsmToken::EndOfStatement),
5713             "unexpected token in 'include' directive") ||
5714       // Attempt to switch the lexer to the included file before consuming the
5715       // end of statement to avoid losing it when we switch.
5716       check(enterIncludeFile(Filename), IncludeLoc,
5717             "Could not find include file '" + Filename + "'"))
5718     return true;
5719 
5720   return false;
5721 }
5722 
5723 /// parseDirectiveIf
5724 /// ::= .if{,eq,ge,gt,le,lt,ne} expression
5725 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
5726   TheCondStack.push_back(TheCondState);
5727   TheCondState.TheCond = AsmCond::IfCond;
5728   if (TheCondState.Ignore) {
5729     eatToEndOfStatement();
5730   } else {
5731     int64_t ExprValue;
5732     if (parseAbsoluteExpression(ExprValue) ||
5733         parseToken(AsmToken::EndOfStatement,
5734                    "unexpected token in '.if' directive"))
5735       return true;
5736 
5737     switch (DirKind) {
5738     default:
5739       llvm_unreachable("unsupported directive");
5740     case DK_IF:
5741       break;
5742     case DK_IFE:
5743       ExprValue = ExprValue == 0;
5744       break;
5745     }
5746 
5747     TheCondState.CondMet = ExprValue;
5748     TheCondState.Ignore = !TheCondState.CondMet;
5749   }
5750 
5751   return false;
5752 }
5753 
5754 /// parseDirectiveIfb
5755 /// ::= .ifb string
5756 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5757   TheCondStack.push_back(TheCondState);
5758   TheCondState.TheCond = AsmCond::IfCond;
5759 
5760   if (TheCondState.Ignore) {
5761     eatToEndOfStatement();
5762   } else {
5763     std::string Str;
5764     if (parseTextItem(Str))
5765       return TokError("expected string parameter for 'ifb' directive");
5766 
5767     if (parseToken(AsmToken::EndOfStatement,
5768                    "unexpected token in 'ifb' directive"))
5769       return true;
5770 
5771     TheCondState.CondMet = ExpectBlank == Str.empty();
5772     TheCondState.Ignore = !TheCondState.CondMet;
5773   }
5774 
5775   return false;
5776 }
5777 
5778 /// parseDirectiveIfidn
5779 ///   ::= ifidn string1, string2
5780 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, bool CaseInsensitive) {
5781   std::string String1, String2;
5782 
5783   if (parseTextItem(String1)) {
5784     if (ExpectEqual)
5785       return TokError("expected string parameter for 'ifidn' directive");
5786     return TokError("expected string parameter for 'ifdif' directive");
5787   }
5788 
5789   if (Lexer.isNot(AsmToken::Comma)) {
5790     if (ExpectEqual)
5791       return TokError(
5792           "expected comma after first string for 'ifidn' directive");
5793     return TokError("expected comma after first string for 'ifdif' directive");
5794   }
5795   Lex();
5796 
5797   if (parseTextItem(String2)) {
5798     if (ExpectEqual)
5799       return TokError("expected string parameter for 'ifidn' directive");
5800     return TokError("expected string parameter for 'ifdif' directive");
5801   }
5802 
5803   TheCondStack.push_back(TheCondState);
5804   TheCondState.TheCond = AsmCond::IfCond;
5805   if (CaseInsensitive)
5806     TheCondState.CondMet =
5807         ExpectEqual == (StringRef(String1).equals_lower(String2));
5808   else
5809     TheCondState.CondMet = ExpectEqual == (String1 == String2);
5810   TheCondState.Ignore = !TheCondState.CondMet;
5811 
5812   return false;
5813 }
5814 
5815 /// parseDirectiveIfdef
5816 /// ::= ifdef symbol
5817 ///   | ifdef variable
5818 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
5819   TheCondStack.push_back(TheCondState);
5820   TheCondState.TheCond = AsmCond::IfCond;
5821 
5822   if (TheCondState.Ignore) {
5823     eatToEndOfStatement();
5824   } else {
5825     bool is_defined = false;
5826     unsigned RegNo;
5827     SMLoc StartLoc, EndLoc;
5828     is_defined = (getTargetParser().tryParseRegister(
5829                       RegNo, StartLoc, EndLoc) == MatchOperand_Success);
5830     if (!is_defined) {
5831       StringRef Name;
5832       if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||
5833           parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'"))
5834         return true;
5835 
5836       if (Variables.find(Name) != Variables.end()) {
5837         is_defined = true;
5838       } else {
5839         MCSymbol *Sym = getContext().lookupSymbol(Name);
5840         is_defined = (Sym && !Sym->isUndefined(false));
5841       }
5842     }
5843 
5844     TheCondState.CondMet = (is_defined == expect_defined);
5845     TheCondState.Ignore = !TheCondState.CondMet;
5846   }
5847 
5848   return false;
5849 }
5850 
5851 /// parseDirectiveElseIf
5852 /// ::= elseif expression
5853 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
5854                                       DirectiveKind DirKind) {
5855   if (TheCondState.TheCond != AsmCond::IfCond &&
5856       TheCondState.TheCond != AsmCond::ElseIfCond)
5857     return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5858                                " .if or  an .elseif");
5859   TheCondState.TheCond = AsmCond::ElseIfCond;
5860 
5861   bool LastIgnoreState = false;
5862   if (!TheCondStack.empty())
5863     LastIgnoreState = TheCondStack.back().Ignore;
5864   if (LastIgnoreState || TheCondState.CondMet) {
5865     TheCondState.Ignore = true;
5866     eatToEndOfStatement();
5867   } else {
5868     int64_t ExprValue;
5869     if (parseAbsoluteExpression(ExprValue))
5870       return true;
5871 
5872     if (parseToken(AsmToken::EndOfStatement,
5873                    "unexpected token in '.elseif' directive"))
5874       return true;
5875 
5876     switch (DirKind) {
5877     default:
5878       llvm_unreachable("unsupported directive");
5879     case DK_ELSEIF:
5880       break;
5881     case DK_ELSEIFE:
5882       ExprValue = ExprValue == 0;
5883       break;
5884     }
5885 
5886     TheCondState.CondMet = ExprValue;
5887     TheCondState.Ignore = !TheCondState.CondMet;
5888   }
5889 
5890   return false;
5891 }
5892 
5893 /// parseDirectiveElseIfb
5894 /// ::= elseifb expression
5895 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5896   if (TheCondState.TheCond != AsmCond::IfCond &&
5897       TheCondState.TheCond != AsmCond::ElseIfCond)
5898     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
5899                                " if or an elseif");
5900   TheCondState.TheCond = AsmCond::ElseIfCond;
5901 
5902   bool LastIgnoreState = false;
5903   if (!TheCondStack.empty())
5904     LastIgnoreState = TheCondStack.back().Ignore;
5905   if (LastIgnoreState || TheCondState.CondMet) {
5906     TheCondState.Ignore = true;
5907     eatToEndOfStatement();
5908   } else {
5909     std::string Str;
5910     if (parseTextItem(Str))
5911       return TokError("expected string parameter for 'elseifb' directive");
5912 
5913     if (parseToken(AsmToken::EndOfStatement,
5914                    "unexpected token in 'elseifb' directive"))
5915       return true;
5916 
5917     TheCondState.CondMet = ExpectBlank == Str.empty();
5918     TheCondState.Ignore = !TheCondState.CondMet;
5919   }
5920 
5921   return false;
5922 }
5923 
5924 /// parseDirectiveElseIfdef
5925 /// ::= elseifdef symbol
5926 ///   | elseifdef variable
5927 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
5928                                          bool expect_defined) {
5929   if (TheCondState.TheCond != AsmCond::IfCond &&
5930       TheCondState.TheCond != AsmCond::ElseIfCond)
5931     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
5932                                " if or an elseif");
5933   TheCondState.TheCond = AsmCond::ElseIfCond;
5934 
5935   bool LastIgnoreState = false;
5936   if (!TheCondStack.empty())
5937     LastIgnoreState = TheCondStack.back().Ignore;
5938   if (LastIgnoreState || TheCondState.CondMet) {
5939     TheCondState.Ignore = true;
5940     eatToEndOfStatement();
5941   } else {
5942     bool is_defined = false;
5943     unsigned RegNo;
5944     SMLoc StartLoc, EndLoc;
5945     is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
5946                   MatchOperand_Success);
5947     if (!is_defined) {
5948       StringRef Name;
5949       if (check(parseIdentifier(Name),
5950                 "expected identifier after 'elseifdef'") ||
5951           parseToken(AsmToken::EndOfStatement,
5952                      "unexpected token in 'elseifdef'"))
5953         return true;
5954 
5955       if (Variables.find(Name) != Variables.end()) {
5956         is_defined = true;
5957       } else {
5958         MCSymbol *Sym = getContext().lookupSymbol(Name);
5959         is_defined = (Sym && !Sym->isUndefined(false));
5960       }
5961     }
5962 
5963     TheCondState.CondMet = (is_defined == expect_defined);
5964     TheCondState.Ignore = !TheCondState.CondMet;
5965   }
5966 
5967   return false;
5968 }
5969 
5970 /// parseDirectiveElseIfidn
5971 /// ::= elseifidn string1, string2
5972 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
5973                                          bool CaseInsensitive) {
5974   if (TheCondState.TheCond != AsmCond::IfCond &&
5975       TheCondState.TheCond != AsmCond::ElseIfCond)
5976     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
5977                                " if or an elseif");
5978   TheCondState.TheCond = AsmCond::ElseIfCond;
5979 
5980   bool LastIgnoreState = false;
5981   if (!TheCondStack.empty())
5982     LastIgnoreState = TheCondStack.back().Ignore;
5983   if (LastIgnoreState || TheCondState.CondMet) {
5984     TheCondState.Ignore = true;
5985     eatToEndOfStatement();
5986   } else {
5987     std::string String1, String2;
5988 
5989     if (parseTextItem(String1)) {
5990       if (ExpectEqual)
5991         return TokError("expected string parameter for 'elseifidn' directive");
5992       return TokError("expected string parameter for 'elseifdif' directive");
5993     }
5994 
5995     if (Lexer.isNot(AsmToken::Comma)) {
5996       if (ExpectEqual)
5997         return TokError(
5998             "expected comma after first string for 'elseifidn' directive");
5999       return TokError(
6000           "expected comma after first string for 'elseifdif' directive");
6001     }
6002     Lex();
6003 
6004     if (parseTextItem(String2)) {
6005       if (ExpectEqual)
6006         return TokError("expected string parameter for 'elseifidn' directive");
6007       return TokError("expected string parameter for 'elseifdif' directive");
6008     }
6009 
6010     if (CaseInsensitive)
6011       TheCondState.CondMet =
6012           ExpectEqual == (StringRef(String1).equals_lower(String2));
6013     else
6014       TheCondState.CondMet = ExpectEqual == (String1 == String2);
6015     TheCondState.Ignore = !TheCondState.CondMet;
6016   }
6017 
6018   return false;
6019 }
6020 
6021 /// parseDirectiveElse
6022 /// ::= else
6023 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
6024   if (parseToken(AsmToken::EndOfStatement,
6025                  "unexpected token in 'else' directive"))
6026     return true;
6027 
6028   if (TheCondState.TheCond != AsmCond::IfCond &&
6029       TheCondState.TheCond != AsmCond::ElseIfCond)
6030     return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"
6031                                " or an elseif");
6032   TheCondState.TheCond = AsmCond::ElseCond;
6033   bool LastIgnoreState = false;
6034   if (!TheCondStack.empty())
6035     LastIgnoreState = TheCondStack.back().Ignore;
6036   if (LastIgnoreState || TheCondState.CondMet)
6037     TheCondState.Ignore = true;
6038   else
6039     TheCondState.Ignore = false;
6040 
6041   return false;
6042 }
6043 
6044 /// parseDirectiveEnd
6045 /// ::= end
6046 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
6047   if (parseToken(AsmToken::EndOfStatement,
6048                  "unexpected token in 'end' directive"))
6049     return true;
6050 
6051   while (Lexer.isNot(AsmToken::Eof))
6052     Lexer.Lex();
6053 
6054   return false;
6055 }
6056 
6057 /// parseDirectiveError
6058 ///   ::= .err [message]
6059 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
6060   if (!TheCondStack.empty()) {
6061     if (TheCondStack.back().Ignore) {
6062       eatToEndOfStatement();
6063       return false;
6064     }
6065   }
6066 
6067   StringRef Message = ".err directive invoked in source file";
6068   if (Lexer.isNot(AsmToken::EndOfStatement))
6069     Message = parseStringToEndOfStatement();
6070   Lex();
6071 
6072   return Error(DirectiveLoc, Message);
6073 }
6074 
6075 /// parseDirectiveErrorIfb
6076 ///   ::= .errb textitem[, message]
6077 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
6078   if (!TheCondStack.empty()) {
6079     if (TheCondStack.back().Ignore) {
6080       eatToEndOfStatement();
6081       return false;
6082     }
6083   }
6084 
6085   std::string Text;
6086   if (parseTextItem(Text))
6087     return Error(getTok().getLoc(), "missing text item in '.errb' directive");
6088 
6089   StringRef Message = ".errb directive invoked in source file";
6090   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6091     if (parseToken(AsmToken::Comma))
6092       return addErrorSuffix(" in '.errb' directive");
6093     Message = parseStringToEndOfStatement();
6094   }
6095   Lex();
6096 
6097   if (Text.empty() == ExpectBlank)
6098     return Error(DirectiveLoc, Message);
6099   return false;
6100 }
6101 
6102 /// parseDirectiveErrorIfdef
6103 ///   ::= .errdef name[, message]
6104 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
6105                                           bool ExpectDefined) {
6106   if (!TheCondStack.empty()) {
6107     if (TheCondStack.back().Ignore) {
6108       eatToEndOfStatement();
6109       return false;
6110     }
6111   }
6112 
6113   bool IsDefined = false;
6114   unsigned RegNo;
6115   SMLoc StartLoc, EndLoc;
6116   IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
6117                MatchOperand_Success);
6118   if (!IsDefined) {
6119     StringRef Name;
6120     if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))
6121       return true;
6122 
6123     if (Variables.find(Name) != Variables.end()) {
6124       IsDefined = true;
6125     } else {
6126       MCSymbol *Sym = getContext().lookupSymbol(Name);
6127       IsDefined = (Sym && !Sym->isUndefined(false));
6128     }
6129   }
6130 
6131   StringRef Message = ".errdef directive invoked in source file";
6132   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6133     if (parseToken(AsmToken::Comma))
6134       return addErrorSuffix(" in '.errdef' directive");
6135     Message = parseStringToEndOfStatement();
6136   }
6137   Lex();
6138 
6139   if (IsDefined == ExpectDefined)
6140     return Error(DirectiveLoc, Message);
6141   return false;
6142 }
6143 
6144 /// parseDirectiveErrorIfidn
6145 ///   ::= .erridn textitem1, textitem2[, message]
6146 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6147                                           bool CaseInsensitive) {
6148   if (!TheCondStack.empty()) {
6149     if (TheCondStack.back().Ignore) {
6150       eatToEndOfStatement();
6151       return false;
6152     }
6153   }
6154 
6155   std::string String1, String2;
6156 
6157   if (parseTextItem(String1)) {
6158     if (ExpectEqual)
6159       return TokError("expected string parameter for '.erridn' directive");
6160     return TokError("expected string parameter for '.errdif' directive");
6161   }
6162 
6163   if (Lexer.isNot(AsmToken::Comma)) {
6164     if (ExpectEqual)
6165       return TokError(
6166           "expected comma after first string for '.erridn' directive");
6167     return TokError(
6168         "expected comma after first string for '.errdif' directive");
6169   }
6170   Lex();
6171 
6172   if (parseTextItem(String2)) {
6173     if (ExpectEqual)
6174       return TokError("expected string parameter for '.erridn' directive");
6175     return TokError("expected string parameter for '.errdif' directive");
6176   }
6177 
6178   StringRef Message;
6179   if (ExpectEqual)
6180     Message = ".erridn directive invoked in source file";
6181   else
6182     Message = ".errdif directive invoked in source file";
6183   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6184     if (parseToken(AsmToken::Comma))
6185       return addErrorSuffix(" in '.erridn' directive");
6186     Message = parseStringToEndOfStatement();
6187   }
6188   Lex();
6189 
6190   if (CaseInsensitive)
6191     TheCondState.CondMet =
6192         ExpectEqual == (StringRef(String1).equals_lower(String2));
6193   else
6194     TheCondState.CondMet = ExpectEqual == (String1 == String2);
6195   TheCondState.Ignore = !TheCondState.CondMet;
6196 
6197   if ((CaseInsensitive &&
6198        ExpectEqual == StringRef(String1).equals_lower(String2)) ||
6199       (ExpectEqual == (String1 == String2)))
6200     return Error(DirectiveLoc, Message);
6201   return false;
6202 }
6203 
6204 /// parseDirectiveErrorIfe
6205 ///   ::= .erre expression[, message]
6206 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
6207   if (!TheCondStack.empty()) {
6208     if (TheCondStack.back().Ignore) {
6209       eatToEndOfStatement();
6210       return false;
6211     }
6212   }
6213 
6214   int64_t ExprValue;
6215   if (parseAbsoluteExpression(ExprValue))
6216     return addErrorSuffix(" in '.erre' directive");
6217 
6218   StringRef Message = ".erre directive invoked in source file";
6219   if (Lexer.isNot(AsmToken::EndOfStatement)) {
6220     if (parseToken(AsmToken::Comma))
6221       return addErrorSuffix(" in '.erre' directive");
6222     Message = parseStringToEndOfStatement();
6223   }
6224   Lex();
6225 
6226   if ((ExprValue == 0) == ExpectZero)
6227     return Error(DirectiveLoc, Message);
6228   return false;
6229 }
6230 
6231 /// parseDirectiveEndIf
6232 /// ::= .endif
6233 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
6234   if (parseToken(AsmToken::EndOfStatement,
6235                  "unexpected token in '.endif' directive"))
6236     return true;
6237 
6238   if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
6239     return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
6240                                "an .if or .else");
6241   if (!TheCondStack.empty()) {
6242     TheCondState = TheCondStack.back();
6243     TheCondStack.pop_back();
6244   }
6245 
6246   return false;
6247 }
6248 
6249 void MasmParser::initializeDirectiveKindMap() {
6250   DirectiveKindMap["="] = DK_ASSIGN;
6251   DirectiveKindMap["equ"] = DK_EQU;
6252   DirectiveKindMap["textequ"] = DK_TEXTEQU;
6253   // DirectiveKindMap[".ascii"] = DK_ASCII;
6254   // DirectiveKindMap[".asciz"] = DK_ASCIZ;
6255   // DirectiveKindMap[".string"] = DK_STRING;
6256   DirectiveKindMap["byte"] = DK_BYTE;
6257   DirectiveKindMap["sbyte"] = DK_SBYTE;
6258   DirectiveKindMap["word"] = DK_WORD;
6259   DirectiveKindMap["sword"] = DK_SWORD;
6260   DirectiveKindMap["dword"] = DK_DWORD;
6261   DirectiveKindMap["sdword"] = DK_SDWORD;
6262   DirectiveKindMap["fword"] = DK_FWORD;
6263   DirectiveKindMap["qword"] = DK_QWORD;
6264   DirectiveKindMap["sqword"] = DK_SQWORD;
6265   DirectiveKindMap["real4"] = DK_REAL4;
6266   DirectiveKindMap["real8"] = DK_REAL8;
6267   DirectiveKindMap["real10"] = DK_REAL10;
6268   DirectiveKindMap["align"] = DK_ALIGN;
6269   // DirectiveKindMap[".org"] = DK_ORG;
6270   DirectiveKindMap["extern"] = DK_EXTERN;
6271   DirectiveKindMap["public"] = DK_PUBLIC;
6272   // DirectiveKindMap[".comm"] = DK_COMM;
6273   DirectiveKindMap["comment"] = DK_COMMENT;
6274   DirectiveKindMap["include"] = DK_INCLUDE;
6275   DirectiveKindMap["repeat"] = DK_REPEAT;
6276   DirectiveKindMap["rept"] = DK_REPEAT;
6277   DirectiveKindMap["while"] = DK_WHILE;
6278   DirectiveKindMap["for"] = DK_FOR;
6279   DirectiveKindMap["irp"] = DK_FOR;
6280   DirectiveKindMap["forc"] = DK_FORC;
6281   DirectiveKindMap["irpc"] = DK_FORC;
6282   DirectiveKindMap["if"] = DK_IF;
6283   DirectiveKindMap["ife"] = DK_IFE;
6284   DirectiveKindMap["ifb"] = DK_IFB;
6285   DirectiveKindMap["ifnb"] = DK_IFNB;
6286   DirectiveKindMap["ifdef"] = DK_IFDEF;
6287   DirectiveKindMap["ifndef"] = DK_IFNDEF;
6288   DirectiveKindMap["ifdif"] = DK_IFDIF;
6289   DirectiveKindMap["ifdifi"] = DK_IFDIFI;
6290   DirectiveKindMap["ifidn"] = DK_IFIDN;
6291   DirectiveKindMap["ifidni"] = DK_IFIDNI;
6292   DirectiveKindMap["elseif"] = DK_ELSEIF;
6293   DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;
6294   DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;
6295   DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;
6296   DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;
6297   DirectiveKindMap["else"] = DK_ELSE;
6298   DirectiveKindMap["end"] = DK_END;
6299   DirectiveKindMap["endif"] = DK_ENDIF;
6300   // DirectiveKindMap[".file"] = DK_FILE;
6301   // DirectiveKindMap[".line"] = DK_LINE;
6302   // DirectiveKindMap[".loc"] = DK_LOC;
6303   // DirectiveKindMap[".stabs"] = DK_STABS;
6304   // DirectiveKindMap[".cv_file"] = DK_CV_FILE;
6305   // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
6306   // DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
6307   // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
6308   // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
6309   // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
6310   // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
6311   // DirectiveKindMap[".cv_string"] = DK_CV_STRING;
6312   // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
6313   // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
6314   // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
6315   // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
6316   // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
6317   // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
6318   // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
6319   // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
6320   // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
6321   // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
6322   // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
6323   // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
6324   // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
6325   // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
6326   // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
6327   // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
6328   // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
6329   // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
6330   // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
6331   // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
6332   // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
6333   // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
6334   // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
6335   // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
6336   // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
6337   // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
6338   DirectiveKindMap["macro"] = DK_MACRO;
6339   DirectiveKindMap["exitm"] = DK_EXITM;
6340   DirectiveKindMap["endm"] = DK_ENDM;
6341   // DirectiveKindMap[".purgem"] = DK_PURGEM;
6342   DirectiveKindMap[".err"] = DK_ERR;
6343   DirectiveKindMap[".errb"] = DK_ERRB;
6344   DirectiveKindMap[".errnb"] = DK_ERRNB;
6345   DirectiveKindMap[".errdef"] = DK_ERRDEF;
6346   DirectiveKindMap[".errndef"] = DK_ERRNDEF;
6347   DirectiveKindMap[".errdif"] = DK_ERRDIF;
6348   DirectiveKindMap[".errdifi"] = DK_ERRDIFI;
6349   DirectiveKindMap[".erridn"] = DK_ERRIDN;
6350   DirectiveKindMap[".erridni"] = DK_ERRIDNI;
6351   DirectiveKindMap[".erre"] = DK_ERRE;
6352   DirectiveKindMap[".errnz"] = DK_ERRNZ;
6353   DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
6354   DirectiveKindMap[".pushreg"] = DK_PUSHREG;
6355   DirectiveKindMap[".savereg"] = DK_SAVEREG;
6356   DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
6357   DirectiveKindMap[".setframe"] = DK_SETFRAME;
6358   DirectiveKindMap[".radix"] = DK_RADIX;
6359   DirectiveKindMap["db"] = DK_DB;
6360   DirectiveKindMap["dd"] = DK_DD;
6361   DirectiveKindMap["df"] = DK_DF;
6362   DirectiveKindMap["dq"] = DK_DQ;
6363   DirectiveKindMap["dw"] = DK_DW;
6364   DirectiveKindMap["echo"] = DK_ECHO;
6365   DirectiveKindMap["struc"] = DK_STRUCT;
6366   DirectiveKindMap["struct"] = DK_STRUCT;
6367   DirectiveKindMap["union"] = DK_UNION;
6368   DirectiveKindMap["ends"] = DK_ENDS;
6369 }
6370 
6371 bool MasmParser::isMacroLikeDirective() {
6372   if (getLexer().is(AsmToken::Identifier)) {
6373     bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier())
6374                            .CasesLower("repeat", "rept", true)
6375                            .CaseLower("while", true)
6376                            .CasesLower("for", "irp", true)
6377                            .CasesLower("forc", "irpc", true)
6378                            .Default(false);
6379     if (IsMacroLike)
6380       return true;
6381   }
6382   if (getLexer().peekTok().is(AsmToken::Identifier) &&
6383       getLexer().peekTok().getIdentifier().equals_lower("macro"))
6384     return true;
6385 
6386   return false;
6387 }
6388 
6389 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
6390   AsmToken EndToken, StartToken = getTok();
6391 
6392   unsigned NestLevel = 0;
6393   while (true) {
6394     // Check whether we have reached the end of the file.
6395     if (getLexer().is(AsmToken::Eof)) {
6396       printError(DirectiveLoc, "no matching 'endm' in definition");
6397       return nullptr;
6398     }
6399 
6400     if (isMacroLikeDirective())
6401       ++NestLevel;
6402 
6403     // Otherwise, check whether we have reached the endm.
6404     if (Lexer.is(AsmToken::Identifier) &&
6405         getTok().getIdentifier().equals_lower("endm")) {
6406       if (NestLevel == 0) {
6407         EndToken = getTok();
6408         Lex();
6409         if (Lexer.isNot(AsmToken::EndOfStatement)) {
6410           printError(getTok().getLoc(), "unexpected token in 'endm' directive");
6411           return nullptr;
6412         }
6413         break;
6414       }
6415       --NestLevel;
6416     }
6417 
6418     // Otherwise, scan till the end of the statement.
6419     eatToEndOfStatement();
6420   }
6421 
6422   const char *BodyStart = StartToken.getLoc().getPointer();
6423   const char *BodyEnd = EndToken.getLoc().getPointer();
6424   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
6425 
6426   // We Are Anonymous.
6427   MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
6428   return &MacroLikeBodies.back();
6429 }
6430 
6431 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6432                                           raw_svector_ostream &OS) {
6433   instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS);
6434 }
6435 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6436                                           SMLoc ExitLoc,
6437                                           raw_svector_ostream &OS) {
6438   OS << "endm\n";
6439 
6440   std::unique_ptr<MemoryBuffer> Instantiation =
6441       MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
6442 
6443   // Create the macro instantiation object and add to the current macro
6444   // instantiation stack.
6445   MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,
6446                                                   ExitLoc, TheCondStack.size()};
6447   ActiveMacros.push_back(MI);
6448 
6449   // Jump to the macro instantiation and prime the lexer.
6450   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
6451   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
6452   Lex();
6453 }
6454 
6455 /// parseDirectiveRepeat
6456 ///   ::= ("repeat" | "rept") count
6457 ///       body
6458 ///     endm
6459 bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
6460   const MCExpr *CountExpr;
6461   SMLoc CountLoc = getTok().getLoc();
6462   if (parseExpression(CountExpr))
6463     return true;
6464 
6465   int64_t Count;
6466   if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
6467     return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
6468   }
6469 
6470   if (check(Count < 0, CountLoc, "Count is negative") ||
6471       parseToken(AsmToken::EndOfStatement,
6472                  "unexpected token in '" + Dir + "' directive"))
6473     return true;
6474 
6475   // Lex the repeat definition.
6476   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6477   if (!M)
6478     return true;
6479 
6480   // Macro instantiation is lexical, unfortunately. We construct a new buffer
6481   // to hold the macro body with substitutions.
6482   SmallString<256> Buf;
6483   raw_svector_ostream OS(Buf);
6484   while (Count--) {
6485     if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
6486       return true;
6487   }
6488   instantiateMacroLikeBody(M, DirectiveLoc, OS);
6489 
6490   return false;
6491 }
6492 
6493 /// parseDirectiveWhile
6494 /// ::= "while" expression
6495 ///       body
6496 ///     endm
6497 bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
6498   const MCExpr *CondExpr;
6499   SMLoc CondLoc = getTok().getLoc();
6500   if (parseExpression(CondExpr))
6501     return true;
6502 
6503   // Lex the repeat definition.
6504   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6505   if (!M)
6506     return true;
6507 
6508   // Macro instantiation is lexical, unfortunately. We construct a new buffer
6509   // to hold the macro body with substitutions.
6510   SmallString<256> Buf;
6511   raw_svector_ostream OS(Buf);
6512   int64_t Condition;
6513   if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
6514     return Error(CondLoc, "expected absolute expression in 'while' directive");
6515   if (Condition) {
6516     // Instantiate the macro, then resume at this directive to recheck the
6517     // condition.
6518     if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
6519       return true;
6520     instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
6521   }
6522 
6523   return false;
6524 }
6525 
6526 /// parseDirectiveFor
6527 /// ::= ("for" | "irp") symbol [":" qualifier], <values>
6528 ///       body
6529 ///     endm
6530 bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
6531   MCAsmMacroParameter Parameter;
6532   MCAsmMacroArguments A;
6533   if (check(parseIdentifier(Parameter.Name),
6534             "expected identifier in '" + Dir + "' directive"))
6535     return true;
6536 
6537   // Parse optional qualifier (default value, or "req")
6538   if (parseOptionalToken(AsmToken::Colon)) {
6539     if (parseOptionalToken(AsmToken::Equal)) {
6540       // Default value
6541       SMLoc ParamLoc;
6542 
6543       ParamLoc = Lexer.getLoc();
6544       if (parseMacroArgument(nullptr, Parameter.Value))
6545         return true;
6546     } else {
6547       SMLoc QualLoc;
6548       StringRef Qualifier;
6549 
6550       QualLoc = Lexer.getLoc();
6551       if (parseIdentifier(Qualifier))
6552         return Error(QualLoc, "missing parameter qualifier for "
6553                               "'" +
6554                                   Parameter.Name + "' in '" + Dir +
6555                                   "' directive");
6556 
6557       if (Qualifier.equals_lower("req"))
6558         Parameter.Required = true;
6559       else
6560         return Error(QualLoc,
6561                      Qualifier + " is not a valid parameter qualifier for '" +
6562                          Parameter.Name + "' in '" + Dir + "' directive");
6563     }
6564   }
6565 
6566   if (parseToken(AsmToken::Comma,
6567                  "expected comma in '" + Dir + "' directive") ||
6568       parseToken(AsmToken::Less,
6569                  "values in '" + Dir +
6570                      "' directive must be enclosed in angle brackets"))
6571     return true;
6572 
6573   while (true) {
6574     A.emplace_back();
6575     if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater))
6576       return addErrorSuffix(" in arguments for '" + Dir + "' directive");
6577 
6578     // If we see a comma, continue, and allow line continuation.
6579     if (!parseOptionalToken(AsmToken::Comma))
6580       break;
6581     parseOptionalToken(AsmToken::EndOfStatement);
6582   }
6583 
6584   if (parseToken(AsmToken::Greater,
6585                  "values in '" + Dir +
6586                      "' directive must be enclosed in angle brackets") ||
6587       parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
6588     return true;
6589 
6590   // Lex the for definition.
6591   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6592   if (!M)
6593     return true;
6594 
6595   // Macro instantiation is lexical, unfortunately. We construct a new buffer
6596   // to hold the macro body with substitutions.
6597   SmallString<256> Buf;
6598   raw_svector_ostream OS(Buf);
6599 
6600   for (const MCAsmMacroArgument &Arg : A) {
6601     if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
6602       return true;
6603   }
6604 
6605   instantiateMacroLikeBody(M, DirectiveLoc, OS);
6606 
6607   return false;
6608 }
6609 
6610 /// parseDirectiveForc
6611 /// ::= ("forc" | "irpc") symbol, <string>
6612 ///       body
6613 ///     endm
6614 bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
6615   MCAsmMacroParameter Parameter;
6616 
6617   std::string Argument;
6618   if (check(parseIdentifier(Parameter.Name),
6619             "expected identifier in '" + Directive + "' directive") ||
6620       parseToken(AsmToken::Comma,
6621                  "expected comma in '" + Directive + "' directive"))
6622     return true;
6623   if (parseAngleBracketString(Argument)) {
6624     // Match ml64.exe; treat all characters to end of statement as a string,
6625     // ignoring comment markers, then discard anything following a space (using
6626     // the C locale).
6627     Argument = parseStringToEndOfStatement().str();
6628     if (getTok().is(AsmToken::EndOfStatement))
6629       Argument += getTok().getString();
6630     size_t End = 0;
6631     for (; End < Argument.size(); ++End) {
6632       if (isSpace(Argument[End]))
6633         break;
6634     }
6635     Argument.resize(End);
6636   }
6637   if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
6638     return true;
6639 
6640   // Lex the irpc definition.
6641   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6642   if (!M)
6643     return true;
6644 
6645   // Macro instantiation is lexical, unfortunately. We construct a new buffer
6646   // to hold the macro body with substitutions.
6647   SmallString<256> Buf;
6648   raw_svector_ostream OS(Buf);
6649 
6650   StringRef Values(Argument);
6651   for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
6652     MCAsmMacroArgument Arg;
6653     Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
6654 
6655     if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
6656       return true;
6657   }
6658 
6659   instantiateMacroLikeBody(M, DirectiveLoc, OS);
6660 
6661   return false;
6662 }
6663 
6664 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
6665                                       size_t Len) {
6666   const MCExpr *Value;
6667   SMLoc ExprLoc = getLexer().getLoc();
6668   if (parseExpression(Value))
6669     return true;
6670   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
6671   if (!MCE)
6672     return Error(ExprLoc, "unexpected expression in _emit");
6673   uint64_t IntValue = MCE->getValue();
6674   if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
6675     return Error(ExprLoc, "literal value out of range for directive");
6676 
6677   Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
6678   return false;
6679 }
6680 
6681 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
6682   const MCExpr *Value;
6683   SMLoc ExprLoc = getLexer().getLoc();
6684   if (parseExpression(Value))
6685     return true;
6686   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
6687   if (!MCE)
6688     return Error(ExprLoc, "unexpected expression in align");
6689   uint64_t IntValue = MCE->getValue();
6690   if (!isPowerOf2_64(IntValue))
6691     return Error(ExprLoc, "literal value not a power of two greater then zero");
6692 
6693   Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
6694   return false;
6695 }
6696 
6697 bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {
6698   const SMLoc Loc = getLexer().getLoc();
6699   StringRef RadixString = parseStringToEndOfStatement().trim();
6700   unsigned Radix;
6701   if (RadixString.getAsInteger(10, Radix)) {
6702     return Error(Loc,
6703                  "radix must be a decimal number in the range 2 to 16; was " +
6704                      RadixString);
6705   }
6706   if (Radix < 2 || Radix > 16)
6707     return Error(Loc, "radix must be in the range 2 to 16; was " +
6708                           std::to_string(Radix));
6709   getLexer().setMasmDefaultRadix(Radix);
6710   return false;
6711 }
6712 
6713 bool MasmParser::parseDirectiveEcho() {
6714   StringRef Message = parseStringToEndOfStatement();
6715   Lex();  // eat end of statement
6716   llvm::outs() << Message << '\n';
6717   return false;
6718 }
6719 
6720 // We are comparing pointers, but the pointers are relative to a single string.
6721 // Thus, this should always be deterministic.
6722 static int rewritesSort(const AsmRewrite *AsmRewriteA,
6723                         const AsmRewrite *AsmRewriteB) {
6724   if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
6725     return -1;
6726   if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
6727     return 1;
6728 
6729   // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
6730   // rewrite to the same location.  Make sure the SizeDirective rewrite is
6731   // performed first, then the Imm/ImmPrefix and finally the Input/Output.  This
6732   // ensures the sort algorithm is stable.
6733   if (AsmRewritePrecedence[AsmRewriteA->Kind] >
6734       AsmRewritePrecedence[AsmRewriteB->Kind])
6735     return -1;
6736 
6737   if (AsmRewritePrecedence[AsmRewriteA->Kind] <
6738       AsmRewritePrecedence[AsmRewriteB->Kind])
6739     return 1;
6740   llvm_unreachable("Unstable rewrite sort.");
6741 }
6742 
6743 bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {
6744   const std::pair<StringRef, StringRef> BaseMember = Name.split('.');
6745   const StringRef Base = BaseMember.first, Member = BaseMember.second;
6746   return lookUpField(Base, Member, Info);
6747 }
6748 
6749 bool MasmParser::lookUpField(StringRef Base, StringRef Member,
6750                              AsmFieldInfo &Info) const {
6751   if (Base.empty())
6752     return true;
6753 
6754   AsmFieldInfo BaseInfo;
6755   if (Base.contains('.') && !lookUpField(Base, BaseInfo))
6756     Base = BaseInfo.Type.Name;
6757 
6758   auto StructIt = Structs.find(Base.lower());
6759   auto TypeIt = KnownType.find(Base.lower());
6760   if (TypeIt != KnownType.end()) {
6761     StructIt = Structs.find(TypeIt->second.Name.lower());
6762   }
6763   if (StructIt != Structs.end())
6764     return lookUpField(StructIt->second, Member, Info);
6765 
6766   return true;
6767 }
6768 
6769 bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
6770                              AsmFieldInfo &Info) const {
6771   if (Member.empty()) {
6772     Info.Type.Name = Structure.Name;
6773     Info.Type.Size = Structure.Size;
6774     Info.Type.ElementSize = Structure.Size;
6775     Info.Type.Length = 1;
6776     return false;
6777   }
6778 
6779   std::pair<StringRef, StringRef> Split = Member.split('.');
6780   const StringRef FieldName = Split.first, FieldMember = Split.second;
6781 
6782   auto StructIt = Structs.find(FieldName.lower());
6783   if (StructIt != Structs.end())
6784     return lookUpField(StructIt->second, FieldMember, Info);
6785 
6786   auto FieldIt = Structure.FieldsByName.find(FieldName.lower());
6787   if (FieldIt == Structure.FieldsByName.end())
6788     return true;
6789 
6790   const FieldInfo &Field = Structure.Fields[FieldIt->second];
6791   if (FieldMember.empty()) {
6792     Info.Offset += Field.Offset;
6793     Info.Type.Size = Field.SizeOf;
6794     Info.Type.ElementSize = Field.Type;
6795     Info.Type.Length = Field.LengthOf;
6796     if (Field.Contents.FT == FT_STRUCT)
6797       Info.Type.Name = Field.Contents.StructInfo.Structure.Name;
6798     else
6799       Info.Type.Name = "";
6800     return false;
6801   }
6802 
6803   if (Field.Contents.FT != FT_STRUCT)
6804     return true;
6805   const StructFieldInfo &StructInfo = Field.Contents.StructInfo;
6806 
6807   if (lookUpField(StructInfo.Structure, FieldMember, Info))
6808     return true;
6809 
6810   Info.Offset += Field.Offset;
6811   return false;
6812 }
6813 
6814 bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
6815   unsigned Size = StringSwitch<unsigned>(Name)
6816                       .CasesLower("byte", "db", "sbyte", 1)
6817                       .CasesLower("word", "dw", "sword", 2)
6818                       .CasesLower("dword", "dd", "sdword", 4)
6819                       .CasesLower("fword", "df", 6)
6820                       .CasesLower("qword", "dq", "sqword", 8)
6821                       .CaseLower("real4", 4)
6822                       .CaseLower("real8", 8)
6823                       .CaseLower("real10", 10)
6824                       .Default(0);
6825   if (Size) {
6826     Info.Name = Name;
6827     Info.ElementSize = Size;
6828     Info.Length = 1;
6829     Info.Size = Size;
6830     return false;
6831   }
6832 
6833   auto StructIt = Structs.find(Name.lower());
6834   if (StructIt != Structs.end()) {
6835     const StructInfo &Structure = StructIt->second;
6836     Info.Name = Name;
6837     Info.ElementSize = Structure.Size;
6838     Info.Length = 1;
6839     Info.Size = Structure.Size;
6840     return false;
6841   }
6842 
6843   return true;
6844 }
6845 
6846 bool MasmParser::parseMSInlineAsm(
6847     void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
6848     unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
6849     SmallVectorImpl<std::string> &Constraints,
6850     SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
6851     const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
6852   SmallVector<void *, 4> InputDecls;
6853   SmallVector<void *, 4> OutputDecls;
6854   SmallVector<bool, 4> InputDeclsAddressOf;
6855   SmallVector<bool, 4> OutputDeclsAddressOf;
6856   SmallVector<std::string, 4> InputConstraints;
6857   SmallVector<std::string, 4> OutputConstraints;
6858   SmallVector<unsigned, 4> ClobberRegs;
6859 
6860   SmallVector<AsmRewrite, 4> AsmStrRewrites;
6861 
6862   // Prime the lexer.
6863   Lex();
6864 
6865   // While we have input, parse each statement.
6866   unsigned InputIdx = 0;
6867   unsigned OutputIdx = 0;
6868   while (getLexer().isNot(AsmToken::Eof)) {
6869     // Parse curly braces marking block start/end.
6870     if (parseCurlyBlockScope(AsmStrRewrites))
6871       continue;
6872 
6873     ParseStatementInfo Info(&AsmStrRewrites);
6874     bool StatementErr = parseStatement(Info, &SI);
6875 
6876     if (StatementErr || Info.ParseError) {
6877       // Emit pending errors if any exist.
6878       printPendingErrors();
6879       return true;
6880     }
6881 
6882     // No pending error should exist here.
6883     assert(!hasPendingError() && "unexpected error from parseStatement");
6884 
6885     if (Info.Opcode == ~0U)
6886       continue;
6887 
6888     const MCInstrDesc &Desc = MII->get(Info.Opcode);
6889 
6890     // Build the list of clobbers, outputs and inputs.
6891     for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
6892       MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
6893 
6894       // Register operand.
6895       if (Operand.isReg() && !Operand.needAddressOf() &&
6896           !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
6897         unsigned NumDefs = Desc.getNumDefs();
6898         // Clobber.
6899         if (NumDefs && Operand.getMCOperandNum() < NumDefs)
6900           ClobberRegs.push_back(Operand.getReg());
6901         continue;
6902       }
6903 
6904       // Expr/Input or Output.
6905       StringRef SymName = Operand.getSymName();
6906       if (SymName.empty())
6907         continue;
6908 
6909       void *OpDecl = Operand.getOpDecl();
6910       if (!OpDecl)
6911         continue;
6912 
6913       StringRef Constraint = Operand.getConstraint();
6914       if (Operand.isImm()) {
6915         // Offset as immediate.
6916         if (Operand.isOffsetOfLocal())
6917           Constraint = "r";
6918         else
6919           Constraint = "i";
6920       }
6921 
6922       bool isOutput = (i == 1) && Desc.mayStore();
6923       SMLoc Start = SMLoc::getFromPointer(SymName.data());
6924       if (isOutput) {
6925         ++InputIdx;
6926         OutputDecls.push_back(OpDecl);
6927         OutputDeclsAddressOf.push_back(Operand.needAddressOf());
6928         OutputConstraints.push_back(("=" + Constraint).str());
6929         AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
6930       } else {
6931         InputDecls.push_back(OpDecl);
6932         InputDeclsAddressOf.push_back(Operand.needAddressOf());
6933         InputConstraints.push_back(Constraint.str());
6934         if (Desc.OpInfo[i - 1].isBranchTarget())
6935           AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size());
6936         else
6937           AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
6938       }
6939     }
6940 
6941     // Consider implicit defs to be clobbers.  Think of cpuid and push.
6942     ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
6943                                 Desc.getNumImplicitDefs());
6944     ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
6945   }
6946 
6947   // Set the number of Outputs and Inputs.
6948   NumOutputs = OutputDecls.size();
6949   NumInputs = InputDecls.size();
6950 
6951   // Set the unique clobbers.
6952   array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
6953   ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
6954                     ClobberRegs.end());
6955   Clobbers.assign(ClobberRegs.size(), std::string());
6956   for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
6957     raw_string_ostream OS(Clobbers[I]);
6958     IP->printRegName(OS, ClobberRegs[I]);
6959   }
6960 
6961   // Merge the various outputs and inputs.  Output are expected first.
6962   if (NumOutputs || NumInputs) {
6963     unsigned NumExprs = NumOutputs + NumInputs;
6964     OpDecls.resize(NumExprs);
6965     Constraints.resize(NumExprs);
6966     for (unsigned i = 0; i < NumOutputs; ++i) {
6967       OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
6968       Constraints[i] = OutputConstraints[i];
6969     }
6970     for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
6971       OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
6972       Constraints[j] = InputConstraints[i];
6973     }
6974   }
6975 
6976   // Build the IR assembly string.
6977   std::string AsmStringIR;
6978   raw_string_ostream OS(AsmStringIR);
6979   StringRef ASMString =
6980       SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
6981   const char *AsmStart = ASMString.begin();
6982   const char *AsmEnd = ASMString.end();
6983   array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
6984   for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) {
6985     const AsmRewrite &AR = *it;
6986     // Check if this has already been covered by another rewrite...
6987     if (AR.Done)
6988       continue;
6989     AsmRewriteKind Kind = AR.Kind;
6990 
6991     const char *Loc = AR.Loc.getPointer();
6992     assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
6993 
6994     // Emit everything up to the immediate/expression.
6995     if (unsigned Len = Loc - AsmStart)
6996       OS << StringRef(AsmStart, Len);
6997 
6998     // Skip the original expression.
6999     if (Kind == AOK_Skip) {
7000       AsmStart = Loc + AR.Len;
7001       continue;
7002     }
7003 
7004     unsigned AdditionalSkip = 0;
7005     // Rewrite expressions in $N notation.
7006     switch (Kind) {
7007     default:
7008       break;
7009     case AOK_IntelExpr:
7010       assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
7011       if (AR.IntelExp.NeedBracs)
7012         OS << "[";
7013       if (AR.IntelExp.hasBaseReg())
7014         OS << AR.IntelExp.BaseReg;
7015       if (AR.IntelExp.hasIndexReg())
7016         OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
7017            << AR.IntelExp.IndexReg;
7018       if (AR.IntelExp.Scale > 1)
7019         OS << " * $$" << AR.IntelExp.Scale;
7020       if (AR.IntelExp.hasOffset()) {
7021         if (AR.IntelExp.hasRegs())
7022           OS << " + ";
7023         // Fuse this rewrite with a rewrite of the offset name, if present.
7024         StringRef OffsetName = AR.IntelExp.OffsetName;
7025         SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data());
7026         size_t OffsetLen = OffsetName.size();
7027         auto rewrite_it = std::find_if(
7028             it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
7029               return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
7030                      (FusingAR.Kind == AOK_Input ||
7031                       FusingAR.Kind == AOK_CallInput);
7032             });
7033         if (rewrite_it == AsmStrRewrites.end()) {
7034           OS << "offset " << OffsetName;
7035         } else if (rewrite_it->Kind == AOK_CallInput) {
7036           OS << "${" << InputIdx++ << ":P}";
7037           rewrite_it->Done = true;
7038         } else {
7039           OS << '$' << InputIdx++;
7040           rewrite_it->Done = true;
7041         }
7042       }
7043       if (AR.IntelExp.Imm || AR.IntelExp.emitImm())
7044         OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm;
7045       if (AR.IntelExp.NeedBracs)
7046         OS << "]";
7047       break;
7048     case AOK_Label:
7049       OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
7050       break;
7051     case AOK_Input:
7052       OS << '$' << InputIdx++;
7053       break;
7054     case AOK_CallInput:
7055       OS << "${" << InputIdx++ << ":P}";
7056       break;
7057     case AOK_Output:
7058       OS << '$' << OutputIdx++;
7059       break;
7060     case AOK_SizeDirective:
7061       switch (AR.Val) {
7062       default: break;
7063       case 8:  OS << "byte ptr "; break;
7064       case 16: OS << "word ptr "; break;
7065       case 32: OS << "dword ptr "; break;
7066       case 64: OS << "qword ptr "; break;
7067       case 80: OS << "xword ptr "; break;
7068       case 128: OS << "xmmword ptr "; break;
7069       case 256: OS << "ymmword ptr "; break;
7070       }
7071       break;
7072     case AOK_Emit:
7073       OS << ".byte";
7074       break;
7075     case AOK_Align: {
7076       // MS alignment directives are measured in bytes. If the native assembler
7077       // measures alignment in bytes, we can pass it straight through.
7078       OS << ".align";
7079       if (getContext().getAsmInfo()->getAlignmentIsInBytes())
7080         break;
7081 
7082       // Alignment is in log2 form, so print that instead and skip the original
7083       // immediate.
7084       unsigned Val = AR.Val;
7085       OS << ' ' << Val;
7086       assert(Val < 10 && "Expected alignment less then 2^10.");
7087       AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
7088       break;
7089     }
7090     case AOK_EVEN:
7091       OS << ".even";
7092       break;
7093     case AOK_EndOfStatement:
7094       OS << "\n\t";
7095       break;
7096     }
7097 
7098     // Skip the original expression.
7099     AsmStart = Loc + AR.Len + AdditionalSkip;
7100   }
7101 
7102   // Emit the remainder of the asm string.
7103   if (AsmStart != AsmEnd)
7104     OS << StringRef(AsmStart, AsmEnd - AsmStart);
7105 
7106   AsmString = OS.str();
7107   return false;
7108 }
7109 
7110 /// Create an MCAsmParser instance.
7111 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
7112                                       MCStreamer &Out, const MCAsmInfo &MAI,
7113                                       unsigned CB) {
7114   return new MasmParser(SM, C, Out, MAI, CB);
7115 }
7116