//===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_MC_MCEXPR_H
#define LLVM_MC_MCEXPR_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/SMLoc.h"
#include <cstdint>

namespace llvm {

class MCAsmInfo;
class MCAsmLayout;
class MCAssembler;
class MCContext;
class MCFixup;
class MCFragment;
class MCSection;
class MCStreamer;
class MCSymbol;
class MCValue;
class raw_ostream;
class StringRef;

using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;

/// Base class for the full range of assembler expressions which are
/// needed for parsing.
class MCExpr {
public:
  enum ExprKind : uint8_t {
    Binary,    ///< Binary expressions.
    Constant,  ///< Constant expressions.
    SymbolRef, ///< References to labels and assigned expressions.
    Unary,     ///< Unary expressions.
    Target     ///< Target specific expression.
  };

private:
  static const unsigned NumSubclassDataBits = 24;
  static_assert(
      NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)),
      "ExprKind and SubclassData together should take up one word");

  ExprKind Kind;
  /// Field reserved for use by MCExpr subclasses.
  unsigned SubclassData : NumSubclassDataBits;
  SMLoc Loc;

  bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
                          const MCAsmLayout *Layout,
                          const SectionAddrMap *Addrs, bool InSet) const;

protected:
  explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0)
      : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
    assert(SubclassData < (1 << NumSubclassDataBits) &&
           "Subclass data too large");
  }

  bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
                                 const MCAsmLayout *Layout,
                                 const MCFixup *Fixup,
                                 const SectionAddrMap *Addrs, bool InSet) const;

  unsigned getSubclassData() const { return SubclassData; }

public:
  MCExpr(const MCExpr &) = delete;
  MCExpr &operator=(const MCExpr &) = delete;

  /// \name Accessors
  /// @{

  ExprKind getKind() const { return Kind; }
  SMLoc getLoc() const { return Loc; }

  /// @}
  /// \name Utility Methods
  /// @{

  void print(raw_ostream &OS, const MCAsmInfo *MAI,
             bool InParens = false) const;
  void dump() const;

  /// @}
  /// \name Expression Evaluation
  /// @{

  /// Try to evaluate the expression to an absolute value.
  ///
  /// \param Res - The absolute value, if evaluation succeeds.
  /// \param Layout - The assembler layout object to use for evaluating symbol
  /// values. If not given, then only non-symbolic expressions will be
  /// evaluated.
  /// \return - True on success.
  bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
                          const SectionAddrMap &Addrs) const;
  bool evaluateAsAbsolute(int64_t &Res) const;
  bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
  bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const;
  bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;

  bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;

  /// Try to evaluate the expression to a relocatable value, i.e. an
  /// expression of the fixed form (a - b + constant).
  ///
  /// \param Res - The relocatable value, if evaluation succeeds.
  /// \param Layout - The assembler layout object to use for evaluating values.
  /// \param Fixup - The Fixup object if available.
  /// \return - True on success.
  bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
                             const MCFixup *Fixup) const;

  /// Try to evaluate the expression to the form (a - b + constant) where
  /// neither a nor b are variables.
  ///
  /// This is a more aggressive variant of evaluateAsRelocatable. The intended
  /// use is for when relocations are not available, like the .size directive.
  bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;

  /// Find the "associated section" for this expression, which is
  /// currently defined as the absolute section for constants, or
  /// otherwise the section associated with the first defined symbol in the
  /// expression.
  MCFragment *findAssociatedFragment() const;

  /// @}
};

inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
  E.print(OS, nullptr);
  return OS;
}

////  Represent a constant integer expression.
class MCConstantExpr : public MCExpr {
  int64_t Value;

  // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
  static const unsigned SizeInBytesBits = 8;
  static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
  static const unsigned PrintInHexBit = 1 << SizeInBytesBits;

  static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
    assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
    return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
  }

  MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
      : MCExpr(MCExpr::Constant, SMLoc(),
               encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}

public:
  /// \name Construction
  /// @{

  static const MCConstantExpr *create(int64_t Value, MCContext &Ctx,
                                      bool PrintInHex = false,
                                      unsigned SizeInBytes = 0);

  /// @}
  /// \name Accessors
  /// @{

  int64_t getValue() const { return Value; }
  unsigned getSizeInBytes() const {
    return getSubclassData() & SizeInBytesMask;
  }

  bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; }

  /// @}

  static bool classof(const MCExpr *E) {
    return E->getKind() == MCExpr::Constant;
  }
};

///  Represent a reference to a symbol from inside an expression.
///
/// A symbol reference in an expression may be a use of a label, a use of an
/// assembler variable (defined constant), or constitute an implicit definition
/// of the symbol as external.
class MCSymbolRefExpr : public MCExpr {
public:
  enum VariantKind : uint16_t {
    VK_None,
    VK_Invalid,

