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