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