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