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