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