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