Home | History | Annotate | Download | only in MC
      1 //===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_MC_MCEXPR_H
     11 #define LLVM_MC_MCEXPR_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/Support/SMLoc.h"
     15 #include <cstdint>
     16 
     17 namespace llvm {
     18 
     19 class MCAsmInfo;
     20 class MCAsmLayout;
     21 class MCAssembler;
     22 class MCContext;
     23 class MCFixup;
     24 class MCFragment;
     25 class MCSection;
     26 class MCStreamer;
     27 class MCSymbol;
     28 class MCValue;
     29 class raw_ostream;
     30 class StringRef;
     31 typedef DenseMap<const MCSection *, uint64_t> SectionAddrMap;
     32 
     33 /// \brief Base class for the full range of assembler expressions which are
     34 /// needed for parsing.
     35 class MCExpr {
     36 public:
     37   enum ExprKind {
     38     Binary,    ///< Binary expressions.
     39     Constant,  ///< Constant expressions.
     40     SymbolRef, ///< References to labels and assigned expressions.
     41     Unary,     ///< Unary expressions.
     42     Target     ///< Target specific expression.
     43   };
     44 
     45 private:
     46   ExprKind Kind;
     47   SMLoc Loc;
     48 
     49   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
     50                           const MCAsmLayout *Layout,
     51                           const SectionAddrMap *Addrs) const;
     52 
     53   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
     54                           const MCAsmLayout *Layout,
     55                           const SectionAddrMap *Addrs, bool InSet) const;
     56 
     57 protected:
     58   explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
     59 
     60   bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
     61                                  const MCAsmLayout *Layout,
     62                                  const MCFixup *Fixup,
     63                                  const SectionAddrMap *Addrs, bool InSet) const;
     64 
     65 public:
     66   MCExpr(const MCExpr &) = delete;
     67   MCExpr &operator=(const MCExpr &) = delete;
     68 
     69   /// \name Accessors
     70   /// @{
     71 
     72   ExprKind getKind() const { return Kind; }
     73   SMLoc getLoc() const { return Loc; }
     74 
     75   /// @}
     76   /// \name Utility Methods
     77   /// @{
     78 
     79   void print(raw_ostream &OS, const MCAsmInfo *MAI,
     80              bool InParens = false) const;
     81   void dump() const;
     82 
     83   /// @}
     84   /// \name Expression Evaluation
     85   /// @{
     86 
     87   /// \brief Try to evaluate the expression to an absolute value.
     88   ///
     89   /// \param Res - The absolute value, if evaluation succeeds.
     90   /// \param Layout - The assembler layout object to use for evaluating symbol
     91   /// values. If not given, then only non-symbolic expressions will be
     92   /// evaluated.
     93   /// \return - True on success.
     94   bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
     95                           const SectionAddrMap &Addrs) const;
     96   bool evaluateAsAbsolute(int64_t &Res) const;
     97   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
     98   bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
     99 
    100   bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
    101 
    102   /// \brief Try to evaluate the expression to a relocatable value, i.e. an
    103   /// expression of the fixed form (a - b + constant).
    104   ///
    105   /// \param Res - The relocatable value, if evaluation succeeds.
    106   /// \param Layout - The assembler layout object to use for evaluating values.
    107   /// \param Fixup - The Fixup object if available.
    108   /// \return - True on success.
    109   bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
    110                              const MCFixup *Fixup) const;
    111 
    112   /// \brief Try to evaluate the expression to the form (a - b + constant) where
    113   /// neither a nor b are variables.
    114   ///
    115   /// This is a more aggressive variant of evaluateAsRelocatable. The intended
    116   /// use is for when relocations are not available, like the .size directive.
    117   bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
    118 
    119   /// \brief Find the "associated section" for this expression, which is
    120   /// currently defined as the absolute section for constants, or
    121   /// otherwise the section associated with the first defined symbol in the
    122   /// expression.
    123   MCFragment *findAssociatedFragment() const;
    124 
    125   /// @}
    126 };
    127 
    128 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
    129   E.print(OS, nullptr);
    130   return OS;
    131 }
    132 
    133 //// \brief  Represent a constant integer expression.
    134 class MCConstantExpr : public MCExpr {
    135   int64_t Value;
    136 
    137   explicit MCConstantExpr(int64_t Value)
    138       : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
    139 
    140 public:
    141   /// \name Construction
    142   /// @{
    143 
    144   static const MCConstantExpr *create(int64_t Value, MCContext &Ctx);
    145 
    146   /// @}
    147   /// \name Accessors
    148   /// @{
    149 
    150   int64_t getValue() const { return Value; }
    151 
    152   /// @}
    153 
    154   static bool classof(const MCExpr *E) {
    155     return E->getKind() == MCExpr::Constant;
    156   }
    157 };
    158 
    159 /// \brief  Represent a reference to a symbol from inside an expression.
    160 ///
    161 /// A symbol reference in an expression may be a use of a label, a use of an
    162 /// assembler variable (defined constant), or constitute an implicit definition
    163 /// of the symbol as external.
    164 class MCSymbolRefExpr : public MCExpr {
    165 public:
    166   enum VariantKind : uint16_t {
    167     VK_None,
    168     VK_Invalid,
    169 
    170     VK_GOT,
    171     VK_GOTOFF,
    172     VK_GOTREL,
    173     VK_GOTPCREL,
    174     VK_GOTTPOFF,
    175     VK_INDNTPOFF,
    176     VK_NTPOFF,
    177     VK_GOTNTPOFF,
    178     VK_PLT,
    179     VK_TLSGD,
    180     VK_TLSLD,
    181     VK_TLSLDM,
    182     VK_TPOFF,
    183     VK_DTPOFF,
    184     VK_TLSCALL,   // symbol(tlscall)
    185     VK_TLSDESC,   // symbol(tlsdesc)
    186     VK_TLVP,      // Mach-O thread local variable relocations
    187     VK_TLVPPAGE,
    188     VK_TLVPPAGEOFF,
    189     VK_PAGE,
    190     VK_PAGEOFF,
    191     VK_GOTPAGE,
    192     VK_GOTPAGEOFF,
    193     VK_SECREL,
    194     VK_SIZE,      // symbol@SIZE
    195     VK_WEAKREF,   // The link between the symbols in .weakref foo, bar
    196 
    197     VK_X86_ABS8,
    198 
    199     VK_ARM_NONE,
    200     VK_ARM_GOT_PREL,
    201     VK_ARM_TARGET1,
    202     VK_ARM_TARGET2,
    203     VK_ARM_PREL31,
    204     VK_ARM_SBREL,          // symbol(sbrel)
    205     VK_ARM_TLSLDO,         // symbol(tlsldo)
    206     VK_ARM_TLSDESCSEQ,
    207 
    208     VK_PPC_LO,             // symbol@l
    209     VK_PPC_HI,             // symbol@h
    210     VK_PPC_HA,             // symbol@ha
    211     VK_PPC_HIGHER,         // symbol@higher
    212     VK_PPC_HIGHERA,        // symbol@highera
    213     VK_PPC_HIGHEST,        // symbol@highest
    214     VK_PPC_HIGHESTA,       // symbol@highesta
    215     VK_PPC_GOT_LO,         // symbol@got@l
    216     VK_PPC_GOT_HI,         // symbol@got@h
    217     VK_PPC_GOT_HA,         // symbol@got@ha
    218     VK_PPC_TOCBASE,        // symbol@tocbase
    219     VK_PPC_TOC,            // symbol@toc
    220     VK_PPC_TOC_LO,         // symbol@toc@l
    221     VK_PPC_TOC_HI,         // symbol@toc@h
    222     VK_PPC_TOC_HA,         // symbol@toc@ha
    223     VK_PPC_DTPMOD,         // symbol@dtpmod
    224     VK_PPC_TPREL_LO,       // symbol@tprel@l
    225     VK_PPC_TPREL_HI,       // symbol@tprel@h
    226     VK_PPC_TPREL_HA,       // symbol@tprel@ha
    227     VK_PPC_TPREL_HIGHER,   // symbol@tprel@higher
    228     VK_PPC_TPREL_HIGHERA,  // symbol@tprel@highera
    229     VK_PPC_TPREL_HIGHEST,  // symbol@tprel@highest
    230     VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
    231     VK_PPC_DTPREL_LO,      // symbol@dtprel@l
    232     VK_PPC_DTPREL_HI,      // symbol@dtprel@h
    233     VK_PPC_DTPREL_HA,      // symbol@dtprel@ha
    234     VK_PPC_DTPREL_HIGHER,  // symbol@dtprel@higher
    235     VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
    236     VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
    237     VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
    238     VK_PPC_GOT_TPREL,      // symbol@got@tprel
    239     VK_PPC_GOT_TPREL_LO,   // symbol@got@tprel@l
    240     VK_PPC_GOT_TPREL_HI,   // symbol@got@tprel@h
    241     VK_PPC_GOT_TPREL_HA,   // symbol@got@tprel@ha
    242     VK_PPC_GOT_DTPREL,     // symbol@got@dtprel
    243     VK_PPC_GOT_DTPREL_LO,  // symbol@got@dtprel@l
    244     VK_PPC_GOT_DTPREL_HI,  // symbol@got@dtprel@h
    245     VK_PPC_GOT_DTPREL_HA,  // symbol@got@dtprel@ha
    246     VK_PPC_TLS,            // symbol@tls
    247     VK_PPC_GOT_TLSGD,      // symbol@got@tlsgd
    248     VK_PPC_GOT_TLSGD_LO,   // symbol@got@tlsgd@l
    249     VK_PPC_GOT_TLSGD_HI,   // symbol@got@tlsgd@h
    250     VK_PPC_GOT_TLSGD_HA,   // symbol@got@tlsgd@ha
    251     VK_PPC_TLSGD,          // symbol@tlsgd
    252     VK_PPC_GOT_TLSLD,      // symbol@got@tlsld
    253     VK_PPC_GOT_TLSLD_LO,   // symbol@got@tlsld@l
    254     VK_PPC_GOT_TLSLD_HI,   // symbol@got@tlsld@h
    255     VK_PPC_GOT_TLSLD_HA,   // symbol@got@tlsld@ha
    256     VK_PPC_TLSLD,          // symbol@tlsld
    257     VK_PPC_LOCAL,          // symbol@local
    258 
    259     VK_COFF_IMGREL32, // symbol@imgrel (image-relative)
    260 
    261     VK_Hexagon_PCREL,
    262     VK_Hexagon_LO16,
    263     VK_Hexagon_HI16,
    264     VK_Hexagon_GPREL,
    265     VK_Hexagon_GD_GOT,
    266     VK_Hexagon_LD_GOT,
    267     VK_Hexagon_GD_PLT,
    268     VK_Hexagon_LD_PLT,
    269     VK_Hexagon_IE,
    270     VK_Hexagon_IE_GOT,
    271 
    272     VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr
    273     VK_WebAssembly_TYPEINDEX,// Type table index
    274 
    275     VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
    276     VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
    277     VK_AMDGPU_REL32_LO,      // symbol@rel32@lo
    278     VK_AMDGPU_REL32_HI,      // symbol@rel32@hi
    279 
    280     VK_TPREL,
    281     VK_DTPREL
    282   };
    283 
    284 private:
    285   /// The symbol reference modifier.
    286   const VariantKind Kind;
    287 
    288   /// Specifies how the variant kind should be printed.
    289   const unsigned UseParensForSymbolVariant : 1;
    290 
    291   // FIXME: Remove this bit.
    292   const unsigned HasSubsectionsViaSymbols : 1;
    293 
    294   /// The symbol being referenced.
    295   const MCSymbol *Symbol;
    296 
    297   explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
    298                            const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
    299 
    300 public:
    301   /// \name Construction
    302   /// @{
    303 
    304   static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
    305     return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
    306   }
    307 
    308   static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
    309                                        MCContext &Ctx, SMLoc Loc = SMLoc());
    310   static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
    311                                        MCContext &Ctx);
    312 
    313   /// @}
    314   /// \name Accessors
    315   /// @{
    316 
    317   const MCSymbol &getSymbol() const { return *Symbol; }
    318 
    319   VariantKind getKind() const { return Kind; }
    320 
    321   void printVariantKind(raw_ostream &OS) const;
    322 
    323   bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
    324 
    325   /// @}
    326   /// \name Static Utility Functions
    327   /// @{
    328 
    329   static StringRef getVariantKindName(VariantKind Kind);
    330 
    331   static VariantKind getVariantKindForName(StringRef Name);
    332 
    333   /// @}
    334 
    335   static bool classof(const MCExpr *E) {
    336     return E->getKind() == MCExpr::SymbolRef;
    337   }
    338 };
    339 
    340 /// \brief Unary assembler expressions.
    341 class MCUnaryExpr : public MCExpr {
    342 public:
    343   enum Opcode {
    344     LNot,  ///< Logical negation.
    345     Minus, ///< Unary minus.
    346     Not,   ///< Bitwise negation.
    347     Plus   ///< Unary plus.
    348   };
    349 
    350 private:
    351   Opcode Op;
    352   const MCExpr *Expr;
    353 
    354   MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
    355       : MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {}
    356 
    357 public:
    358   /// \name Construction
    359   /// @{
    360 
    361   static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
    362                                    MCContext &Ctx, SMLoc Loc = SMLoc());
    363 
    364   static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    365     return create(LNot, Expr, Ctx, Loc);
    366   }
    367 
    368   static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    369     return create(Minus, Expr, Ctx, Loc);
    370   }
    371 
    372   static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    373     return create(Not, Expr, Ctx, Loc);
    374   }
    375 
    376   static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    377     return create(Plus, Expr, Ctx, Loc);
    378   }
    379 
    380   /// @}
    381   /// \name Accessors
    382   /// @{
    383 
    384   /// \brief Get the kind of this unary expression.
    385   Opcode getOpcode() const { return Op; }
    386 
    387   /// \brief Get the child of this unary expression.
    388   const MCExpr *getSubExpr() const { return Expr; }
    389 
    390   /// @}
    391 
    392   static bool classof(const MCExpr *E) {
    393     return E->getKind() == MCExpr::Unary;
    394   }
    395 };
    396 
    397 /// \brief Binary assembler expressions.
    398 class MCBinaryExpr : public MCExpr {
    399 public:
    400   enum Opcode {
    401     Add,  ///< Addition.
    402     And,  ///< Bitwise and.
    403     Div,  ///< Signed division.
    404     EQ,   ///< Equality comparison.
    405     GT,   ///< Signed greater than comparison (result is either 0 or some
    406           ///< target-specific non-zero value)
    407     GTE,  ///< Signed greater than or equal comparison (result is either 0 or
    408           ///< some target-specific non-zero value).
    409     LAnd, ///< Logical and.
    410     LOr,  ///< Logical or.
    411     LT,   ///< Signed less than comparison (result is either 0 or
    412           ///< some target-specific non-zero value).
    413     LTE,  ///< Signed less than or equal comparison (result is either 0 or
    414           ///< some target-specific non-zero value).
    415     Mod,  ///< Signed remainder.
    416     Mul,  ///< Multiplication.
    417     NE,   ///< Inequality comparison.
    418     Or,   ///< Bitwise or.
    419     Shl,  ///< Shift left.
    420     AShr, ///< Arithmetic shift right.
    421     LShr, ///< Logical shift right.
    422     Sub,  ///< Subtraction.
    423     Xor   ///< Bitwise exclusive or.
    424   };
    425 
    426 private:
    427   Opcode Op;
    428   const MCExpr *LHS, *RHS;
    429 
    430   MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
    431                SMLoc Loc = SMLoc())
    432       : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {}
    433 
    434 public:
    435   /// \name Construction
    436   /// @{
    437 
    438   static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
    439                                     const MCExpr *RHS, MCContext &Ctx,
    440                                     SMLoc Loc = SMLoc());
    441 
    442   static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
    443                                        MCContext &Ctx) {
    444     return create(Add, LHS, RHS, Ctx);
    445   }
    446 
    447   static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
    448                                        MCContext &Ctx) {
    449     return create(And, LHS, RHS, Ctx);
    450   }
    451 
    452   static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
    453                                        MCContext &Ctx) {
    454     return create(Div, LHS, RHS, Ctx);
    455   }
    456 
    457   static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
    458                                       MCContext &Ctx) {
    459     return create(EQ, LHS, RHS, Ctx);
    460   }
    461 
    462   static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
    463                                       MCContext &Ctx) {
    464     return create(GT, LHS, RHS, Ctx);
    465   }
    466 
    467   static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
    468                                        MCContext &Ctx) {
    469     return create(GTE, LHS, RHS, Ctx);
    470   }
    471 
    472   static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
    473                                         MCContext &Ctx) {
    474     return create(LAnd, LHS, RHS, Ctx);
    475   }
    476 
    477   static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
    478                                        MCContext &Ctx) {
    479     return create(LOr, LHS, RHS, Ctx);
    480   }
    481 
    482   static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
    483                                       MCContext &Ctx) {
    484     return create(LT, LHS, RHS, Ctx);
    485   }
    486 
    487   static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
    488                                        MCContext &Ctx) {
    489     return create(LTE, LHS, RHS, Ctx);
    490   }
    491 
    492   static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
    493                                        MCContext &Ctx) {
    494     return create(Mod, LHS, RHS, Ctx);
    495   }
    496 
    497   static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
    498                                        MCContext &Ctx) {
    499     return create(Mul, LHS, RHS, Ctx);
    500   }
    501 
    502   static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
    503                                       MCContext &Ctx) {
    504     return create(NE, LHS, RHS, Ctx);
    505   }
    506 
    507   static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
    508                                       MCContext &Ctx) {
    509     return create(Or, LHS, RHS, Ctx);
    510   }
    511 
    512   static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
    513                                        MCContext &Ctx) {
    514     return create(Shl, LHS, RHS, Ctx);
    515   }
    516 
    517   static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
    518                                        MCContext &Ctx) {
    519     return create(AShr, LHS, RHS, Ctx);
    520   }
    521 
    522   static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
    523                                        MCContext &Ctx) {
    524     return create(LShr, LHS, RHS, Ctx);
    525   }
    526 
    527   static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
    528                                        MCContext &Ctx) {
    529     return create(Sub, LHS, RHS, Ctx);
    530   }
    531 
    532   static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
    533                                        MCContext &Ctx) {
    534     return create(Xor, LHS, RHS, Ctx);
    535   }
    536 
    537   /// @}
    538   /// \name Accessors
    539   /// @{
    540 
    541   /// \brief Get the kind of this binary expression.
    542   Opcode getOpcode() const { return Op; }
    543 
    544   /// \brief Get the left-hand side expression of the binary operator.
    545   const MCExpr *getLHS() const { return LHS; }
    546 
    547   /// \brief Get the right-hand side expression of the binary operator.
    548   const MCExpr *getRHS() const { return RHS; }
    549 
    550   /// @}
    551 
    552   static bool classof(const MCExpr *E) {
    553     return E->getKind() == MCExpr::Binary;
    554   }
    555 };
    556 
    557 /// \brief This is an extension point for target-specific MCExpr subclasses to
    558 /// implement.
    559 ///
    560 /// NOTE: All subclasses are required to have trivial destructors because
    561 /// MCExprs are bump pointer allocated and not destructed.
    562 class MCTargetExpr : public MCExpr {
    563   virtual void anchor();
    564 
    565 protected:
    566   MCTargetExpr() : MCExpr(Target, SMLoc()) {}
    567   virtual ~MCTargetExpr() = default;
    568 
    569 public:
    570   virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
    571   virtual bool evaluateAsRelocatableImpl(MCValue &Res,
    572                                          const MCAsmLayout *Layout,
    573                                          const MCFixup *Fixup) const = 0;
    574   virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
    575   virtual MCFragment *findAssociatedFragment() const = 0;
    576 
    577   virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
    578 
    579   static bool classof(const MCExpr *E) {
    580     return E->getKind() == MCExpr::Target;
    581   }
    582 };
    583 
    584 } // end namespace llvm
    585 
    586 #endif // LLVM_MC_MCEXPR_H
    587