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