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