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