    VK_GOT,
    VK_GOTOFF,
    VK_GOTREL,
    VK_PCREL,
    VK_GOTPCREL,
    VK_GOTTPOFF,
    VK_INDNTPOFF,
    VK_NTPOFF,
    VK_GOTNTPOFF,
    VK_PLT,
    VK_TLSGD,
    VK_TLSLD,
    VK_TLSLDM,
    VK_TPOFF,
    VK_DTPOFF,
    VK_TLSCALL, // symbol(tlscall)
    VK_TLSDESC, // symbol(tlsdesc)
    VK_TLVP,    // Mach-O thread local variable relocations
    VK_TLVPPAGE,
    VK_TLVPPAGEOFF,
    VK_PAGE,
    VK_PAGEOFF,
    VK_GOTPAGE,
    VK_GOTPAGEOFF,
    VK_SECREL,
    VK_SIZE,    // symbol@SIZE
    VK_WEAKREF, // The link between the symbols in .weakref foo, bar

    VK_X86_ABS8,

    VK_ARM_NONE,
    VK_ARM_GOT_PREL,
    VK_ARM_TARGET1,
    VK_ARM_TARGET2,
    VK_ARM_PREL31,
    VK_ARM_SBREL,  // symbol(sbrel)
    VK_ARM_TLSLDO, // symbol(tlsldo)
    VK_ARM_TLSDESCSEQ,

    VK_AVR_NONE,
    VK_AVR_LO8,
    VK_AVR_HI8,
    VK_AVR_HLO8,
    VK_AVR_DIFF8,
    VK_AVR_DIFF16,
    VK_AVR_DIFF32,

    VK_PPC_LO,              // symbol@l
    VK_PPC_HI,              // symbol@h
    VK_PPC_HA,              // symbol@ha
    VK_PPC_HIGH,            // symbol@high
    VK_PPC_HIGHA,           // symbol@higha
    VK_PPC_HIGHER,          // symbol@higher
    VK_PPC_HIGHERA,         // symbol@highera
    VK_PPC_HIGHEST,         // symbol@highest
    VK_PPC_HIGHESTA,        // symbol@highesta
    VK_PPC_GOT_LO,          // symbol@got@l
    VK_PPC_GOT_HI,          // symbol@got@h
    VK_PPC_GOT_HA,          // symbol@got@ha
    VK_PPC_TOCBASE,         // symbol@tocbase
    VK_PPC_TOC,             // symbol@toc
    VK_PPC_TOC_LO,          // symbol@toc@l
    VK_PPC_TOC_HI,          // symbol@toc@h
    VK_PPC_TOC_HA,          // symbol@toc@ha
    VK_PPC_U,               // symbol@u
    VK_PPC_L,               // symbol@l
    VK_PPC_DTPMOD,          // symbol@dtpmod
    VK_PPC_TPREL_LO,        // symbol@tprel@l
    VK_PPC_TPREL_HI,        // symbol@tprel@h
    VK_PPC_TPREL_HA,        // symbol@tprel@ha
    VK_PPC_TPREL_HIGH,      // symbol@tprel@high
    VK_PPC_TPREL_HIGHA,     // symbol@tprel@higha
    VK_PPC_TPREL_HIGHER,    // symbol@tprel@higher
    VK_PPC_TPREL_HIGHERA,   // symbol@tprel@highera
    VK_PPC_TPREL_HIGHEST,   // symbol@tprel@highest
    VK_PPC_TPREL_HIGHESTA,  // symbol@tprel@highesta
    VK_PPC_DTPREL_LO,       // symbol@dtprel@l
    VK_PPC_DTPREL_HI,       // symbol@dtprel@h
    VK_PPC_DTPREL_HA,       // symbol@dtprel@ha
    VK_PPC_DTPREL_HIGH,     // symbol@dtprel@high
    VK_PPC_DTPREL_HIGHA,    // symbol@dtprel@higha
    VK_PPC_DTPREL_HIGHER,   // symbol@dtprel@higher
    VK_PPC_DTPREL_HIGHERA,  // symbol@dtprel@highera
    VK_PPC_DTPREL_HIGHEST,  // symbol@dtprel@highest
    VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta
    VK_PPC_GOT_TPREL,       // symbol@got@tprel
    VK_PPC_GOT_TPREL_LO,    // symbol@got@tprel@l
    VK_PPC_GOT_TPREL_HI,    // symbol@got@tprel@h
    VK_PPC_GOT_TPREL_HA,    // symbol@got@tprel@ha
    VK_PPC_GOT_DTPREL,      // symbol@got@dtprel
    VK_PPC_GOT_DTPREL_LO,   // symbol@got@dtprel@l
    VK_PPC_GOT_DTPREL_HI,   // symbol@got@dtprel@h
    VK_PPC_GOT_DTPREL_HA,   // symbol@got@dtprel@ha
    VK_PPC_TLS,             // symbol@tls
    VK_PPC_GOT_TLSGD,       // symbol@got@tlsgd
    VK_PPC_GOT_TLSGD_LO,    // symbol@got@tlsgd@l
    VK_PPC_GOT_TLSGD_HI,    // symbol@got@tlsgd@h
    VK_PPC_GOT_TLSGD_HA,    // symbol@got@tlsgd@ha
    VK_PPC_TLSGD,           // symbol@tlsgd
    VK_PPC_GOT_TLSLD,       // symbol@got@tlsld
    VK_PPC_GOT_TLSLD_LO,    // symbol@got@tlsld@l
    VK_PPC_GOT_TLSLD_HI,    // symbol@got@tlsld@h
    VK_PPC_GOT_TLSLD_HA,    // symbol@got@tlsld@ha
    VK_PPC_GOT_PCREL,       // symbol@got@pcrel
    VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
    VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel
    VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
    VK_PPC_TLS_PCREL,       // symbol@tls@pcrel
    VK_PPC_TLSLD,           // symbol@tlsld
    VK_PPC_LOCAL,           // symbol@local
    VK_PPC_NOTOC,           // symbol@notoc
    VK_PPC_PCREL_OPT,       // .reloc expr, R_PPC64_PCREL_OPT, expr

