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