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