    VK_COFF_IMGREL32, // symbol@imgrel (image-relative)

    VK_Hexagon_LO16,
    VK_Hexagon_HI16,
    VK_Hexagon_GPREL,
    VK_Hexagon_GD_GOT,
    VK_Hexagon_LD_GOT,
    VK_Hexagon_GD_PLT,
    VK_Hexagon_LD_PLT,
    VK_Hexagon_IE,
    VK_Hexagon_IE_GOT,

    VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
    VK_WASM_MBREL,     // Memory address relative to memory base
    VK_WASM_TBREL,     // Table index relative to table bare

    VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
    VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
    VK_AMDGPU_REL32_LO,      // symbol@rel32@lo
    VK_AMDGPU_REL32_HI,      // symbol@rel32@hi
    VK_AMDGPU_REL64,         // symbol@rel64
    VK_AMDGPU_ABS32_LO,      // symbol@abs32@lo
    VK_AMDGPU_ABS32_HI,      // symbol@abs32@hi

    VK_VE_HI32,        // symbol@hi
    VK_VE_LO32,        // symbol@lo
    VK_VE_PC_HI32,     // symbol@pc_hi
    VK_VE_PC_LO32,     // symbol@pc_lo
    VK_VE_GOT_HI32,    // symbol@got_hi
    VK_VE_GOT_LO32,    // symbol@got_lo
    VK_VE_GOTOFF_HI32, // symbol@gotoff_hi
    VK_VE_GOTOFF_LO32, // symbol@gotoff_lo
    VK_VE_PLT_HI32,    // symbol@plt_hi
    VK_VE_PLT_LO32,    // symbol@plt_lo
    VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi
    VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo
    VK_VE_TPOFF_HI32,  // symbol@tpoff_hi
    VK_VE_TPOFF_LO32,  // symbol@tpoff_lo

    VK_TPREL,
    VK_DTPREL
  };

private:
  /// The symbol being referenced.
  const MCSymbol *Symbol;

  // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols
  // in bit 16.
  static const unsigned VariantKindBits = 16;
  static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;

  // FIXME: Remove this bit.
  static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits;

  static unsigned encodeSubclassData(VariantKind Kind,
                                     bool HasSubsectionsViaSymbols) {
    return (unsigned)Kind |
           (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
  }

  explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
                           const MCAsmInfo *MAI, SMLoc Loc = SMLoc());

public:
  /// \name Construction
  /// @{

  static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
    return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
  }

  static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
                                       MCContext &Ctx, SMLoc Loc = SMLoc());
  static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
                                       MCContext &Ctx);

  /// @}
  /// \name Accessors
  /// @{

  const MCSymbol &getSymbol() const { return *Symbol; }

  VariantKind getKind() const {
    return (VariantKind)(getSubclassData() & VariantKindMask);
  }

  bool hasSubsectionsViaSymbols() const {
    return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
  }

  /// @}
  /// \name Static Utility Functions
  /// @{

  static StringRef getVariantKindName(VariantKind Kind);

  static VariantKind getVariantKindForName(StringRef Name);

  /// @}

  static bool classof(const MCExpr *E) {
    return E->getKind() == MCExpr::SymbolRef;
  }
};

/// Unary assembler expressions.
class MCUnaryExpr : public MCExpr {
public:
  enum Opcode {
    LNot,  ///< Logical negation.
    Minus, ///< Unary minus.
    Not,   ///< Bitwise negation.
    Plus   ///< Unary plus.
  };

private:
  const MCExpr *Expr;

  MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
      : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}

public:
  /// \name Construction
  /// @{

  static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
                                   MCContext &Ctx, SMLoc Loc = SMLoc());

  static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    return create(LNot, Expr, Ctx, Loc);
  }

  static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    return create(Minus, Expr, Ctx, Loc);
  }

  static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    return create(Not, Expr, Ctx, Loc);
  }

  static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    return create(Plus, Expr, Ctx, Loc);
  }

  /// @}
  /// \name Accessors
  /// @{

  /// Get the kind of this unary expression.
  Opcode getOpcode() const { return (Opcode)getSubclassData(); }

  /// Get the child of this unary expression.
  const MCExpr *getSubExpr() const { return Expr; }

  /// @}

  static bool classof(const MCExpr *E) {
    return E->getKind() == MCExpr::Unary;
  }
};

/// Binary assembler expressions.
class MCBinaryExpr : public MCExpr {
public:
  enum Opcode {
    Add,  ///< Addition.
    And,  ///< Bitwise and.
    Div,  ///< Signed division.
    EQ,   ///< Equality comparison.
    GT,   ///< Signed greater than comparison (result is either 0 or some
          ///< target-specific non-zero value)
    GTE,  ///< Signed greater than or equal comparison (result is either 0 or
          ///< some target-specific non-zero value).
    LAnd, ///< Logical and.
    LOr,  ///< Logical or.
    LT,   ///< Signed less than comparison (result is either 0 or
          ///< some target-specific non-zero value).
    LTE,  ///< Signed less than or equal comparison (result is either 0 or
          ///< some target-specific non-zero value).
    Mod,  ///< Signed remainder.
    Mul,  ///< Multiplication.
    NE,   ///< Inequality comparison.
    Or,   ///< Bitwise or.
    OrNot, ///< Bitwise or not.
    Shl,  ///< Shift left.
    AShr, ///< Arithmetic shift right.
    LShr, ///< Logical shift right.
    Sub,  ///< Subtraction.
    Xor   ///< Bitwise exclusive or.
  };

private:
  const MCExpr *LHS, *RHS;

  MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
               SMLoc Loc = SMLoc())
      : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}

public:
  /// \name Construction
  /// @{

  static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
                                    const MCExpr *RHS, MCContext &Ctx,
                                    SMLoc Loc = SMLoc());

  static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Add, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(And, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Div, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
                                      MCContext &Ctx) {
    return create(EQ, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
                                      MCContext &Ctx) {
    return create(GT, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(GTE, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
                                        MCContext &Ctx) {
    return create(LAnd, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(LOr, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
                                      MCContext &Ctx) {
    return create(LT, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(LTE, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Mod, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Mul, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
                                      MCContext &Ctx) {
    return create(NE, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
                                      MCContext &Ctx) {
    return create(Or, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Shl, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(AShr, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(LShr, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Sub, LHS, RHS, Ctx);
  }

  static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
                                       MCContext &Ctx) {
    return create(Xor, LHS, RHS, Ctx);
  }

  /// @}
  /// \name Accessors
  /// @{

  /// Get the kind of this binary expression.
  Opcode getOpcode() const { return (Opcode)getSubclassData(); }

  /// Get the left-hand side expression of the binary operator.
  const MCExpr *getLHS() const { return LHS; }

  /// Get the right-hand side expression of the binary operator.
  const MCExpr *getRHS() const { return RHS; }

  /// @}

  static bool classof(const MCExpr *E) {
    return E->getKind() == MCExpr::Binary;
  }
};

/// This is an extension point for target-specific MCExpr subclasses to
/// implement.
///
/// NOTE: All subclasses are required to have trivial destructors because
/// MCExprs are bump pointer allocated and not destructed.
class MCTargetExpr : public MCExpr {
  virtual void anchor();

protected:
  MCTargetExpr() : MCExpr(Target, SMLoc()) {}
  virtual ~MCTargetExpr() = default;

public:
  virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
  virtual bool evaluateAsRelocatableImpl(MCValue &Res,
                                         const MCAsmLayout *Layout,
                                         const MCFixup *Fixup) const = 0;
  // allow Target Expressions to be checked for equality
  virtual bool isEqualTo(const MCExpr *x) const { return false; }
  // This should be set when assigned expressions are not valid ".set"
  // expressions, e.g. registers, and must be inlined.
  virtual bool inlineAssignedExpr() const { return false; }
  virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
  virtual MCFragment *findAssociatedFragment() const = 0;

  virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;

  static bool classof(const MCExpr *E) {
    return E->getKind() == MCExpr::Target;
  }
};

} // end namespace llvm

#endif // LLVM_MC_MCEXPR_H
