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

Generated by: LCOV version 1.13