1321369Sdim//===- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser -----*- C++ -*-===// 2303231Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303231Sdim// 7303231Sdim//===----------------------------------------------------------------------===// 8303231Sdim 9303231Sdim#ifndef LLVM_MC_MCPARSER_MCTARGETASMPARSER_H 10303231Sdim#define LLVM_MC_MCPARSER_MCTARGETASMPARSER_H 11303231Sdim 12321369Sdim#include "llvm/ADT/StringRef.h" 13303231Sdim#include "llvm/MC/MCExpr.h" 14327952Sdim#include "llvm/MC/MCInstrInfo.h" 15321369Sdim#include "llvm/MC/MCParser/MCAsmLexer.h" 16341825Sdim#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 17303231Sdim#include "llvm/MC/MCParser/MCAsmParserExtension.h" 18303231Sdim#include "llvm/MC/MCTargetOptions.h" 19353358Sdim#include "llvm/MC/SubtargetFeature.h" 20321369Sdim#include "llvm/Support/SMLoc.h" 21321369Sdim#include <cstdint> 22303231Sdim#include <memory> 23303231Sdim 24303231Sdimnamespace llvm { 25321369Sdim 26303231Sdimclass MCInst; 27303231Sdimclass MCParsedAsmOperand; 28303231Sdimclass MCStreamer; 29303231Sdimclass MCSubtargetInfo; 30303231Sdimtemplate <typename T> class SmallVectorImpl; 31303231Sdim 32321369Sdimusing OperandVector = SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>>; 33303231Sdim 34303231Sdimenum AsmRewriteKind { 35303231Sdim AOK_Align, // Rewrite align as .align. 36303231Sdim AOK_EVEN, // Rewrite even as .even. 37303231Sdim AOK_Emit, // Rewrite _emit as .byte. 38360784Sdim AOK_CallInput, // Rewrite in terms of ${N:P}. 39303231Sdim AOK_Input, // Rewrite in terms of $N. 40303231Sdim AOK_Output, // Rewrite in terms of $N. 41303231Sdim AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). 42303231Sdim AOK_Label, // Rewrite local labels. 43303231Sdim AOK_EndOfStatement, // Add EndOfStatement (e.g., "\n\t"). 44327952Sdim AOK_Skip, // Skip emission (e.g., offset/type operators). 45327952Sdim AOK_IntelExpr // SizeDirective SymDisp [BaseReg + IndexReg * Scale + ImmDisp] 46303231Sdim}; 47303231Sdim 48303231Sdimconst char AsmRewritePrecedence [] = { 49303231Sdim 2, // AOK_Align 50303231Sdim 2, // AOK_EVEN 51303231Sdim 2, // AOK_Emit 52303231Sdim 3, // AOK_Input 53360784Sdim 3, // AOK_CallInput 54303231Sdim 3, // AOK_Output 55303231Sdim 5, // AOK_SizeDirective 56303231Sdim 1, // AOK_Label 57303231Sdim 5, // AOK_EndOfStatement 58327952Sdim 2, // AOK_Skip 59327952Sdim 2 // AOK_IntelExpr 60303231Sdim}; 61303231Sdim 62327952Sdim// Represnt the various parts which makes up an intel expression, 63327952Sdim// used for emitting compound intel expressions 64327952Sdimstruct IntelExpr { 65327952Sdim bool NeedBracs; 66327952Sdim int64_t Imm; 67327952Sdim StringRef BaseReg; 68327952Sdim StringRef IndexReg; 69360784Sdim StringRef OffsetName; 70327952Sdim unsigned Scale; 71327952Sdim 72360784Sdim IntelExpr() 73360784Sdim : NeedBracs(false), Imm(0), BaseReg(StringRef()), IndexReg(StringRef()), 74360784Sdim OffsetName(StringRef()), Scale(1) {} 75360784Sdim // [BaseReg + IndexReg * ScaleExpression + OFFSET name + ImmediateExpression] 76360784Sdim IntelExpr(StringRef baseReg, StringRef indexReg, unsigned scale, 77360784Sdim StringRef offsetName, int64_t imm, bool needBracs) 78360784Sdim : NeedBracs(needBracs), Imm(imm), BaseReg(baseReg), IndexReg(indexReg), 79360784Sdim OffsetName(offsetName), Scale(1) { 80327952Sdim if (scale) 81327952Sdim Scale = scale; 82327952Sdim } 83360784Sdim bool hasBaseReg() const { return !BaseReg.empty(); } 84360784Sdim bool hasIndexReg() const { return !IndexReg.empty(); } 85360784Sdim bool hasRegs() const { return hasBaseReg() || hasIndexReg(); } 86360784Sdim bool hasOffset() const { return !OffsetName.empty(); } 87360784Sdim // Normally we won't emit immediates unconditionally, 88360784Sdim // unless we've got no other components 89360784Sdim bool emitImm() const { return !(hasRegs() || hasOffset()); } 90327952Sdim bool isValid() const { 91327952Sdim return (Scale == 1) || 92327952Sdim (hasIndexReg() && (Scale == 2 || Scale == 4 || Scale == 8)); 93327952Sdim } 94327952Sdim}; 95327952Sdim 96303231Sdimstruct AsmRewrite { 97303231Sdim AsmRewriteKind Kind; 98303231Sdim SMLoc Loc; 99303231Sdim unsigned Len; 100360784Sdim bool Done; 101327952Sdim int64_t Val; 102303231Sdim StringRef Label; 103327952Sdim IntelExpr IntelExp; 104321369Sdim 105303231Sdimpublic: 106327952Sdim AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, int64_t val = 0) 107360784Sdim : Kind(kind), Loc(loc), Len(len), Done(false), Val(val) {} 108303231Sdim AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len, StringRef label) 109327952Sdim : AsmRewrite(kind, loc, len) { Label = label; } 110327952Sdim AsmRewrite(SMLoc loc, unsigned len, IntelExpr exp) 111327952Sdim : AsmRewrite(AOK_IntelExpr, loc, len) { IntelExp = exp; } 112303231Sdim}; 113303231Sdim 114303231Sdimstruct ParseInstructionInfo { 115321369Sdim SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr; 116303231Sdim 117321369Sdim ParseInstructionInfo() = default; 118303231Sdim ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites) 119303231Sdim : AsmRewrites(rewrites) {} 120303231Sdim}; 121303231Sdim 122314564Sdimenum OperandMatchResultTy { 123314564Sdim MatchOperand_Success, // operand matched successfully 124314564Sdim MatchOperand_NoMatch, // operand did not match 125314564Sdim MatchOperand_ParseFail // operand matched but had errors 126314564Sdim}; 127314564Sdim 128341825Sdimenum class DiagnosticPredicateTy { 129341825Sdim Match, 130341825Sdim NearMatch, 131341825Sdim NoMatch, 132341825Sdim}; 133341825Sdim 134341825Sdim// When an operand is parsed, the assembler will try to iterate through a set of 135341825Sdim// possible operand classes that the operand might match and call the 136341825Sdim// corresponding PredicateMethod to determine that. 137341825Sdim// 138341825Sdim// If there are two AsmOperands that would give a specific diagnostic if there 139341825Sdim// is no match, there is currently no mechanism to distinguish which operand is 140341825Sdim// a closer match. The DiagnosticPredicate distinguishes between 'completely 141341825Sdim// no match' and 'near match', so the assembler can decide whether to give a 142341825Sdim// specific diagnostic, or use 'InvalidOperand' and continue to find a 143341825Sdim// 'better matching' diagnostic. 144341825Sdim// 145341825Sdim// For example: 146341825Sdim// opcode opnd0, onpd1, opnd2 147341825Sdim// 148341825Sdim// where: 149341825Sdim// opnd2 could be an 'immediate of range [-8, 7]' 150341825Sdim// opnd2 could be a 'register + shift/extend'. 151341825Sdim// 152341825Sdim// If opnd2 is a valid register, but with a wrong shift/extend suffix, it makes 153341825Sdim// little sense to give a diagnostic that the operand should be an immediate 154341825Sdim// in range [-8, 7]. 155341825Sdim// 156341825Sdim// This is a light-weight alternative to the 'NearMissInfo' approach 157341825Sdim// below which collects *all* possible diagnostics. This alternative 158341825Sdim// is optional and fully backward compatible with existing 159341825Sdim// PredicateMethods that return a 'bool' (match or no match). 160341825Sdimstruct DiagnosticPredicate { 161341825Sdim DiagnosticPredicateTy Type; 162341825Sdim 163341825Sdim explicit DiagnosticPredicate(bool Match) 164341825Sdim : Type(Match ? DiagnosticPredicateTy::Match 165341825Sdim : DiagnosticPredicateTy::NearMatch) {} 166341825Sdim DiagnosticPredicate(DiagnosticPredicateTy T) : Type(T) {} 167341825Sdim DiagnosticPredicate(const DiagnosticPredicate &) = default; 168360784Sdim DiagnosticPredicate& operator=(const DiagnosticPredicate &) = default; 169341825Sdim 170341825Sdim operator bool() const { return Type == DiagnosticPredicateTy::Match; } 171341825Sdim bool isMatch() const { return Type == DiagnosticPredicateTy::Match; } 172341825Sdim bool isNearMatch() const { return Type == DiagnosticPredicateTy::NearMatch; } 173341825Sdim bool isNoMatch() const { return Type == DiagnosticPredicateTy::NoMatch; } 174341825Sdim}; 175341825Sdim 176327952Sdim// When matching of an assembly instruction fails, there may be multiple 177327952Sdim// encodings that are close to being a match. It's often ambiguous which one 178327952Sdim// the programmer intended to use, so we want to report an error which mentions 179327952Sdim// each of these "near-miss" encodings. This struct contains information about 180327952Sdim// one such encoding, and why it did not match the parsed instruction. 181327952Sdimclass NearMissInfo { 182327952Sdimpublic: 183327952Sdim enum NearMissKind { 184327952Sdim NoNearMiss, 185327952Sdim NearMissOperand, 186327952Sdim NearMissFeature, 187327952Sdim NearMissPredicate, 188327952Sdim NearMissTooFewOperands, 189327952Sdim }; 190327952Sdim 191327952Sdim // The encoding is valid for the parsed assembly string. This is only used 192327952Sdim // internally to the table-generated assembly matcher. 193327952Sdim static NearMissInfo getSuccess() { return NearMissInfo(); } 194327952Sdim 195327952Sdim // The instruction encoding is not valid because it requires some target 196327952Sdim // features that are not currently enabled. MissingFeatures has a bit set for 197327952Sdim // each feature that the encoding needs but which is not enabled. 198353358Sdim static NearMissInfo getMissedFeature(const FeatureBitset &MissingFeatures) { 199327952Sdim NearMissInfo Result; 200327952Sdim Result.Kind = NearMissFeature; 201327952Sdim Result.Features = MissingFeatures; 202327952Sdim return Result; 203327952Sdim } 204327952Sdim 205327952Sdim // The instruction encoding is not valid because the target-specific 206327952Sdim // predicate function returned an error code. FailureCode is the 207327952Sdim // target-specific error code returned by the predicate. 208327952Sdim static NearMissInfo getMissedPredicate(unsigned FailureCode) { 209327952Sdim NearMissInfo Result; 210327952Sdim Result.Kind = NearMissPredicate; 211327952Sdim Result.PredicateError = FailureCode; 212327952Sdim return Result; 213327952Sdim } 214327952Sdim 215327952Sdim // The instruction encoding is not valid because one (and only one) parsed 216327952Sdim // operand is not of the correct type. OperandError is the error code 217327952Sdim // relating to the operand class expected by the encoding. OperandClass is 218327952Sdim // the type of the expected operand. Opcode is the opcode of the encoding. 219327952Sdim // OperandIndex is the index into the parsed operand list. 220327952Sdim static NearMissInfo getMissedOperand(unsigned OperandError, 221327952Sdim unsigned OperandClass, unsigned Opcode, 222327952Sdim unsigned OperandIndex) { 223327952Sdim NearMissInfo Result; 224327952Sdim Result.Kind = NearMissOperand; 225327952Sdim Result.MissedOperand.Error = OperandError; 226327952Sdim Result.MissedOperand.Class = OperandClass; 227327952Sdim Result.MissedOperand.Opcode = Opcode; 228327952Sdim Result.MissedOperand.Index = OperandIndex; 229327952Sdim return Result; 230327952Sdim } 231327952Sdim 232327952Sdim // The instruction encoding is not valid because it expects more operands 233327952Sdim // than were parsed. OperandClass is the class of the expected operand that 234327952Sdim // was not provided. Opcode is the instruction encoding. 235327952Sdim static NearMissInfo getTooFewOperands(unsigned OperandClass, 236327952Sdim unsigned Opcode) { 237327952Sdim NearMissInfo Result; 238327952Sdim Result.Kind = NearMissTooFewOperands; 239327952Sdim Result.TooFewOperands.Class = OperandClass; 240327952Sdim Result.TooFewOperands.Opcode = Opcode; 241327952Sdim return Result; 242327952Sdim } 243327952Sdim 244327952Sdim operator bool() const { return Kind != NoNearMiss; } 245327952Sdim 246327952Sdim NearMissKind getKind() const { return Kind; } 247327952Sdim 248327952Sdim // Feature flags required by the instruction, that the current target does 249327952Sdim // not have. 250353358Sdim const FeatureBitset& getFeatures() const { 251327952Sdim assert(Kind == NearMissFeature); 252327952Sdim return Features; 253327952Sdim } 254327952Sdim // Error code returned by the target predicate when validating this 255327952Sdim // instruction encoding. 256327952Sdim unsigned getPredicateError() const { 257327952Sdim assert(Kind == NearMissPredicate); 258327952Sdim return PredicateError; 259327952Sdim } 260327952Sdim // MatchClassKind of the operand that we expected to see. 261327952Sdim unsigned getOperandClass() const { 262327952Sdim assert(Kind == NearMissOperand || Kind == NearMissTooFewOperands); 263327952Sdim return MissedOperand.Class; 264327952Sdim } 265327952Sdim // Opcode of the encoding we were trying to match. 266327952Sdim unsigned getOpcode() const { 267327952Sdim assert(Kind == NearMissOperand || Kind == NearMissTooFewOperands); 268327952Sdim return MissedOperand.Opcode; 269327952Sdim } 270327952Sdim // Error code returned when validating the operand. 271327952Sdim unsigned getOperandError() const { 272327952Sdim assert(Kind == NearMissOperand); 273327952Sdim return MissedOperand.Error; 274327952Sdim } 275327952Sdim // Index of the actual operand we were trying to match in the list of parsed 276327952Sdim // operands. 277327952Sdim unsigned getOperandIndex() const { 278327952Sdim assert(Kind == NearMissOperand); 279327952Sdim return MissedOperand.Index; 280327952Sdim } 281327952Sdim 282327952Sdimprivate: 283327952Sdim NearMissKind Kind; 284327952Sdim 285327952Sdim // These two structs share a common prefix, so we can safely rely on the fact 286327952Sdim // that they overlap in the union. 287327952Sdim struct MissedOpInfo { 288327952Sdim unsigned Class; 289327952Sdim unsigned Opcode; 290327952Sdim unsigned Error; 291327952Sdim unsigned Index; 292327952Sdim }; 293327952Sdim 294327952Sdim struct TooFewOperandsInfo { 295327952Sdim unsigned Class; 296327952Sdim unsigned Opcode; 297327952Sdim }; 298327952Sdim 299327952Sdim union { 300353358Sdim FeatureBitset Features; 301327952Sdim unsigned PredicateError; 302327952Sdim MissedOpInfo MissedOperand; 303327952Sdim TooFewOperandsInfo TooFewOperands; 304327952Sdim }; 305327952Sdim 306327952Sdim NearMissInfo() : Kind(NoNearMiss) {} 307327952Sdim}; 308327952Sdim 309303231Sdim/// MCTargetAsmParser - Generic interface to target specific assembly parsers. 310303231Sdimclass MCTargetAsmParser : public MCAsmParserExtension { 311303231Sdimpublic: 312303231Sdim enum MatchResultTy { 313303231Sdim Match_InvalidOperand, 314341825Sdim Match_InvalidTiedOperand, 315303231Sdim Match_MissingFeature, 316303231Sdim Match_MnemonicFail, 317303231Sdim Match_Success, 318327952Sdim Match_NearMisses, 319303231Sdim FIRST_TARGET_MATCH_RESULT_TY 320303231Sdim }; 321303231Sdim 322303231Sdimprotected: // Can only create subclasses. 323327952Sdim MCTargetAsmParser(MCTargetOptions const &, const MCSubtargetInfo &STI, 324327952Sdim const MCInstrInfo &MII); 325303231Sdim 326303231Sdim /// Create a copy of STI and return a non-const reference to it. 327303231Sdim MCSubtargetInfo ©STI(); 328303231Sdim 329303231Sdim /// AvailableFeatures - The current set of available features. 330353358Sdim FeatureBitset AvailableFeatures; 331303231Sdim 332303231Sdim /// ParsingInlineAsm - Are we parsing ms-style inline assembly? 333321369Sdim bool ParsingInlineAsm = false; 334303231Sdim 335303231Sdim /// SemaCallback - The Sema callback implementation. Must be set when parsing 336303231Sdim /// ms-style inline assembly. 337303231Sdim MCAsmParserSemaCallback *SemaCallback; 338303231Sdim 339303231Sdim /// Set of options which affects instrumentation of inline assembly. 340303231Sdim MCTargetOptions MCOptions; 341303231Sdim 342303231Sdim /// Current STI. 343303231Sdim const MCSubtargetInfo *STI; 344303231Sdim 345327952Sdim const MCInstrInfo &MII; 346327952Sdim 347303231Sdimpublic: 348321369Sdim MCTargetAsmParser(const MCTargetAsmParser &) = delete; 349321369Sdim MCTargetAsmParser &operator=(const MCTargetAsmParser &) = delete; 350321369Sdim 351303231Sdim ~MCTargetAsmParser() override; 352303231Sdim 353303231Sdim const MCSubtargetInfo &getSTI() const; 354303231Sdim 355353358Sdim const FeatureBitset& getAvailableFeatures() const { 356353358Sdim return AvailableFeatures; 357353358Sdim } 358353358Sdim void setAvailableFeatures(const FeatureBitset& Value) { 359353358Sdim AvailableFeatures = Value; 360353358Sdim } 361303231Sdim 362303231Sdim bool isParsingInlineAsm () { return ParsingInlineAsm; } 363303231Sdim void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; } 364303231Sdim 365303231Sdim MCTargetOptions getTargetOptions() const { return MCOptions; } 366303231Sdim 367303231Sdim void setSemaCallback(MCAsmParserSemaCallback *Callback) { 368303231Sdim SemaCallback = Callback; 369303231Sdim } 370303231Sdim 371341825Sdim // Target-specific parsing of expression. 372341825Sdim virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 373341825Sdim return getParser().parsePrimaryExpr(Res, EndLoc); 374341825Sdim } 375341825Sdim 376303231Sdim virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 377303231Sdim SMLoc &EndLoc) = 0; 378303231Sdim 379303231Sdim /// ParseInstruction - Parse one assembly instruction. 380303231Sdim /// 381303231Sdim /// The parser is positioned following the instruction name. The target 382303231Sdim /// specific instruction parser should parse the entire instruction and 383303231Sdim /// construct the appropriate MCInst, or emit an error. On success, the entire 384303231Sdim /// line should be parsed up to and including the end-of-statement token. On 385303231Sdim /// failure, the parser is not required to read to the end of the line. 386303231Sdim // 387303231Sdim /// \param Name - The instruction name. 388303231Sdim /// \param NameLoc - The source location of the name. 389303231Sdim /// \param Operands [out] - The list of parsed operands, this returns 390303231Sdim /// ownership of them to the caller. 391303231Sdim /// \return True on failure. 392303231Sdim virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 393303231Sdim SMLoc NameLoc, OperandVector &Operands) = 0; 394303231Sdim virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 395303231Sdim AsmToken Token, OperandVector &Operands) { 396303231Sdim return ParseInstruction(Info, Name, Token.getLoc(), Operands); 397303231Sdim } 398303231Sdim 399303231Sdim /// ParseDirective - Parse a target specific assembler directive 400303231Sdim /// 401303231Sdim /// The parser is positioned following the directive name. The target 402303231Sdim /// specific directive parser should parse the entire directive doing or 403303231Sdim /// recording any target specific work, or return true and do nothing if the 404303231Sdim /// directive is not target specific. If the directive is specific for 405303231Sdim /// the target, the entire line is parsed up to and including the 406303231Sdim /// end-of-statement token and false is returned. 407303231Sdim /// 408303231Sdim /// \param DirectiveID - the identifier token of the directive. 409303231Sdim virtual bool ParseDirective(AsmToken DirectiveID) = 0; 410303231Sdim 411303231Sdim /// MatchAndEmitInstruction - Recognize a series of operands of a parsed 412303231Sdim /// instruction as an actual MCInst and emit it to the specified MCStreamer. 413303231Sdim /// This returns false on success and returns true on failure to match. 414303231Sdim /// 415303231Sdim /// On failure, the target parser is responsible for emitting a diagnostic 416303231Sdim /// explaining the match failure. 417303231Sdim virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 418303231Sdim OperandVector &Operands, MCStreamer &Out, 419303231Sdim uint64_t &ErrorInfo, 420303231Sdim bool MatchingInlineAsm) = 0; 421303231Sdim 422303231Sdim /// Allows targets to let registers opt out of clobber lists. 423303231Sdim virtual bool OmitRegisterFromClobberLists(unsigned RegNo) { return false; } 424303231Sdim 425303231Sdim /// Allow a target to add special case operand matching for things that 426303231Sdim /// tblgen doesn't/can't handle effectively. For example, literal 427303231Sdim /// immediates on ARM. TableGen expects a token operand, but the parser 428303231Sdim /// will recognize them as immediates. 429303231Sdim virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 430303231Sdim unsigned Kind) { 431303231Sdim return Match_InvalidOperand; 432303231Sdim } 433303231Sdim 434314564Sdim /// Validate the instruction match against any complex target predicates 435314564Sdim /// before rendering any operands to it. 436314564Sdim virtual unsigned 437314564Sdim checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands) { 438314564Sdim return Match_Success; 439314564Sdim } 440314564Sdim 441303231Sdim /// checkTargetMatchPredicate - Validate the instruction match against 442303231Sdim /// any complex target predicates not expressible via match classes. 443303231Sdim virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { 444303231Sdim return Match_Success; 445303231Sdim } 446303231Sdim 447303231Sdim virtual void convertToMapAndConstraints(unsigned Kind, 448303231Sdim const OperandVector &Operands) = 0; 449303231Sdim 450341825Sdim /// Returns whether two registers are equal and is used by the tied-operands 451341825Sdim /// checks in the AsmMatcher. This method can be overridden allow e.g. a 452341825Sdim /// sub- or super-register as the tied operand. 453341825Sdim virtual bool regsEqual(const MCParsedAsmOperand &Op1, 454341825Sdim const MCParsedAsmOperand &Op2) const { 455341825Sdim assert(Op1.isReg() && Op2.isReg() && "Operands not all regs"); 456341825Sdim return Op1.getReg() == Op2.getReg(); 457341825Sdim } 458341825Sdim 459303231Sdim // Return whether this parser uses assignment statements with equals tokens 460303231Sdim virtual bool equalIsAsmAssignment() { return true; }; 461303231Sdim // Return whether this start of statement identifier is a label 462303231Sdim virtual bool isLabel(AsmToken &Token) { return true; }; 463327952Sdim // Return whether this parser accept star as start of statement 464327952Sdim virtual bool starIsStartOfStatement() { return false; }; 465303231Sdim 466303231Sdim virtual const MCExpr *applyModifierToExpr(const MCExpr *E, 467303231Sdim MCSymbolRefExpr::VariantKind, 468303231Sdim MCContext &Ctx) { 469303231Sdim return nullptr; 470303231Sdim } 471303231Sdim 472344779Sdim // For actions that have to be performed before a label is emitted 473344779Sdim virtual void doBeforeLabelEmit(MCSymbol *Symbol) {} 474344779Sdim 475321369Sdim virtual void onLabelParsed(MCSymbol *Symbol) {} 476314564Sdim 477314564Sdim /// Ensure that all previously parsed instructions have been emitted to the 478314564Sdim /// output streamer, if the target does not emit them immediately. 479321369Sdim virtual void flushPendingInstructions(MCStreamer &Out) {} 480314564Sdim 481314564Sdim virtual const MCExpr *createTargetUnaryExpr(const MCExpr *E, 482314564Sdim AsmToken::TokenKind OperatorToken, 483314564Sdim MCContext &Ctx) { 484314564Sdim return nullptr; 485314564Sdim } 486344779Sdim 487344779Sdim // For any checks or cleanups at the end of parsing. 488344779Sdim virtual void onEndOfFile() {} 489303231Sdim}; 490303231Sdim 491321369Sdim} // end namespace llvm 492303231Sdim 493321369Sdim#endif // LLVM_MC_MCPARSER_MCTARGETASMPARSER_H 494