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