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