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