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