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