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