LCOV - code coverage report
Current view: top level - lib/MC/MCParser - AsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 2482 2647 93.8 %
Date: 2018-07-13 00:08:38 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       99767 : static cl::opt<unsigned> AsmMacroMaxNestingDepth(
      78      199534 :      "asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
      79      299301 :      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     2609974 : 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     5219978 :     : 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       34884 :   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      494047 :   void addDirectiveHandler(StringRef Directive,
     193             :                            ExtensionDirectiveHandler Handler) override {
     194      494047 :     ExtensionDirectiveMap[Directive] = Handler;
     195      494047 :   }
     196             : 
     197       15095 :   void addAliasForDirective(StringRef Directive, StringRef Alias) override {
     198       30190 :     DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
     199       15095 :   }
     200             : 
     201             :   /// @name MCAsmParser Interface
     202             :   /// {
     203             : 
     204         117 :   SourceMgr &getSourceManager() override { return SrcMgr; }
     205    54216234 :   MCAsmLexer &getLexer() override { return Lexer; }
     206     5082193 :   MCContext &getContext() override { return Ctx; }
     207     1898993 :   MCStreamer &getStreamer() override { return Out; }
     208             : 
     209         106 :   CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
     210             : 
     211     1168637 :   unsigned getAssemblerDialect() override {
     212     1168637 :     if (AssemblerDialect == ~0U)
     213     1030781 :       return MAI.getAssemblerDialect();
     214             :     else
     215             :       return AssemblerDialect;
     216             :   }
     217       10384 :   void setAssemblerDialect(unsigned i) override {
     218       10384 :     AssemblerDialect = i;
     219       10384 :   }
     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     1173457 :   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       47894 :     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       17442 : AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
     673       17442 :                      const MCAsmInfo &MAI, unsigned CB = 0)
     674             :     : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
     675       69768 :       CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
     676       17442 :   HadError = false;
     677             :   // Save the old handler.
     678       17442 :   SavedDiagHandler = SrcMgr.getDiagHandler();
     679       17442 :   SavedDiagContext = SrcMgr.getDiagContext();
     680             :   // Set our own handler which calls the saved handler.
     681             :   SrcMgr.setDiagHandler(DiagHandler, this);
     682       34884 :   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
     683             : 
     684             :   // Initialize the platform / file format parser.
     685       17442 :   switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
     686         307 :   case MCObjectFileInfo::IsCOFF:
     687         307 :     PlatformParser.reset(createCOFFAsmParser());
     688             :     break;
     689         936 :   case MCObjectFileInfo::IsMachO:
     690         936 :     PlatformParser.reset(createDarwinAsmParser());
     691         936 :     IsDarwin = true;
     692         936 :     break;
     693       16198 :   case MCObjectFileInfo::IsELF:
     694       16198 :     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       17442 :   PlatformParser->Initialize(*this);
     706       17442 :   initializeDirectiveKindMap();
     707             : 
     708       17442 :   NumOfMacroInstantiations = 0;
     709       17442 : }
     710             : 
     711      104412 : 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       17402 :   SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
     718       34804 : }
     719             : 
     720       47853 : 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       47890 :        it != ie; ++it)
     726          74 :     printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
     727             :                  "while in macro instantiation");
     728       47853 : }
     729             : 
     730        3048 : void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
     731        3048 :   printPendingErrors();
     732        3048 :   printMessage(L, SourceMgr::DK_Note, Msg, Range);
     733        3048 :   printMacroInstantiations();
     734        3048 : }
     735             : 
     736        3180 : bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
     737        6360 :   if(getTargetParser().getTargetOptions().MCNoWarn)
     738             :     return false;
     739        6358 :   if (getTargetParser().getTargetOptions().MCFatalWarnings)
     740           1 :     return Error(L, Msg, Range);
     741        3178 :   printMessage(L, SourceMgr::DK_Warning, Msg, Range);
     742        3178 :   printMacroInstantiations();
     743        3178 :   return false;
     744             : }
     745             : 
     746       41627 : bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
     747       41627 :   HadError = true;
     748       41627 :   printMessage(L, SourceMgr::DK_Error, Msg, Range);
     749       41627 :   printMacroInstantiations();
     750       41627 :   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      166549 : void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
     792      166549 :   CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
     793      499647 :   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
     794             :                   Loc.getPointer());
     795      166549 : }
     796             : 
     797     8143984 : const AsmToken &AsmParser::Lex() {
     798     8143984 :   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     8143984 :   if (getTok().is(AsmToken::EndOfStatement)) {
     803             :     // if this is a line comment output it.
     804     8087727 :     if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
     805     3993654 :         getTok().getString().front() != '\r' && MAI.preserveAsmComments())
     806      122528 :       Out.addExplicitComment(Twine(getTok().getString()));
     807             :   }
     808             : 
     809     8143984 :   const AsmToken *tok = &Lexer.Lex();
     810             : 
     811             :   // Parse comments here to be deferred until end of next statement.
     812     8144192 :   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     8143984 :   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       17276 :     SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
     822       17276 :     if (ParentIncludeLoc != SMLoc()) {
     823           3 :       jumpToLoc(ParentIncludeLoc);
     824           3 :       return Lex();
     825             :     }
     826             :   }
     827             : 
     828             :   return *tok;
     829             : }
     830             : 
     831      457404 : bool AsmParser::enabledGenDwarfForAssembly() {
     832             :   // Check whether the user specified -g.
     833      457404 :   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          99 :   if (getContext().getGenDwarfFileNumber() == 0)
     839             :     getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
     840             :         0, StringRef(), getContext().getMainFileName()));
     841             :   return true;
     842             : }
     843             : 
     844       17208 : bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
     845             :   // Create the initial section, if requested.
     846       17208 :   if (!NoInitialTextSection)
     847        7085 :     Out.InitSections(false);
     848             : 
     849             :   // Prime the lexer.
     850       17208 :   Lex();
     851             : 
     852       17208 :   HadError = false;
     853       17208 :   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       17208 :   if (getContext().getGenDwarfForAssembly()) {
     861             :     MCSection *Sec = getStreamer().getCurrentSectionOnly();
     862          31 :     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     2626709 :   while (Lexer.isNot(AsmToken::Eof)) {
     874             :     ParseStatementInfo Info(&AsmStrRewrites);
     875     2609516 :     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       41100 :     if (!hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
     882           0 :       Lex();
     883             :     }
     884             : 
     885             :     // parseStatement returned true so may need to emit an error.
     886       39661 :     printPendingErrors();
     887             : 
     888             :     // Skipping to the next line if needed.
     889       39661 :     if (!getLexer().isAtStartOfStatement())
     890       11085 :       eatToEndOfStatement();
     891             :   }
     892             : 
     893             :   // All errors should have been emitted.
     894             :   assert(!hasPendingError() && "unexpected error from parseStatement");
     895             : 
     896       34386 :   getTargetParser().flushPendingInstructions(getStreamer());
     897             : 
     898       34385 :   if (TheCondState.TheCond != StartingCondState.TheCond ||
     899       17192 :       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       17193 :   if (!LineTables.empty()) {
     904             :     unsigned Index = 0;
     905        3362 :     for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
     906        1543 :       if (File.Name.empty() && Index != 0)
     907          18 :         printError(getTok().getLoc(), "unassigned file number: " +
     908          12 :                                           Twine(Index) +
     909           6 :                                           " for .file directives");
     910        1543 :       ++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       17193 :   if (!NoFinalize) {
     919        7091 :     if (MAI.hasSubsectionsViaSymbols()) {
     920        3256 :       for (const auto &TableEntry : getContext().getSymbols()) {
     921        2410 :         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        4980 :         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        7323 :     for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
     937         232 :       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       17193 :   if (!HadError && !NoFinalize)
     949        5704 :     Out.Finish();
     950             : 
     951       50098 :   return HadError || getContext().hadError();
     952             : }
     953             : 
     954      487711 : bool AsmParser::checkForValidSection() {
     955      974792 :   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       18727 : void AsmParser::eatToEndOfStatement() {
     965      116129 :   while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
     966       48701 :     Lexer.Lex();
     967             : 
     968             :   // Eat EOL.
     969       18727 :   if (Lexer.is(AsmToken::EndOfStatement))
     970       18727 :     Lexer.Lex();
     971       18727 : }
     972             : 
     973         816 : StringRef AsmParser::parseStringToEndOfStatement() {
     974        1632 :   const char *Start = getTok().getLoc().getPointer();
     975             : 
     976       12394 :   while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
     977        5789 :     Lexer.Lex();
     978             : 
     979        1632 :   const char *End = getTok().getLoc().getPointer();
     980         816 :   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        1310 : bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
    1000        1310 :   if (parseExpression(Res))
    1001             :     return true;
    1002        1309 :   if (Lexer.isNot(AsmToken::RParen))
    1003           2 :     return TokError("expected ')' in parentheses expression");
    1004        1308 :   EndLoc = Lexer.getTok().getEndLoc();
    1005        1308 :   Lex();
    1006        1308 :   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      568327 : bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
    1030      568327 :   SMLoc FirstTokenLoc = getLexer().getLoc();
    1031             :   AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
    1032      568327 :   switch (FirstTokenKind) {
    1033        1922 :   default:
    1034        3844 :     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       33494 :   case AsmToken::Dollar:
    1045             :   case AsmToken::At:
    1046             :   case AsmToken::String:
    1047             :   case AsmToken::Identifier: {
    1048       33494 :     StringRef Identifier;
    1049       33494 :     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       33483 :     std::pair<StringRef, StringRef> Split;
    1068       33483 :     if (!MAI.useParensForSymbolVariant()) {
    1069       32256 :       if (FirstTokenKind == AsmToken::String) {
    1070          59 :         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       32197 :         Split = Identifier.split('@');
    1081             :       }
    1082        1227 :     } 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       33481 :     EndLoc = SMLoc::getFromPointer(Identifier.end());
    1094             : 
    1095             :     // This is a symbol reference.
    1096       33481 :     StringRef SymbolName = Identifier;
    1097       33481 :     if (SymbolName.empty())
    1098             :       return true;
    1099             : 
    1100             :     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
    1101             : 
    1102             :     // Lookup the symbol variant if used.
    1103       33480 :     if (!Split.second.empty()) {
    1104        1933 :       Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
    1105        1933 :       if (Variant != MCSymbolRefExpr::VK_Invalid) {
    1106        1923 :         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       33474 :     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       33474 :     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         552 :       if (DoInline) {
    1125         276 :         if (Variant)
    1126           0 :           return Error(EndLoc, "unexpected modifier on variable reference");
    1127         276 :         Res = Sym->getVariableValue(/*SetUsed*/ false);
    1128         276 :         return false;
    1129             :       }
    1130             :     }
    1131             : 
    1132             :     // Otherwise create a symbol ref.
    1133       33198 :     Res = MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
    1134       33198 :     return false;
    1135             :   }
    1136           1 :   case AsmToken::BigNum:
    1137           2 :     return TokError("literal value out of range for directive");
    1138      488010 :   case AsmToken::Integer: {
    1139      488010 :     SMLoc Loc = getTok().getLoc();
    1140      488010 :     int64_t IntVal = getTok().getIntVal();
    1141      488010 :     Res = MCConstantExpr::create(IntVal, getContext());
    1142      488010 :     EndLoc = Lexer.getTok().getEndLoc();
    1143      488010 :     Lex(); // Eat token.
    1144             :     // Look for 'b' or 'f' following an Integer as a directional label
    1145      488010 :     if (Lexer.getKind() == AsmToken::Identifier) {
    1146       19730 :       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       19730 :       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         340 :             Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
    1159         340 :         Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
    1160          56 :         if (IDVal == "b" && Sym->isUndefined())
    1161           2 :           return Error(Loc, "directional label undefined");
    1162         336 :         DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
    1163         168 :         EndLoc = Lexer.getTok().getEndLoc();
    1164         168 :         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        1213 :   case AsmToken::LParen:
    1188        1213 :     Lex(); // Eat the '('.
    1189        1213 :     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       19433 :   case AsmToken::Minus:
    1196       19433 :     Lex(); // Eat the operator.
    1197       19433 :     if (parsePrimaryExpr(Res, EndLoc))
    1198             :       return true;
    1199       38698 :     Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
    1200       19349 :     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       11138 :   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       11138 :     Lex(); // Eat the operator.
    1240       11138 :     if (Lexer.isNot(AsmToken::LParen))
    1241           0 :       return TokError("expected '(' after operator");
    1242       11138 :     Lex(); // Eat the operator.
    1243       11138 :     if (parseExpression(Res, EndLoc))
    1244             :       return true;
    1245       11138 :     if (Lexer.isNot(AsmToken::RParen))
    1246           0 :       return TokError("expected ')'");
    1247       11138 :     Lex(); // Eat the operator.
    1248       11138 :     Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
    1249       11138 :     return !Res;
    1250             :   }
    1251             : }
    1252             : 
    1253             : bool AsmParser::parseExpression(const MCExpr *&Res) {
    1254      359920 :   SMLoc EndLoc;
    1255      359920 :   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      543832 : bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
    1359             :   // Parse the expression.
    1360      543832 :   Res = nullptr;
    1361      543832 :   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      541885 :   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      541882 :   if (Res->evaluateAsAbsolute(Value))
    1392      498608 :     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      338252 : bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
    1424             :   const MCExpr *Expr;
    1425             : 
    1426      338252 :   SMLoc StartLoc = Lexer.getLoc();
    1427      338252 :   if (parseExpression(Expr))
    1428             :     return true;
    1429             : 
    1430      676494 :   if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
    1431          24 :     return Error(StartLoc, "expected absolute expression");
    1432             : 
    1433             :   return false;
    1434             : }
    1435             : 
    1436       20223 : static unsigned getDarwinBinOpPrecedence(AsmToken::TokenKind K,
    1437             :                                          MCBinaryExpr::Opcode &Kind,
    1438             :                                          bool ShouldUseLogicalShr) {
    1439       20223 :   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      531132 : static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K,
    1515             :                                       MCBinaryExpr::Opcode &Kind,
    1516             :                                       bool ShouldUseLogicalShr) {
    1517      531132 :   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        1516 :   case AsmToken::Plus:
    1552        1516 :     Kind = MCBinaryExpr::Add;
    1553        1516 :     return 4;
    1554        1865 :   case AsmToken::Minus:
    1555        1865 :     Kind = MCBinaryExpr::Sub;
    1556        1865 :     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      551355 : unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K,
    1591             :                                        MCBinaryExpr::Opcode &Kind) {
    1592      551355 :   bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
    1593     1082487 :   return IsDarwin ? getDarwinBinOpPrecedence(K, Kind, ShouldUseLogicalShr)
    1594     1082487 :                   : 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      541981 : bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
    1600             :                               SMLoc &EndLoc) {
    1601      541981 :   SMLoc StartLoc = Lexer.getLoc();
    1602             :   while (true) {
    1603      546668 :     MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
    1604      546668 :     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      546668 :     if (TokPrec < Precedence)
    1609      541981 :       return false;
    1610             : 
    1611        4691 :     Lex();
    1612             : 
    1613             :     // Eat the next primary expression.
    1614             :     const MCExpr *RHS;
    1615        4691 :     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        4687 :     unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
    1622        4687 :     if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
    1623             :       return true;
    1624             : 
    1625             :     // Merge LHS and RHS according to operator.
    1626        4687 :     Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
    1627        4687 :   }
    1628             : }
    1629             : 
    1630             : /// ParseStatement:
    1631             : ///   ::= EndOfStatement
    1632             : ///   ::= Label* Directive ...Operands... EndOfStatement
    1633             : ///   ::= Label* Identifier OperandList* EndOfStatement
    1634     2609989 : bool AsmParser::parseStatement(ParseStatementInfo &Info,
    1635             :                                MCAsmParserSemaCallback *SI) {
    1636             :   assert(!hasPendingError() && "parseStatement started with pending error");
    1637             :   // Eat initial spaces and comments
    1638     2609989 :   while (Lexer.is(AsmToken::Space))
    1639           0 :     Lex();
    1640     2609989 :   if (Lexer.is(AsmToken::EndOfStatement)) {
    1641             :     // if this is a line comment we can drop it safely
    1642     4243298 :     if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
    1643     1414432 :         getTok().getString().front() == '\n')
    1644      663001 :       Out.AddBlankLine();
    1645     1414433 :     Lex();
    1646     1414433 :     return false;
    1647             :   }
    1648             :   // Statements always start with an identifier.
    1649     1195556 :   AsmToken ID = getTok();
    1650     1195556 :   SMLoc IDLoc = ID.getLoc();
    1651     1195556 :   StringRef IDVal;
    1652             :   int64_t LocalLabelVal = -1;
    1653     1195556 :   if (Lexer.is(AsmToken::HashDirective))
    1654          30 :     return parseCppHashLineFilenameComment(IDLoc);
    1655             :   // Allow an integer followed by a ':' as a directional local label.
    1656     1195526 :   if (Lexer.is(AsmToken::Integer)) {
    1657         163 :     LocalLabelVal = getTok().getIntVal();
    1658         163 :     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         163 :       IDVal = getTok().getString();
    1666         163 :       Lex(); // Consume the integer token to be used as an identifier token.
    1667         163 :       if (Lexer.getKind() != AsmToken::Colon) {
    1668           6 :         if (!TheCondState.Ignore) {
    1669           6 :           Lex(); // always eat a token
    1670           6 :           return Error(IDLoc, "unexpected token at start of statement");
    1671             :         }
    1672             :       }
    1673             :     }
    1674     1195363 :   } else if (Lexer.is(AsmToken::Dot)) {
    1675             :     // Treat '.' as a valid identifier in this context.
    1676          13 :     Lex();
    1677          13 :     IDVal = ".";
    1678     1195350 :   } else if (Lexer.is(AsmToken::LCurly)) {
    1679             :     // Treat '{' as a valid identifier in this context.
    1680         657 :     Lex();
    1681         657 :     IDVal = "{";
    1682             : 
    1683     1194693 :   } else if (Lexer.is(AsmToken::RCurly)) {
    1684             :     // Treat '}' as a valid identifier in this context.
    1685         656 :     Lex();
    1686         656 :     IDVal = "}";
    1687     1194044 :   } 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     1194030 :   } 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     2391010 :       DirectiveKindMap.find(IDVal);
    1705     1195505 :   DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
    1706     1405894 :                               ? DK_NO_DIRECTIVE
    1707             :                               : DirKindIt->getValue();
    1708      210389 :   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     1194897 :   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     1194684 :   switch (Lexer.getKind()) {
    1755       21194 :   case AsmToken::Colon: {
    1756       21194 :     if (!getTargetParser().isLabel(ID))
    1757             :       break;
    1758       20647 :     if (checkForValidSection())
    1759             :       return true;
    1760             : 
    1761             :     // identifier ':'   -> Label.
    1762       20647 :     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       20646 :     if (LocalLabelVal == -1) {
    1775       20489 :       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       20489 :       Sym = getContext().getOrCreateSymbol(IDVal);
    1785             :     } else
    1786         157 :       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       20646 :     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       20646 :     if (getTok().is(AsmToken::EndOfStatement)) {
    1800       20374 :       Lex();
    1801             :     }
    1802             : 
    1803             :     // Emit the label.
    1804       20646 :     if (!getTargetParser().isParsingInlineAsm())
    1805       20628 :       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       20646 :     if (enabledGenDwarfForAssembly())
    1810          47 :       MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
    1811             :                                  IDLoc);
    1812             : 
    1813       20646 :     getTargetParser().onLabelParsed(Sym);
    1814             : 
    1815       20646 :     return false;
    1816             :   }
    1817             : 
    1818        1936 :   case AsmToken::Equal:
    1819        1936 :     if (!getTargetParser().equalIsAsmAssignment())
    1820             :       break;
    1821             :     // identifier '=' ... -> assignment statement
    1822         580 :     Lex();
    1823             : 
    1824         580 :     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     1173457 :   if (areMacrosEnabled())
    1832      164894 :     if (const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
    1833      164894 :       return handleMacroEntry(M, IDLoc);
    1834             :     }
    1835             : 
    1836             :   // Otherwise, we have a normal instruction or directive.
    1837             : 
    1838             :   // Directives start with "."
    1839     2017126 :   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     1131318 :     getTargetParser().flushPendingInstructions(getStreamer());
    1852             : 
    1853      565659 :     SMLoc StartTokLoc = getTok().getLoc();
    1854     1696973 :     bool TPDirectiveReturn = getTargetParser().ParseDirective(ID);
    1855             : 
    1856      565655 :     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     1122912 :     if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
    1864             :       return true;
    1865             :     // Return if we did some parsing or believe we succeeded.
    1866     1688110 :     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      557672 :         ExtensionDirectiveMap.lookup(IDVal);
    1873      557672 :     if (Handler.first)
    1874      349036 :       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      208636 :     switch (DirKind) {
    1879             :     default:
    1880             :       break;
    1881         194 :     case DK_SET:
    1882             :     case DK_EQU:
    1883         194 :       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         857 :     case DK_ASCIZ:
    1889             :     case DK_STRING:
    1890         857 :       return parseDirectiveAscii(IDVal, true);
    1891        8449 :     case DK_BYTE:
    1892             :     case DK_DC_B:
    1893        8449 :       return parseDirectiveValue(IDVal, 1);
    1894        1838 :     case DK_DC:
    1895             :     case DK_DC_W:
    1896             :     case DK_SHORT:
    1897             :     case DK_VALUE:
    1898             :     case DK_2BYTE:
    1899        1838 :       return parseDirectiveValue(IDVal, 2);
    1900        5435 :     case DK_LONG:
    1901             :     case DK_INT:
    1902             :     case DK_4BYTE:
    1903             :     case DK_DC_L:
    1904        5435 :       return parseDirectiveValue(IDVal, 4);
    1905        1344 :     case DK_QUAD:
    1906             :     case DK_8BYTE:
    1907        1344 :       return parseDirectiveValue(IDVal, 8);
    1908         108 :     case DK_DC_A:
    1909         108 :       return parseDirectiveValue(
    1910         108 :           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        1291 :     case DK_ALIGN: {
    1921        1291 :       bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
    1922        1291 :       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         409 :     case DK_BALIGN:
    1929         409 :       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         643 :     case DK_P2ALIGN:
    1935         643 :       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         567 :     case DK_FILL:
    1943         567 :       return parseDirectiveFill();
    1944          89 :     case DK_ZERO:
    1945          89 :       return parseDirectiveZero();
    1946          12 :     case DK_EXTERN:
    1947          12 :       eatToEndOfStatement(); // .extern is the default, ignore it.
    1948          12 :       return false;
    1949       13825 :     case DK_GLOBL:
    1950             :     case DK_GLOBAL:
    1951       13825 :       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         176 :     case DK_COMM:
    1969             :     case DK_COMMON:
    1970         176 :       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         240 :     case DK_ULEB128:
    2000         240 :       return parseDirectiveLEB128(false);
    2001         362 :     case DK_SPACE:
    2002             :     case DK_SKIP:
    2003         362 :       return parseDirectiveSpace(IDVal);
    2004         246 :     case DK_FILE:
    2005         246 :       return parseDirectiveFile(IDLoc);
    2006          16 :     case DK_LINE:
    2007          16 :       return parseDirectiveLine();
    2008         316 :     case DK_LOC:
    2009         316 :       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         360 :     case DK_CFI_STARTPROC:
    2037         360 :       return parseDirectiveCFIStartProc();
    2038         353 :     case DK_CFI_ENDPROC:
    2039         706 :       return parseDirectiveCFIEndProc();
    2040          22 :     case DK_CFI_DEF_CFA:
    2041          22 :       return parseDirectiveCFIDefCfa(IDLoc);
    2042         116 :     case DK_CFI_DEF_CFA_OFFSET:
    2043         116 :       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         227 :     case DK_MACRO:
    2080         227 :       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      164884 :     case DK_ENDM:
    2087             :     case DK_ENDMACRO:
    2088      164884 :       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          85 :     return Error(IDLoc, "unknown directive");
    2134             :   }
    2135             : 
    2136             :   // __asm _emit or __asm __emit
    2137      442904 :   if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
    2138             :                            IDVal == "_EMIT" || IDVal == "__EMIT"))
    2139           7 :     return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
    2140             : 
    2141             :   // __asm align
    2142      442897 :   if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
    2143          12 :     return parseDirectiveMSAlign(IDLoc, Info);
    2144             : 
    2145      442885 :   if (ParsingInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
    2146           1 :     Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
    2147      442885 :   if (checkForValidSection())
    2148             :     return true;
    2149             : 
    2150             :   // Canonicalize the opcode to lower case.
    2151      442885 :   std::string OpcodeStr = IDVal.lower();
    2152      442885 :   ParseInstructionInfo IInfo(Info.AsmRewrites);
    2153     1771540 :   bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
    2154      885770 :                                                           Info.ParsedOperands);
    2155      442885 :   Info.ParseError = ParseHadError;
    2156             : 
    2157             :   // Dump the parsed representation, if requested.
    2158      442885 :   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      442885 :   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      436810 :   if (!ParseHadError && enabledGenDwarfForAssembly() &&
    2179             :       getContext().getGenDwarfSectionSyms().count(
    2180             :           getStreamer().getCurrentSectionOnly())) {
    2181             :     unsigned Line;
    2182          52 :     if (ActiveMacros.empty())
    2183          47 :       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          52 :     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          52 :     getStreamer().EmitDwarfLocDirective(
    2202             :         getContext().getGenDwarfFileNumber(), Line, 0,
    2203             :         DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0,
    2204          52 :         StringRef());
    2205             :   }
    2206             : 
    2207             :   // If parsing succeeded, match the instruction.
    2208             :   if (!ParseHadError) {
    2209             :     uint64_t ErrorInfo;
    2210      873516 :     if (getTargetParser().MatchAndEmitInstruction(
    2211             :             IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
    2212      436758 :             getTargetParser().isParsingInlineAsm()))
    2213       32602 :       return true;
    2214             :   }
    2215      404152 :   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       48256 : void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
    2265             :   const AsmParser *Parser = static_cast<const AsmParser *>(Context);
    2266       48256 :   raw_ostream &OS = errs();
    2267             : 
    2268       48256 :   const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
    2269             :   SMLoc DiagLoc = Diag.getLoc();
    2270       48256 :   unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
    2271             :   unsigned CppHashBuf =
    2272       48256 :       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       48256 :   unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
    2277       48256 :   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       48256 :   if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
    2287             :       DiagBuf != CppHashBuf) {
    2288       48197 :     if (Parser->SavedDiagHandler)
    2289         190 :       Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
    2290             :     else
    2291       48007 :       Diag.print(nullptr, OS);
    2292       48197 :     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          59 :   int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
    2301             :   int CppHashLocLineNo =
    2302         118 :       Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
    2303          59 :   int LineNo =
    2304          59 :       Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
    2305             : 
    2306          59 :   SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
    2307             :                        Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
    2308         177 :                        Diag.getLineContents(), Diag.getRanges());
    2309             : 
    2310          59 :   if (Parser->SavedDiagHandler)
    2311           0 :     Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
    2312             :   else
    2313          59 :     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     1071858 : static bool isIdentifierChar(char c) {
    2321     1071858 :   return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
    2322     1071858 :          c == '.';
    2323             : }
    2324             : 
    2325      183042 : bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
    2326             :                             ArrayRef<MCAsmMacroParameter> Parameters,
    2327             :                             ArrayRef<MCAsmMacroArgument> A,
    2328             :                             bool EnableAtPseudoVariable, SMLoc L) {
    2329      183042 :   unsigned NParameters = Parameters.size();
    2330      358966 :   bool HasVararg = NParameters ? Parameters.back().Vararg : false;
    2331      183042 :   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     1249569 :   while (!Body.empty()) {
    2337             :     // Scan for the next substitution.
    2338             :     std::size_t End = Body.size(), Pos = 0;
    2339    21949043 :     for (; Pos != End; ++Pos) {
    2340             :       // Check for a substitution or escape.
    2341    11149635 :       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    22292004 :         if (Body[Pos] == '\\' && Pos + 1 != End)
    2353             :           break;
    2354             :       }
    2355             :     }
    2356             : 
    2357             :     // Add the prefix.
    2358     1432602 :     OS << Body.slice(0, Pos);
    2359             : 
    2360             :     // Check if we reached the end.
    2361      716301 :     if (Pos == End)
    2362             :       break;
    2363             : 
    2364      533264 :     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      533073 :       unsigned I = Pos + 1;
    2392             : 
    2393             :       // Check for the \@ pseudo-variable.
    2394     1066141 :       if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
    2395             :         ++I;
    2396             :       else
    2397     2140616 :         while (isIdentifierChar(Body[I]) && I + 1 != End)
    2398             :           ++I;
    2399             : 
    2400      533073 :       const char *Begin = Body.data() + Pos + 1;
    2401      533073 :       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      544114 :         for (; Index < NParameters; ++Index)
    2409      533732 :           if (Parameters[Index].Name == Argument)
    2410             :             break;
    2411             : 
    2412      532994 :         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      528172 :           bool VarargParameter = HasVararg && Index == (NParameters - 1);
    2421     1056344 :           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      529020 :             if ((Lexer.IsaAltMacroMode()) &&
    2428      528996 :                  (*(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      529004 :                      (*(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      529104 :             else if (Token.isNot(AsmToken::String) || VarargParameter)
    2443      528962 :               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      533264 :     Body = Body.substr(Pos);
    2453             :   }
    2454             : 
    2455             :   return false;
    2456             : }
    2457             : 
    2458             : MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
    2459      166540 :                                        size_t CondStackDepth)
    2460             :     : InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
    2461      166540 :       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      177555 : bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
    2512             : 
    2513      177555 :   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      177473 :   AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
    2525             : 
    2526             :   bool SpaceEaten;
    2527             : 
    2528             :   while (true) {
    2529             :     SpaceEaten = false;
    2530      354405 :     if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
    2531           0 :       return TokError("unexpected token in macro instantiation");
    2532             : 
    2533      354405 :     if (ParenLevel == 0) {
    2534             : 
    2535      354239 :       if (Lexer.is(AsmToken::Comma))
    2536             :         break;
    2537             : 
    2538      342915 :       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      342915 :       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      342804 :       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      342686 :     if (Lexer.is(AsmToken::EndOfStatement))
    2565             :       break;
    2566             : 
    2567             :     // Adjust the current parentheses level.
    2568      176821 :     if (Lexer.is(AsmToken::LParen))
    2569          49 :       ++ParenLevel;
    2570      176772 :     else if (Lexer.is(AsmToken::RParen) && ParenLevel)
    2571          49 :       --ParenLevel;
    2572             : 
    2573             :     // Append the token to the current argument list.
    2574      176821 :     MA.push_back(getTok());
    2575      176821 :     Lexer.Lex();
    2576             :   }
    2577             : 
    2578      177473 :   if (ParenLevel != 0)
    2579           0 :     return TokError("unbalanced parentheses in macro argument");
    2580             :   return false;
    2581             : }
    2582             : 
    2583             : // Parse the macro instantiation arguments.
    2584      166017 : bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
    2585             :                                     MCAsmMacroArguments &A) {
    2586      330910 :   const unsigned NParameters = M ? M->Parameters.size() : 0;
    2587             :   bool NamedParametersFound = false;
    2588             :   SmallVector<SMLoc, 4> FALocs;
    2589             : 
    2590      166017 :   A.resize(NParameters);
    2591      166017 :   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      330807 :   bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
    2597      189087 :   for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
    2598             :        ++Parameter) {
    2599      177550 :     SMLoc IDLoc = Lexer.getLoc();
    2600             :     MCAsmMacroParameter FA;
    2601             : 
    2602      519491 :     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      177550 :     bool Vararg = HasVararg && Parameter == (NParameters - 1);
    2614             : 
    2615      177560 :     if (NamedParametersFound && FA.Name.empty())
    2616           2 :       return Error(IDLoc, "cannot mix positional and keyword arguments");
    2617             : 
    2618      177549 :     SMLoc StrLoc = Lexer.getLoc();
    2619      177549 :     SMLoc EndLoc;
    2620      177572 :     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      177556 :     } 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      177534 :     } else if(parseMacroArgument(FA.Value, Vararg))
    2644             :         return true;
    2645             : 
    2646             :     unsigned PI = Parameter;
    2647      177549 :     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      177548 :     if (!FA.Value.empty()) {
    2662      352748 :       if (A.size() <= PI)
    2663       11240 :         A.resize(PI + 1);
    2664      352748 :       A[PI] = FA.Value;
    2665             : 
    2666      176374 :       if (FALocs.size() <= PI)
    2667       11240 :         FALocs.resize(PI + 1);
    2668             : 
    2669      176374 :       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      177548 :     if (Lexer.is(AsmToken::EndOfStatement)) {
    2676             :       bool Failure = false;
    2677      496335 :       for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
    2678      330322 :         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      164894 : 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      329788 :   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      164893 :   MCAsmMacroArguments A;
    2714      164893 :   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      164885 :   StringRef Body = M->Body;
    2721             :   raw_svector_ostream OS(Buf);
    2722             : 
    2723      329770 :   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      164884 :   OS << ".endmacro\n";
    2729             : 
    2730             :   std::unique_ptr<MemoryBuffer> Instantiation =
    2731      329768 :       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      494652 :       NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
    2737      164884 :   ActiveMacros.push_back(MI);
    2738             : 
    2739      164884 :   ++NumOfMacroInstantiations;
    2740             : 
    2741             :   // Jump to the macro instantiation and prime the lexer.
    2742      494652 :   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
    2743      329768 :   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
    2744      164884 :   Lex();
    2745             : 
    2746             :   return false;
    2747             : }
    2748             : 
    2749      166539 : void AsmParser::handleMacroExit() {
    2750             :   // Jump to the EndOfStatement we should return to, and consume it.
    2751      166539 :   jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
    2752      166539 :   Lex();
    2753             : 
    2754             :   // Pop the instantiation entry.
    2755      166539 :   delete ActiveMacros.back();
    2756             :   ActiveMacros.pop_back();
    2757      166539 : }
    2758             : 
    2759         782 : bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
    2760             :                                 bool NoDeadStrip, bool AllowExtendedExpr) {
    2761             :   MCSymbol *Sym;
    2762             :   const MCExpr *Value;
    2763         782 :   if (MCParserUtils::parseAssignmentExpression(Name, allow_redef, *this, Sym,
    2764             :                                                Value, AllowExtendedExpr))
    2765             :     return true;
    2766             : 
    2767         767 :   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         755 :   Out.EmitAssignment(Sym, Value);
    2776         755 :   if (NoDeadStrip)
    2777         192 :     Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip);
    2778             : 
    2779             :   return false;
    2780             : }
    2781             : 
    2782             : /// parseIdentifier:
    2783             : ///   ::= identifier
    2784             : ///   ::= string
    2785     1254611 : 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     1254611 :   if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
    2792         414 :     SMLoc PrefixLoc = getLexer().getLoc();
    2793             : 
    2794             :     // Consume the prefix character, and check for a following identifier.
    2795             : 
    2796        2070 :     AsmToken Buf[1];
    2797         828 :     Lexer.peekTokens(Buf, false);
    2798             : 
    2799         414 :     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         784 :     if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
    2804             :       return true;
    2805             : 
    2806             :     // eat $ or @
    2807         392 :     Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
    2808             :     // Construct the joined identifier and consume the token.
    2809         392 :     Res =
    2810         784 :         StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
    2811         392 :     Lex(); // Parser Lex to maintain invariants.
    2812         392 :     return false;
    2813             :   }
    2814             : 
    2815     1254409 :   if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
    2816             :     return true;
    2817             : 
    2818     2508328 :   Res = getTok().getIdentifier();
    2819             : 
    2820     1254164 :   Lex(); // Consume the identifier token.
    2821             : 
    2822     1254164 :   return false;
    2823             : }
    2824             : 
    2825             : /// parseDirectiveSet:
    2826             : ///   ::= .equ identifier ',' expression
    2827             : ///   ::= .equiv identifier ',' expression
    2828             : ///   ::= .set identifier ',' expression
    2829         202 : bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
    2830         202 :   StringRef Name;
    2831         808 :   if (check(parseIdentifier(Name), "expected identifier") ||
    2832         798 :       parseToken(AsmToken::Comma) || parseAssignment(Name, allow_redef, true))
    2833          10 :     return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
    2834             :   return false;
    2835             : }
    2836             : 
    2837        1332 : bool AsmParser::parseEscapedString(std::string &Data) {
    2838        3996 :   if (check(getTok().isNot(AsmToken::String), "expected string"))
    2839             :     return true;
    2840             : 
    2841             :   Data = "";
    2842        1330 :   StringRef Str = getTok().getStringContents();
    2843       16222 :   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
    2844       44311 :     if (Str[i] != '\\') {
    2845       14527 :       Data += Str[i];
    2846       14527 :       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        1330 :   Lex();
    2894        1330 :   return false;
    2895             : }
    2896             : 
    2897             : /// parseDirectiveAscii:
    2898             : ///   ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
    2899         959 : bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
    2900         961 :   auto parseOp = [&]() -> bool {
    2901             :     std::string Data;
    2902        1819 :     if (checkForValidSection() || parseEscapedString(Data))
    2903             :       return true;
    2904        1918 :     getStreamer().EmitBytes(Data);
    2905         959 :     if (ZeroTerminated)
    2906        1716 :       getStreamer().EmitBytes(StringRef("\0", 1));
    2907             :     return false;
    2908         959 :   };
    2909             : 
    2910        1918 :   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       17174 : bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
    2966       17962 :   auto parseOp = [&]() -> bool {
    2967             :     const MCExpr *Value;
    2968       71840 :     SMLoc ExprLoc = getLexer().getLoc();
    2969       35923 :     if (checkForValidSection() || parseExpression(Value))
    2970             :       return true;
    2971             :     // Special case constant expressions to match code generator.
    2972       17955 :     if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
    2973             :       assert(Size <= 8 && "Invalid size");
    2974       15293 :       uint64_t IntValue = MCE->getValue();
    2975       17955 :       if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
    2976          22 :         return Error(ExprLoc, "out of range literal value");
    2977       15282 :       getStreamer().EmitIntValue(IntValue, Size);
    2978             :     } else
    2979        2662 :       getStreamer().EmitValue(Value, Size, ExprLoc);
    2980             :     return false;
    2981       17174 :   };
    2982             : 
    2983       34348 :   if (parseMany(parseOp))
    2984          46 :     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          89 : bool AsmParser::parseDirectiveZero() {
    3093          89 :   SMLoc NumBytesLoc = Lexer.getLoc();
    3094             :   const MCExpr *NumBytes;
    3095         178 :   if (checkForValidSection() || parseExpression(NumBytes))
    3096             :     return true;
    3097             : 
    3098          89 :   int64_t Val = 0;
    3099          89 :   if (getLexer().is(AsmToken::Comma)) {
    3100           2 :     Lex();
    3101           2 :     if (parseAbsoluteExpression(Val))
    3102             :       return true;
    3103             :   }
    3104             : 
    3105         178 :   if (parseToken(AsmToken::EndOfStatement,
    3106             :                  "unexpected token in '.zero' directive"))
    3107             :     return true;
    3108          89 :   getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
    3109             : 
    3110          89 :   return false;
    3111             : }
    3112             : 
    3113             : /// parseDirectiveFill
    3114             : ///  ::= .fill expression [ , expression [ , expression ] ]
    3115         567 : bool AsmParser::parseDirectiveFill() {
    3116         567 :   SMLoc NumValuesLoc = Lexer.getLoc();
    3117             :   const MCExpr *NumValues;
    3118        1134 :   if (checkForValidSection() || parseExpression(NumValues))
    3119             :     return true;
    3120             : 
    3121         567 :   int64_t FillSize = 1;
    3122         567 :   int64_t FillExpr = 0;
    3123             : 
    3124         567 :   SMLoc SizeLoc, ExprLoc;
    3125             : 
    3126         567 :   if (parseOptionalToken(AsmToken::Comma)) {
    3127         555 :     SizeLoc = getTok().getLoc();
    3128         555 :     if (parseAbsoluteExpression(FillSize))
    3129             :       return true;
    3130         555 :     if (parseOptionalToken(AsmToken::Comma)) {
    3131         549 :       ExprLoc = getTok().getLoc();
    3132         549 :       if (parseAbsoluteExpression(FillExpr))
    3133             :         return true;
    3134             :     }
    3135             :   }
    3136         567 :   if (parseToken(AsmToken::EndOfStatement,
    3137             :                  "unexpected token in '.fill' directive"))
    3138             :     return true;
    3139             : 
    3140         563 :   if (FillSize < 0) {
    3141           2 :     Warning(SizeLoc, "'.fill' directive with negative size has no effect");
    3142           2 :     return false;
    3143             :   }
    3144         561 :   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         561 :   if (!isUInt<32>(FillExpr) && FillSize > 4)
    3150           2 :     Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
    3151             : 
    3152         561 :   getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
    3153             : 
    3154         561 :   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        2366 : bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
    3180        2366 :   SMLoc AlignmentLoc = getLexer().getLoc();
    3181             :   int64_t Alignment;
    3182        2366 :   SMLoc MaxBytesLoc;
    3183        2366 :   bool HasFillExpr = false;
    3184        2366 :   int64_t FillExpr = 0;
    3185        2366 :   int64_t MaxBytesToFill = 0;
    3186             : 
    3187        2365 :   auto parseAlign = [&]() -> bool {
    3188        7127 :     if (parseAbsoluteExpression(Alignment))
    3189             :       return true;
    3190        2365 :     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         798 :       if (getTok().isNot(AsmToken::Comma)) {
    3195         797 :         HasFillExpr = true;
    3196         797 :         if (parseAbsoluteExpression(FillExpr))
    3197             :           return true;
    3198             :       }
    3199         798 :       if (parseOptionalToken(AsmToken::Comma))
    3200           4 :         if (parseTokenLoc(MaxBytesLoc) ||
    3201           2 :             parseAbsoluteExpression(MaxBytesToFill))
    3202             :           return true;
    3203             :     }
    3204        4730 :     return parseToken(AsmToken::EndOfStatement);
    3205        2366 :   };
    3206             : 
    3207        2366 :   if (checkForValidSection())
    3208           0 :     return addErrorSuffix(" in directive");
    3209             :   // Ignore empty '.p2align' directives for GNU-as compatibility
    3210        2366 :   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        2365 :   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        2349 :   if (IsPow2) {
    3222             :     // FIXME: Diagnose overflow.
    3223        1052 :     if (Alignment >= 32) {
    3224           2 :       ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
    3225           1 :       Alignment = 31;
    3226             :     }
    3227             : 
    3228        1052 :     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        1297 :     if (Alignment == 0)
    3234           7 :       Alignment = 1;
    3235        1297 :     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        2349 :   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        2349 :   bool UseCodeAlign = Section->UseCodeAlign();
    3260        3146 :   if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
    3261        4679 :       ValueSize == 1 && UseCodeAlign) {
    3262        1663 :     getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
    3263             :   } else {
    3264             :     // FIXME: Target specific behavior about how the "extra" bytes are filled.
    3265         686 :     getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize,
    3266         686 :                                        MaxBytesToFill);
    3267             :   }
    3268             : 
    3269             :   return ReturnVal;
    3270             : }
    3271             : 
    3272             : /// parseDirectiveFile
    3273             : /// ::= .file filename
    3274             : /// ::= .file number [directory] filename [md5 checksum] [source source-text]
    3275         246 : bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
    3276             :   // FIXME: I'm not sure what this is.
    3277             :   int64_t FileNumber = -1;
    3278         246 :   if (getLexer().is(AsmToken::Integer)) {
    3279         140 :     FileNumber = getTok().getIntVal();
    3280         140 :     Lex();
    3281             : 
    3282         140 :     if (FileNumber < 0)
    3283           0 :       return TokError("negative file number");
    3284             :   }
    3285             : 
    3286             :   std::string Path;
    3287             : 
    3288             :   // Usually the directory and filename together, otherwise just the directory.
    3289             :   // Allow the strings to have escaped octal character sequence.
    3290         738 :   if (check(getTok().isNot(AsmToken::String),
    3291         492 :             "unexpected token in '.file' directive") ||
    3292         246 :       parseEscapedString(Path))
    3293             :     return true;
    3294             : 
    3295         246 :   StringRef Directory;
    3296         246 :   StringRef Filename;
    3297             :   std::string FilenameData;
    3298         246 :   if (getLexer().is(AsmToken::String)) {
    3299          68 :     if (check(FileNumber == -1,
    3300          68 :               "explicit path specified, but no file number") ||
    3301          34 :         parseEscapedString(FilenameData))
    3302             :       return true;
    3303          34 :     Filename = FilenameData;
    3304          34 :     Directory = Path;
    3305             :   } else {
    3306         212 :     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         268 :   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         238 :   if (Ctx.getGenDwarfForAssembly()) {
    3345             :     Ctx.getMCDwarfLineTable(0).resetRootFile();
    3346           1 :     Ctx.setGenDwarfForAssembly(false);
    3347             :   }
    3348             : 
    3349         238 :   if (FileNumber == -1)
    3350         104 :     getStreamer().EmitFileDirective(Filename);
    3351             :   else {
    3352             :     MD5::MD5Result *CKMem = nullptr;
    3353         134 :     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         134 :     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         134 :     if (FileNumber == 0) {
    3366           7 :       if (Ctx.getDwarfVersion() < 5)
    3367           4 :         return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
    3368           6 :       getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
    3369             :     } else {
    3370             :       Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
    3371         254 :           FileNumber, Directory, Filename, CKMem, Source);
    3372         127 :       if (!FileNumOrErr)
    3373           0 :         return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
    3374             :       FileNumber = FileNumOrErr.get();
    3375             :     }
    3376             :     // Alert the user if there are some .file directives with MD5 and some not.
    3377             :     // But only do that once.
    3378         130 :     if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
    3379           2 :       ReportedInconsistentMD5 = true;
    3380           2 :       return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
    3381             :     }
    3382             :   }
    3383             : 
    3384             :   return false;
    3385             : }
    3386             : 
    3387             : /// parseDirectiveLine
    3388             : /// ::= .line [number]
    3389          16 : bool AsmParser::parseDirectiveLine() {
    3390             :   int64_t LineNumber;
    3391          16 :   if (getLexer().is(AsmToken::Integer)) {
    3392          20 :     if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
    3393             :       return true;
    3394             :     (void)LineNumber;
    3395             :     // FIXME: Do something with the .line.
    3396             :   }
    3397          32 :   if (parseToken(AsmToken::EndOfStatement,
    3398             :                  "unexpected token in '.line' directive"))
    3399             :     return true;
    3400             : 
    3401          12 :   return false;
    3402             : }
    3403             : 
    3404             : /// parseDirectiveLoc
    3405             : /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
    3406             : ///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
    3407             : /// The first number is a file number, must have been previously assigned with
    3408             : /// a .file directive, the second number is the line number and optionally the
    3409             : /// third number is a column position (zero if not specified).  The remaining
    3410             : /// optional items are .loc sub-directives.
    3411         316 : bool AsmParser::parseDirectiveLoc() {
    3412         316 :   int64_t FileNumber = 0, LineNumber = 0;
    3413         316 :   SMLoc Loc = getTok().getLoc();
    3414         948 :   if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
    3415         632 :       check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
    3416         631 :             "file number less than one in '.loc' directive") ||
    3417         631 :       check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
    3418             :             "unassigned file number in '.loc' directive"))
    3419             :     return true;
    3420             : 
    3421             :   // optional
    3422         315 :   if (getLexer().is(AsmToken::Integer)) {
    3423         309 :     LineNumber = getTok().getIntVal();
    3424         309 :     if (LineNumber < 0)
    3425           0 :       return TokError("line number less than zero in '.loc' directive");
    3426         309 :     Lex();
    3427             :   }
    3428             : 
    3429             :   int64_t ColumnPos = 0;
    3430         315 :   if (getLexer().is(AsmToken::Integer)) {
    3431         294 :     ColumnPos = getTok().getIntVal();
    3432         294 :     if (ColumnPos < 0)
    3433           0 :       return TokError("column position less than zero in '.loc' directive");
    3434         294 :     Lex();
    3435             :   }
    3436             : 
    3437         315 :   unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
    3438         315 :   unsigned Isa = 0;
    3439         315 :   int64_t Discriminator = 0;
    3440             : 
    3441         122 :   auto parseLocOp = [&]() -> bool {
    3442         122 :     StringRef Name;
    3443         205 :     SMLoc Loc = getTok().getLoc();
    3444         122 :     if (parseIdentifier(Name))
    3445           4 :       return TokError("unexpected token in '.loc' directive");
    3446             : 
    3447             :     if (Name == "basic_block")
    3448         115 :       Flags |= DWARF2_FLAG_BASIC_BLOCK;
    3449             :     else if (Name == "prologue_end")
    3450          78 :       Flags |= DWARF2_FLAG_PROLOGUE_END;
    3451             :     else if (Name == "epilogue_begin")
    3452           0 :       Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
    3453             :     else if (Name == "is_stmt") {
    3454          37 :       Loc = getTok().getLoc();
    3455             :       const MCExpr *Value;
    3456          37 :       if (parseExpression(Value))
    3457           0 :         return true;
    3458             :       // The expression must be the constant 0 or 1.
    3459          37 :       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
    3460          37 :         int Value = MCE->getValue();
    3461          37 :         if (Value == 0)
    3462          19 :           Flags &= ~DWARF2_FLAG_IS_STMT;
    3463          18 :         else if (Value == 1)
    3464          18 :           Flags |= DWARF2_FLAG_IS_STMT;
    3465             :         else
    3466           0 :           return Error(Loc, "is_stmt value not 0 or 1");
    3467             :       } else {
    3468           0 :         return Error(Loc, "is_stmt value not the constant value of 0 or 1");
    3469             :       }
    3470             :     } else if (Name == "isa") {
    3471           2 :       Loc = getTok().getLoc();
    3472             :       const MCExpr *Value;
    3473           2 :       if (parseExpression(Value))
    3474           0 :         return true;
    3475             :       // The expression must be a constant greater or equal to 0.
    3476           2 :       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
    3477           2 :         int Value = MCE->getValue();
    3478           2 :         if (Value < 0)
    3479           0 :           return Error(Loc, "isa number less than zero");
    3480           2 :         Isa = Value;
    3481             :       } else {
    3482           0 :         return Error(Loc, "isa number not a constant value");
    3483             :       }
    3484             :     } else if (Name == "discriminator") {
    3485           3 :       if (parseAbsoluteExpression(Discriminator))
    3486             :         return true;
    3487             :     } else {
    3488           0 :       return Error(Loc, "unknown sub-directive in '.loc' directive");
    3489             :     }
    3490             :     return false;
    3491         315 :   };
    3492             : 
    3493         315 :   if (parseMany(parseLocOp, false /*hasComma*/))
    3494             :     return true;
    3495             : 
    3496         313 :   getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
    3497         313 :                                       Isa, Discriminator, StringRef());
    3498             : 
    3499         313 :   return false;
    3500             : }
    3501             : 
    3502             : /// parseDirectiveStabs
    3503             : /// ::= .stabs string, number, number, number
    3504             : bool AsmParser::parseDirectiveStabs() {
    3505           0 :   return TokError("unsupported directive '.stabs'");
    3506             : }
    3507             : 
    3508             : /// parseDirectiveCVFile
    3509             : /// ::= .cv_file number filename [checksum] [checksumkind]
    3510          34 : bool AsmParser::parseDirectiveCVFile() {
    3511          34 :   SMLoc FileNumberLoc = getTok().getLoc();
    3512             :   int64_t FileNumber;
    3513             :   std::string Filename;
    3514             :   std::string Checksum;
    3515          34 :   int64_t ChecksumKind = 0;
    3516             : 
    3517          68 :   if (parseIntToken(FileNumber,
    3518          33 :                     "expected file number in '.cv_file' directive") ||
    3519          99 :       check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
    3520          98 :       check(getTok().isNot(AsmToken::String),
    3521          66 :             "unexpected token in '.cv_file' directive") ||
    3522          32 :       parseEscapedString(Filename))
    3523             :     return true;
    3524          32 :   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
    3525          48 :     if (check(getTok().isNot(AsmToken::String),
    3526          14 :               "unexpected token in '.cv_file' directive") ||
    3527          28 :         parseEscapedString(Checksum) ||
    3528          30 :         parseIntToken(ChecksumKind,
    3529          30 :                       "expected checksum kind in '.cv_file' directive") ||
    3530          30 :         parseToken(AsmToken::EndOfStatement,
    3531             :                    "unexpected token in '.cv_file' directive"))
    3532             :       return true;
    3533             :   }
    3534             : 
    3535          60 :   Checksum = fromHex(Checksum);
    3536          30 :   void *CKMem = Ctx.allocate(Checksum.size(), 1);
    3537          60 :   memcpy(CKMem, Checksum.data(), Checksum.size());
    3538             :   ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
    3539             :                                     Checksum.size());
    3540             : 
    3541          60 :   if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
    3542          30 :                                          static_cast<uint8_t>(ChecksumKind)))
    3543           0 :     return Error(FileNumberLoc, "file number already allocated");
    3544             : 
    3545             :   return false;
    3546             : }
    3547             : 
    3548         192 : bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
    3549             :                                   StringRef DirectiveName) {
    3550         192 :   SMLoc Loc;
    3551         384 :   return parseTokenLoc(Loc) ||
    3552         384 :          parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
    3553         572 :                                        "' directive") ||
    3554         380 :          check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
    3555         192 :                "expected function id within range [0, UINT_MAX)");
    3556             : }
    3557             : 
    3558         107 : bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
    3559         107 :   SMLoc Loc;
    3560         214 :   return parseTokenLoc(Loc) ||
    3561         214 :          parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
    3562         214 :                                        "' directive") ||
    3563         214 :          check(FileNumber < 1, Loc, "file number less than one in '" +
    3564         427 :                                         DirectiveName + "' directive") ||
    3565         212 :          check(!getCVContext().isValidFileNumber(FileNumber), Loc,
    3566         214 :                "unassigned file number in '" + DirectiveName + "' directive");
    3567             : }
    3568             : 
    3569             : /// parseDirectiveCVFuncId
    3570             : /// ::= .cv_func_id FunctionId
    3571             : ///
    3572             : /// Introduces a function ID that can be used with .cv_loc.
    3573          35 : bool AsmParser::parseDirectiveCVFuncId() {
    3574          35 :   SMLoc FunctionIdLoc = getTok().getLoc();
    3575             :   int64_t FunctionId;
    3576             : 
    3577         102 :   if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
    3578          67 :       parseToken(AsmToken::EndOfStatement,
    3579             :                  "unexpected token in '.cv_func_id' directive"))
    3580             :     return true;
    3581             : 
    3582          32 :   if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
    3583           0 :     return Error(FunctionIdLoc, "function id already allocated");
    3584             : 
    3585             :   return false;
    3586             : }
    3587             : 
    3588             : /// parseDirectiveCVInlineSiteId
    3589             : /// ::= .cv_inline_site_id FunctionId
    3590             : ///         "within" IAFunc
    3591             : ///         "inlined_at" IAFile IALine [IACol]
    3592             : ///
    3593             : /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
    3594             : /// at" source location information for use in the line table of the caller,
    3595             : /// whether the caller is a real function or another inlined call site.
    3596          14 : bool AsmParser::parseDirectiveCVInlineSiteId() {
    3597          14 :   SMLoc FunctionIdLoc = getTok().getLoc();
    3598             :   int64_t FunctionId;
    3599             :   int64_t IAFunc;
    3600             :   int64_t IAFile;
    3601             :   int64_t IALine;
    3602             :   int64_t IACol = 0;
    3603             : 
    3604             :   // FunctionId
    3605          14 :   if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
    3606             :     return true;
    3607             : 
    3608             :   // "within"
    3609          26 :   if (check((getLexer().isNot(AsmToken::Identifier) ||
    3610          12 :              getTok().getIdentifier() != "within"),
    3611             :             "expected 'within' identifier in '.cv_inline_site_id' directive"))
    3612             :     return true;
    3613          12 :   Lex();
    3614             : 
    3615             :   // IAFunc
    3616          12 :   if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
    3617             :     return true;
    3618             : 
    3619             :   // "inlined_at"
    3620          22 :   if (check((getLexer().isNot(AsmToken::Identifier) ||
    3621          11 :              getTok().getIdentifier() != "inlined_at"),
    3622             :             "expected 'inlined_at' identifier in '.cv_inline_site_id' "
    3623             :             "directive") )
    3624             :     return true;
    3625          10 :   Lex();
    3626             : 
    3627             :   // IAFile IALine
    3628          28 :   if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
    3629          18 :       parseIntToken(IALine, "expected line number after 'inlined_at'"))
    3630             :     return true;
    3631             : 
    3632             :   // [IACol]
    3633           8 :   if (getLexer().is(AsmToken::Integer)) {
    3634           8 :     IACol = getTok().getIntVal();
    3635           8 :     Lex();
    3636             :   }
    3637             : 
    3638           8 :   if (parseToken(AsmToken::EndOfStatement,
    3639             :                  "unexpected token in '.cv_inline_site_id' directive"))
    3640             :     return true;
    3641             : 
    3642           8 :   if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
    3643           8 :                                                  IALine, IACol, FunctionIdLoc))
    3644           1 :     return Error(FunctionIdLoc, "function id already allocated");
    3645             : 
    3646             :   return false;
    3647             : }
    3648             : 
    3649             : /// parseDirectiveCVLoc
    3650             : /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
    3651             : ///                                [is_stmt VALUE]
    3652             : /// The first number is a file number, must have been previously assigned with
    3653             : /// a .file directive, the second number is the line number and optionally the
    3654             : /// third number is a column position (zero if not specified).  The remaining
    3655             : /// optional items are .loc sub-directives.
    3656          97 : bool AsmParser::parseDirectiveCVLoc() {
    3657          97 :   SMLoc DirectiveLoc = getTok().getLoc();
    3658             :   int64_t FunctionId, FileNumber;
    3659         291 :   if (parseCVFunctionId(FunctionId, ".cv_loc") ||
    3660         194 :       parseCVFileId(FileNumber, ".cv_loc"))
    3661             :     return true;
    3662             : 
    3663             :   int64_t LineNumber = 0;
    3664          97 :   if (getLexer().is(AsmToken::Integer)) {
    3665          93 :     LineNumber = getTok().getIntVal();
    3666          93 :     if (LineNumber < 0)
    3667           0 :       return TokError("line number less than zero in '.cv_loc' directive");
    3668          93 :     Lex();
    3669             :   }
    3670             : 
    3671             :   int64_t ColumnPos = 0;
    3672          97 :   if (getLexer().is(AsmToken::Integer)) {
    3673          93 :     ColumnPos = getTok().getIntVal();
    3674          93 :     if (ColumnPos < 0)
    3675           0 :       return TokError("column position less than zero in '.cv_loc' directive");
    3676          93 :     Lex();
    3677             :   }
    3678             : 
    3679          97 :   bool PrologueEnd = false;
    3680          97 :   uint64_t IsStmt = 0;
    3681             : 
    3682          24 :   auto parseOp = [&]() -> bool {
    3683          24 :     StringRef Name;
    3684          70 :     SMLoc Loc = getTok().getLoc();
    3685          24 :     if (parseIdentifier(Name))
    3686           4 :       return TokError("unexpected token in '.cv_loc' directive");
    3687             :     if (Name == "prologue_end")
    3688           0 :       PrologueEnd = true;
    3689             :     else if (Name == "is_stmt") {
    3690          22 :       Loc = getTok().getLoc();
    3691             :       const MCExpr *Value;
    3692          22 :       if (parseExpression(Value))
    3693           0 :         return true;
    3694             :       // The expression must be the constant 0 or 1.
    3695          22 :       IsStmt = ~0ULL;
    3696          22 :       if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
    3697          22 :         IsStmt = MCE->getValue();
    3698             : 
    3699          22 :       if (IsStmt > 1)
    3700           0 :         return Error(Loc, "is_stmt value not 0 or 1");
    3701             :     } else {
    3702           0 :       return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
    3703             :     }
    3704             :     return false;
    3705          97 :   };
    3706             : 
    3707          97 :   if (parseMany(parseOp, false /*hasComma*/))
    3708             :     return true;
    3709             : 
    3710          95 :   getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
    3711             :                                    ColumnPos, PrologueEnd, IsStmt, StringRef(),
    3712          95 :                                    DirectiveLoc);
    3713          95 :   return false;
    3714             : }
    3715             : 
    3716             : /// parseDirectiveCVLinetable
    3717             : /// ::= .cv_linetable FunctionId, FnStart, FnEnd
    3718          28 : bool AsmParser::parseDirectiveCVLinetable() {
    3719             :   int64_t FunctionId;
    3720          28 :   StringRef FnStartName, FnEndName;
    3721          28 :   SMLoc Loc = getTok().getLoc();
    3722          84 :   if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
    3723          56 :       parseToken(AsmToken::Comma,
    3724          27 :                  "unexpected token in '.cv_linetable' directive") ||
    3725          82 :       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
    3726          27 :                                   "expected identifier in directive") ||
    3727          55 :       parseToken(AsmToken::Comma,
    3728          27 :                  "unexpected token in '.cv_linetable' directive") ||
    3729         109 :       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
    3730             :                                   "expected identifier in directive"))
    3731             :     return true;
    3732             : 
    3733          27 :   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
    3734          27 :   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
    3735             : 
    3736          27 :   getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
    3737          27 :   return false;
    3738             : }
    3739             : 
    3740             : /// parseDirectiveCVInlineLinetable
    3741             : /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
    3742           6 : bool AsmParser::parseDirectiveCVInlineLinetable() {
    3743             :   int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
    3744           6 :   StringRef FnStartName, FnEndName;
    3745           6 :   SMLoc Loc = getTok().getLoc();
    3746          18 :   if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
    3747          12 :       parseTokenLoc(Loc) ||
    3748          12 :       parseIntToken(
    3749             :           SourceFileId,
    3750           6 :           "expected SourceField in '.cv_inline_linetable' directive") ||
    3751          12 :       check(SourceFileId <= 0, Loc,
    3752           6 :             "File id less than zero in '.cv_inline_linetable' directive") ||
    3753          12 :       parseTokenLoc(Loc) ||
    3754          12 :       parseIntToken(
    3755             :           SourceLineNum,
    3756           6 :           "expected SourceLineNum in '.cv_inline_linetable' directive") ||
    3757          12 :       check(SourceLineNum < 0, Loc,
    3758           6 :             "Line number less than zero in '.cv_inline_linetable' directive") ||
    3759          18 :       parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
    3760           6 :                                   "expected identifier in directive") ||
    3761          24 :       parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
    3762             :                                   "expected identifier in directive"))
    3763             :     return true;
    3764             : 
    3765           6 :   if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
    3766             :     return true;
    3767             : 
    3768           6 :   MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
    3769           6 :   MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
    3770           6 :   getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
    3771             :                                                SourceLineNum, FnStartSym,
    3772           6 :                                                FnEndSym);
    3773           6 :   return false;
    3774             : }
    3775             : 
    3776             : /// parseDirectiveCVDefRange
    3777             : /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
    3778           3 : bool AsmParser::parseDirectiveCVDefRange() {
    3779             :   SMLoc Loc;
    3780             :   std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
    3781          17 :   while (getLexer().is(AsmToken::Identifier)) {
    3782           7 :     Loc = getLexer().getLoc();
    3783           7 :     StringRef GapStartName;
    3784           7 :     if (parseIdentifier(GapStartName))
    3785           0 :       return Error(Loc, "expected identifier in directive");
    3786           7 :     MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
    3787             : 
    3788           7 :     Loc = getLexer().getLoc();
    3789           7 :     StringRef GapEndName;
    3790           7 :     if (parseIdentifier(GapEndName))
    3791           0 :       return Error(Loc, "expected identifier in directive");
    3792           7 :     MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
    3793             : 
    3794           7 :     Ranges.push_back({GapStartSym, GapEndSym});
    3795             :   }
    3796             : 
    3797             :   std::string FixedSizePortion;
    3798           9 :   if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
    3799           3 :       parseEscapedString(FixedSizePortion))
    3800             :     return true;
    3801             : 
    3802           6 :   getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
    3803           3 :   return false;
    3804             : }
    3805             : 
    3806             : /// parseDirectiveCVStringTable
    3807             : /// ::= .cv_stringtable
    3808             : bool AsmParser::parseDirectiveCVStringTable() {
    3809          26 :   getStreamer().EmitCVStringTableDirective();
    3810             :   return false;
    3811             : }
    3812             : 
    3813             : /// parseDirectiveCVFileChecksums
    3814             : /// ::= .cv_filechecksums
    3815             : bool AsmParser::parseDirectiveCVFileChecksums() {
    3816          22 :   getStreamer().EmitCVFileChecksumsDirective();
    3817             :   return false;
    3818             : }
    3819             : 
    3820             : /// parseDirectiveCVFileChecksumOffset
    3821             : /// ::= .cv_filechecksumoffset fileno
    3822           1 : bool AsmParser::parseDirectiveCVFileChecksumOffset() {
    3823             :   int64_t FileNo;
    3824           2 :   if (parseIntToken(FileNo, "expected identifier in directive"))
    3825             :     return true;
    3826           1 :   if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
    3827             :     return true;
    3828           1 :   getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
    3829           1 :   return false;
    3830             : }
    3831             : 
    3832             : /// parseDirectiveCVFPOData
    3833             : /// ::= .cv_fpo_data procsym
    3834          17 : bool AsmParser::parseDirectiveCVFPOData() {
    3835          17 :   SMLoc DirLoc = getLexer().getLoc();
    3836          17 :   StringRef ProcName;
    3837          17 :   if (parseIdentifier(ProcName))
    3838           4 :     return TokError("expected symbol name");
    3839          30 :   if (parseEOL("unexpected tokens"))
    3840           1 :     return addErrorSuffix(" in '.cv_fpo_data' directive");
    3841          14 :   MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
    3842          14 :   getStreamer().EmitCVFPOData(ProcSym, DirLoc);
    3843          14 :   return false;
    3844             : }
    3845             : 
    3846             : /// parseDirectiveCFISections
    3847             : /// ::= .cfi_sections section [, section]
    3848          21 : bool AsmParser::parseDirectiveCFISections() {
    3849          21 :   StringRef Name;
    3850             :   bool EH = false;
    3851             :   bool Debug = false;
    3852             : 
    3853          21 :   if (parseIdentifier(Name))
    3854           0 :     return TokError("Expected an identifier");
    3855             : 
    3856             :   if (Name == ".eh_frame")
    3857             :     EH = true;
    3858             :   else if (Name == ".debug_frame")
    3859             :     Debug = true;
    3860             : 
    3861          21 :   if (getLexer().is(AsmToken::Comma)) {
    3862           0 :     Lex();
    3863             : 
    3864           0 :     if (parseIdentifier(Name))
    3865           0 :       return TokError("Expected an identifier");
    3866             : 
    3867             :     if (Name == ".eh_frame")
    3868             :       EH = true;
    3869             :     else if (Name == ".debug_frame")
    3870             :       Debug = true;
    3871             :   }
    3872             : 
    3873          21 :   getStreamer().EmitCFISections(EH, Debug);
    3874          21 :   return false;
    3875             : }
    3876             : 
    3877             : /// parseDirectiveCFIStartProc
    3878             : /// ::= .cfi_startproc [simple]
    3879         360 : bool AsmParser::parseDirectiveCFIStartProc() {
    3880         360 :   StringRef Simple;
    3881         360 :   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
    3882          21 :     if (check(parseIdentifier(Simple) || Simple != "simple",
    3883          12 :               "unexpected token") ||
    3884          12 :         parseToken(AsmToken::EndOfStatement))
    3885           4 :       return addErrorSuffix(" in '.cfi_startproc' directive");
    3886             :   }
    3887             : 
    3888         356 :   getStreamer().EmitCFIStartProc(!Simple.empty());
    3889         356 :   return false;
    3890             : }
    3891             : 
    3892             : /// parseDirectiveCFIEndProc
    3893             : /// ::= .cfi_endproc
    3894             : bool AsmParser::parseDirectiveCFIEndProc() {
    3895         353 :   getStreamer().EmitCFIEndProc();
    3896             :   return false;
    3897             : }
    3898             : 
    3899             : /// parse register name or number.
    3900         577 : bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
    3901             :                                               SMLoc DirectiveLoc) {
    3902             :   unsigned RegNo;
    3903             : 
    3904         577 :   if (getLexer().isNot(AsmToken::Integer)) {
    3905         558 :     if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
    3906             :       return true;
    3907         545 :     Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
    3908             :   } else
    3909          19 :     return parseAbsoluteExpression(Register);
    3910             : 
    3911         545 :   return false;
    3912             : }
    3913             : 
    3914             : /// parseDirectiveCFIDefCfa
    3915             : /// ::= .cfi_def_cfa register,  offset
    3916          22 : bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
    3917          22 :   int64_t Register = 0, Offset = 0;
    3918          44 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
    3919          66 :       parseToken(AsmToken::Comma, "unexpected token in directive") ||
    3920          22 :       parseAbsoluteExpression(Offset))
    3921             :     return true;
    3922             : 
    3923          22 :   getStreamer().EmitCFIDefCfa(Register, Offset);
    3924          22 :   return false;
    3925             : }
    3926             : 
    3927             : /// parseDirectiveCFIDefCfaOffset
    3928             : /// ::= .cfi_def_cfa_offset offset
    3929         116 : bool AsmParser::parseDirectiveCFIDefCfaOffset() {
    3930         116 :   int64_t Offset = 0;
    3931         116 :   if (parseAbsoluteExpression(Offset))
    3932             :     return true;
    3933             : 
    3934         116 :   getStreamer().EmitCFIDefCfaOffset(Offset);
    3935         116 :   return false;
    3936             : }
    3937             : 
    3938             : /// parseDirectiveCFIRegister
    3939             : /// ::= .cfi_register register, register
    3940           5 : bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
    3941           5 :   int64_t Register1 = 0, Register2 = 0;
    3942          10 :   if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
    3943          15 :       parseToken(AsmToken::Comma, "unexpected token in directive") ||
    3944           5 :       parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
    3945             :     return true;
    3946             : 
    3947           5 :   getStreamer().EmitCFIRegister(Register1, Register2);
    3948           5 :   return false;
    3949             : }
    3950             : 
    3951             : /// parseDirectiveCFIWindowSave
    3952             : /// ::= .cfi_window_save
    3953             : bool AsmParser::parseDirectiveCFIWindowSave() {
    3954           4 :   getStreamer().EmitCFIWindowSave();
    3955             :   return false;
    3956             : }
    3957             : 
    3958             : /// parseDirectiveCFIAdjustCfaOffset
    3959             : /// ::= .cfi_adjust_cfa_offset adjustment
    3960           3 : bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
    3961           3 :   int64_t Adjustment = 0;
    3962           3 :   if (parseAbsoluteExpression(Adjustment))
    3963             :     return true;
    3964             : 
    3965           3 :   getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
    3966           3 :   return false;
    3967             : }
    3968             : 
    3969             : /// parseDirectiveCFIDefCfaRegister
    3970             : /// ::= .cfi_def_cfa_register register
    3971          79 : bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
    3972          79 :   int64_t Register = 0;
    3973          79 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
    3974             :     return true;
    3975             : 
    3976          79 :   getStreamer().EmitCFIDefCfaRegister(Register);
    3977          79 :   return false;
    3978             : }
    3979             : 
    3980             : /// parseDirectiveCFIOffset
    3981             : /// ::= .cfi_offset register, offset
    3982         450 : bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
    3983         450 :   int64_t Register = 0;
    3984         450 :   int64_t Offset = 0;
    3985             : 
    3986         887 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
    3987        1324 :       parseToken(AsmToken::Comma, "unexpected token in directive") ||
    3988         437 :       parseAbsoluteExpression(Offset))
    3989             :     return true;
    3990             : 
    3991         437 :   getStreamer().EmitCFIOffset(Register, Offset);
    3992         437 :   return false;
    3993             : }
    3994             : 
    3995             : /// parseDirectiveCFIRelOffset
    3996             : /// ::= .cfi_rel_offset register, offset
    3997           4 : bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
    3998           4 :   int64_t Register = 0, Offset = 0;
    3999             : 
    4000           8 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
    4001          12 :       parseToken(AsmToken::Comma, "unexpected token in directive") ||
    4002           4 :       parseAbsoluteExpression(Offset))
    4003             :     return true;
    4004             : 
    4005           4 :   getStreamer().EmitCFIRelOffset(Register, Offset);
    4006           4 :   return false;
    4007             : }
    4008             : 
    4009          55 : static bool isValidEncoding(int64_t Encoding) {
    4010          55 :   if (Encoding & ~0xff)
    4011             :     return false;
    4012             : 
    4013          55 :   if (Encoding == dwarf::DW_EH_PE_omit)
    4014             :     return true;
    4015             : 
    4016          55 :   const unsigned Format = Encoding & 0xf;
    4017          55 :   if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
    4018          43 :       Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
    4019          28 :       Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
    4020          11 :       Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
    4021             :     return false;
    4022             : 
    4023          55 :   const unsigned Application = Encoding & 0x70;
    4024         110 :   if (Application != dwarf::DW_EH_PE_absptr &&
    4025          55 :       Application != dwarf::DW_EH_PE_pcrel)
    4026             :     return false;
    4027             : 
    4028          55 :   return true;
    4029             : }
    4030             : 
    4031             : /// parseDirectiveCFIPersonalityOrLsda
    4032             : /// IsPersonality true for cfi_personality, false for cfi_lsda
    4033             : /// ::= .cfi_personality encoding, [symbol_name]
    4034             : /// ::= .cfi_lsda encoding, [symbol_name]
    4035          55 : bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
    4036          55 :   int64_t Encoding = 0;
    4037          55 :   if (parseAbsoluteExpression(Encoding))
    4038             :     return true;
    4039          55 :   if (Encoding == dwarf::DW_EH_PE_omit)
    4040             :     return false;
    4041             : 
    4042          55 :   StringRef Name;
    4043         220 :   if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
    4044         220 :       parseToken(AsmToken::Comma, "unexpected token in directive") ||
    4045         110 :       check(parseIdentifier(Name), "expected identifier in directive"))
    4046             :     return true;
    4047             : 
    4048          55 :   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
    4049             : 
    4050          55 :   if (IsPersonality)
    4051          46 :     getStreamer().EmitCFIPersonality(Sym, Encoding);
    4052             :   else
    4053           9 :     getStreamer().EmitCFILsda(Sym, Encoding);
    4054             :   return false;
    4055             : }
    4056             : 
    4057             : /// parseDirectiveCFIRememberState
    4058             : /// ::= .cfi_remember_state
    4059             : bool AsmParser::parseDirectiveCFIRememberState() {
    4060           2 :   getStreamer().EmitCFIRememberState();
    4061             :   return false;
    4062             : }
    4063             : 
    4064             : /// parseDirectiveCFIRestoreState
    4065             : /// ::= .cfi_remember_state
    4066             : bool AsmParser::parseDirectiveCFIRestoreState() {
    4067           2 :   getStreamer().EmitCFIRestoreState();
    4068             :   return false;
    4069             : }
    4070             : 
    4071             : /// parseDirectiveCFISameValue
    4072             : /// ::= .cfi_same_value register
    4073           2 : bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
    4074           2 :   int64_t Register = 0;
    4075             : 
    4076           2 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
    4077             :     return true;
    4078             : 
    4079           2 :   getStreamer().EmitCFISameValue(Register);
    4080           2 :   return false;
    4081             : }
    4082             : 
    4083             : /// parseDirectiveCFIRestore
    4084             : /// ::= .cfi_restore register
    4085           3 : bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
    4086           3 :   int64_t Register = 0;
    4087           3 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
    4088             :     return true;
    4089             : 
    4090           3 :   getStreamer().EmitCFIRestore(Register);
    4091           3 :   return false;
    4092             : }
    4093             : 
    4094             : /// parseDirectiveCFIEscape
    4095             : /// ::= .cfi_escape expression[,...]
    4096           2 : bool AsmParser::parseDirectiveCFIEscape() {
    4097             :   std::string Values;
    4098             :   int64_t CurrValue;
    4099           2 :   if (parseAbsoluteExpression(CurrValue))
    4100             :     return true;
    4101             : 
    4102           2 :   Values.push_back((uint8_t)CurrValue);
    4103             : 
    4104           8 :   while (getLexer().is(AsmToken::Comma)) {
    4105           3 :     Lex();
    4106             : 
    4107           3 :     if (parseAbsoluteExpression(CurrValue))
    4108             :       return true;
    4109             : 
    4110           3 :     Values.push_back((uint8_t)CurrValue);
    4111             :   }
    4112             : 
    4113           4 :   getStreamer().EmitCFIEscape(Values);
    4114           2 :   return false;
    4115             : }
    4116             : 
    4117             : /// parseDirectiveCFIReturnColumn
    4118             : /// ::= .cfi_return_column register
    4119           6 : bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
    4120           6 :   int64_t Register = 0;
    4121           6 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
    4122             :     return true;
    4123           6 :   getStreamer().EmitCFIReturnColumn(Register);
    4124           6 :   return false;
    4125             : }
    4126             : 
    4127             : /// parseDirectiveCFISignalFrame
    4128             : /// ::= .cfi_signal_frame
    4129           1 : bool AsmParser::parseDirectiveCFISignalFrame() {
    4130           2 :   if (parseToken(AsmToken::EndOfStatement,
    4131             :                  "unexpected token in '.cfi_signal_frame'"))
    4132             :     return true;
    4133             : 
    4134           1 :   getStreamer().EmitCFISignalFrame();
    4135           1 :   return false;
    4136             : }
    4137             : 
    4138             : /// parseDirectiveCFIUndefined
    4139             : /// ::= .cfi_undefined register
    4140           1 : bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
    4141           1 :   int64_t Register = 0;
    4142             : 
    4143           1 :   if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
    4144             :     return true;
    4145             : 
    4146           1 :   getStreamer().EmitCFIUndefined(Register);
    4147           1 :   return false;
    4148             : }
    4149             : 
    4150             : /// parseDirectiveAltmacro
    4151             : /// ::= .altmacro
    4152             : /// ::= .noaltmacro
    4153          10 : bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
    4154          10 :   if (getLexer().isNot(AsmToken::EndOfStatement))
    4155           0 :     return TokError("unexpected token in '" + Directive + "' directive");
    4156             :   if (Directive == ".altmacro")
    4157             :     getLexer().SetAltMacroMode(true);
    4158             :   else
    4159             :     getLexer().SetAltMacroMode(false);
    4160             :   return false;
    4161             : }
    4162             : 
    4163             : /// parseDirectiveMacrosOnOff
    4164             : /// ::= .macros_on
    4165             : /// ::= .macros_off
    4166           2 : bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
    4167           6 :   if (parseToken(AsmToken::EndOfStatement,
    4168           2 :                  "unexpected token in '" + Directive + "' directive"))
    4169             :     return true;
    4170             : 
    4171             :   setMacrosEnabled(Directive == ".macros_on");
    4172           2 :   return false;
    4173             : }
    4174             : 
    4175             : /// parseDirectiveMacro
    4176             : /// ::= .macro name[,] [parameters]
    4177         227 : bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
    4178         227 :   StringRef Name;
    4179         227 :   if (parseIdentifier(Name))
    4180           2 :     return TokError("expected identifier in '.macro' directive");
    4181             : 
    4182         226 :   if (getLexer().is(AsmToken::Comma))
    4183           1 :     Lex();
    4184             : 
    4185         226 :   MCAsmMacroParameters Parameters;
    4186         447 :   while (getLexer().isNot(AsmToken::EndOfStatement)) {
    4187             : 
    4188         227 :     if (!Parameters.empty() && Parameters.back().Vararg)
    4189           0 :       return Error(Lexer.getLoc(),
    4190           0 :                    "Vararg parameter '" + Parameters.back().Name +
    4191           0 :                    "' should be last one in the list of parameters.");
    4192             : 
    4193             :     MCAsmMacroParameter Parameter;
    4194         227 :     if (parseIdentifier(Parameter.Name))
    4195           4 :       return TokError("expected identifier in '.macro' directive");
    4196             : 
    4197             :     // Emit an error if two (or more) named parameters share the same name
    4198         311 :     for (const MCAsmMacroParameter& CurrParam : Parameters)
    4199             :       if (CurrParam.Name.equals(Parameter.Name))
    4200           3 :         return TokError("macro '" + Name + "' has multiple parameters"
    4201           2 :                         " named '" + Parameter.Name + "'");
    4202             : 
    4203         224 :     if (Lexer.is(AsmToken::Colon)) {
    4204          28 :       Lex();  // consume ':'
    4205             : 
    4206             :       SMLoc QualLoc;
    4207          28 :       StringRef Qualifier;
    4208             : 
    4209          28 :       QualLoc = Lexer.getLoc();
    4210          28 :       if (parseIdentifier(Qualifier))
    4211           4 :         return Error(QualLoc, "missing parameter qualifier for "
    4212           2 :                      "'" + Parameter.Name + "' in macro '" + Name + "'");
    4213             : 
    4214             :       if (Qualifier == "req")
    4215           7 :         Parameter.Required = true;
    4216             :       else if (Qualifier == "vararg")
    4217          18 :         Parameter.Vararg = true;
    4218             :       else
    4219           3 :         return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
    4220           2 :                      "for '" + Parameter.Name + "' in macro '" + Name + "'");
    4221             :     }
    4222             : 
    4223         221 :     if (getLexer().is(AsmToken::Equal)) {
    4224          21 :       Lex();
    4225             : 
    4226             :       SMLoc ParamLoc;
    4227             : 
    4228          21 :       ParamLoc = Lexer.getLoc();
    4229          21 :       if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
    4230           0 :         return true;
    4231             : 
    4232          21 :       if (Parameter.Required)
    4233           4 :         Warning(ParamLoc, "pointless default value for required parameter "
    4234           2 :                 "'" + Parameter.Name + "' in macro '" + Name + "'");
    4235             :     }
    4236             : 
    4237             :     Parameters.push_back(std::move(Parameter));
    4238             : 
    4239         221 :     if (getLexer().is(AsmToken::Comma))
    4240          33 :       Lex();
    4241             :   }
    4242             : 
    4243             :   // Eat just the end of statement.
    4244         220 :   Lexer.Lex();
    4245             : 
    4246             :   // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
    4247         220 :   AsmToken EndToken, StartToken = getTok();
    4248             :   unsigned MacroDepth = 0;
    4249             :   // Lex the macro definition.
    4250         552 :   while (true) {
    4251             :     // Ignore Lexing errors in macros.
    4252         772 :     while (Lexer.is(AsmToken::Error)) {
    4253           0 :       Lexer.Lex();
    4254             :     }
    4255             : 
    4256             :     // Check whether we have reached the end of the file.
    4257         772 :     if (getLexer().is(AsmToken::Eof))
    4258           1 :       return Error(DirectiveLoc, "no matching '.endmacro' in definition");
    4259             : 
    4260             :     // Otherwise, check whether we have reach the .endmacro.
    4261         771 :     if (getLexer().is(AsmToken::Identifier)) {
    4262         731 :       if (getTok().getIdentifier() == ".endm" ||
    4263         527 :           getTok().getIdentifier() == ".endmacro") {
    4264         222 :         if (MacroDepth == 0) { // Outermost macro.
    4265         219 :           EndToken = getTok();
    4266         219 :           Lexer.Lex();
    4267         219 :           if (getLexer().isNot(AsmToken::EndOfStatement))
    4268           0 :             return TokError("unexpected token in '" + EndToken.getIdentifier() +
    4269           0 :                             "' directive");
    4270             :           break;
    4271             :         } else {
    4272             :           // Otherwise we just found the end of an inner macro.
    4273           3 :           --MacroDepth;
    4274             :         }
    4275         509 :       } else if (getTok().getIdentifier() == ".macro") {
    4276             :         // We allow nested macros. Those aren't instantiated until the outermost
    4277             :         // macro is expanded so just ignore them for now.
    4278           3 :         ++MacroDepth;
    4279             :       }
    4280             :     }
    4281             : 
    4282             :     // Otherwise, scan til the end of the statement.
    4283         552 :     eatToEndOfStatement();
    4284             :   }
    4285             : 
    4286           2 :   if (getContext().lookupMacro(Name)) {
    4287           2 :     return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
    4288             :   }
    4289             : 
    4290         434 :   const char *BodyStart = StartToken.getLoc().getPointer();
    4291         434 :   const char *BodyEnd = EndToken.getLoc().getPointer();
    4292         217 :   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
    4293         217 :   checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
    4294         217 :   MCAsmMacro Macro(Name, Body, std::move(Parameters));
    4295             :   DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
    4296             :                   Macro.dump());
    4297         434 :   getContext().defineMacro(Name, std::move(Macro));
    4298             :   return false;
    4299             : }
    4300             : 
    4301             : /// checkForBadMacro
    4302             : ///
    4303             : /// With the support added for named parameters there may be code out there that
    4304             : /// is transitioning from positional parameters.  In versions of gas that did
    4305             : /// not support named parameters they would be ignored on the macro definition.
    4306             : /// But to support both styles of parameters this is not possible so if a macro
    4307             : /// definition has named parameters but does not use them and has what appears
    4308             : /// to be positional parameters, strings like $1, $2, ... and $n, then issue a
    4309             : /// warning that the positional parameter found in body which have no effect.
    4310             : /// Hoping the developer will either remove the named parameters from the macro
    4311             : /// definition so the positional parameters get used if that was what was
    4312             : /// intended or change the macro to use the named parameters.  It is possible
    4313             : /// this warning will trigger when the none of the named parameters are used
    4314             : /// and the strings like $1 are infact to simply to be passed trough unchanged.
    4315         217 : void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
    4316             :                                  StringRef Body,
    4317             :                                  ArrayRef<MCAsmMacroParameter> Parameters) {
    4318             :   // If this macro is not defined with named parameters the warning we are
    4319             :   // checking for here doesn't apply.
    4320         217 :   unsigned NParameters = Parameters.size();
    4321         217 :   if (NParameters == 0)
    4322             :     return;
    4323             : 
    4324             :   bool NamedParametersFound = false;
    4325             :   bool PositionalParametersFound = false;
    4326             : 
    4327             :   // Look at the body of the macro for use of both the named parameters and what
    4328             :   // are likely to be positional parameters.  This is what expandMacro() is
    4329             :   // doing when it finds the parameters in the body.
    4330         633 :   while (!Body.empty()) {
    4331             :     // Scan for the next possible parameter.
    4332             :     std::size_t End = Body.size(), Pos = 0;
    4333       13208 :     for (; Pos != End; ++Pos) {
    4334             :       // Check for a substitution or escape.
    4335             :       // This macro is defined with parameters, look for \foo, \bar, etc.
    4336       13524 :       if (Body[Pos] == '\\' && Pos + 1 != End)
    4337             :         break;
    4338             : 
    4339             :       // This macro should have parameters, but look for $0, $1, ..., $n too.
    4340       12572 :       if (Body[Pos] != '$' || Pos + 1 == End)
    4341             :         continue;
    4342             :       char Next = Body[Pos + 1];
    4343          32 :       if (Next == '$' || Next == 'n' ||
    4344          16 :           isdigit(static_cast<unsigned char>(Next)))
    4345             :         break;
    4346             :     }
    4347             : 
    4348             :     // Check if we reached the end.
    4349         628 :     if (Pos == End)
    4350             :       break;
    4351             : 
    4352         944 :     if (Body[Pos] == '$') {
    4353           8 :       switch (Body[Pos + 1]) {
    4354             :       // $$ => $
    4355             :       case '$':
    4356             :         break;
    4357             : 
    4358             :       // $n => number of arguments
    4359           0 :       case 'n':
    4360             :         PositionalParametersFound = true;
    4361             :         break;
    4362             : 
    4363             :       // $[0-9] => argument
    4364           4 :       default: {
    4365             :         PositionalParametersFound = true;
    4366             :         break;
    4367             :       }
    4368             :       }
    4369           4 :       Pos += 2;
    4370             :     } else {
    4371         468 :       unsigned I = Pos + 1;
    4372        3100 :       while (isIdentifierChar(Body[I]) && I + 1 != End)
    4373             :         ++I;
    4374             : 
    4375         468 :       const char *Begin = Body.data() + Pos + 1;
    4376         468 :       StringRef Argument(Begin, I - (Pos + 1));
    4377             :       unsigned Index = 0;
    4378         776 :       for (; Index < NParameters; ++Index)
    4379         582 :         if (Parameters[Index].Name == Argument)
    4380             :           break;
    4381             : 
    4382         468 :       if (Index == NParameters) {
    4383          76 :         if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
    4384          36 :           Pos += 3;
    4385             :         else {
    4386             :           Pos = I;
    4387             :         }
    4388             :       } else {
    4389             :         NamedParametersFound = true;
    4390             :         Pos += 1 + Argument.size();
    4391             :       }
    4392             :     }
    4393             :     // Update the scan point.
    4394         472 :     Body = Body.substr(Pos);
    4395             :   }
    4396             : 
    4397         161 :   if (!NamedParametersFound && PositionalParametersFound)
    4398           1 :     Warning(DirectiveLoc, "macro defined with named parameters which are not "
    4399             :                           "used in macro body, possible positional parameter "
    4400             :                           "found in body which will have no effect");
    4401             : }
    4402             : 
    4403             : /// parseDirectiveExitMacro
    4404             : /// ::= .exitm
    4405           3 : bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
    4406           9 :   if (parseToken(AsmToken::EndOfStatement,
    4407           3 :                  "unexpected token in '" + Directive + "' directive"))
    4408             :     return true;
    4409             : 
    4410           3 :   if (!isInsideMacroInstantiation())
    4411           0 :     return TokError("unexpected '" + Directive + "' in file, "
    4412           0 :                                                  "no current macro definition");
    4413             : 
    4414             :   // Exit all conditionals that are active in the current macro.
    4415           8 :   while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
    4416           1 :     TheCondState = TheCondStack.back();
    4417             :     TheCondStack.pop_back();
    4418             :   }
    4419             : 
    4420           3 :   handleMacroExit();
    4421           3 :   return false;
    4422             : }
    4423             : 
    4424             : /// parseDirectiveEndMacro
    4425             : /// ::= .endm
    4426             : /// ::= .endmacro
    4427      164884 : bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
    4428      164884 :   if (getLexer().isNot(AsmToken::EndOfStatement))
    4429           0 :     return TokError("unexpected token in '" + Directive + "' directive");
    4430             : 
    4431             :   // If we are inside a macro instantiation, terminate the current
    4432             :   // instantiation.
    4433      164884 :   if (isInsideMacroInstantiation()) {
    4434      164881 :     handleMacroExit();
    4435      164881 :     return false;
    4436             :   }
    4437             : 
    4438             :   // Otherwise, this .endmacro is a stray entry in the file; well formed
    4439             :   // .endmacro directives are handled during the macro definition parsing.
    4440           9 :   return TokError("unexpected '" + Directive + "' in file, "
    4441           6 :                                                "no current macro definition");
    4442             : }
    4443             : 
    4444             : /// parseDirectivePurgeMacro
    4445             : /// ::= .purgem
    4446           5 : bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
    4447           5 :   StringRef Name;
    4448           5 :   SMLoc Loc;
    4449          10 :   if (parseTokenLoc(Loc) ||
    4450          10 :       check(parseIdentifier(Name), Loc,
    4451          10 :             "expected identifier in '.purgem' directive") ||
    4452          10 :       parseToken(AsmToken::EndOfStatement,
    4453             :                  "unexpected token in '.purgem' directive"))
    4454             :     return true;
    4455             : 
    4456           4 :   if (!getContext().lookupMacro(Name))
    4457           1 :     return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
    4458             : 
    4459             :   getContext().undefineMacro(Name);
    4460             :   DEBUG_WITH_TYPE("asm-macros", dbgs()
    4461             :                                     << "Un-defining macro: " << Name << "\n");
    4462           4 :   return false;
    4463             : }
    4464             : 
    4465             : /// parseDirectiveBundleAlignMode
    4466             : /// ::= {.bundle_align_mode} expression
    4467          43 : bool AsmParser::parseDirectiveBundleAlignMode() {
    4468             :   // Expect a single argument: an expression that evaluates to a constant
    4469             :   // in the inclusive range 0-30.
    4470          43 :   SMLoc ExprLoc = getLexer().getLoc();
    4471             :   int64_t AlignSizePow2;
    4472         128 :   if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
    4473         127 :       parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
    4474             :                                            "in '.bundle_align_mode' "
    4475          85 :                                            "directive") ||
    4476          85 :       check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
    4477             :             "invalid bundle alignment size (expected between 0 and 30)"))
    4478             :     return true;
    4479             : 
    4480             :   // Because of AlignSizePow2's verified range we can safely truncate it to
    4481             :   // unsigned.
    4482          42 :   getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
    4483          42 :   return false;
    4484             : }
    4485             : 
    4486             : /// parseDirectiveBundleLock
    4487             : /// ::= {.bundle_lock} [align_to_end]
    4488         573 : bool AsmParser::parseDirectiveBundleLock() {
    4489         573 :   if (checkForValidSection())
    4490             :     return true;
    4491             :   bool AlignToEnd = false;
    4492             : 
    4493         573 :   StringRef Option;
    4494         573 :   SMLoc Loc = getTok().getLoc();
    4495             :   const char *kInvalidOptionError =
    4496             :       "invalid option for '.bundle_lock' directive";
    4497             : 
    4498         573 :   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
    4499         857 :     if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
    4500        1142 :         check(Option != "align_to_end", Loc, kInvalidOptionError) ||
    4501         571 :         parseToken(AsmToken::EndOfStatement,
    4502             :                    "unexpected token after '.bundle_lock' directive option"))
    4503             :       return true;
    4504             :     AlignToEnd = true;
    4505             :   }
    4506             : 
    4507         570 :   getStreamer().EmitBundleLock(AlignToEnd);
    4508         569 :   return false;
    4509             : }
    4510             : 
    4511             : /// parseDirectiveBundleLock
    4512             : /// ::= {.bundle_lock}
    4513         565 : bool AsmParser::parseDirectiveBundleUnlock() {
    4514        1130 :   if (checkForValidSection() ||
    4515        1130 :       parseToken(AsmToken::EndOfStatement,
    4516             :                  "unexpected token in '.bundle_unlock' directive"))
    4517             :     return true;
    4518             : 
    4519         565 :   getStreamer().EmitBundleUnlock();
    4520         562 :   return false;
    4521             : }
    4522             : 
    4523             : /// parseDirectiveSpace
    4524             : /// ::= (.skip | .space) expression [ , expression ]
    4525         362 : bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
    4526         362 :   SMLoc NumBytesLoc = Lexer.getLoc();
    4527             :   const MCExpr *NumBytes;
    4528         724 :   if (checkForValidSection() || parseExpression(NumBytes))
    4529             :     return true;
    4530             : 
    4531         362 :   int64_t FillExpr = 0;
    4532         362 :   if (parseOptionalToken(AsmToken::Comma))
    4533          22 :     if (parseAbsoluteExpression(FillExpr))
    4534           0 :       return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
    4535         362 :   if (parseToken(AsmToken::EndOfStatement))
    4536           0 :     return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
    4537             : 
    4538             :   // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
    4539         362 :   getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
    4540             : 
    4541         362 :   return false;
    4542             : }
    4543             : 
    4544             : /// parseDirectiveDCB
    4545             : /// ::= .dcb.{b, l, w} expression, expression
    4546          14 : bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
    4547          14 :   SMLoc NumValuesLoc = Lexer.getLoc();
    4548             :   int64_t NumValues;
    4549          14 :   if (checkForValidSection() || parseAbsoluteExpression(NumValues))
    4550             :     return true;
    4551             : 
    4552          14 :   if (NumValues < 0) {
    4553           2 :     Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
    4554           2 :     return false;
    4555             :   }
    4556             : 
    4557          36 :   if (parseToken(AsmToken::Comma,
    4558          12 :                  "unexpected token in '" + Twine(IDVal) + "' directive"))
    4559             :     return true;
    4560             : 
    4561             :   const MCExpr *Value;
    4562          10 :   SMLoc ExprLoc = getLexer().getLoc();
    4563          10 :   if (parseExpression(Value))
    4564             :     return true;
    4565             : 
    4566             :   // Special case constant expressions to match code generator.
    4567          10 :   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
    4568             :     assert(Size <= 8 && "Invalid size");
    4569          10 :     uint64_t IntValue = MCE->getValue();
    4570          10 :     if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
    4571           0 :       return Error(ExprLoc, "literal value out of range for directive");
    4572          56 :     for (uint64_t i = 0, e = NumValues; i != e; ++i)
    4573          18 :       getStreamer().EmitIntValue(IntValue, Size);
    4574             :   } else {
    4575           0 :     for (uint64_t i = 0, e = NumValues; i != e; ++i)
    4576           0 :       getStreamer().EmitValue(Value, Size, ExprLoc);
    4577             :   }
    4578             : 
    4579          20 :   if (parseToken(AsmToken::EndOfStatement,
    4580          10 :                  "unexpected token in '" + Twine(IDVal) + "' directive"))
    4581             :     return true;
    4582             : 
    4583           8 :   return false;
    4584             : }
    4585             : 
    4586             : /// parseDirectiveRealDCB
    4587             : /// ::= .dcb.{d, s} expression, expression
    4588           4 : bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
    4589           4 :   SMLoc NumValuesLoc = Lexer.getLoc();
    4590             :   int64_t NumValues;
    4591           4 :   if (checkForValidSection() || parseAbsoluteExpression(NumValues))
    4592             :     return true;
    4593             : 
    4594           4 :   if (NumValues < 0) {
    4595           0 :     Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
    4596           0 :     return false;
    4597             :   }
    4598             : 
    4599          12 :   if (parseToken(AsmToken::Comma,
    4600           4 :                  "unexpected token in '" + Twine(IDVal) + "' directive"))
    4601             :     return true;
    4602             : 
    4603             :   APInt AsInt;
    4604           4 :   if (parseRealValue(Semantics, AsInt))
    4605             :     return true;
    4606             : 
    4607           8 :   if (parseToken(AsmToken::EndOfStatement,
    4608           4 :                  "unexpected token in '" + Twine(IDVal) + "' directive"))
    4609             :     return true;
    4610             : 
    4611          22 :   for (uint64_t i = 0, e = NumValues; i != e; ++i)
    4612          36 :     getStreamer().EmitIntValue(AsInt.getLimitedValue(),
    4613          18 :                                AsInt.getBitWidth() / 8);
    4614             : 
    4615             :   return false;
    4616             : }
    4617             : 
    4618             : /// parseDirectiveDS
    4619             : /// ::= .ds.{b, d, l, p, s, w, x} expression
    4620          20 : bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
    4621          20 :   SMLoc NumValuesLoc = Lexer.getLoc();
    4622             :   int64_t NumValues;
    4623          20 :   if (checkForValidSection() || parseAbsoluteExpression(NumValues))
    4624             :     return true;
    4625             : 
    4626          20 :   if (NumValues < 0) {
    4627           2 :     Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
    4628           2 :     return false;
    4629             :   }
    4630             : 
    4631          54 :   if (parseToken(AsmToken::EndOfStatement,
    4632          18 :                  "unexpected token in '" + Twine(IDVal) + "' directive"))
    4633             :     return true;
    4634             : 
    4635          48 :   for (uint64_t i = 0, e = NumValues; i != e; ++i)
    4636          32 :     getStreamer().emitFill(Size, 0);
    4637             : 
    4638             :   return false;
    4639             : }
    4640             : 
    4641             : /// parseDirectiveLEB128
    4642             : /// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
    4643         305 : bool AsmParser::parseDirectiveLEB128(bool Signed) {
    4644         305 :   if (checkForValidSection())
    4645             :     return true;
    4646             : 
    4647         305 :   auto parseOp = [&]() -> bool {
    4648             :     const MCExpr *Value;
    4649         911 :     if (parseExpression(Value))
    4650             :       return true;
    4651         301 :     if (Signed)
    4652          61 :       getStreamer().EmitSLEB128Value(Value);
    4653             :     else
    4654         240 :       getStreamer().EmitULEB128Value(Value);
    4655             :     return false;
    4656         305 :   };
    4657             : 
    4658         610 :   if (parseMany(parseOp))
    4659           8 :     return addErrorSuffix(" in directive");
    4660             : 
    4661             :   return false;
    4662             : }
    4663             : 
    4664             : /// parseDirectiveSymbolAttribute
    4665             : ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
    4666       13895 : bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
    4667       14017 :   auto parseOp = [&]() -> bool {
    4668       14017 :     StringRef Name;
    4669       42051 :     SMLoc Loc = getTok().getLoc();
    4670       14017 :     if (parseIdentifier(Name))
    4671           0 :       return Error(Loc, "expected identifier");
    4672       14017 :     MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
    4673             : 
    4674             :     // Assembler local symbols don't make any sense here. Complain loudly.
    4675       14017 :     if (Sym->isTemporary())
    4676           0 :       return Error(Loc, "non-local symbol required");
    4677             : 
    4678       14017 :     if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
    4679           0 :       return Error(Loc, "unable to emit symbol attribute");
    4680             :     return false;
    4681       13895 :   };
    4682             : 
    4683       27790 :   if (parseMany(parseOp))
    4684          18 :     return addErrorSuffix(" in directive");
    4685             :   return false;
    4686             : }
    4687             : 
    4688             : /// parseDirectiveComm
    4689             : ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
    4690         199 : bool AsmParser::parseDirectiveComm(bool IsLocal) {
    4691         199 :   if (checkForValidSection())
    4692             :     return true;
    4693             : 
    4694         199 :   SMLoc IDLoc = getLexer().getLoc();
    4695         199 :   StringRef Name;
    4696         199 :   if (parseIdentifier(Name))
    4697           0 :     return TokError("expected identifier in directive");
    4698             : 
    4699             :   // Handle the identifier as the key symbol.
    4700         199 :   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
    4701             : 
    4702         199 :   if (getLexer().isNot(AsmToken::Comma))
    4703           0 :     return TokError("unexpected token in directive");
    4704         199 :   Lex();
    4705             : 
    4706             :   int64_t Size;
    4707         199 :   SMLoc SizeLoc = getLexer().getLoc();
    4708         199 :   if (parseAbsoluteExpression(Size))
    4709             :     return true;
    4710             : 
    4711         199 :   int64_t Pow2Alignment = 0;
    4712         199 :   SMLoc Pow2AlignmentLoc;
    4713         199 :   if (getLexer().is(AsmToken::Comma)) {
    4714         169 :     Lex();
    4715         169 :     Pow2AlignmentLoc = getLexer().getLoc();
    4716         169 :     if (parseAbsoluteExpression(Pow2Alignment))
    4717             :       return true;
    4718             : 
    4719         169 :     LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
    4720         169 :     if (IsLocal && LCOMM == LCOMM::NoAlignment)
    4721           2 :       return Error(Pow2AlignmentLoc, "alignment not supported on this target");
    4722             : 
    4723             :     // If this target takes alignments in bytes (not log) validate and convert.
    4724         211 :     if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
    4725          43 :         (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
    4726         129 :       if (!isPowerOf2_64(Pow2Alignment))
    4727           0 :         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
    4728         129 :       Pow2Alignment = Log2_64(Pow2Alignment);
    4729             :     }
    4730             :   }
    4731             : 
    4732         396 :   if (parseToken(AsmToken::EndOfStatement,
    4733             :                  "unexpected token in '.comm' or '.lcomm' directive"))
    4734             :     return true;
    4735             : 
    4736             :   // NOTE: a size of zero for a .comm should create a undefined symbol
    4737             :   // but a size of .lcomm creates a bss symbol of size zero.
    4738         198 :   if (Size < 0)
    4739           0 :     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
    4740           0 :                           "be less than zero");
    4741             : 
    4742             :   // NOTE: The alignment in the directive is a power of 2 value, the assembler
    4743             :   // may internally end up wanting an alignment in bytes.
    4744             :   // FIXME: Diagnose overflow.
    4745         198 :   if (Pow2Alignment < 0)
    4746           0 :     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
    4747           0 :                                    "alignment, can't be less than zero");
    4748             : 
    4749             :   Sym->redefineIfPossible();
    4750         198 :   if (!Sym->isUndefined())
    4751           0 :     return Error(IDLoc, "invalid symbol redefinition");
    4752             : 
    4753             :   // Create the Symbol as a common or local common with Size and Pow2Alignment
    4754         198 :   if (IsLocal) {
    4755          22 :     getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
    4756          22 :     return false;
    4757             :   }
    4758             : 
    4759         176 :   getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
    4760         175 :   return false;
    4761             : }
    4762             : 
    4763             : /// parseDirectiveAbort
    4764             : ///  ::= .abort [... message ...]
    4765           1 : bool AsmParser::parseDirectiveAbort() {
    4766             :   // FIXME: Use loc from directive.
    4767           1 :   SMLoc Loc = getLexer().getLoc();
    4768             : 
    4769           1 :   StringRef Str = parseStringToEndOfStatement();
    4770           2 :   if (parseToken(AsmToken::EndOfStatement,
    4771             :                  "unexpected token in '.abort' directive"))
    4772             :     return true;
    4773             : 
    4774           1 :   if (Str.empty())
    4775           0 :     return Error(Loc, ".abort detected. Assembly stopping.");
    4776             :   else
    4777           1 :     return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
    4778             :   // FIXME: Actually abort assembly here.
    4779             : 
    4780             :   return false;
    4781             : }
    4782             : 
    4783             : /// parseDirectiveInclude
    4784             : ///  ::= .include "filename"
    4785           4 : bool AsmParser::parseDirectiveInclude() {
    4786             :   // Allow the strings to have escaped octal character sequence.
    4787             :   std::string Filename;
    4788           4 :   SMLoc IncludeLoc = getTok().getLoc();
    4789             : 
    4790          12 :   if (check(getTok().isNot(AsmToken::String),
    4791           4 :             "expected string in '.include' directive") ||
    4792           8 :       parseEscapedString(Filename) ||
    4793          12 :       check(getTok().isNot(AsmToken::EndOfStatement),
    4794           8 :             "unexpected token in '.include' directive") ||
    4795             :       // Attempt to switch the lexer to the included file before consuming the
    4796             :       // end of statement to avoid losing it when we switch.
    4797           8 :       check(enterIncludeFile(Filename), IncludeLoc,
    4798          16 :             "Could not find include file '" + Filename + "'"))
    4799             :     return true;
    4800             : 
    4801           4 :   return false;
    4802             : }
    4803             : 
    4804             : /// parseDirectiveIncbin
    4805             : ///  ::= .incbin "filename" [ , skip [ , count ] ]
    4806          22 : bool AsmParser::parseDirectiveIncbin() {
    4807             :   // Allow the strings to have escaped octal character sequence.
    4808             :   std::string Filename;
    4809          22 :   SMLoc IncbinLoc = getTok().getLoc();
    4810          46 :   if (check(getTok().isNot(AsmToken::String),
    4811          42 :             "expected string in '.incbin' directive") ||
    4812          20 :       parseEscapedString(Filename))
    4813             :     return true;
    4814             : 
    4815          20 :   int64_t Skip = 0;
    4816          20 :   const MCExpr *Count = nullptr;
    4817          20 :   SMLoc SkipLoc, CountLoc;
    4818          20 :   if (parseOptionalToken(AsmToken::Comma)) {
    4819             :     // The skip expression can be omitted while specifying the count, e.g:
    4820             :     //  .incbin "filename",,4
    4821          12 :     if (getTok().isNot(AsmToken::Comma)) {
    4822           8 :       if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
    4823             :         return true;
    4824             :     }
    4825          12 :     if (parseOptionalToken(AsmToken::Comma)) {
    4826           6 :       CountLoc = getTok().getLoc();
    4827           6 :       if (parseExpression(Count))
    4828             :         return true;
    4829             :     }
    4830             :   }
    4831             : 
    4832          20 :   if (parseToken(AsmToken::EndOfStatement,
    4833             :                  "unexpected token in '.incbin' directive"))
    4834             :     return true;
    4835             : 
    4836          16 :   if (check(Skip < 0, SkipLoc, "skip is negative"))
    4837             :     return true;
    4838             : 
    4839             :   // Attempt to process the included file.
    4840          14 :   if (processIncbinFile(Filename, Skip, Count, CountLoc))
    4841           0 :     return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
    4842             :   return false;
    4843             : }
    4844             : 
    4845             : /// parseDirectiveIf
    4846             : /// ::= .if{,eq,ge,gt,le,lt,ne} expression
    4847         136 : bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
    4848         136 :   TheCondStack.push_back(TheCondState);
    4849         136 :   TheCondState.TheCond = AsmCond::IfCond;
    4850         136 :   if (TheCondState.Ignore) {
    4851           0 :     eatToEndOfStatement();
    4852             :   } else {
    4853             :     int64_t ExprValue;
    4854         262 :     if (parseAbsoluteExpression(ExprValue) ||
    4855         388 :         parseToken(AsmToken::EndOfStatement,
    4856             :                    "unexpected token in '.if' directive"))
    4857          11 :       return true;
    4858             : 
    4859         125 :     switch (DirKind) {
    4860           0 :     default:
    4861           0 :       llvm_unreachable("unsupported directive");
    4862             :     case DK_IF:
    4863             :     case DK_IFNE:
    4864             :       break;
    4865           1 :     case DK_IFEQ:
    4866           1 :       ExprValue = ExprValue == 0;
    4867             :       break;
    4868           3 :     case DK_IFGE:
    4869           3 :       ExprValue = ExprValue >= 0;
    4870             :       break;
    4871           3 :     case DK_IFGT:
    4872           3 :       ExprValue = ExprValue > 0;
    4873             :       break;
    4874           3 :     case DK_IFLE:
    4875           3 :       ExprValue = ExprValue <= 0;
    4876             :       break;
    4877           3 :     case DK_IFLT:
    4878           3 :       ExprValue = ExprValue < 0;
    4879             :       break;
    4880             :     }
    4881             : 
    4882         125 :     TheCondState.CondMet = ExprValue;
    4883         125 :     TheCondState.Ignore = !TheCondState.CondMet;
    4884             :   }
    4885             : 
    4886             :   return false;
    4887             : }
    4888             : 
    4889             : /// parseDirectiveIfb
    4890             : /// ::= .ifb string
    4891          67 : bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
    4892          67 :   TheCondStack.push_back(TheCondState);
    4893          67 :   TheCondState.TheCond = AsmCond::IfCond;
    4894             : 
    4895          67 :   if (TheCondState.Ignore) {
    4896           0 :     eatToEndOfStatement();
    4897             :   } else {
    4898          67 :     StringRef Str = parseStringToEndOfStatement();
    4899             : 
    4900         134 :     if (parseToken(AsmToken::EndOfStatement,
    4901             :                    "unexpected token in '.ifb' directive"))
    4902           0 :       return true;
    4903             : 
    4904          67 :     TheCondState.CondMet = ExpectBlank == Str.empty();
    4905          67 :     TheCondState.Ignore = !TheCondState.CondMet;
    4906             :   }
    4907             : 
    4908             :   return false;
    4909             : }
    4910             : 
    4911             : /// parseDirectiveIfc
    4912             : /// ::= .ifc string1, string2
    4913             : /// ::= .ifnc string1, string2
    4914          15 : bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
    4915          15 :   TheCondStack.push_back(TheCondState);
    4916          15 :   TheCondState.TheCond = AsmCond::IfCond;
    4917             : 
    4918          15 :   if (TheCondState.Ignore) {
    4919           0 :     eatToEndOfStatement();
    4920             :   } else {
    4921          15 :     StringRef Str1 = parseStringToComma();
    4922             : 
    4923          30 :     if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
    4924           0 :       return true;
    4925             : 
    4926          15 :     StringRef Str2 = parseStringToEndOfStatement();
    4927             : 
    4928          15 :     if (parseToken(AsmToken::EndOfStatement,
    4929             :                    "unexpected token in '.ifc' directive"))
    4930             :       return true;
    4931             : 
    4932          15 :     TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
    4933          15 :     TheCondState.Ignore = !TheCondState.CondMet;
    4934             :   }
    4935             : 
    4936             :   return false;
    4937             : }
    4938             : 
    4939             : /// parseDirectiveIfeqs
    4940             : ///   ::= .ifeqs string1, string2
    4941          13 : bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
    4942          13 :   if (Lexer.isNot(AsmToken::String)) {
    4943           2 :     if (ExpectEqual)
    4944           2 :       return TokError("expected string parameter for '.ifeqs' directive");
    4945           2 :     return TokError("expected string parameter for '.ifnes' directive");
    4946             :   }
    4947             : 
    4948          11 :   StringRef String1 = getTok().getStringContents();
    4949          11 :   Lex();
    4950             : 
    4951          11 :   if (Lexer.isNot(AsmToken::Comma)) {
    4952           2 :     if (ExpectEqual)
    4953           1 :       return TokError(
    4954           1 :           "expected comma after first string for '.ifeqs' directive");
    4955           1 :     return TokError("expected comma after first string for '.ifnes' directive");
    4956             :   }
    4957             : 
    4958           9 :   Lex();
    4959             : 
    4960           9 :   if (Lexer.isNot(AsmToken::String)) {
    4961           2 :     if (ExpectEqual)
    4962           1 :       return TokError("expected string parameter for '.ifeqs' directive");
    4963           1 :     return TokError("expected string parameter for '.ifnes' directive");
    4964             :   }
    4965             : 
    4966           7 :   StringRef String2 = getTok().getStringContents();
    4967           7 :   Lex();
    4968             : 
    4969           7 :   TheCondStack.push_back(TheCondState);
    4970           7 :   TheCondState.TheCond = AsmCond::IfCond;
    4971           7 :   TheCondState.CondMet = ExpectEqual == (String1 == String2);
    4972           7 :   TheCondState.Ignore = !TheCondState.CondMet;
    4973             : 
    4974           7 :   return false;
    4975             : }
    4976             : 
    4977             : /// parseDirectiveIfdef
    4978             : /// ::= .ifdef symbol
    4979          13 : bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
    4980          13 :   StringRef Name;
    4981          13 :   TheCondStack.push_back(TheCondState);
    4982          13 :   TheCondState.TheCond = AsmCond::IfCond;
    4983             : 
    4984          13 :   if (TheCondState.Ignore) {
    4985           0 :     eatToEndOfStatement();
    4986             :   } else {
    4987          52 :     if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
    4988          26 :         parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
    4989             :       return true;
    4990             : 
    4991          13 :     MCSymbol *Sym = getContext().lookupSymbol(Name);
    4992             : 
    4993          13 :     if (expect_defined)
    4994          11 :       TheCondState.CondMet = (Sym && !Sym->isUndefined());
    4995             :     else
    4996          10 :       TheCondState.CondMet = (!Sym || Sym->isUndefined());
    4997          13 :     TheCondState.Ignore = !TheCondState.CondMet;
    4998             :   }
    4999             : 
    5000             :   return false;
    5001             : }
    5002             : 
    5003             : /// parseDirectiveElseIf
    5004             : /// ::= .elseif expression
    5005           1 : bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
    5006           1 :   if (TheCondState.TheCond != AsmCond::IfCond &&
    5007             :       TheCondState.TheCond != AsmCond::ElseIfCond)
    5008           0 :     return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
    5009           0 :                                " .if or  an .elseif");
    5010           1 :   TheCondState.TheCond = AsmCond::ElseIfCond;
    5011             : 
    5012             :   bool LastIgnoreState = false;
    5013           1 :   if (!TheCondStack.empty())
    5014           1 :     LastIgnoreState = TheCondStack.back().Ignore;
    5015           1 :   if (LastIgnoreState || TheCondState.CondMet) {
    5016           0 :     TheCondState.Ignore = true;
    5017           0 :     eatToEndOfStatement();
    5018             :   } else {
    5019             :     int64_t ExprValue;
    5020           1 :     if (parseAbsoluteExpression(ExprValue))
    5021           0 :       return true;
    5022             : 
    5023           2 :     if (parseToken(AsmToken::EndOfStatement,
    5024             :                    "unexpected token in '.elseif' directive"))
    5025             :       return true;
    5026             : 
    5027           1 :     TheCondState.CondMet = ExprValue;
    5028           1 :     TheCondState.Ignore = !TheCondState.CondMet;
    5029             :   }
    5030             : 
    5031             :   return false;
    5032             : }
    5033             : 
    5034             : /// parseDirectiveElse
    5035             : /// ::= .else
    5036         127 : bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
    5037         254 :   if (parseToken(AsmToken::EndOfStatement,
    5038             :                  "unexpected token in '.else' directive"))
    5039             :     return true;
    5040             : 
    5041         127 :   if (TheCondState.TheCond != AsmCond::IfCond &&
    5042             :       TheCondState.TheCond != AsmCond::ElseIfCond)
    5043           0 :     return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
    5044           0 :                                " an .if or an .elseif");
    5045         127 :   TheCondState.TheCond = AsmCond::ElseCond;
    5046             :   bool LastIgnoreState = false;
    5047         127 :   if (!TheCondStack.empty())
    5048         127 :     LastIgnoreState = TheCondStack.back().Ignore;
    5049         127 :   if (LastIgnoreState || TheCondState.CondMet)
    5050          95 :     TheCondState.Ignore = true;
    5051             :   else
    5052          32 :     TheCondState.Ignore = false;
    5053             : 
    5054             :   return false;
    5055             : }
    5056             : 
    5057             : /// parseDirectiveEnd
    5058             : /// ::= .end
    5059           2 : bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
    5060           4 :   if (parseToken(AsmToken::EndOfStatement,
    5061             :                  "unexpected token in '.end' directive"))
    5062             :     return true;
    5063             : 
    5064          26 :   while (Lexer.isNot(AsmToken::Eof))
    5065          24 :     Lexer.Lex();
    5066             : 
    5067             :   return false;
    5068             : }
    5069             : 
    5070             : /// parseDirectiveError
    5071             : ///   ::= .err
    5072             : ///   ::= .error [string]
    5073           6 : bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
    5074           6 :   if (!TheCondStack.empty()) {
    5075           2 :     if (TheCondStack.back().Ignore) {
    5076           1 :       eatToEndOfStatement();
    5077           1 :       return false;
    5078             :     }
    5079             :   }
    5080             : 
    5081           5 :   if (!WithMessage)
    5082           4 :     return Error(L, ".err encountered");
    5083             : 
    5084             :   StringRef Message = ".error directive invoked in source file";
    5085           3 :   if (Lexer.isNot(AsmToken::EndOfStatement)) {
    5086           2 :     if (Lexer.isNot(AsmToken::String))
    5087           2 :       return TokError(".error argument must be a string");
    5088             : 
    5089           1 :     Message = getTok().getStringContents();
    5090           1 :     Lex();
    5091             :   }
    5092             : 
    5093           4 :   return Error(L, Message);
    5094             : }
    5095             : 
    5096             : /// parseDirectiveWarning
    5097             : ///   ::= .warning [string]
    5098          13 : bool AsmParser::parseDirectiveWarning(SMLoc L) {
    5099          13 :   if (!TheCondStack.empty()) {
    5100           1 :     if (TheCondStack.back().Ignore) {
    5101           0 :       eatToEndOfStatement();
    5102           0 :       return false;
    5103             :     }
    5104             :   }
    5105             : 
    5106             :   StringRef Message = ".warning directive invoked in source file";
    5107             : 
    5108          13 :   if (!parseOptionalToken(AsmToken::EndOfStatement)) {
    5109           7 :     if (Lexer.isNot(AsmToken::String))
    5110           2 :       return TokError(".warning argument must be a string");
    5111             : 
    5112           5 :     Message = getTok().getStringContents();
    5113           5 :     Lex();
    5114           5 :     if (parseToken(AsmToken::EndOfStatement,
    5115             :                    "expected end of statement in '.warning' directive"))
    5116             :       return true;
    5117             :   }
    5118             : 
    5119           9 :   return Warning(L, Message);
    5120             : }
    5121             : 
    5122             : /// parseDirectiveEndIf
    5123             : /// ::= .endif
    5124         236 : bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
    5125         472 :   if (parseToken(AsmToken::EndOfStatement,
    5126             :                  "unexpected token in '.endif' directive"))
    5127             :     return true;
    5128             : 
    5129         472 :   if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
    5130           0 :     return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
    5131           0 :                                "an .if or .else");
    5132             :   if (!TheCondStack.empty()) {
    5133         236 :     TheCondState = TheCondStack.back();
    5134             :     TheCondStack.pop_back();
    5135             :   }
    5136             : 
    5137         236 :   return false;
    5138             : }
    5139             : 
    5140       17442 : void AsmParser::initializeDirectiveKindMap() {
    5141       34884 :   DirectiveKindMap[".set"] = DK_SET;
    5142       17442 :   DirectiveKindMap[".equ"] = DK_EQU;
    5143       17442 :   DirectiveKindMap[".equiv"] = DK_EQUIV;
    5144       17442 :   DirectiveKindMap[".ascii"] = DK_ASCII;
    5145       17442 :   DirectiveKindMap[".asciz"] = DK_ASCIZ;
    5146       17442 :   DirectiveKindMap[".string"] = DK_STRING;
    5147       17442 :   DirectiveKindMap[".byte"] = DK_BYTE;
    5148       17442 :   DirectiveKindMap[".short"] = DK_SHORT;
    5149       17442 :   DirectiveKindMap[".value"] = DK_VALUE;
    5150       17442 :   DirectiveKindMap[".2byte"] = DK_2BYTE;
    5151       17442 :   DirectiveKindMap[".long"] = DK_LONG;
    5152       17442 :   DirectiveKindMap[".int"] = DK_INT;
    5153       17442 :   DirectiveKindMap[".4byte"] = DK_4BYTE;
    5154       17442 :   DirectiveKindMap[".quad"] = DK_QUAD;
    5155       17442 :   DirectiveKindMap[".8byte"] = DK_8BYTE;
    5156       17442 :   DirectiveKindMap[".octa"] = DK_OCTA;
    5157       17442 :   DirectiveKindMap[".single"] = DK_SINGLE;
    5158       17442 :   DirectiveKindMap[".float"] = DK_FLOAT;
    5159       17442 :   DirectiveKindMap[".double"] = DK_DOUBLE;
    5160       17442 :   DirectiveKindMap[".align"] = DK_ALIGN;
    5161       17442 :   DirectiveKindMap[".align32"] = DK_ALIGN32;
    5162       17442 :   DirectiveKindMap[".balign"] = DK_BALIGN;
    5163       17442 :   DirectiveKindMap[".balignw"] = DK_BALIGNW;
    5164       17442 :   DirectiveKindMap[".balignl"] = DK_BALIGNL;
    5165       17442 :   DirectiveKindMap[".p2align"] = DK_P2ALIGN;
    5166       17442 :   DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
    5167       17442 :   DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
    5168       17442 :   DirectiveKindMap[".org"] = DK_ORG;
    5169       17442 :   DirectiveKindMap[".fill"] = DK_FILL;
    5170       17442 :   DirectiveKindMap[".zero"] = DK_ZERO;
    5171       17442 :   DirectiveKindMap[".extern"] = DK_EXTERN;
    5172       17442 :   DirectiveKindMap[".globl"] = DK_GLOBL;
    5173       17442 :   DirectiveKindMap[".global"] = DK_GLOBAL;
    5174       17442 :   DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
    5175       17442 :   DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
    5176       17442 :   DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
    5177       17442 :   DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
    5178       17442 :   DirectiveKindMap[".reference"] = DK_REFERENCE;
    5179       17442 :   DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
    5180       17442 :   DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
    5181       17442 :   DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
    5182       17442 :   DirectiveKindMap[".comm"] = DK_COMM;
    5183       17442 :   DirectiveKindMap[".common"] = DK_COMMON;
    5184       17442 :   DirectiveKindMap[".lcomm"] = DK_LCOMM;
    5185       17442 :   DirectiveKindMap[".abort"] = DK_ABORT;
    5186       17442 :   DirectiveKindMap[".include"] = DK_INCLUDE;
    5187       17442 :   DirectiveKindMap[".incbin"] = DK_INCBIN;
    5188       17442 :   DirectiveKindMap[".code16"] = DK_CODE16;
    5189       17442 :   DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
    5190       17442 :   DirectiveKindMap[".rept"] = DK_REPT;
    5191       17442 :   DirectiveKindMap[".rep"] = DK_REPT;
    5192       17442 :   DirectiveKindMap[".irp"] = DK_IRP;
    5193       17442 :   DirectiveKindMap[".irpc"] = DK_IRPC;
    5194       17442 :   DirectiveKindMap[".endr"] = DK_ENDR;
    5195       17442 :   DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
    5196       17442 :   DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
    5197       17442 :   DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
    5198       17442 :   DirectiveKindMap[".if"] = DK_IF;
    5199       17442 :   DirectiveKindMap[".ifeq"] = DK_IFEQ;
    5200       17442 :   DirectiveKindMap[".ifge"] = DK_IFGE;
    5201       17442 :   DirectiveKindMap[".ifgt"] = DK_IFGT;
    5202       17442 :   DirectiveKindMap[".ifle"] = DK_IFLE;
    5203       17442 :   DirectiveKindMap[".iflt"] = DK_IFLT;
    5204       17442 :   DirectiveKindMap[".ifne"] = DK_IFNE;
    5205       17442 :   DirectiveKindMap[".ifb"] = DK_IFB;
    5206       17442 :   DirectiveKindMap[".ifnb"] = DK_IFNB;
    5207       17442 :   DirectiveKindMap[".ifc"] = DK_IFC;
    5208       17442 :   DirectiveKindMap[".ifeqs"] = DK_IFEQS;
    5209       17442 :   DirectiveKindMap[".ifnc"] = DK_IFNC;
    5210       17442 :   DirectiveKindMap[".ifnes"] = DK_IFNES;
    5211       17442 :   DirectiveKindMap[".ifdef"] = DK_IFDEF;
    5212       17442 :   DirectiveKindMap[".ifndef"] = DK_IFNDEF;
    5213       17442 :   DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
    5214       17442 :   DirectiveKindMap[".elseif"] = DK_ELSEIF;
    5215       17442 :   DirectiveKindMap[".else"] = DK_ELSE;
    5216       17442 :   DirectiveKindMap[".end"] = DK_END;
    5217       17442 :   DirectiveKindMap[".endif"] = DK_ENDIF;
    5218       17442 :   DirectiveKindMap[".skip"] = DK_SKIP;
    5219       17442 :   DirectiveKindMap[".space"] = DK_SPACE;
    5220       17442 :   DirectiveKindMap[".file"] = DK_FILE;
    5221       17442 :   DirectiveKindMap[".line"] = DK_LINE;
    5222       17442 :   DirectiveKindMap[".loc"] = DK_LOC;
    5223       17442 :   DirectiveKindMap[".stabs"] = DK_STABS;
    5224       17442 :   DirectiveKindMap[".cv_file"] = DK_CV_FILE;
    5225       17442 :   DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
    5226       17442 :   DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
    5227       17442 :   DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
    5228       17442 :   DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
    5229       17442 :   DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
    5230       17442 :   DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
    5231       17442 :   DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
    5232       17442 :   DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
    5233       17442 :   DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
    5234       17442 :   DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
    5235       17442 :   DirectiveKindMap[".sleb128"] = DK_SLEB128;
    5236       17442 :   DirectiveKindMap[".uleb128"] = DK_ULEB128;
    5237       17442 :   DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
    5238       17442 :   DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
    5239       17442 :   DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
    5240       17442 :   DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
    5241       17442 :   DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
    5242       17442 :   DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
    5243       17442 :   DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
    5244       17442 :   DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
    5245       17442 :   DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
    5246       17442 :   DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
    5247       17442 :   DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
    5248       17442 :   DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
    5249       17442 :   DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
    5250       17442 :   DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
    5251       17442 :   DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
    5252       17442 :   DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
    5253       17442 :   DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
    5254       17442 :   DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
    5255       17442 :   DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
    5256       17442 :   DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
    5257       17442 :   DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
    5258       17442 :   DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
    5259       17442 :   DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
    5260       17442 :   DirectiveKindMap[".macro"] = DK_MACRO;
    5261       17442 :   DirectiveKindMap[".exitm"] = DK_EXITM;
    5262       17442 :   DirectiveKindMap[".endm"] = DK_ENDM;
    5263       17442 :   DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
    5264       17442 :   DirectiveKindMap[".purgem"] = DK_PURGEM;
    5265       17442 :   DirectiveKindMap[".err"] = DK_ERR;
    5266       17442 :   DirectiveKindMap[".error"] = DK_ERROR;
    5267       17442 :   DirectiveKindMap[".warning"] = DK_WARNING;
    5268       17442 :   DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
    5269       17442 :   DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
    5270       17442 :   DirectiveKindMap[".reloc"] = DK_RELOC;
    5271       17442 :   DirectiveKindMap[".dc"] = DK_DC;
    5272       17442 :   DirectiveKindMap[".dc.a"] = DK_DC_A;
    5273       17442 :   DirectiveKindMap[".dc.b"] = DK_DC_B;
    5274       17442 :   DirectiveKindMap[".dc.d"] = DK_DC_D;
    5275       17442 :   DirectiveKindMap[".dc.l"] = DK_DC_L;
    5276       17442 :   DirectiveKindMap[".dc.s"] = DK_DC_S;
    5277       17442 :   DirectiveKindMap[".dc.w"] = DK_DC_W;
    5278       17442 :   DirectiveKindMap[".dc.x"] = DK_DC_X;
    5279       17442 :   DirectiveKindMap[".dcb"] = DK_DCB;
    5280       17442 :   DirectiveKindMap[".dcb.b"] = DK_DCB_B;
    5281       17442 :   DirectiveKindMap[".dcb.d"] = DK_DCB_D;
    5282       17442 :   DirectiveKindMap[".dcb.l"] = DK_DCB_L;
    5283       17442 :   DirectiveKindMap[".dcb.s"] = DK_DCB_S;
    5284       17442 :   DirectiveKindMap[".dcb.w"] = DK_DCB_W;
    5285       17442 :   DirectiveKindMap[".dcb.x"] = DK_DCB_X;
    5286       17442 :   DirectiveKindMap[".ds"] = DK_DS;
    5287       17442 :   DirectiveKindMap[".ds.b"] = DK_DS_B;
    5288       17442 :   DirectiveKindMap[".ds.d"] = DK_DS_D;
    5289       17442 :   DirectiveKindMap[".ds.l"] = DK_DS_L;
    5290       17442 :   DirectiveKindMap[".ds.p"] = DK_DS_P;
    5291       17442 :   DirectiveKindMap[".ds.s"] = DK_DS_S;
    5292       17442 :   DirectiveKindMap[".ds.w"] = DK_DS_W;
    5293       17442 :   DirectiveKindMap[".ds.x"] = DK_DS_X;
    5294       17442 :   DirectiveKindMap[".print"] = DK_PRINT;
    5295       17442 : }
    5296             : 
    5297        1657 : MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
    5298        1657 :   AsmToken EndToken, StartToken = getTok();
    5299             : 
    5300             :   unsigned NestLevel = 0;
    5301             :   while (true) {
    5302             :     // Check whether we have reached the end of the file.
    5303       14373 :     if (getLexer().is(AsmToken::Eof)) {
    5304           1 :       printError(DirectiveLoc, "no matching '.endr' in definition");
    5305           1 :       return nullptr;
    5306             :     }
    5307             : 
    5308        8014 :     if (Lexer.is(AsmToken::Identifier) &&
    5309        8012 :         (getTok().getIdentifier() == ".rept" ||
    5310        8011 :          getTok().getIdentifier() == ".irp" ||
    5311        7887 :          getTok().getIdentifier() == ".irpc")) {
    5312         126 :       ++NestLevel;
    5313             :     }
    5314             : 
    5315             :     // Otherwise, check whether we have reached the .endr.
    5316        8014 :     if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
    5317        1782 :       if (NestLevel == 0) {
    5318        1656 :         EndToken = getTok();
    5319        1656 :         Lex();
    5320        1656 :         if (Lexer.isNot(AsmToken::EndOfStatement)) {
    5321           0 :           printError(getTok().getLoc(),
    5322             :                      "unexpected token in '.endr' directive");
    5323           0 :           return nullptr;
    5324             :         }
    5325             :         break;
    5326             :       }
    5327         126 :       --NestLevel;
    5328             :     }
    5329             : 
    5330             :     // Otherwise, scan till the end of the statement.
    5331        6358 :     eatToEndOfStatement();
    5332             :   }
    5333             : 
    5334        3312 :   const char *BodyStart = StartToken.getLoc().getPointer();
    5335        3312 :   const char *BodyEnd = EndToken.getLoc().getPointer();
    5336        1656 :   StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
    5337             : 
    5338             :   // We Are Anonymous.
    5339        3312 :   MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
    5340        1656 :   return &MacroLikeBodies.back();
    5341             : }
    5342             : 
    5343        1656 : void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
    5344             :                                          raw_svector_ostream &OS) {
    5345        1656 :   OS << ".endr\n";
    5346             : 
    5347             :   std::unique_ptr<MemoryBuffer> Instantiation =
    5348        3312 :       MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
    5349             : 
    5350             :   // Create the macro instantiation object and add to the current macro
    5351             :   // instantiation stack.
    5352             :   MacroInstantiation *MI = new MacroInstantiation(
    5353        4968 :       DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
    5354        1656 :   ActiveMacros.push_back(MI);
    5355             : 
    5356             :   // Jump to the macro instantiation and prime the lexer.
    5357        4968 :   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
    5358        3312 :   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
    5359        1656 :   Lex();
    5360        1656 : }
    5361             : 
    5362             : /// parseDirectiveRept
    5363             : ///   ::= .rep | .rept count
    5364         537 : bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
    5365             :   const MCExpr *CountExpr;
    5366         537 :   SMLoc CountLoc = getTok().getLoc();
    5367         537 :   if (parseExpression(CountExpr))
    5368             :     return true;
    5369             : 
    5370             :   int64_t Count;
    5371        1072 :   if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
    5372           1 :     return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
    5373             :   }
    5374             : 
    5375        1604 :   if (check(Count < 0, CountLoc, "Count is negative") ||
    5376         534 :       parseToken(AsmToken::EndOfStatement,
    5377         535 :                  "unexpected token in '" + Dir + "' directive"))
    5378             :     return true;
    5379             : 
    5380             :   // Lex the rept definition.
    5381         533 :   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
    5382         533 :   if (!M)
    5383             :     return true;
    5384             : 
    5385             :   // Macro instantiation is lexical, unfortunately. We construct a new buffer
    5386             :   // to hold the macro body with substitutions.
    5387             :   SmallString<256> Buf;
    5388             :   raw_svector_ostream OS(Buf);
    5389        7547 :   while (Count--) {
    5390             :     // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
    5391       14030 :     if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
    5392             :       return true;
    5393             :   }
    5394         532 :   instantiateMacroLikeBody(M, DirectiveLoc, OS);
    5395             : 
    5396         532 :   return false;
    5397             : }
    5398             : 
    5399             : /// parseDirectiveIrp
    5400             : /// ::= .irp symbol,values
    5401        1117 : bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
    5402             :   MCAsmMacroParameter Parameter;
    5403        1117 :   MCAsmMacroArguments A;
    5404        3351 :   if (check(parseIdentifier(Parameter.Name),
    5405        1117 :             "expected identifier in '.irp' directive") ||
    5406        3351 :       parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
    5407        3351 :       parseMacroArguments(nullptr, A) ||
    5408        2234 :       parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
    5409             :     return true;
    5410             : 
    5411             :   // Lex the irp definition.
    5412        1117 :   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
    5413        1117 :   if (!M)
    5414             :     return true;
    5415             : 
    5416             :   // Macro instantiation is lexical, unfortunately. We construct a new buffer
    5417             :   // to hold the macro body with substitutions.
    5418             :   SmallString<256> Buf;
    5419             :   raw_svector_ostream OS(Buf);
    5420             : 
    5421       12241 :   for (const MCAsmMacroArgument &Arg : A) {
    5422             :     // Note that the AtPseudoVariable is enabled for instantiations of .irp.
    5423             :     // This is undocumented, but GAS seems to support it.
    5424       22248 :     if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
    5425             :       return true;
    5426             :   }
    5427             : 
    5428        1117 :   instantiateMacroLikeBody(M, DirectiveLoc, OS);
    5429             : 
    5430        1117 :   return false;
    5431             : }
    5432             : 
    5433             : /// parseDirectiveIrpc
    5434             : /// ::= .irpc symbol,values
    5435           7 : bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
    5436             :   MCAsmMacroParameter Parameter;
    5437           7 :   MCAsmMacroArguments A;
    5438             : 
    5439          21 :   if (check(parseIdentifier(Parameter.Name),
    5440           7 :             "expected identifier in '.irpc' directive") ||
    5441          28 :       parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
    5442           7 :       parseMacroArguments(nullptr, A))
    5443             :     return true;
    5444             : 
    5445          21 :   if (A.size() != 1 || A.front().size() != 1)
    5446           0 :     return TokError("unexpected token in '.irpc' directive");
    5447             : 
    5448             :   // Eat the end of statement.
    5449           7 :   if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
    5450             :     return true;
    5451             : 
    5452             :   // Lex the irpc definition.
    5453           7 :   MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
    5454           7 :   if (!M)
    5455             :     return true;
    5456             : 
    5457             :   // Macro instantiation is lexical, unfortunately. We construct a new buffer
    5458             :   // to hold the macro body with substitutions.
    5459             :   SmallString<256> Buf;
    5460             :   raw_svector_ostream OS(Buf);
    5461             : 
    5462           7 :   StringRef Values = A.front().front().getString();
    5463          43 :   for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
    5464          18 :     MCAsmMacroArgument Arg;
    5465          36 :     Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
    5466             : 
    5467             :     // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
    5468             :     // This is undocumented, but GAS seems to support it.
    5469          36 :     if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
    5470           0 :       return true;
    5471             :   }
    5472             : 
    5473           7 :   instantiateMacroLikeBody(M, DirectiveLoc, OS);
    5474             : 
    5475           7 :   return false;
    5476             : }
    5477             : 
    5478        1656 : bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
    5479        1656 :   if (ActiveMacros.empty())
    5480           2 :     return TokError("unmatched '.endr' directive");
    5481             : 
    5482             :   // The only .repl that should get here are the ones created by
    5483             :   // instantiateMacroLikeBody.
    5484             :   assert(getLexer().is(AsmToken::EndOfStatement));
    5485             : 
    5486        1655 :   handleMacroExit();
    5487             :   return false;
    5488             : }
    5489             : 
    5490           7 : bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
    5491             :                                      size_t Len) {
    5492             :   const MCExpr *Value;
    5493           7 :   SMLoc ExprLoc = getLexer().getLoc();
    5494           7 :   if (parseExpression(Value))
    5495             :     return true;
    5496           7 :   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
    5497             :   if (!MCE)
    5498           0 :     return Error(ExprLoc, "unexpected expression in _emit");
    5499           7 :   uint64_t IntValue = MCE->getValue();
    5500           7 :   if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
    5501           0 :     return Error(ExprLoc, "literal value out of range for directive");
    5502             : 
    5503           7 :   Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
    5504             :   return false;
    5505             : }
    5506             : 
    5507          12 : bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
    5508             :   const MCExpr *Value;
    5509          12 :   SMLoc ExprLoc = getLexer().getLoc();
    5510          12 :   if (parseExpression(Value))
    5511             :     return true;
    5512          12 :   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
    5513             :   if (!MCE)
    5514           0 :     return Error(ExprLoc, "unexpected expression in align");
    5515          12 :   uint64_t IntValue = MCE->getValue();
    5516             :   if (!isPowerOf2_64(IntValue))
    5517           0 :     return Error(ExprLoc, "literal value not a power of two greater then zero");
    5518             : 
    5519          24 :   Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
    5520             :   return false;
    5521             : }
    5522             : 
    5523           4 : bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
    5524           4 :   const AsmToken StrTok = getTok();
    5525           4 :   Lex();
    5526           7 :   if (StrTok.isNot(AsmToken::String) || StrTok.getString().front() != '"')
    5527           1 :     return Error(DirectiveLoc, "expected double quoted string after .print");
    5528           3 :   if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
    5529             :     return true;
    5530           2 :   llvm::outs() << StrTok.getStringContents() << '\n';
    5531             :   return false;
    5532             : }
    5533             : 
    5534             : // We are comparing pointers, but the pointers are relative to a single string.
    5535             : // Thus, this should always be deterministic.
    5536         510 : static int rewritesSort(const AsmRewrite *AsmRewriteA,
    5537             :                         const AsmRewrite *AsmRewriteB) {
    5538         510 :   if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
    5539             :     return -1;
    5540          97 :   if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
    5541             :     return 1;
    5542             : 
    5543             :   // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
    5544             :   // rewrite to the same location.  Make sure the SizeDirective rewrite is
    5545             :   // performed first, then the Imm/ImmPrefix and finally the Input/Output.  This
    5546             :   // ensures the sort algorithm is stable.
    5547          54 :   if (AsmRewritePrecedence[AsmRewriteA->Kind] >
    5548          27 :       AsmRewritePrecedence[AsmRewriteB->Kind])
    5549             :     return -1;
    5550             : 
    5551           5 :   if (AsmRewritePrecedence[AsmRewriteA->Kind] <
    5552             :       AsmRewritePrecedence[AsmRewriteB->Kind])
    5553             :     return 1;
    5554           0 :   llvm_unreachable("Unstable rewrite sort.");
    5555             : }
    5556             : 
    5557         225 : bool AsmParser::parseMSInlineAsm(
    5558             :     void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
    5559             :     unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
    5560             :     SmallVectorImpl<std::string> &Constraints,
    5561             :     SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
    5562             :     const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
    5563             :   SmallVector<void *, 4> InputDecls;
    5564             :   SmallVector<void *, 4> OutputDecls;
    5565             :   SmallVector<bool, 4> InputDeclsAddressOf;
    5566             :   SmallVector<bool, 4> OutputDeclsAddressOf;
    5567         225 :   SmallVector<std::string, 4> InputConstraints;
    5568         225 :   SmallVector<std::string, 4> OutputConstraints;
    5569             :   SmallVector<unsigned, 4> ClobberRegs;
    5570             : 
    5571             :   SmallVector<AsmRewrite, 4> AsmStrRewrites;
    5572             : 
    5573             :   // Prime the lexer.
    5574         225 :   Lex();
    5575             : 
    5576             :   // While we have input, parse each statement.
    5577             :   unsigned InputIdx = 0;
    5578             :   unsigned OutputIdx = 0;
    5579         702 :   while (getLexer().isNot(AsmToken::Eof)) {
    5580             :     // Parse curly braces marking block start/end
    5581         495 :     if (parseCurlyBlockScope(AsmStrRewrites))
    5582         114 :       continue;
    5583             : 
    5584             :     ParseStatementInfo Info(&AsmStrRewrites);
    5585         473 :     bool StatementErr = parseStatement(Info, &SI);
    5586             : 
    5587         473 :     if (StatementErr || Info.ParseError) {
    5588             :       // Emit pending errors if any exist.
    5589          18 :       printPendingErrors();
    5590             :       return true;
    5591             :     }
    5592             : 
    5593             :     // No pending error should exist here.
    5594             :     assert(!hasPendingError() && "unexpected error from parseStatement");
    5595             : 
    5596         455 :     if (Info.Opcode == ~0U)
    5597             :       continue;
    5598             : 
    5599         385 :     const MCInstrDesc &Desc = MII->get(Info.Opcode);
    5600             : 
    5601             :     // Build the list of clobbers, outputs and inputs.
    5602        1039 :     for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
    5603         654 :       MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
    5604             : 
    5605             :       // Immediate.
    5606         654 :       if (Operand.isImm())
    5607         623 :         continue;
    5608             : 
    5609             :       // Register operand.
    5610         893 :       if (Operand.isReg() && !Operand.needAddressOf() &&
    5611         343 :           !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
    5612         337 :         unsigned NumDefs = Desc.getNumDefs();
    5613             :         // Clobber.
    5614         645 :         if (NumDefs && Operand.getMCOperandNum() < NumDefs)
    5615         268 :           ClobberRegs.push_back(Operand.getReg());
    5616         337 :         continue;
    5617             :       }
    5618             : 
    5619             :       // Expr/Input or Output.
    5620         213 :       StringRef SymName = Operand.getSymName();
    5621         276 :       if (SymName.empty())
    5622          63 :         continue;
    5623             : 
    5624         150 :       void *OpDecl = Operand.getOpDecl();
    5625         150 :       if (!OpDecl)
    5626          15 :         continue;
    5627             : 
    5628         166 :       bool isOutput = (i == 1) && Desc.mayStore();
    5629         135 :       SMLoc Start = SMLoc::getFromPointer(SymName.data());
    5630         135 :       if (isOutput) {
    5631          20 :         ++InputIdx;
    5632          20 :         OutputDecls.push_back(OpDecl);
    5633          20 :         OutputDeclsAddressOf.push_back(Operand.needAddressOf());
    5634          60 :         OutputConstraints.push_back(("=" + Operand.getConstraint()).str());
    5635          20 :         AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
    5636             :       } else {
    5637         115 :         InputDecls.push_back(OpDecl);
    5638         115 :         InputDeclsAddressOf.push_back(Operand.needAddressOf());
    5639         230 :         InputConstraints.push_back(Operand.getConstraint().str());
    5640         115 :         AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
    5641             :       }
    5642             :     }
    5643             : 
    5644             :     // Consider implicit defs to be clobbers.  Think of cpuid and push.
    5645             :     ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
    5646         770 :                                 Desc.getNumImplicitDefs());
    5647         385 :     ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
    5648             :   }
    5649             : 
    5650             :   // Set the number of Outputs and Inputs.
    5651         207 :   NumOutputs = OutputDecls.size();
    5652         207 :   NumInputs = InputDecls.size();
    5653             : 
    5654             :   // Set the unique clobbers.
    5655             :   array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
    5656             :   ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
    5657             :                     ClobberRegs.end());
    5658         414 :   Clobbers.assign(ClobberRegs.size(), std::string());
    5659         440 :   for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
    5660         466 :     raw_string_ostream OS(Clobbers[I]);
    5661         466 :     IP->printRegName(OS, ClobberRegs[I]);
    5662             :   }
    5663             : 
    5664             :   // Merge the various outputs and inputs.  Output are expected first.
    5665         207 :   if (NumOutputs || NumInputs) {
    5666          83 :     unsigned NumExprs = NumOutputs + NumInputs;
    5667          83 :     OpDecls.resize(NumExprs);
    5668          83 :     Constraints.resize(NumExprs);
    5669         123 :     for (unsigned i = 0; i < NumOutputs; ++i) {
    5670          40 :       OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
    5671             :       Constraints[i] = OutputConstraints[i];
    5672             :     }
    5673         313 :     for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
    5674         230 :       OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
    5675             :       Constraints[j] = InputConstraints[i];
    5676             :     }
    5677             :   }
    5678             : 
    5679             :   // Build the IR assembly string.
    5680             :   std::string AsmStringIR;
    5681         207 :   raw_string_ostream OS(AsmStringIR);
    5682             :   StringRef ASMString =
    5683         207 :       SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
    5684             :   const char *AsmStart = ASMString.begin();
    5685             :   const char *AsmEnd = ASMString.end();
    5686             :   array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
    5687        1277 :   for (const AsmRewrite &AR : AsmStrRewrites) {
    5688         535 :     AsmRewriteKind Kind = AR.Kind;
    5689             : 
    5690             :     const char *Loc = AR.Loc.getPointer();
    5691             :     assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
    5692             : 
    5693             :     // Emit everything up to the immediate/expression.
    5694         535 :     if (unsigned Len = Loc - AsmStart)
    5695         720 :       OS << StringRef(AsmStart, Len);
    5696             : 
    5697             :     // Skip the original expression.
    5698         649 :     if (Kind == AOK_Skip) {
    5699         114 :       AsmStart = Loc + AR.Len;
    5700         114 :       continue;
    5701             :     }
    5702             : 
    5703             :     unsigned AdditionalSkip = 0;
    5704             :     // Rewrite expressions in $N notation.
    5705         421 :     switch (Kind) {
    5706             :     default:
    5707             :       break;
    5708         201 :     case AOK_IntelExpr:
    5709             :       assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
    5710         201 :       if (AR.IntelExp.NeedBracs)
    5711          94 :         OS << "[";
    5712         201 :       if (AR.IntelExp.hasBaseReg())
    5713          50 :         OS << AR.IntelExp.BaseReg;
    5714         201 :       if (AR.IntelExp.hasIndexReg())
    5715           4 :         OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
    5716           4 :            << AR.IntelExp.IndexReg;
    5717         201 :       if (AR.IntelExp.Scale > 1)
    5718           3 :           OS << " * $$" << AR.IntelExp.Scale;
    5719         201 :       if (AR.IntelExp.Imm || !AR.IntelExp.hasRegs())
    5720         184 :         OS << (AR.IntelExp.hasRegs() ? " + $$" : "$$") << AR.IntelExp.Imm;
    5721         201 :       if (AR.IntelExp.NeedBracs)
    5722          94 :         OS << "]";
    5723             :       break;
    5724          38 :     case AOK_Label:
    5725          38 :       OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
    5726          38 :       break;
    5727             :     case AOK_Input:
    5728         115 :       OS << '$' << InputIdx++;
    5729             :       break;
    5730             :     case AOK_Output:
    5731          20 :       OS << '$' << OutputIdx++;
    5732             :       break;
    5733          22 :     case AOK_SizeDirective:
    5734          22 :       switch (AR.Val) {
    5735             :       default: break;
    5736           2 :       case 8:  OS << "byte ptr "; break;
    5737           2 :       case 16: OS << "word ptr "; break;
    5738          15 :       case 32: OS << "dword ptr "; break;
    5739           3 :       case 64: OS << "qword ptr "; break;
    5740           0 :       case 80: OS << "xword ptr "; break;
    5741           0 :       case 128: OS << "xmmword ptr "; break;
    5742           0 :       case 256: OS << "ymmword ptr "; break;
    5743             :       }
    5744             :       break;
    5745           7 :     case AOK_Emit:
    5746           7 :       OS << ".byte";
    5747           7 :       break;
    5748          12 :     case AOK_Align: {
    5749             :       // MS alignment directives are measured in bytes. If the native assembler
    5750             :       // measures alignment in bytes, we can pass it straight through.
    5751          12 :       OS << ".align";
    5752          12 :       if (getContext().getAsmInfo()->getAlignmentIsInBytes())
    5753             :         break;
    5754             : 
    5755             :       // Alignment is in log2 form, so print that instead and skip the original
    5756             :       // immediate.
    5757           8 :       unsigned Val = AR.Val;
    5758             :       OS << ' ' << Val;
    5759             :       assert(Val < 10 && "Expected alignment less then 2^10.");
    5760           8 :       AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
    5761             :       break;
    5762             :     }
    5763           1 :     case AOK_EVEN:
    5764           1 :       OS << ".even";
    5765           1 :       break;
    5766           5 :     case AOK_EndOfStatement:
    5767           5 :       OS << "\n\t";
    5768           5 :       break;
    5769             :     }
    5770             : 
    5771             :     // Skip the original expression.
    5772         421 :     AsmStart = Loc + AR.Len + AdditionalSkip;
    5773             :   }
    5774             : 
    5775             :   // Emit the remainder of the asm string.
    5776         207 :   if (AsmStart != AsmEnd)
    5777         120 :     OS << StringRef(AsmStart, AsmEnd - AsmStart);
    5778             : 
    5779             :   AsmString = OS.str();
    5780             :   return false;
    5781             : }
    5782             : 
    5783             : namespace llvm {
    5784             : namespace MCParserUtils {
    5785             : 
    5786             : /// Returns whether the given symbol is used anywhere in the given expression,
    5787             : /// or subexpressions.
    5788         380 : static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
    5789         385 :   switch (Value->getKind()) {
    5790          23 :   case MCExpr::Binary: {
    5791             :     const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value);
    5792          43 :     return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
    5793          20 :            isSymbolUsedInExpression(Sym, BE->getRHS());
    5794             :   }
    5795             :   case MCExpr::Target:
    5796             :   case MCExpr::Constant:
    5797             :     return false;
    5798         135 :   case MCExpr::SymbolRef: {
    5799             :     const MCSymbol &S =
    5800         135 :         static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
    5801         135 :     if (S.isVariable())
    5802           5 :       return isSymbolUsedInExpression(Sym, S.getVariableValue());
    5803         130 :     return &S == Sym;
    5804             :   }
    5805           0 :   case MCExpr::Unary:
    5806           0 :     return isSymbolUsedInExpression(
    5807           0 :         Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr());
    5808             :   }
    5809             : 
    5810           0 :   llvm_unreachable("Unknown expr kind!");
    5811             : }
    5812             : 
    5813         809 : bool parseAssignmentExpression(StringRef Name, bool allow_redef,
    5814             :                                MCAsmParser &Parser, MCSymbol *&Sym,
    5815             :                                const MCExpr *&Value, bool AllowExtendedExpr) {
    5816             : 
    5817             :   // FIXME: Use better location, we should use proper tokens.
    5818         809 :   SMLoc EqualLoc = Parser.getTok().getLoc();
    5819         809 :   SMLoc EndLoc;
    5820         809 :   if (AllowExtendedExpr) {
    5821         580 :     if (Parser.getTargetParser().parseAssignmentExpression(Value, EndLoc)) {
    5822           0 :       return Parser.TokError("missing expression");
    5823             :     }
    5824         229 :   } else if (Parser.parseExpression(Value, EndLoc))
    5825           4 :       return Parser.TokError("missing expression");
    5826             : 
    5827             :   // Note: we don't count b as used in "a = b". This is to allow
    5828             :   // a = b
    5829             :   // b = c
    5830             : 
    5831         805 :   if (Parser.parseToken(AsmToken::EndOfStatement))
    5832             :     return true;
    5833             : 
    5834             :   // Validate that the LHS is allowed to be a variable (either it has not been
    5835             :   // used as a symbol, or it is an absolute symbol).
    5836        1592 :   Sym = Parser.getContext().lookupSymbol(Name);
    5837         796 :   if (Sym) {
    5838             :     // Diagnose assignment to a label.
    5839             :     //
    5840             :     // FIXME: Diagnostics. Note the location of the definition as a label.
    5841             :     // FIXME: Diagnose assignment to protected identifier (e.g., register name).
    5842         337 :     if (isSymbolUsedInExpression(Sym, Value))
    5843           4 :       return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
    5844        1278 :     else if (Sym->isUndefined(/*SetUsed*/ false) && !Sym->isUsed() &&
    5845             :              !Sym->isVariable())
    5846             :       ; // Allow redefinitions of undefined symbols only used in directives.
    5847          79 :     else if (Sym->isVariable() && !Sym->isUsed() && allow_redef)
    5848             :       ; // Allow redefinitions of variables that haven't yet been used.
    5849          12 :     else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
    5850           4 :       return Parser.Error(EqualLoc, "redefinition of '" + Name + "'");
    5851           4 :     else if (!Sym->isVariable())
    5852           0 :       return Parser.Error(EqualLoc, "invalid assignment to '" + Name + "'");
    5853           2 :     else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
    5854           2 :       return Parser.Error(EqualLoc,
    5855           2 :                           "invalid reassignment of non-absolute variable '" +
    5856           4 :                               Name + "'");
    5857             :   } else if (Name == ".") {
    5858          12 :     Parser.getStreamer().emitValueToOffset(Value, 0, EqualLoc);
    5859          12 :     return false;
    5860             :   } else
    5861         894 :     Sym = Parser.getContext().getOrCreateSymbol(Name);
    5862             : 
    5863         774 :   Sym->setRedefinable(allow_redef);
    5864             : 
    5865         774 :   return false;
    5866             : }
    5867             : 
    5868             : } // end namespace MCParserUtils
    5869             : } // end namespace llvm
    5870             : 
    5871             : /// Create an MCAsmParser instance.
    5872       17442 : MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,
    5873             :                                      MCStreamer &Out, const MCAsmInfo &MAI,
    5874             :                                      unsigned CB) {
    5875       17442 :   return new AsmParser(SM, C, Out, MAI, CB);
    5876      299301 : }

Generated by: LCOV version 1.13