LCOV - code coverage report
Current view: top level - lib/MC/MCParser - AsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 2363 2648 89.2 %
Date: 2018-10-20 13:21:21 Functions: 135 154 87.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13