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