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