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