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