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