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