LCOV - code coverage report
Current view: top level - lib/MC/MCParser - AsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 2481 2646 93.8 %
Date: 2018-06-17 00:07:59 Functions: 153 154 99.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13