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