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   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
3239   unsigned Isa = 0;
3240   int64_t Discriminator = 0;
3241 
3242   auto parseLocOp = [&]() -> bool {
3243     StringRef Name;
3244     SMLoc Loc = getTok().getLoc();
3245     if (parseIdentifier(Name))
3246       return TokError("unexpected token in '.loc' directive");
3247 
3248     if (Name == "basic_block")
3249       Flags |= DWARF2_FLAG_BASIC_BLOCK;
3250     else if (Name == "prologue_end")
3251       Flags |= DWARF2_FLAG_PROLOGUE_END;
3252     else if (Name == "epilogue_begin")
3253       Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
3254     else if (Name == "is_stmt") {
3255       Loc = getTok().getLoc();
3256       const MCExpr *Value;
3257       if (parseExpression(Value))
3258         return true;
3259       // The expression must be the constant 0 or 1.
3260       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3261         int Value = MCE->getValue();
3262         if (Value == 0)
3263           Flags &= ~DWARF2_FLAG_IS_STMT;
3264         else if (Value == 1)
3265           Flags |= DWARF2_FLAG_IS_STMT;
3266         else
3267           return Error(Loc, "is_stmt value not 0 or 1");
3268       } else {
3269         return Error(Loc, "is_stmt value not the constant value of 0 or 1");
3270       }
3271     } else if (Name == "isa") {
3272       Loc = getTok().getLoc();
3273       const MCExpr *Value;
3274       if (parseExpression(Value))
3275         return true;
3276       // The expression must be a constant greater or equal to 0.
3277       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3278         int Value = MCE->getValue();
3279         if (Value < 0)
3280           return Error(Loc, "isa number less than zero");
3281         Isa = Value;
3282       } else {
3283         return Error(Loc, "isa number not a constant value");
3284       }
3285     } else if (Name == "discriminator") {
3286       if (parseAbsoluteExpression(Discriminator))
3287         return true;
3288     } else {
3289       return Error(Loc, "unknown sub-directive in '.loc' directive");
3290     }
3291     return false;
3292   };
3293 
3294   if (parseMany(parseLocOp, false /*hasComma*/))
3295     return true;
3296 
3297   getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3298                                       Isa, Discriminator, StringRef());
3299 
3300   return false;
3301 }
3302 
3303 /// parseDirectiveStabs
3304 /// ::= .stabs string, number, number, number
3305 bool MasmParser::parseDirectiveStabs() {
3306   return TokError("unsupported directive '.stabs'");
3307 }
3308 
3309 /// parseDirectiveCVFile
3310 /// ::= .cv_file number filename [checksum] [checksumkind]
3311 bool MasmParser::parseDirectiveCVFile() {
3312   SMLoc FileNumberLoc = getTok().getLoc();
3313   int64_t FileNumber;
3314   std::string Filename;
3315   std::string Checksum;
3316   int64_t ChecksumKind = 0;
3317 
3318   if (parseIntToken(FileNumber,
3319                     "expected file number in '.cv_file' directive") ||
3320       check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
3321       check(getTok().isNot(AsmToken::String),
3322             "unexpected token in '.cv_file' directive") ||
3323       parseEscapedString(Filename))
3324     return true;
3325   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3326     if (check(getTok().isNot(AsmToken::String),
3327               "unexpected token in '.cv_file' directive") ||
3328         parseEscapedString(Checksum) ||
3329         parseIntToken(ChecksumKind,
3330                       "expected checksum kind in '.cv_file' directive") ||
3331         parseToken(AsmToken::EndOfStatement,
3332                    "unexpected token in '.cv_file' directive"))
3333       return true;
3334   }
3335 
3336   Checksum = fromHex(Checksum);
3337   void *CKMem = Ctx.allocate(Checksum.size(), 1);
3338   memcpy(CKMem, Checksum.data(), Checksum.size());
3339   ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
3340                                     Checksum.size());
3341 
3342   if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3343                                          static_cast<uint8_t>(ChecksumKind)))
3344     return Error(FileNumberLoc, "file number already allocated");
3345 
3346   return false;
3347 }
3348 
3349 bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
3350                                    StringRef DirectiveName) {
3351   SMLoc Loc;
3352   return parseTokenLoc(Loc) ||
3353          parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
3354                                        "' directive") ||
3355          check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3356                "expected function id within range [0, UINT_MAX)");
3357 }
3358 
3359 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3360   SMLoc Loc;
3361   return parseTokenLoc(Loc) ||
3362          parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
3363                                        "' directive") ||
3364          check(FileNumber < 1, Loc, "file number less than one in '" +
3365                                         DirectiveName + "' directive") ||
3366          check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3367                "unassigned file number in '" + DirectiveName + "' directive");
3368 }
3369 
3370 /// parseDirectiveCVFuncId
3371 /// ::= .cv_func_id FunctionId
3372 ///
3373 /// Introduces a function ID that can be used with .cv_loc.
3374 bool MasmParser::parseDirectiveCVFuncId() {
3375   SMLoc FunctionIdLoc = getTok().getLoc();
3376   int64_t FunctionId;
3377 
3378   if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
3379       parseToken(AsmToken::EndOfStatement,
3380                  "unexpected token in '.cv_func_id' directive"))
3381     return true;
3382 
3383   if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
3384     return Error(FunctionIdLoc, "function id already allocated");
3385 
3386   return false;
3387 }
3388 
3389 /// parseDirectiveCVInlineSiteId
3390 /// ::= .cv_inline_site_id FunctionId
3391 ///         "within" IAFunc
3392 ///         "inlined_at" IAFile IALine [IACol]
3393 ///
3394 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
3395 /// at" source location information for use in the line table of the caller,
3396 /// whether the caller is a real function or another inlined call site.
3397 bool MasmParser::parseDirectiveCVInlineSiteId() {
3398   SMLoc FunctionIdLoc = getTok().getLoc();
3399   int64_t FunctionId;
3400   int64_t IAFunc;
3401   int64_t IAFile;
3402   int64_t IALine;
3403   int64_t IACol = 0;
3404 
3405   // FunctionId
3406   if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
3407     return true;
3408 
3409   // "within"
3410   if (check((getLexer().isNot(AsmToken::Identifier) ||
3411              getTok().getIdentifier() != "within"),
3412             "expected 'within' identifier in '.cv_inline_site_id' directive"))
3413     return true;
3414   Lex();
3415 
3416   // IAFunc
3417   if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
3418     return true;
3419 
3420   // "inlined_at"
3421   if (check((getLexer().isNot(AsmToken::Identifier) ||
3422              getTok().getIdentifier() != "inlined_at"),
3423             "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3424             "directive") )
3425     return true;
3426   Lex();
3427 
3428   // IAFile IALine
3429   if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
3430       parseIntToken(IALine, "expected line number after 'inlined_at'"))
3431     return true;
3432 
3433   // [IACol]
3434   if (getLexer().is(AsmToken::Integer)) {
3435     IACol = getTok().getIntVal();
3436     Lex();
3437   }
3438 
3439   if (parseToken(AsmToken::EndOfStatement,
3440                  "unexpected token in '.cv_inline_site_id' directive"))
3441     return true;
3442 
3443   if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3444                                                  IALine, IACol, FunctionIdLoc))
3445     return Error(FunctionIdLoc, "function id already allocated");
3446 
3447   return false;
3448 }
3449 
3450 /// parseDirectiveCVLoc
3451 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
3452 ///                                [is_stmt VALUE]
3453 /// The first number is a file number, must have been previously assigned with
3454 /// a .file directive, the second number is the line number and optionally the
3455 /// third number is a column position (zero if not specified).  The remaining
3456 /// optional items are .loc sub-directives.
3457 bool MasmParser::parseDirectiveCVLoc() {
3458   SMLoc DirectiveLoc = getTok().getLoc();
3459   int64_t FunctionId, FileNumber;
3460   if (parseCVFunctionId(FunctionId, ".cv_loc") ||
3461       parseCVFileId(FileNumber, ".cv_loc"))
3462     return true;
3463 
3464   int64_t LineNumber = 0;
3465   if (getLexer().is(AsmToken::Integer)) {
3466     LineNumber = getTok().getIntVal();
3467     if (LineNumber < 0)
3468       return TokError("line number less than zero in '.cv_loc' directive");
3469     Lex();
3470   }
3471 
3472   int64_t ColumnPos = 0;
3473   if (getLexer().is(AsmToken::Integer)) {
3474     ColumnPos = getTok().getIntVal();
3475     if (ColumnPos < 0)
3476       return TokError("column position less than zero in '.cv_loc' directive");
3477     Lex();
3478   }
3479 
3480   bool PrologueEnd = false;
3481   uint64_t IsStmt = 0;
3482 
3483   auto parseOp = [&]() -> bool {
3484     StringRef Name;
3485     SMLoc Loc = getTok().getLoc();
3486     if (parseIdentifier(Name))
3487       return TokError("unexpected token in '.cv_loc' directive");
3488     if (Name == "prologue_end")
3489       PrologueEnd = true;
3490     else if (Name == "is_stmt") {
3491       Loc = getTok().getLoc();
3492       const MCExpr *Value;
3493       if (parseExpression(Value))
3494         return true;
3495       // The expression must be the constant 0 or 1.
3496       IsStmt = ~0ULL;
3497       if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
3498         IsStmt = MCE->getValue();
3499 
3500       if (IsStmt > 1)
3501         return Error(Loc, "is_stmt value not 0 or 1");
3502     } else {
3503       return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
3504     }
3505     return false;
3506   };
3507 
3508   if (parseMany(parseOp, false /*hasComma*/))
3509     return true;
3510 
3511   getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
3512                                    ColumnPos, PrologueEnd, IsStmt, StringRef(),
3513                                    DirectiveLoc);
3514   return false;
3515 }
3516 
3517 /// parseDirectiveCVLinetable
3518 /// ::= .cv_linetable FunctionId, FnStart, FnEnd
3519 bool MasmParser::parseDirectiveCVLinetable() {
3520   int64_t FunctionId;
3521   StringRef FnStartName, FnEndName;
3522   SMLoc Loc = getTok().getLoc();
3523   if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
3524       parseToken(AsmToken::Comma,
3525                  "unexpected token in '.cv_linetable' directive") ||
3526       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3527                                   "expected identifier in directive") ||
3528       parseToken(AsmToken::Comma,
3529                  "unexpected token in '.cv_linetable' directive") ||
3530       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3531                                   "expected identifier in directive"))
3532     return true;
3533 
3534   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3535   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3536 
3537   getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
3538   return false;
3539 }
3540 
3541 /// parseDirectiveCVInlineLinetable
3542 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
3543 bool MasmParser::parseDirectiveCVInlineLinetable() {
3544   int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3545   StringRef FnStartName, FnEndName;
3546   SMLoc Loc = getTok().getLoc();
3547   if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
3548       parseTokenLoc(Loc) ||
3549       parseIntToken(
3550           SourceFileId,
3551           "expected SourceField in '.cv_inline_linetable' directive") ||
3552       check(SourceFileId <= 0, Loc,
3553             "File id less than zero in '.cv_inline_linetable' directive") ||
3554       parseTokenLoc(Loc) ||
3555       parseIntToken(
3556           SourceLineNum,
3557           "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3558       check(SourceLineNum < 0, Loc,
3559             "Line number less than zero in '.cv_inline_linetable' directive") ||
3560       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3561                                   "expected identifier in directive") ||
3562       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3563                                   "expected identifier in directive"))
3564     return true;
3565 
3566   if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3567     return true;
3568 
3569   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3570   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3571   getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
3572                                                SourceLineNum, FnStartSym,
3573                                                FnEndSym);
3574   return false;
3575 }
3576 
3577 void MasmParser::initializeCVDefRangeTypeMap() {
3578   CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
3579   CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
3580   CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
3581   CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
3582 }
3583 
3584 /// parseDirectiveCVDefRange
3585 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
3586 bool MasmParser::parseDirectiveCVDefRange() {
3587   SMLoc Loc;
3588   std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
3589   while (getLexer().is(AsmToken::Identifier)) {
3590     Loc = getLexer().getLoc();
3591     StringRef GapStartName;
3592     if (parseIdentifier(GapStartName))
3593       return Error(Loc, "expected identifier in directive");
3594     MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
3595 
3596     Loc = getLexer().getLoc();
3597     StringRef GapEndName;
3598     if (parseIdentifier(GapEndName))
3599       return Error(Loc, "expected identifier in directive");
3600     MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
3601 
3602     Ranges.push_back({GapStartSym, GapEndSym});
3603   }
3604 
3605   StringRef CVDefRangeTypeStr;
3606   if (parseToken(
3607           AsmToken::Comma,
3608           "expected comma before def_range type in .cv_def_range directive") ||
3609       parseIdentifier(CVDefRangeTypeStr))
3610     return Error(Loc, "expected def_range type in directive");
3611 
3612   StringMap<CVDefRangeType>::const_iterator CVTypeIt =
3613       CVDefRangeTypeMap.find(CVDefRangeTypeStr);
3614   CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
3615                                 ? CVDR_DEFRANGE
3616                                 : CVTypeIt->getValue();
3617   switch (CVDRType) {
3618   case CVDR_DEFRANGE_REGISTER: {
3619     int64_t DRRegister;
3620     if (parseToken(AsmToken::Comma, "expected comma before register number in "
3621                                     ".cv_def_range directive") ||
3622         parseAbsoluteExpression(DRRegister))
3623       return Error(Loc, "expected register number");
3624 
3625     codeview::DefRangeRegisterHeader DRHdr;
3626     DRHdr.Register = DRRegister;
3627     DRHdr.MayHaveNoName = 0;
3628     getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3629     break;
3630   }
3631   case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
3632     int64_t DROffset;
3633     if (parseToken(AsmToken::Comma,
3634                    "expected comma before offset in .cv_def_range directive") ||
3635         parseAbsoluteExpression(DROffset))
3636       return Error(Loc, "expected offset value");
3637 
3638     codeview::DefRangeFramePointerRelHeader DRHdr;
3639     DRHdr.Offset = DROffset;
3640     getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3641     break;
3642   }
3643   case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
3644     int64_t DRRegister;
3645     int64_t DROffsetInParent;
3646     if (parseToken(AsmToken::Comma, "expected comma before register number in "
3647                                     ".cv_def_range directive") ||
3648         parseAbsoluteExpression(DRRegister))
3649       return Error(Loc, "expected register number");
3650     if (parseToken(AsmToken::Comma,
3651                    "expected comma before offset in .cv_def_range directive") ||
3652         parseAbsoluteExpression(DROffsetInParent))
3653       return Error(Loc, "expected offset value");
3654 
3655     codeview::DefRangeSubfieldRegisterHeader DRHdr;
3656     DRHdr.Register = DRRegister;
3657     DRHdr.MayHaveNoName = 0;
3658     DRHdr.OffsetInParent = DROffsetInParent;
3659     getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3660     break;
3661   }
3662   case CVDR_DEFRANGE_REGISTER_REL: {
3663     int64_t DRRegister;
3664     int64_t DRFlags;
3665     int64_t DRBasePointerOffset;
3666     if (parseToken(AsmToken::Comma, "expected comma before register number in "
3667                                     ".cv_def_range directive") ||
3668         parseAbsoluteExpression(DRRegister))
3669       return Error(Loc, "expected register value");
3670     if (parseToken(
3671             AsmToken::Comma,
3672             "expected comma before flag value in .cv_def_range directive") ||
3673         parseAbsoluteExpression(DRFlags))
3674       return Error(Loc, "expected flag value");
3675     if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
3676                                     "in .cv_def_range directive") ||
3677         parseAbsoluteExpression(DRBasePointerOffset))
3678       return Error(Loc, "expected base pointer offset value");
3679 
3680     codeview::DefRangeRegisterRelHeader DRHdr;
3681     DRHdr.Register = DRRegister;
3682     DRHdr.Flags = DRFlags;
3683     DRHdr.BasePointerOffset = DRBasePointerOffset;
3684     getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3685     break;
3686   }
3687   default:
3688     return Error(Loc, "unexpected def_range type in .cv_def_range directive");
3689   }
3690   return true;
3691 }
3692 
3693 /// parseDirectiveCVString
3694 /// ::= .cv_stringtable "string"
3695 bool MasmParser::parseDirectiveCVString() {
3696   std::string Data;
3697   if (checkForValidSection() || parseEscapedString(Data))
3698     return addErrorSuffix(" in '.cv_string' directive");
3699 
3700   // Put the string in the table and emit the offset.
3701   std::pair<StringRef, unsigned> Insertion =
3702       getCVContext().addToStringTable(Data);
3703   getStreamer().emitIntValue(Insertion.second, 4);
3704   return false;
3705 }
3706 
3707 /// parseDirectiveCVStringTable
3708 /// ::= .cv_stringtable
3709 bool MasmParser::parseDirectiveCVStringTable() {
3710   getStreamer().EmitCVStringTableDirective();
3711   return false;
3712 }
3713 
3714 /// parseDirectiveCVFileChecksums
3715 /// ::= .cv_filechecksums
3716 bool MasmParser::parseDirectiveCVFileChecksums() {
3717   getStreamer().EmitCVFileChecksumsDirective();
3718   return false;
3719 }
3720 
3721 /// parseDirectiveCVFileChecksumOffset
3722 /// ::= .cv_filechecksumoffset fileno
3723 bool MasmParser::parseDirectiveCVFileChecksumOffset() {
3724   int64_t FileNo;
3725   if (parseIntToken(FileNo, "expected identifier in directive"))
3726     return true;
3727   if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3728     return true;
3729   getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
3730   return false;
3731 }
3732 
3733 /// parseDirectiveCVFPOData
3734 /// ::= .cv_fpo_data procsym
3735 bool MasmParser::parseDirectiveCVFPOData() {
3736   SMLoc DirLoc = getLexer().getLoc();
3737   StringRef ProcName;
3738   if (parseIdentifier(ProcName))
3739     return TokError("expected symbol name");
3740   if (parseEOL("unexpected tokens"))
3741     return addErrorSuffix(" in '.cv_fpo_data' directive");
3742   MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3743   getStreamer().EmitCVFPOData(ProcSym, DirLoc);
3744   return false;
3745 }
3746 
3747 /// parseDirectiveCFISections
3748 /// ::= .cfi_sections section [, section]
3749 bool MasmParser::parseDirectiveCFISections() {
3750   StringRef Name;
3751   bool EH = false;
3752   bool Debug = false;
3753 
3754   if (parseIdentifier(Name))
3755     return TokError("Expected an identifier");
3756 
3757   if (Name == ".eh_frame")
3758     EH = true;
3759   else if (Name == ".debug_frame")
3760     Debug = true;
3761 
3762   if (getLexer().is(AsmToken::Comma)) {
3763     Lex();
3764 
3765     if (parseIdentifier(Name))
3766       return TokError("Expected an identifier");
3767 
3768     if (Name == ".eh_frame")
3769       EH = true;
3770     else if (Name == ".debug_frame")
3771       Debug = true;
3772   }
3773 
3774   getStreamer().emitCFISections(EH, Debug);
3775   return false;
3776 }
3777 
3778 /// parseDirectiveCFIStartProc
3779 /// ::= .cfi_startproc [simple]
3780 bool MasmParser::parseDirectiveCFIStartProc() {
3781   StringRef Simple;
3782   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3783     if (check(parseIdentifier(Simple) || Simple != "simple",
3784               "unexpected token") ||
3785         parseToken(AsmToken::EndOfStatement))
3786       return addErrorSuffix(" in '.cfi_startproc' directive");
3787   }
3788 
3789   // TODO(kristina): Deal with a corner case of incorrect diagnostic context
3790   // being produced if this directive is emitted as part of preprocessor macro
3791   // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
3792   // Tools like llvm-mc on the other hand are not affected by it, and report
3793   // correct context information.
3794   getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc());
3795   return false;
3796 }
3797 
3798 /// parseDirectiveCFIEndProc
3799 /// ::= .cfi_endproc
3800 bool MasmParser::parseDirectiveCFIEndProc() {
3801   getStreamer().emitCFIEndProc();
3802   return false;
3803 }
3804 
3805 /// parse register name or number.
3806 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register,
3807                                                SMLoc DirectiveLoc) {
3808   unsigned RegNo;
3809 
3810   if (getLexer().isNot(AsmToken::Integer)) {
3811     if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
3812       return true;
3813     Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
3814   } else
3815     return parseAbsoluteExpression(Register);
3816 
3817   return false;
3818 }
3819 
3820 /// parseDirectiveCFIDefCfa
3821 /// ::= .cfi_def_cfa register,  offset
3822 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
3823   int64_t Register = 0, Offset = 0;
3824   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3825       parseToken(AsmToken::Comma, "unexpected token in directive") ||
3826       parseAbsoluteExpression(Offset))
3827     return true;
3828 
3829   getStreamer().emitCFIDefCfa(Register, Offset);
3830   return false;
3831 }
3832 
3833 /// parseDirectiveCFIDefCfaOffset
3834 /// ::= .cfi_def_cfa_offset offset
3835 bool MasmParser::parseDirectiveCFIDefCfaOffset() {
3836   int64_t Offset = 0;
3837   if (parseAbsoluteExpression(Offset))
3838     return true;
3839 
3840   getStreamer().emitCFIDefCfaOffset(Offset);
3841   return false;
3842 }
3843 
3844 /// parseDirectiveCFIRegister
3845 /// ::= .cfi_register register, register
3846 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
3847   int64_t Register1 = 0, Register2 = 0;
3848   if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
3849       parseToken(AsmToken::Comma, "unexpected token in directive") ||
3850       parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
3851     return true;
3852 
3853   getStreamer().emitCFIRegister(Register1, Register2);
3854   return false;
3855 }
3856 
3857 /// parseDirectiveCFIWindowSave
3858 /// ::= .cfi_window_save
3859 bool MasmParser::parseDirectiveCFIWindowSave() {
3860   getStreamer().emitCFIWindowSave();
3861   return false;
3862 }
3863 
3864 /// parseDirectiveCFIAdjustCfaOffset
3865 /// ::= .cfi_adjust_cfa_offset adjustment
3866 bool MasmParser::parseDirectiveCFIAdjustCfaOffset() {
3867   int64_t Adjustment = 0;
3868   if (parseAbsoluteExpression(Adjustment))
3869     return true;
3870 
3871   getStreamer().emitCFIAdjustCfaOffset(Adjustment);
3872   return false;
3873 }
3874 
3875 /// parseDirectiveCFIDefCfaRegister
3876 /// ::= .cfi_def_cfa_register register
3877 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
3878   int64_t Register = 0;
3879   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
3880     return true;
3881 
3882   getStreamer().emitCFIDefCfaRegister(Register);
3883   return false;
3884 }
3885 
3886 /// parseDirectiveCFIOffset
3887 /// ::= .cfi_offset register, offset
3888 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
3889   int64_t Register = 0;
3890   int64_t Offset = 0;
3891 
3892   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3893       parseToken(AsmToken::Comma, "unexpected token in directive") ||
3894       parseAbsoluteExpression(Offset))
3895     return true;
3896 
3897   getStreamer().emitCFIOffset(Register, Offset);
3898   return false;
3899 }
3900 
3901 /// parseDirectiveCFIRelOffset
3902 /// ::= .cfi_rel_offset register, offset
3903 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
3904   int64_t Register = 0, Offset = 0;
3905 
3906   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3907       parseToken(AsmToken::Comma, "unexpected token in directive") ||
3908       parseAbsoluteExpression(Offset))
3909     return true;
3910 
3911   getStreamer().emitCFIRelOffset(Register, Offset);
3912   return false;
3913 }
3914 
3915 static bool isValidEncoding(int64_t Encoding) {
3916   if (Encoding & ~0xff)
3917     return false;
3918 
3919   if (Encoding == dwarf::DW_EH_PE_omit)
3920     return true;
3921 
3922   const unsigned Format = Encoding & 0xf;
3923   if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
3924       Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
3925       Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
3926       Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
3927     return false;
3928 
3929   const unsigned Application = Encoding & 0x70;
3930   if (Application != dwarf::DW_EH_PE_absptr &&
3931       Application != dwarf::DW_EH_PE_pcrel)
3932     return false;
3933 
3934   return true;
3935 }
3936 
3937 /// parseDirectiveCFIPersonalityOrLsda
3938 /// IsPersonality true for cfi_personality, false for cfi_lsda
3939 /// ::= .cfi_personality encoding, [symbol_name]
3940 /// ::= .cfi_lsda encoding, [symbol_name]
3941 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
3942   int64_t Encoding = 0;
3943   if (parseAbsoluteExpression(Encoding))
3944     return true;
3945   if (Encoding == dwarf::DW_EH_PE_omit)
3946     return false;
3947 
3948   StringRef Name;
3949   if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
3950       parseToken(AsmToken::Comma, "unexpected token in directive") ||
3951       check(parseIdentifier(Name), "expected identifier in directive"))
3952     return true;
3953 
3954   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3955 
3956   if (IsPersonality)
3957     getStreamer().emitCFIPersonality(Sym, Encoding);
3958   else
3959     getStreamer().emitCFILsda(Sym, Encoding);
3960   return false;
3961 }
3962 
3963 /// parseDirectiveCFIRememberState
3964 /// ::= .cfi_remember_state
3965 bool MasmParser::parseDirectiveCFIRememberState() {
3966   getStreamer().emitCFIRememberState();
3967   return false;
3968 }
3969 
3970 /// parseDirectiveCFIRestoreState
3971 /// ::= .cfi_remember_state
3972 bool MasmParser::parseDirectiveCFIRestoreState() {
3973   getStreamer().emitCFIRestoreState();
3974   return false;
3975 }
3976 
3977 /// parseDirectiveCFISameValue
3978 /// ::= .cfi_same_value register
3979 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
3980   int64_t Register = 0;
3981 
3982   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
3983     return true;
3984 
3985   getStreamer().emitCFISameValue(Register);
3986   return false;
3987 }
3988 
3989 /// parseDirectiveCFIRestore
3990 /// ::= .cfi_restore register
3991 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
3992   int64_t Register = 0;
3993   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
3994     return true;
3995 
3996   getStreamer().emitCFIRestore(Register);
3997   return false;
3998 }
3999 
4000 /// parseDirectiveCFIEscape
4001 /// ::= .cfi_escape expression[,...]
4002 bool MasmParser::parseDirectiveCFIEscape() {
4003   std::string Values;
4004   int64_t CurrValue;
4005   if (parseAbsoluteExpression(CurrValue))
4006     return true;
4007 
4008   Values.push_back((uint8_t)CurrValue);
4009 
4010   while (getLexer().is(AsmToken::Comma)) {
4011     Lex();
4012 
4013     if (parseAbsoluteExpression(CurrValue))
4014       return true;
4015 
4016     Values.push_back((uint8_t)CurrValue);
4017   }
4018 
4019   getStreamer().emitCFIEscape(Values);
4020   return false;
4021 }
4022 
4023 /// parseDirectiveCFIReturnColumn
4024 /// ::= .cfi_return_column register
4025 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4026   int64_t Register = 0;
4027   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4028     return true;
4029   getStreamer().emitCFIReturnColumn(Register);
4030   return false;
4031 }
4032 
4033 /// parseDirectiveCFISignalFrame
4034 /// ::= .cfi_signal_frame
4035 bool MasmParser::parseDirectiveCFISignalFrame() {
4036   if (parseToken(AsmToken::EndOfStatement,
4037                  "unexpected token in '.cfi_signal_frame'"))
4038     return true;
4039 
4040   getStreamer().emitCFISignalFrame();
4041   return false;
4042 }
4043 
4044 /// parseDirectiveCFIUndefined
4045 /// ::= .cfi_undefined register
4046 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4047   int64_t Register = 0;
4048 
4049   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4050     return true;
4051 
4052   getStreamer().emitCFIUndefined(Register);
4053   return false;
4054 }
4055 
4056 /// parseDirectiveAltmacro
4057 /// ::= .altmacro
4058 /// ::= .noaltmacro
4059 bool MasmParser::parseDirectiveAltmacro(StringRef Directive) {
4060   if (getLexer().isNot(AsmToken::EndOfStatement))
4061     return TokError("unexpected token in '" + Directive + "' directive");
4062   AltMacroMode = (Directive == ".altmacro");
4063   return false;
4064 }
4065 
4066 /// parseDirectiveMacro
4067 /// ::= .macro name[,] [parameters]
4068 bool MasmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4069   StringRef Name;
4070   if (parseIdentifier(Name))
4071     return TokError("expected identifier in '.macro' directive");
4072 
4073   if (getLexer().is(AsmToken::Comma))
4074     Lex();
4075 
4076   MCAsmMacroParameters Parameters;
4077   while (getLexer().isNot(AsmToken::EndOfStatement)) {
4078 
4079     if (!Parameters.empty() && Parameters.back().Vararg)
4080       return Error(Lexer.getLoc(),
4081                    "Vararg parameter '" + Parameters.back().Name +
4082                    "' should be last one in the list of parameters.");
4083 
4084     MCAsmMacroParameter Parameter;
4085     if (parseIdentifier(Parameter.Name))
4086       return TokError("expected identifier in '.macro' directive");
4087 
4088     // Emit an error if two (or more) named parameters share the same name
4089     for (const MCAsmMacroParameter& CurrParam : Parameters)
4090       if (CurrParam.Name.equals(Parameter.Name))
4091         return TokError("macro '" + Name + "' has multiple parameters"
4092                         " named '" + Parameter.Name + "'");
4093 
4094     if (Lexer.is(AsmToken::Colon)) {
4095       Lex();  // consume ':'
4096 
4097       SMLoc QualLoc;
4098       StringRef Qualifier;
4099 
4100       QualLoc = Lexer.getLoc();
4101       if (parseIdentifier(Qualifier))
4102         return Error(QualLoc, "missing parameter qualifier for "
4103                      "'" + Parameter.Name + "' in macro '" + Name + "'");
4104 
4105       if (Qualifier == "req")
4106         Parameter.Required = true;
4107       else if (Qualifier == "vararg")
4108         Parameter.Vararg = true;
4109       else
4110         return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
4111                      "for '" + Parameter.Name + "' in macro '" + Name + "'");
4112     }
4113 
4114     if (getLexer().is(AsmToken::Equal)) {
4115       Lex();
4116 
4117       SMLoc ParamLoc;
4118 
4119       ParamLoc = Lexer.getLoc();
4120       if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
4121         return true;
4122 
4123       if (Parameter.Required)
4124         Warning(ParamLoc, "pointless default value for required parameter "
4125                 "'" + Parameter.Name + "' in macro '" + Name + "'");
4126     }
4127 
4128     Parameters.push_back(std::move(Parameter));
4129 
4130     if (getLexer().is(AsmToken::Comma))
4131       Lex();
4132   }
4133 
4134   // Eat just the end of statement.
4135   Lexer.Lex();
4136 
4137   // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
4138   AsmToken EndToken, StartToken = getTok();
4139   unsigned MacroDepth = 0;
4140   // Lex the macro definition.
4141   while (true) {
4142     // Ignore Lexing errors in macros.
4143     while (Lexer.is(AsmToken::Error)) {
4144       Lexer.Lex();
4145     }
4146 
4147     // Check whether we have reached the end of the file.
4148     if (getLexer().is(AsmToken::Eof))
4149       return Error(DirectiveLoc, "no matching '.endmacro' in definition");
4150 
4151     // Otherwise, check whether we have reach the .endmacro.
4152     if (getLexer().is(AsmToken::Identifier)) {
4153       if (getTok().getIdentifier() == ".endm" ||
4154           getTok().getIdentifier() == ".endmacro") {
4155         if (MacroDepth == 0) { // Outermost macro.
4156           EndToken = getTok();
4157           Lexer.Lex();
4158           if (getLexer().isNot(AsmToken::EndOfStatement))
4159             return TokError("unexpected token in '" + EndToken.getIdentifier() +
4160                             "' directive");
4161           break;
4162         } else {
4163           // Otherwise we just found the end of an inner macro.
4164           --MacroDepth;
4165         }
4166       } else if (getTok().getIdentifier() == ".macro") {
4167         // We allow nested macros. Those aren't instantiated until the outermost
4168         // macro is expanded so just ignore them for now.
4169         ++MacroDepth;
4170       }
4171     }
4172 
4173     // Otherwise, scan til the end of the statement.
4174     eatToEndOfStatement();
4175   }
4176 
4177   if (getContext().lookupMacro(Name)) {
4178     return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
4179   }
4180 
4181   const char *BodyStart = StartToken.getLoc().getPointer();
4182   const char *BodyEnd = EndToken.getLoc().getPointer();
4183   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
4184   checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4185   MCAsmMacro Macro(Name, Body, std::move(Parameters));
4186   DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
4187                   Macro.dump());
4188   getContext().defineMacro(Name, std::move(Macro));
4189   return false;
4190 }
4191 
4192 /// checkForBadMacro
4193 ///
4194 /// With the support added for named parameters there may be code out there that
4195 /// is transitioning from positional parameters.  In versions of gas that did
4196 /// not support named parameters they would be ignored on the macro definition.
4197 /// But to support both styles of parameters this is not possible so if a macro
4198 /// definition has named parameters but does not use them and has what appears
4199 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a
4200 /// warning that the positional parameter found in body which have no effect.
4201 /// Hoping the developer will either remove the named parameters from the macro
4202 /// definition so the positional parameters get used if that was what was
4203 /// intended or change the macro to use the named parameters.  It is possible
4204 /// this warning will trigger when the none of the named parameters are used
4205 /// and the strings like $1 are infact to simply to be passed trough unchanged.
4206 void MasmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
4207                                   StringRef Body,
4208                                   ArrayRef<MCAsmMacroParameter> Parameters) {
4209   // If this macro is not defined with named parameters the warning we are
4210   // checking for here doesn't apply.
4211   unsigned NParameters = Parameters.size();
4212   if (NParameters == 0)
4213     return;
4214 
4215   bool NamedParametersFound = false;
4216   bool PositionalParametersFound = false;
4217 
4218   // Look at the body of the macro for use of both the named parameters and what
4219   // are likely to be positional parameters.  This is what expandMacro() is
4220   // doing when it finds the parameters in the body.
4221   while (!Body.empty()) {
4222     // Scan for the next possible parameter.
4223     std::size_t End = Body.size(), Pos = 0;
4224     for (; Pos != End; ++Pos) {
4225       // Check for a substitution or escape.
4226       // This macro is defined with parameters, look for \foo, \bar, etc.
4227       if (Body[Pos] == '\\' && Pos + 1 != End)
4228         break;
4229 
4230       // This macro should have parameters, but look for $0, $1, ..., $n too.
4231       if (Body[Pos] != '$' || Pos + 1 == End)
4232         continue;
4233       char Next = Body[Pos + 1];
4234       if (Next == '$' || Next == 'n' ||
4235           isdigit(static_cast<unsigned char>(Next)))
4236         break;
4237     }
4238 
4239     // Check if we reached the end.
4240     if (Pos == End)
4241       break;
4242 
4243     if (Body[Pos] == '$') {
4244       switch (Body[Pos + 1]) {
4245       // $$ => $
4246       case '$':
4247         break;
4248 
4249       // $n => number of arguments
4250       case 'n':
4251         PositionalParametersFound = true;
4252         break;
4253 
4254       // $[0-9] => argument
4255       default: {
4256         PositionalParametersFound = true;
4257         break;
4258       }
4259       }
4260       Pos += 2;
4261     } else {
4262       unsigned I = Pos + 1;
4263       while (isIdentifierChar(Body[I]) && I + 1 != End)
4264         ++I;
4265 
4266       const char *Begin = Body.data() + Pos + 1;
4267       StringRef Argument(Begin, I - (Pos + 1));
4268       unsigned Index = 0;
4269       for (; Index < NParameters; ++Index)
4270         if (Parameters[Index].Name == Argument)
4271           break;
4272 
4273       if (Index == NParameters) {
4274         if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
4275           Pos += 3;
4276         else {
4277           Pos = I;
4278         }
4279       } else {
4280         NamedParametersFound = true;
4281         Pos += 1 + Argument.size();
4282       }
4283     }
4284     // Update the scan point.
4285     Body = Body.substr(Pos);
4286   }
4287 
4288   if (!NamedParametersFound && PositionalParametersFound)
4289     Warning(DirectiveLoc, "macro defined with named parameters which are not "
4290                           "used in macro body, possible positional parameter "
4291                           "found in body which will have no effect");
4292 }
4293 
4294 /// parseDirectiveExitMacro
4295 /// ::= .exitm
4296 bool MasmParser::parseDirectiveExitMacro(StringRef Directive) {
4297   if (parseToken(AsmToken::EndOfStatement,
4298                  "unexpected token in '" + Directive + "' directive"))
4299     return true;
4300 
4301   if (!isInsideMacroInstantiation())
4302     return TokError("unexpected '" + Directive + "' in file, "
4303                                                  "no current macro definition");
4304 
4305   // Exit all conditionals that are active in the current macro.
4306   while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4307     TheCondState = TheCondStack.back();
4308     TheCondStack.pop_back();
4309   }
4310 
4311   handleMacroExit();
4312   return false;
4313 }
4314 
4315 /// parseDirectiveEndMacro
4316 /// ::= .endm
4317 /// ::= .endmacro
4318 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
4319   if (getLexer().isNot(AsmToken::EndOfStatement))
4320     return TokError("unexpected token in '" + Directive + "' directive");
4321 
4322   // If we are inside a macro instantiation, terminate the current
4323   // instantiation.
4324   if (isInsideMacroInstantiation()) {
4325     handleMacroExit();
4326     return false;
4327   }
4328 
4329   // Otherwise, this .endmacro is a stray entry in the file; well formed
4330   // .endmacro directives are handled during the macro definition parsing.
4331   return TokError("unexpected '" + Directive + "' in file, "
4332                                                "no current macro definition");
4333 }
4334 
4335 /// parseDirectivePurgeMacro
4336 /// ::= .purgem
4337 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4338   StringRef Name;
4339   SMLoc Loc;
4340   if (parseTokenLoc(Loc) ||
4341       check(parseIdentifier(Name), Loc,
4342             "expected identifier in '.purgem' directive") ||
4343       parseToken(AsmToken::EndOfStatement,
4344                  "unexpected token in '.purgem' directive"))
4345     return true;
4346 
4347   if (!getContext().lookupMacro(Name))
4348     return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
4349 
4350   getContext().undefineMacro(Name);
4351   DEBUG_WITH_TYPE("asm-macros", dbgs()
4352                                     << "Un-defining macro: " << Name << "\n");
4353   return false;
4354 }
4355 
4356 /// parseDirectiveSymbolAttribute
4357 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
4358 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
4359   auto parseOp = [&]() -> bool {
4360     StringRef Name;
4361     SMLoc Loc = getTok().getLoc();
4362     if (parseIdentifier(Name))
4363       return Error(Loc, "expected identifier");
4364     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4365 
4366     // Assembler local symbols don't make any sense here. Complain loudly.
4367     if (Sym->isTemporary())
4368       return Error(Loc, "non-local symbol required");
4369 
4370     if (!getStreamer().emitSymbolAttribute(Sym, Attr))
4371       return Error(Loc, "unable to emit symbol attribute");
4372     return false;
4373   };
4374 
4375   if (parseMany(parseOp))
4376     return addErrorSuffix(" in directive");
4377   return false;
4378 }
4379 
4380 /// parseDirectiveComm
4381 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
4382 bool MasmParser::parseDirectiveComm(bool IsLocal) {
4383   if (checkForValidSection())
4384     return true;
4385 
4386   SMLoc IDLoc = getLexer().getLoc();
4387   StringRef Name;
4388   if (parseIdentifier(Name))
4389     return TokError("expected identifier in directive");
4390 
4391   // Handle the identifier as the key symbol.
4392   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4393 
4394   if (getLexer().isNot(AsmToken::Comma))
4395     return TokError("unexpected token in directive");
4396   Lex();
4397 
4398   int64_t Size;
4399   SMLoc SizeLoc = getLexer().getLoc();
4400   if (parseAbsoluteExpression(Size))
4401     return true;
4402 
4403   int64_t Pow2Alignment = 0;
4404   SMLoc Pow2AlignmentLoc;
4405   if (getLexer().is(AsmToken::Comma)) {
4406     Lex();
4407     Pow2AlignmentLoc = getLexer().getLoc();
4408     if (parseAbsoluteExpression(Pow2Alignment))
4409       return true;
4410 
4411     LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
4412     if (IsLocal && LCOMM == LCOMM::NoAlignment)
4413       return Error(Pow2AlignmentLoc, "alignment not supported on this target");
4414 
4415     // If this target takes alignments in bytes (not log) validate and convert.
4416     if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
4417         (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
4418       if (!isPowerOf2_64(Pow2Alignment))
4419         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
4420       Pow2Alignment = Log2_64(Pow2Alignment);
4421     }
4422   }
4423 
4424   if (parseToken(AsmToken::EndOfStatement,
4425                  "unexpected token in '.comm' or '.lcomm' directive"))
4426     return true;
4427 
4428   // NOTE: a size of zero for a .comm should create a undefined symbol
4429   // but a size of .lcomm creates a bss symbol of size zero.
4430   if (Size < 0)
4431     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
4432                           "be less than zero");
4433 
4434   // NOTE: The alignment in the directive is a power of 2 value, the assembler
4435   // may internally end up wanting an alignment in bytes.
4436   // FIXME: Diagnose overflow.
4437   if (Pow2Alignment < 0)
4438     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
4439                                    "alignment, can't be less than zero");
4440 
4441   Sym->redefineIfPossible();
4442   if (!Sym->isUndefined())
4443     return Error(IDLoc, "invalid symbol redefinition");
4444 
4445   // Create the Symbol as a common or local common with Size and Pow2Alignment
4446   if (IsLocal) {
4447     getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4448     return false;
4449   }
4450 
4451   getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4452   return false;
4453 }
4454 
4455 /// parseDirectiveComment
4456 ///  ::= comment delimiter [[text]]
4457 ///              [[text]]
4458 ///              [[text]] delimiter [[text]]
4459 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
4460   StringRef FirstLine = parseStringToEndOfStatement();
4461   size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
4462   StringRef Delimiter = FirstLine.take_front(DelimiterEnd);
4463   if (Delimiter.empty())
4464     return Error(DirectiveLoc, "no delimiter in 'comment' directive");
4465   do {
4466     if (getTok().is(AsmToken::Eof))
4467       return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
4468     Lex();  // eat end of statement
4469   } while (!parseStringToEndOfStatement().contains(Delimiter));
4470   return parseToken(AsmToken::EndOfStatement,
4471                     "unexpected token in 'comment' directive");
4472 }
4473 
4474 /// parseDirectiveInclude
4475 ///  ::= include <filename>
4476 ///    | include filename
4477 bool MasmParser::parseDirectiveInclude() {
4478   // Allow the strings to have escaped octal character sequence.
4479   std::string Filename;
4480   SMLoc IncludeLoc = getTok().getLoc();
4481 
4482   if (!parseAngleBracketString(Filename))
4483     Filename = parseStringToEndOfStatement().str();
4484   if (check(!Filename.empty(), "missing filename in 'include' directive") ||
4485       check(getTok().isNot(AsmToken::EndOfStatement),
4486             "unexpected token in 'include' directive") ||
4487       // Attempt to switch the lexer to the included file before consuming the
4488       // end of statement to avoid losing it when we switch.
4489       check(enterIncludeFile(Filename), IncludeLoc,
4490             "Could not find include file '" + Filename + "'"))
4491     return true;
4492 
4493   return false;
4494 }
4495 
4496 /// parseDirectiveIf
4497 /// ::= .if{,eq,ge,gt,le,lt,ne} expression
4498 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
4499   TheCondStack.push_back(TheCondState);
4500   TheCondState.TheCond = AsmCond::IfCond;
4501   if (TheCondState.Ignore) {
4502     eatToEndOfStatement();
4503   } else {
4504     int64_t ExprValue;
4505     if (parseAbsoluteExpression(ExprValue) ||
4506         parseToken(AsmToken::EndOfStatement,
4507                    "unexpected token in '.if' directive"))
4508       return true;
4509 
4510     switch (DirKind) {
4511     default:
4512       llvm_unreachable("unsupported directive");
4513     case DK_IF:
4514       break;
4515     case DK_IFE:
4516       ExprValue = ExprValue == 0;
4517       break;
4518     }
4519 
4520     TheCondState.CondMet = ExprValue;
4521     TheCondState.Ignore = !TheCondState.CondMet;
4522   }
4523 
4524   return false;
4525 }
4526 
4527 /// parseDirectiveIfb
4528 /// ::= .ifb string
4529 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
4530   TheCondStack.push_back(TheCondState);
4531   TheCondState.TheCond = AsmCond::IfCond;
4532 
4533   if (TheCondState.Ignore) {
4534     eatToEndOfStatement();
4535   } else {
4536     std::string Str;
4537     if (parseTextItem(Str))
4538       return TokError("expected string parameter for 'ifb' directive");
4539 
4540     if (parseToken(AsmToken::EndOfStatement,
4541                    "unexpected token in 'ifb' directive"))
4542       return true;
4543 
4544     TheCondState.CondMet = ExpectBlank == Str.empty();
4545     TheCondState.Ignore = !TheCondState.CondMet;
4546   }
4547 
4548   return false;
4549 }
4550 
4551 /// parseDirectiveIfidn
4552 ///   ::= ifidn string1, string2
4553 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, bool CaseInsensitive) {
4554   std::string String1, String2;
4555 
4556   if (parseTextItem(String1)) {
4557     if (ExpectEqual)
4558       return TokError("expected string parameter for 'ifidn' directive");
4559     return TokError("expected string parameter for 'ifdif' directive");
4560   }
4561 
4562   if (Lexer.isNot(AsmToken::Comma)) {
4563     if (ExpectEqual)
4564       return TokError(
4565           "expected comma after first string for 'ifidn' directive");
4566     return TokError("expected comma after first string for 'ifdif' directive");
4567   }
4568   Lex();
4569 
4570   if (parseTextItem(String2)) {
4571     if (ExpectEqual)
4572       return TokError("expected string parameter for 'ifidn' directive");
4573     return TokError("expected string parameter for 'ifdif' directive");
4574   }
4575 
4576   TheCondStack.push_back(TheCondState);
4577   TheCondState.TheCond = AsmCond::IfCond;
4578   if (CaseInsensitive)
4579     TheCondState.CondMet =
4580         ExpectEqual == (StringRef(String1).equals_lower(String2));
4581   else
4582     TheCondState.CondMet = ExpectEqual == (String1 == String2);
4583   TheCondState.Ignore = !TheCondState.CondMet;
4584 
4585   return false;
4586 }
4587 
4588 /// parseDirectiveIfdef
4589 /// ::= ifdef symbol
4590 ///   | ifdef variable
4591 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
4592   TheCondStack.push_back(TheCondState);
4593   TheCondState.TheCond = AsmCond::IfCond;
4594 
4595   if (TheCondState.Ignore) {
4596     eatToEndOfStatement();
4597   } else {
4598     bool is_defined = false;
4599     unsigned RegNo;
4600     SMLoc StartLoc, EndLoc;
4601     is_defined = (getTargetParser().tryParseRegister(
4602                       RegNo, StartLoc, EndLoc) == MatchOperand_Success);
4603     if (!is_defined) {
4604       StringRef Name;
4605       if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||
4606           parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'"))
4607         return true;
4608 
4609       if (Variables.find(Name) != Variables.end()) {
4610         is_defined = true;
4611       } else {
4612         MCSymbol *Sym = getContext().lookupSymbol(Name);
4613         is_defined = (Sym && !Sym->isUndefined(false));
4614       }
4615     }
4616 
4617     TheCondState.CondMet = (is_defined == expect_defined);
4618     TheCondState.Ignore = !TheCondState.CondMet;
4619   }
4620 
4621   return false;
4622 }
4623 
4624 /// parseDirectiveElseIf
4625 /// ::= elseif expression
4626 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
4627                                       DirectiveKind DirKind) {
4628   if (TheCondState.TheCond != AsmCond::IfCond &&
4629       TheCondState.TheCond != AsmCond::ElseIfCond)
4630     return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
4631                                " .if or  an .elseif");
4632   TheCondState.TheCond = AsmCond::ElseIfCond;
4633 
4634   bool LastIgnoreState = false;
4635   if (!TheCondStack.empty())
4636     LastIgnoreState = TheCondStack.back().Ignore;
4637   if (LastIgnoreState || TheCondState.CondMet) {
4638     TheCondState.Ignore = true;
4639     eatToEndOfStatement();
4640   } else {
4641     int64_t ExprValue;
4642     if (parseAbsoluteExpression(ExprValue))
4643       return true;
4644 
4645     if (parseToken(AsmToken::EndOfStatement,
4646                    "unexpected token in '.elseif' directive"))
4647       return true;
4648 
4649     switch (DirKind) {
4650     default:
4651       llvm_unreachable("unsupported directive");
4652     case DK_ELSEIF:
4653       break;
4654     case DK_ELSEIFE:
4655       ExprValue = ExprValue == 0;
4656       break;
4657     }
4658 
4659     TheCondState.CondMet = ExprValue;
4660     TheCondState.Ignore = !TheCondState.CondMet;
4661   }
4662 
4663   return false;
4664 }
4665 
4666 /// parseDirectiveElseIfb
4667 /// ::= elseifb expression
4668 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
4669   if (TheCondState.TheCond != AsmCond::IfCond &&
4670       TheCondState.TheCond != AsmCond::ElseIfCond)
4671     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
4672                                " if or an elseif");
4673   TheCondState.TheCond = AsmCond::ElseIfCond;
4674 
4675   bool LastIgnoreState = false;
4676   if (!TheCondStack.empty())
4677     LastIgnoreState = TheCondStack.back().Ignore;
4678   if (LastIgnoreState || TheCondState.CondMet) {
4679     TheCondState.Ignore = true;
4680     eatToEndOfStatement();
4681   } else {
4682     std::string Str;
4683     if (parseTextItem(Str))
4684       return TokError("expected string parameter for 'elseifb' directive");
4685 
4686     if (parseToken(AsmToken::EndOfStatement,
4687                    "unexpected token in 'elseifb' directive"))
4688       return true;
4689 
4690     TheCondState.CondMet = ExpectBlank == Str.empty();
4691     TheCondState.Ignore = !TheCondState.CondMet;
4692   }
4693 
4694   return false;
4695 }
4696 
4697 /// parseDirectiveElseIfdef
4698 /// ::= elseifdef symbol
4699 ///   | elseifdef variable
4700 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
4701                                          bool expect_defined) {
4702   if (TheCondState.TheCond != AsmCond::IfCond &&
4703       TheCondState.TheCond != AsmCond::ElseIfCond)
4704     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
4705                                " if or an elseif");
4706   TheCondState.TheCond = AsmCond::ElseIfCond;
4707 
4708   bool LastIgnoreState = false;
4709   if (!TheCondStack.empty())
4710     LastIgnoreState = TheCondStack.back().Ignore;
4711   if (LastIgnoreState || TheCondState.CondMet) {
4712     TheCondState.Ignore = true;
4713     eatToEndOfStatement();
4714   } else {
4715     bool is_defined = false;
4716     unsigned RegNo;
4717     SMLoc StartLoc, EndLoc;
4718     is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
4719                   MatchOperand_Success);
4720     if (!is_defined) {
4721       StringRef Name;
4722       if (check(parseIdentifier(Name),
4723                 "expected identifier after 'elseifdef'") ||
4724           parseToken(AsmToken::EndOfStatement,
4725                      "unexpected token in 'elseifdef'"))
4726         return true;
4727 
4728       if (Variables.find(Name) != Variables.end()) {
4729         is_defined = true;
4730       } else {
4731         MCSymbol *Sym = getContext().lookupSymbol(Name);
4732         is_defined = (Sym && !Sym->isUndefined(false));
4733       }
4734     }
4735 
4736     TheCondState.CondMet = (is_defined == expect_defined);
4737     TheCondState.Ignore = !TheCondState.CondMet;
4738   }
4739 
4740   return false;
4741 }
4742 
4743 /// parseDirectiveElseIfidn
4744 /// ::= elseifidn string1, string2
4745 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
4746                                          bool CaseInsensitive) {
4747   if (TheCondState.TheCond != AsmCond::IfCond &&
4748       TheCondState.TheCond != AsmCond::ElseIfCond)
4749     return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
4750                                " if or an elseif");
4751   TheCondState.TheCond = AsmCond::ElseIfCond;
4752 
4753   bool LastIgnoreState = false;
4754   if (!TheCondStack.empty())
4755     LastIgnoreState = TheCondStack.back().Ignore;
4756   if (LastIgnoreState || TheCondState.CondMet) {
4757     TheCondState.Ignore = true;
4758     eatToEndOfStatement();
4759   } else {
4760     std::string String1, String2;
4761 
4762     if (parseTextItem(String1)) {
4763       if (ExpectEqual)
4764         return TokError("expected string parameter for 'elseifidn' directive");
4765       return TokError("expected string parameter for 'elseifdif' directive");
4766     }
4767 
4768     if (Lexer.isNot(AsmToken::Comma)) {
4769       if (ExpectEqual)
4770         return TokError(
4771             "expected comma after first string for 'elseifidn' directive");
4772       return TokError(
4773           "expected comma after first string for 'elseifdif' directive");
4774     }
4775     Lex();
4776 
4777     if (parseTextItem(String2)) {
4778       if (ExpectEqual)
4779         return TokError("expected string parameter for 'elseifidn' directive");
4780       return TokError("expected string parameter for 'elseifdif' directive");
4781     }
4782 
4783     if (CaseInsensitive)
4784       TheCondState.CondMet =
4785           ExpectEqual == (StringRef(String1).equals_lower(String2));
4786     else
4787       TheCondState.CondMet = ExpectEqual == (String1 == String2);
4788     TheCondState.Ignore = !TheCondState.CondMet;
4789   }
4790 
4791   return false;
4792 }
4793 
4794 /// parseDirectiveElse
4795 /// ::= else
4796 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
4797   if (parseToken(AsmToken::EndOfStatement,
4798                  "unexpected token in 'else' directive"))
4799     return true;
4800 
4801   if (TheCondState.TheCond != AsmCond::IfCond &&
4802       TheCondState.TheCond != AsmCond::ElseIfCond)
4803     return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"
4804                                " or an elseif");
4805   TheCondState.TheCond = AsmCond::ElseCond;
4806   bool LastIgnoreState = false;
4807   if (!TheCondStack.empty())
4808     LastIgnoreState = TheCondStack.back().Ignore;
4809   if (LastIgnoreState || TheCondState.CondMet)
4810     TheCondState.Ignore = true;
4811   else
4812     TheCondState.Ignore = false;
4813 
4814   return false;
4815 }
4816 
4817 /// parseDirectiveEnd
4818 /// ::= end
4819 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
4820   if (parseToken(AsmToken::EndOfStatement,
4821                  "unexpected token in 'end' directive"))
4822     return true;
4823 
4824   while (Lexer.isNot(AsmToken::Eof))
4825     Lexer.Lex();
4826 
4827   return false;
4828 }
4829 
4830 /// parseDirectiveError
4831 ///   ::= .err [message]
4832 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
4833   if (!TheCondStack.empty()) {
4834     if (TheCondStack.back().Ignore) {
4835       eatToEndOfStatement();
4836       return false;
4837     }
4838   }
4839 
4840   StringRef Message = ".err directive invoked in source file";
4841   if (Lexer.isNot(AsmToken::EndOfStatement))
4842     Message = parseStringToEndOfStatement();
4843   Lex();
4844 
4845   return Error(DirectiveLoc, Message);
4846 }
4847 
4848 /// parseDirectiveErrorIfb
4849 ///   ::= .errb textitem[, message]
4850 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
4851   if (!TheCondStack.empty()) {
4852     if (TheCondStack.back().Ignore) {
4853       eatToEndOfStatement();
4854       return false;
4855     }
4856   }
4857 
4858   std::string Text;
4859   if (parseTextItem(Text))
4860     return Error(getTok().getLoc(), "missing text item in '.errb' directive");
4861 
4862   StringRef Message = ".errb directive invoked in source file";
4863   if (Lexer.isNot(AsmToken::EndOfStatement)) {
4864     if (parseToken(AsmToken::Comma))
4865       return addErrorSuffix(" in '.errb' directive");
4866     Message = parseStringToEndOfStatement();
4867   }
4868   Lex();
4869 
4870   if (Text.empty() == ExpectBlank)
4871     return Error(DirectiveLoc, Message);
4872   return false;
4873 }
4874 
4875 /// parseDirectiveErrorIfdef
4876 ///   ::= .errdef name[, message]
4877 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
4878                                           bool ExpectDefined) {
4879   if (!TheCondStack.empty()) {
4880     if (TheCondStack.back().Ignore) {
4881       eatToEndOfStatement();
4882       return false;
4883     }
4884   }
4885 
4886   bool IsDefined = false;
4887   unsigned RegNo;
4888   SMLoc StartLoc, EndLoc;
4889   IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
4890                MatchOperand_Success);
4891   if (!IsDefined) {
4892     StringRef Name;
4893     if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))
4894       return true;
4895 
4896     if (Variables.find(Name) != Variables.end()) {
4897       IsDefined = true;
4898     } else {
4899       MCSymbol *Sym = getContext().lookupSymbol(Name);
4900       IsDefined = (Sym && !Sym->isUndefined(false));
4901     }
4902   }
4903 
4904   StringRef Message = ".errdef directive invoked in source file";
4905   if (Lexer.isNot(AsmToken::EndOfStatement)) {
4906     if (parseToken(AsmToken::Comma))
4907       return addErrorSuffix(" in '.errdef' directive");
4908     Message = parseStringToEndOfStatement();
4909   }
4910   Lex();
4911 
4912   if (IsDefined == ExpectDefined)
4913     return Error(DirectiveLoc, Message);
4914   return false;
4915 }
4916 
4917 /// parseDirectiveErrorIfidn
4918 ///   ::= .erridn textitem1, textitem2[, message]
4919 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
4920                                           bool CaseInsensitive) {
4921   if (!TheCondStack.empty()) {
4922     if (TheCondStack.back().Ignore) {
4923       eatToEndOfStatement();
4924       return false;
4925     }
4926   }
4927 
4928   std::string String1, String2;
4929 
4930   if (parseTextItem(String1)) {
4931     if (ExpectEqual)
4932       return TokError("expected string parameter for '.erridn' directive");
4933     return TokError("expected string parameter for '.errdif' directive");
4934   }
4935 
4936   if (Lexer.isNot(AsmToken::Comma)) {
4937     if (ExpectEqual)
4938       return TokError(
4939           "expected comma after first string for '.erridn' directive");
4940     return TokError(
4941         "expected comma after first string for '.errdif' directive");
4942   }
4943   Lex();
4944 
4945   if (parseTextItem(String2)) {
4946     if (ExpectEqual)
4947       return TokError("expected string parameter for '.erridn' directive");
4948     return TokError("expected string parameter for '.errdif' directive");
4949   }
4950 
4951   StringRef Message;
4952   if (ExpectEqual)
4953     Message = ".erridn directive invoked in source file";
4954   else
4955     Message = ".errdif directive invoked in source file";
4956   if (Lexer.isNot(AsmToken::EndOfStatement)) {
4957     if (parseToken(AsmToken::Comma))
4958       return addErrorSuffix(" in '.erridn' directive");
4959     Message = parseStringToEndOfStatement();
4960   }
4961   Lex();
4962 
4963   if (CaseInsensitive)
4964     TheCondState.CondMet =
4965         ExpectEqual == (StringRef(String1).equals_lower(String2));
4966   else
4967     TheCondState.CondMet = ExpectEqual == (String1 == String2);
4968   TheCondState.Ignore = !TheCondState.CondMet;
4969 
4970   if ((CaseInsensitive &&
4971        ExpectEqual == StringRef(String1).equals_lower(String2)) ||
4972       (ExpectEqual == (String1 == String2)))
4973     return Error(DirectiveLoc, Message);
4974   return false;
4975 }
4976 
4977 /// parseDirectiveErrorIfe
4978 ///   ::= .erre expression[, message]
4979 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
4980   if (!TheCondStack.empty()) {
4981     if (TheCondStack.back().Ignore) {
4982       eatToEndOfStatement();
4983       return false;
4984     }
4985   }
4986 
4987   int64_t ExprValue;
4988   if (parseAbsoluteExpression(ExprValue))
4989     return addErrorSuffix(" in '.erre' directive");
4990 
4991   StringRef Message = ".erre directive invoked in source file";
4992   if (Lexer.isNot(AsmToken::EndOfStatement)) {
4993     if (parseToken(AsmToken::Comma))
4994       return addErrorSuffix(" in '.erre' directive");
4995     Message = parseStringToEndOfStatement();
4996   }
4997   Lex();
4998 
4999   if ((ExprValue == 0) == ExpectZero)
5000     return Error(DirectiveLoc, Message);
5001   return false;
5002 }
5003 
5004 /// parseDirectiveEndIf
5005 /// ::= .endif
5006 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5007   if (parseToken(AsmToken::EndOfStatement,
5008                  "unexpected token in '.endif' directive"))
5009     return true;
5010 
5011   if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
5012     return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
5013                                "an .if or .else");
5014   if (!TheCondStack.empty()) {
5015     TheCondState = TheCondStack.back();
5016     TheCondStack.pop_back();
5017   }
5018 
5019   return false;
5020 }
5021 
5022 void MasmParser::initializeDirectiveKindMap() {
5023   DirectiveKindMap["="] = DK_ASSIGN;
5024   DirectiveKindMap["equ"] = DK_EQU;
5025   DirectiveKindMap["textequ"] = DK_TEXTEQU;
5026   // DirectiveKindMap[".ascii"] = DK_ASCII;
5027   // DirectiveKindMap[".asciz"] = DK_ASCIZ;
5028   // DirectiveKindMap[".string"] = DK_STRING;
5029   DirectiveKindMap["byte"] = DK_BYTE;
5030   DirectiveKindMap["sbyte"] = DK_SBYTE;
5031   DirectiveKindMap["word"] = DK_WORD;
5032   DirectiveKindMap["sword"] = DK_SWORD;
5033   DirectiveKindMap["dword"] = DK_DWORD;
5034   DirectiveKindMap["sdword"] = DK_SDWORD;
5035   DirectiveKindMap["fword"] = DK_FWORD;
5036   DirectiveKindMap["qword"] = DK_QWORD;
5037   DirectiveKindMap["sqword"] = DK_SQWORD;
5038   DirectiveKindMap["real4"] = DK_REAL4;
5039   DirectiveKindMap["real8"] = DK_REAL8;
5040   DirectiveKindMap["align"] = DK_ALIGN;
5041   // DirectiveKindMap[".org"] = DK_ORG;
5042   DirectiveKindMap["extern"] = DK_EXTERN;
5043   DirectiveKindMap["public"] = DK_PUBLIC;
5044   // DirectiveKindMap[".comm"] = DK_COMM;
5045   DirectiveKindMap["comment"] = DK_COMMENT;
5046   DirectiveKindMap["include"] = DK_INCLUDE;
5047   // DirectiveKindMap[".rept"] = DK_REPT;
5048   // DirectiveKindMap[".rep"] = DK_REPT;
5049   // DirectiveKindMap[".irp"] = DK_IRP;
5050   // DirectiveKindMap[".irpc"] = DK_IRPC;
5051   // DirectiveKindMap[".endr"] = DK_ENDR;
5052   DirectiveKindMap["if"] = DK_IF;
5053   DirectiveKindMap["ife"] = DK_IFE;
5054   DirectiveKindMap["ifb"] = DK_IFB;
5055   DirectiveKindMap["ifnb"] = DK_IFNB;
5056   DirectiveKindMap["ifdef"] = DK_IFDEF;
5057   DirectiveKindMap["ifndef"] = DK_IFNDEF;
5058   DirectiveKindMap["ifdif"] = DK_IFDIF;
5059   DirectiveKindMap["ifdifi"] = DK_IFDIFI;
5060   DirectiveKindMap["ifidn"] = DK_IFIDN;
5061   DirectiveKindMap["ifidni"] = DK_IFIDNI;
5062   DirectiveKindMap["elseif"] = DK_ELSEIF;
5063   DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;
5064   DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;
5065   DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;
5066   DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;
5067   DirectiveKindMap["else"] = DK_ELSE;
5068   DirectiveKindMap["end"] = DK_END;
5069   DirectiveKindMap["endif"] = DK_ENDIF;
5070   // DirectiveKindMap[".file"] = DK_FILE;
5071   // DirectiveKindMap[".line"] = DK_LINE;
5072   // DirectiveKindMap[".loc"] = DK_LOC;
5073   // DirectiveKindMap[".stabs"] = DK_STABS;
5074   // DirectiveKindMap[".cv_file"] = DK_CV_FILE;
5075   // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
5076   // DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
5077   // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
5078   // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5079   // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5080   // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
5081   // DirectiveKindMap[".cv_string"] = DK_CV_STRING;
5082   // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
5083   // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5084   // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5085   // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
5086   // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
5087   // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
5088   // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
5089   // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5090   // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5091   // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5092   // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5093   // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
5094   // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5095   // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
5096   // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
5097   // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5098   // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5099   // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
5100   // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
5101   // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
5102   // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5103   // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5104   // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
5105   // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
5106   // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5107   // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5108   // DirectiveKindMap[".macro"] = DK_MACRO;
5109   // DirectiveKindMap[".exitm"] = DK_EXITM;
5110   // DirectiveKindMap[".endm"] = DK_ENDM;
5111   // DirectiveKindMap[".purgem"] = DK_PURGEM;
5112   DirectiveKindMap[".err"] = DK_ERR;
5113   DirectiveKindMap[".errb"] = DK_ERRB;
5114   DirectiveKindMap[".errnb"] = DK_ERRNB;
5115   DirectiveKindMap[".errdef"] = DK_ERRDEF;
5116   DirectiveKindMap[".errndef"] = DK_ERRNDEF;
5117   DirectiveKindMap[".errdif"] = DK_ERRDIF;
5118   DirectiveKindMap[".errdifi"] = DK_ERRDIFI;
5119   DirectiveKindMap[".erridn"] = DK_ERRIDN;
5120   DirectiveKindMap[".erridni"] = DK_ERRIDNI;
5121   DirectiveKindMap[".erre"] = DK_ERRE;
5122   DirectiveKindMap[".errnz"] = DK_ERRNZ;
5123   // DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
5124   // DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
5125   DirectiveKindMap["db"] = DK_DB;
5126   DirectiveKindMap["dd"] = DK_DD;
5127   DirectiveKindMap["dq"] = DK_DQ;
5128   DirectiveKindMap["dw"] = DK_DW;
5129   DirectiveKindMap["echo"] = DK_ECHO;
5130 }
5131 
5132 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5133   AsmToken EndToken, StartToken = getTok();
5134 
5135   unsigned NestLevel = 0;
5136   while (true) {
5137     // Check whether we have reached the end of the file.
5138     if (getLexer().is(AsmToken::Eof)) {
5139       printError(DirectiveLoc, "no matching '.endr' in definition");
5140       return nullptr;
5141     }
5142 
5143     if (Lexer.is(AsmToken::Identifier) &&
5144         (getTok().getIdentifier() == ".rep" ||
5145          getTok().getIdentifier() == ".rept" ||
5146          getTok().getIdentifier() == ".irp" ||
5147          getTok().getIdentifier() == ".irpc")) {
5148       ++NestLevel;
5149     }
5150 
5151     // Otherwise, check whether we have reached the .endr.
5152     if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
5153       if (NestLevel == 0) {
5154         EndToken = getTok();
5155         Lex();
5156         if (Lexer.isNot(AsmToken::EndOfStatement)) {
5157           printError(getTok().getLoc(),
5158                      "unexpected token in '.endr' directive");
5159           return nullptr;
5160         }
5161         break;
5162       }
5163       --NestLevel;
5164     }
5165 
5166     // Otherwise, scan till the end of the statement.
5167     eatToEndOfStatement();
5168   }
5169 
5170   const char *BodyStart = StartToken.getLoc().getPointer();
5171   const char *BodyEnd = EndToken.getLoc().getPointer();
5172   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5173 
5174   // We Are Anonymous.
5175   MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
5176   return &MacroLikeBodies.back();
5177 }
5178 
5179 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5180                                           raw_svector_ostream &OS) {
5181   OS << ".endr\n";
5182 
5183   std::unique_ptr<MemoryBuffer> Instantiation =
5184       MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
5185 
5186   // Create the macro instantiation object and add to the current macro
5187   // instantiation stack.
5188   MacroInstantiation *MI = new MacroInstantiation{
5189       DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
5190   ActiveMacros.push_back(MI);
5191 
5192   // Jump to the macro instantiation and prime the lexer.
5193   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
5194   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
5195   Lex();
5196 }
5197 
5198 /// parseDirectiveRept
5199 ///   ::= .rep | .rept count
5200 bool MasmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5201   const MCExpr *CountExpr;
5202   SMLoc CountLoc = getTok().getLoc();
5203   if (parseExpression(CountExpr))
5204     return true;
5205 
5206   int64_t Count;
5207   if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5208     return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
5209   }
5210 
5211   if (check(Count < 0, CountLoc, "Count is negative") ||
5212       parseToken(AsmToken::EndOfStatement,
5213                  "unexpected token in '" + Dir + "' directive"))
5214     return true;
5215 
5216   // Lex the rept definition.
5217   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5218   if (!M)
5219     return true;
5220 
5221   // Macro instantiation is lexical, unfortunately. We construct a new buffer
5222   // to hold the macro body with substitutions.
5223   SmallString<256> Buf;
5224   raw_svector_ostream OS(Buf);
5225   while (Count--) {
5226     // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
5227     if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
5228       return true;
5229   }
5230   instantiateMacroLikeBody(M, DirectiveLoc, OS);
5231 
5232   return false;
5233 }
5234 
5235 /// parseDirectiveIrp
5236 /// ::= .irp symbol,values
5237 bool MasmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5238   MCAsmMacroParameter Parameter;
5239   MCAsmMacroArguments A;
5240   if (check(parseIdentifier(Parameter.Name),
5241             "expected identifier in '.irp' directive") ||
5242       parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
5243       parseMacroArguments(nullptr, A) ||
5244       parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
5245     return true;
5246 
5247   // Lex the irp definition.
5248   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5249   if (!M)
5250     return true;
5251 
5252   // Macro instantiation is lexical, unfortunately. We construct a new buffer
5253   // to hold the macro body with substitutions.
5254   SmallString<256> Buf;
5255   raw_svector_ostream OS(Buf);
5256 
5257   for (const MCAsmMacroArgument &Arg : A) {
5258     // Note that the AtPseudoVariable is enabled for instantiations of .irp.
5259     // This is undocumented, but GAS seems to support it.
5260     if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5261       return true;
5262   }
5263 
5264   instantiateMacroLikeBody(M, DirectiveLoc, OS);
5265 
5266   return false;
5267 }
5268 
5269 /// parseDirectiveIrpc
5270 /// ::= .irpc symbol,values
5271 bool MasmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5272   MCAsmMacroParameter Parameter;
5273   MCAsmMacroArguments A;
5274 
5275   if (check(parseIdentifier(Parameter.Name),
5276             "expected identifier in '.irpc' directive") ||
5277       parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
5278       parseMacroArguments(nullptr, A))
5279     return true;
5280 
5281   if (A.size() != 1 || A.front().size() != 1)
5282     return TokError("unexpected token in '.irpc' directive");
5283 
5284   // Eat the end of statement.
5285   if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5286     return true;
5287 
5288   // Lex the irpc definition.
5289   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5290   if (!M)
5291     return true;
5292 
5293   // Macro instantiation is lexical, unfortunately. We construct a new buffer
5294   // to hold the macro body with substitutions.
5295   SmallString<256> Buf;
5296   raw_svector_ostream OS(Buf);
5297 
5298   StringRef Values = A.front().front().getString();
5299   for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
5300     MCAsmMacroArgument Arg;
5301     Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
5302 
5303     // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
5304     // This is undocumented, but GAS seems to support it.
5305     if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5306       return true;
5307   }
5308 
5309   instantiateMacroLikeBody(M, DirectiveLoc, OS);
5310 
5311   return false;
5312 }
5313 
5314 bool MasmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5315   if (ActiveMacros.empty())
5316     return TokError("unmatched '.endr' directive");
5317 
5318   // The only .repl that should get here are the ones created by
5319   // instantiateMacroLikeBody.
5320   assert(getLexer().is(AsmToken::EndOfStatement));
5321 
5322   handleMacroExit();
5323   return false;
5324 }
5325 
5326 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5327                                       size_t Len) {
5328   const MCExpr *Value;
5329   SMLoc ExprLoc = getLexer().getLoc();
5330   if (parseExpression(Value))
5331     return true;
5332   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5333   if (!MCE)
5334     return Error(ExprLoc, "unexpected expression in _emit");
5335   uint64_t IntValue = MCE->getValue();
5336   if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5337     return Error(ExprLoc, "literal value out of range for directive");
5338 
5339   Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
5340   return false;
5341 }
5342 
5343 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5344   const MCExpr *Value;
5345   SMLoc ExprLoc = getLexer().getLoc();
5346   if (parseExpression(Value))
5347     return true;
5348   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5349   if (!MCE)
5350     return Error(ExprLoc, "unexpected expression in align");
5351   uint64_t IntValue = MCE->getValue();
5352   if (!isPowerOf2_64(IntValue))
5353     return Error(ExprLoc, "literal value not a power of two greater then zero");
5354 
5355   Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
5356   return false;
5357 }
5358 
5359 bool MasmParser::parseDirectiveEcho() {
5360   StringRef Message = parseStringToEndOfStatement();
5361   Lex();  // eat end of statement
5362   llvm::outs() << Message << '\n';
5363   return false;
5364 }
5365 
5366 // We are comparing pointers, but the pointers are relative to a single string.
5367 // Thus, this should always be deterministic.
5368 static int rewritesSort(const AsmRewrite *AsmRewriteA,
5369                         const AsmRewrite *AsmRewriteB) {
5370   if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
5371     return -1;
5372   if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
5373     return 1;
5374 
5375   // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
5376   // rewrite to the same location.  Make sure the SizeDirective rewrite is
5377   // performed first, then the Imm/ImmPrefix and finally the Input/Output.  This
5378   // ensures the sort algorithm is stable.
5379   if (AsmRewritePrecedence[AsmRewriteA->Kind] >
5380       AsmRewritePrecedence[AsmRewriteB->Kind])
5381     return -1;
5382 
5383   if (AsmRewritePrecedence[AsmRewriteA->Kind] <
5384       AsmRewritePrecedence[AsmRewriteB->Kind])
5385     return 1;
5386   llvm_unreachable("Unstable rewrite sort.");
5387 }
5388 
5389 bool MasmParser::parseMSInlineAsm(
5390     void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
5391     unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
5392     SmallVectorImpl<std::string> &Constraints,
5393     SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
5394     const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
5395   SmallVector<void *, 4> InputDecls;
5396   SmallVector<void *, 4> OutputDecls;
5397   SmallVector<bool, 4> InputDeclsAddressOf;
5398   SmallVector<bool, 4> OutputDeclsAddressOf;
5399   SmallVector<std::string, 4> InputConstraints;
5400   SmallVector<std::string, 4> OutputConstraints;
5401   SmallVector<unsigned, 4> ClobberRegs;
5402 
5403   SmallVector<AsmRewrite, 4> AsmStrRewrites;
5404 
5405   // Prime the lexer.
5406   Lex();
5407 
5408   // While we have input, parse each statement.
5409   unsigned InputIdx = 0;
5410   unsigned OutputIdx = 0;
5411   while (getLexer().isNot(AsmToken::Eof)) {
5412     // Parse curly braces marking block start/end
5413     if (parseCurlyBlockScope(AsmStrRewrites))
5414       continue;
5415 
5416     ParseStatementInfo Info(&AsmStrRewrites);
5417     bool StatementErr = parseStatement(Info, &SI);
5418 
5419     if (StatementErr || Info.ParseError) {
5420       // Emit pending errors if any exist.
5421       printPendingErrors();
5422       return true;
5423     }
5424 
5425     // No pending error should exist here.
5426     assert(!hasPendingError() && "unexpected error from parseStatement");
5427 
5428     if (Info.Opcode == ~0U)
5429       continue;
5430 
5431     const MCInstrDesc &Desc = MII->get(Info.Opcode);
5432 
5433     // Build the list of clobbers, outputs and inputs.
5434     for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
5435       MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
5436 
5437       // Register operand.
5438       if (Operand.isReg() && !Operand.needAddressOf() &&
5439           !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
5440         unsigned NumDefs = Desc.getNumDefs();
5441         // Clobber.
5442         if (NumDefs && Operand.getMCOperandNum() < NumDefs)
5443           ClobberRegs.push_back(Operand.getReg());
5444         continue;
5445       }
5446 
5447       // Expr/Input or Output.
5448       StringRef SymName = Operand.getSymName();
5449       if (SymName.empty())
5450         continue;
5451 
5452       void *OpDecl = Operand.getOpDecl();
5453       if (!OpDecl)
5454         continue;
5455 
5456       StringRef Constraint = Operand.getConstraint();
5457       if (Operand.isImm()) {
5458         // Offset as immediate
5459         if (Operand.isOffsetOfLocal())
5460           Constraint = "r";
5461         else
5462           Constraint = "i";
5463       }
5464 
5465       bool isOutput = (i == 1) && Desc.mayStore();
5466       SMLoc Start = SMLoc::getFromPointer(SymName.data());
5467       if (isOutput) {
5468         ++InputIdx;
5469         OutputDecls.push_back(OpDecl);
5470         OutputDeclsAddressOf.push_back(Operand.needAddressOf());
5471         OutputConstraints.push_back(("=" + Constraint).str());
5472         AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
5473       } else {
5474         InputDecls.push_back(OpDecl);
5475         InputDeclsAddressOf.push_back(Operand.needAddressOf());
5476         InputConstraints.push_back(Constraint.str());
5477         if (Desc.OpInfo[i - 1].isBranchTarget())
5478           AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size());
5479         else
5480           AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
5481       }
5482     }
5483 
5484     // Consider implicit defs to be clobbers.  Think of cpuid and push.
5485     ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
5486                                 Desc.getNumImplicitDefs());
5487     ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
5488   }
5489 
5490   // Set the number of Outputs and Inputs.
5491   NumOutputs = OutputDecls.size();
5492   NumInputs = InputDecls.size();
5493 
5494   // Set the unique clobbers.
5495   array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
5496   ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
5497                     ClobberRegs.end());
5498   Clobbers.assign(ClobberRegs.size(), std::string());
5499   for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
5500     raw_string_ostream OS(Clobbers[I]);
5501     IP->printRegName(OS, ClobberRegs[I]);
5502   }
5503 
5504   // Merge the various outputs and inputs.  Output are expected first.
5505   if (NumOutputs || NumInputs) {
5506     unsigned NumExprs = NumOutputs + NumInputs;
5507     OpDecls.resize(NumExprs);
5508     Constraints.resize(NumExprs);
5509     for (unsigned i = 0; i < NumOutputs; ++i) {
5510       OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
5511       Constraints[i] = OutputConstraints[i];
5512     }
5513     for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
5514       OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
5515       Constraints[j] = InputConstraints[i];
5516     }
5517   }
5518 
5519   // Build the IR assembly string.
5520   std::string AsmStringIR;
5521   raw_string_ostream OS(AsmStringIR);
5522   StringRef ASMString =
5523       SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
5524   const char *AsmStart = ASMString.begin();
5525   const char *AsmEnd = ASMString.end();
5526   array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
5527   for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) {
5528     const AsmRewrite &AR = *it;
5529     // Check if this has already been covered by another rewrite...
5530     if (AR.Done)
5531       continue;
5532     AsmRewriteKind Kind = AR.Kind;
5533 
5534     const char *Loc = AR.Loc.getPointer();
5535     assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
5536 
5537     // Emit everything up to the immediate/expression.
5538     if (unsigned Len = Loc - AsmStart)
5539       OS << StringRef(AsmStart, Len);
5540 
5541     // Skip the original expression.
5542     if (Kind == AOK_Skip) {
5543       AsmStart = Loc + AR.Len;
5544       continue;
5545     }
5546 
5547     unsigned AdditionalSkip = 0;
5548     // Rewrite expressions in $N notation.
5549     switch (Kind) {
5550     default:
5551       break;
5552     case AOK_IntelExpr:
5553       assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
5554       if (AR.IntelExp.NeedBracs)
5555         OS << "[";
5556       if (AR.IntelExp.hasBaseReg())
5557         OS << AR.IntelExp.BaseReg;
5558       if (AR.IntelExp.hasIndexReg())
5559         OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
5560            << AR.IntelExp.IndexReg;
5561       if (AR.IntelExp.Scale > 1)
5562         OS << " * $$" << AR.IntelExp.Scale;
5563       if (AR.IntelExp.hasOffset()) {
5564         if (AR.IntelExp.hasRegs())
5565           OS << " + ";
5566         // Fuse this rewrite with a rewrite of the offset name, if present.
5567         StringRef OffsetName = AR.IntelExp.OffsetName;
5568         SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data());
5569         size_t OffsetLen = OffsetName.size();
5570         auto rewrite_it = std::find_if(
5571             it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
5572               return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
5573                      (FusingAR.Kind == AOK_Input ||
5574                       FusingAR.Kind == AOK_CallInput);
5575             });
5576         if (rewrite_it == AsmStrRewrites.end()) {
5577           OS << "offset " << OffsetName;
5578         } else if (rewrite_it->Kind == AOK_CallInput) {
5579           OS << "${" << InputIdx++ << ":P}";
5580           rewrite_it->Done = true;
5581         } else {
5582           OS << '$' << InputIdx++;
5583           rewrite_it->Done = true;
5584         }
5585       }
5586       if (AR.IntelExp.Imm || AR.IntelExp.emitImm())
5587         OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm;
5588       if (AR.IntelExp.NeedBracs)
5589         OS << "]";
5590       break;
5591     case AOK_Label:
5592       OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
5593       break;
5594     case AOK_Input:
5595       OS << '$' << InputIdx++;
5596       break;
5597     case AOK_CallInput:
5598       OS << "${" << InputIdx++ << ":P}";
5599       break;
5600     case AOK_Output:
5601       OS << '$' << OutputIdx++;
5602       break;
5603     case AOK_SizeDirective:
5604       switch (AR.Val) {
5605       default: break;
5606       case 8:  OS << "byte ptr "; break;
5607       case 16: OS << "word ptr "; break;
5608       case 32: OS << "dword ptr "; break;
5609       case 64: OS << "qword ptr "; break;
5610       case 80: OS << "xword ptr "; break;
5611       case 128: OS << "xmmword ptr "; break;
5612       case 256: OS << "ymmword ptr "; break;
5613       }
5614       break;
5615     case AOK_Emit:
5616       OS << ".byte";
5617       break;
5618     case AOK_Align: {
5619       // MS alignment directives are measured in bytes. If the native assembler
5620       // measures alignment in bytes, we can pass it straight through.
5621       OS << ".align";
5622       if (getContext().getAsmInfo()->getAlignmentIsInBytes())
5623         break;
5624 
5625       // Alignment is in log2 form, so print that instead and skip the original
5626       // immediate.
5627       unsigned Val = AR.Val;
5628       OS << ' ' << Val;
5629       assert(Val < 10 && "Expected alignment less then 2^10.");
5630       AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
5631       break;
5632     }
5633     case AOK_EVEN:
5634       OS << ".even";
5635       break;
5636     case AOK_EndOfStatement:
5637       OS << "\n\t";
5638       break;
5639     }
5640 
5641     // Skip the original expression.
5642     AsmStart = Loc + AR.Len + AdditionalSkip;
5643   }
5644 
5645   // Emit the remainder of the asm string.
5646   if (AsmStart != AsmEnd)
5647     OS << StringRef(AsmStart, AsmEnd - AsmStart);
5648 
5649   AsmString = OS.str();
5650   return false;
5651 }
5652 
5653 /// Create an MCAsmParser instance.
5654 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
5655                                       MCStreamer &Out, const MCAsmInfo &MAI,
5656                                       unsigned CB) {
5657   return new MasmParser(SM, C, Out, MAI, CB);
5658 }
5659