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