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