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