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