Thread an MCAsmInfo pointer through the various MC printing APIs,
[oota-llvm.git] / include / llvm / MC / MCExpr.h
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/Support/Casting.h"
14 #include "llvm/Support/DataTypes.h"
15
16 namespace llvm {
17 class MCAsmInfo;
18 class MCContext;
19 class MCSymbol;
20 class MCValue;
21 class raw_ostream;
22
23 /// MCExpr - Base class for the full range of assembler expressions which are
24 /// needed for parsing.
25 class MCExpr {
26 public:
27   enum ExprKind {
28     Binary,    ///< Binary expressions.
29     Constant,  ///< Constant expressions.
30     SymbolRef, ///< References to labels and assigned expressions.
31     Unary      ///< Unary expressions.
32   };
33
34 private:
35   ExprKind Kind;
36
37   MCExpr(const MCExpr&); // DO NOT IMPLEMENT
38   void operator=(const MCExpr&); // DO NOT IMPLEMENT
39
40 protected:
41   MCExpr(ExprKind _Kind) : Kind(_Kind) {}
42
43 public:
44   /// @name Accessors
45   /// @{
46
47   ExprKind getKind() const { return Kind; }
48
49   /// @}
50   /// @name Utility Methods
51   /// @{
52
53   void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
54   void dump() const;
55
56   /// @}
57   /// @name Expression Evaluation
58   /// @{
59
60   /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
61   ///
62   /// @param Res - The absolute value, if evaluation succeeds.
63   /// @result - True on success.
64   bool EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const;
65
66   /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
67   /// value, i.e. an expression of the fixed form (a - b + constant).
68   ///
69   /// @param Res - The relocatable value, if evaluation succeeds.
70   /// @result - True on success.
71   bool EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const;
72
73   /// @}
74
75   static bool classof(const MCExpr *) { return true; }
76 };
77
78 //// MCConstantExpr - Represent a constant integer expression.
79 class MCConstantExpr : public MCExpr {
80   int64_t Value;
81
82   MCConstantExpr(int64_t _Value)
83     : MCExpr(MCExpr::Constant), Value(_Value) {}
84
85 public:
86   /// @name Construction
87   /// @{
88
89   static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
90
91   /// @}
92   /// @name Accessors
93   /// @{
94
95   int64_t getValue() const { return Value; }
96
97   /// @}
98
99   static bool classof(const MCExpr *E) {
100     return E->getKind() == MCExpr::Constant;
101   }
102   static bool classof(const MCConstantExpr *) { return true; }
103 };
104
105 /// MCSymbolRefExpr - Represent a reference to a symbol from inside an
106 /// expression.
107 ///
108 /// A symbol reference in an expression may be a use of a label, a use of an
109 /// assembler variable (defined constant), or constitute an implicit definition
110 /// of the symbol as external.
111 class MCSymbolRefExpr : public MCExpr {
112   const MCSymbol *Symbol;
113
114   MCSymbolRefExpr(const MCSymbol *_Symbol)
115     : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {}
116
117 public:
118   /// @name Construction
119   /// @{
120
121   static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx);
122
123   /// @}
124   /// @name Accessors
125   /// @{
126
127   const MCSymbol &getSymbol() const { return *Symbol; }
128
129   /// @}
130
131   static bool classof(const MCExpr *E) {
132     return E->getKind() == MCExpr::SymbolRef;
133   }
134   static bool classof(const MCSymbolRefExpr *) { return true; }
135 };
136
137 /// MCUnaryExpr - Unary assembler expressions.
138 class MCUnaryExpr : public MCExpr {
139 public:
140   enum Opcode {
141     LNot,  ///< Logical negation.
142     Minus, ///< Unary minus.
143     Not,   ///< Bitwise negation.
144     Plus   ///< Unary plus.
145   };
146
147 private:
148   Opcode Op;
149   const MCExpr *Expr;
150
151   MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
152     : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
153
154 public:
155   /// @name Construction
156   /// @{
157
158   static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
159                                    MCContext &Ctx);
160   static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
161     return Create(LNot, Expr, Ctx);
162   }
163   static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
164     return Create(Minus, Expr, Ctx);
165   }
166   static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
167     return Create(Not, Expr, Ctx);
168   }
169   static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
170     return Create(Plus, Expr, Ctx);
171   }
172
173   /// @}
174   /// @name Accessors
175   /// @{
176
177   /// getOpcode - Get the kind of this unary expression.
178   Opcode getOpcode() const { return Op; }
179
180   /// getSubExpr - Get the child of this unary expression.
181   const MCExpr *getSubExpr() const { return Expr; }
182
183   /// @}
184
185   static bool classof(const MCExpr *E) {
186     return E->getKind() == MCExpr::Unary;
187   }
188   static bool classof(const MCUnaryExpr *) { return true; }
189 };
190
191 /// MCBinaryExpr - Binary assembler expressions.
192 class MCBinaryExpr : public MCExpr {
193 public:
194   enum Opcode {
195     Add,  ///< Addition.
196     And,  ///< Bitwise and.
197     Div,  ///< Division.
198     EQ,   ///< Equality comparison.
199     GT,   ///< Greater than comparison.
200     GTE,  ///< Greater than or equal comparison.
201     LAnd, ///< Logical and.
202     LOr,  ///< Logical or.
203     LT,   ///< Less than comparison.
204     LTE,  ///< Less than or equal comparison.
205     Mod,  ///< Modulus.
206     Mul,  ///< Multiplication.
207     NE,   ///< Inequality comparison.
208     Or,   ///< Bitwise or.
209     Shl,  ///< Bitwise shift left.
210     Shr,  ///< Bitwise shift right.
211     Sub,  ///< Subtraction.
212     Xor   ///< Bitwise exclusive or.
213   };
214
215 private:
216   Opcode Op;
217   const MCExpr *LHS, *RHS;
218
219   MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
220     : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
221
222 public:
223   /// @name Construction
224   /// @{
225
226   static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
227                                     const MCExpr *RHS, MCContext &Ctx);
228   static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
229                                        MCContext &Ctx) {
230     return Create(Add, LHS, RHS, Ctx);
231   }
232   static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
233                                        MCContext &Ctx) {
234     return Create(And, LHS, RHS, Ctx);
235   }
236   static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
237                                        MCContext &Ctx) {
238     return Create(Div, LHS, RHS, Ctx);
239   }
240   static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
241                                       MCContext &Ctx) {
242     return Create(EQ, LHS, RHS, Ctx);
243   }
244   static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
245                                       MCContext &Ctx) {
246     return Create(GT, LHS, RHS, Ctx);
247   }
248   static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
249                                        MCContext &Ctx) {
250     return Create(GTE, LHS, RHS, Ctx);
251   }
252   static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
253                                         MCContext &Ctx) {
254     return Create(LAnd, LHS, RHS, Ctx);
255   }
256   static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
257                                        MCContext &Ctx) {
258     return Create(LOr, LHS, RHS, Ctx);
259   }
260   static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
261                                       MCContext &Ctx) {
262     return Create(LT, LHS, RHS, Ctx);
263   }
264   static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
265                                        MCContext &Ctx) {
266     return Create(LTE, LHS, RHS, Ctx);
267   }
268   static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
269                                        MCContext &Ctx) {
270     return Create(Mod, LHS, RHS, Ctx);
271   }
272   static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
273                                        MCContext &Ctx) {
274     return Create(Mul, LHS, RHS, Ctx);
275   }
276   static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
277                                       MCContext &Ctx) {
278     return Create(NE, LHS, RHS, Ctx);
279   }
280   static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
281                                       MCContext &Ctx) {
282     return Create(Or, LHS, RHS, Ctx);
283   }
284   static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
285                                        MCContext &Ctx) {
286     return Create(Shl, LHS, RHS, Ctx);
287   }
288   static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
289                                        MCContext &Ctx) {
290     return Create(Shr, LHS, RHS, Ctx);
291   }
292   static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
293                                        MCContext &Ctx) {
294     return Create(Sub, LHS, RHS, Ctx);
295   }
296   static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
297                                        MCContext &Ctx) {
298     return Create(Xor, LHS, RHS, Ctx);
299   }
300
301   /// @}
302   /// @name Accessors
303   /// @{
304
305   /// getOpcode - Get the kind of this binary expression.
306   Opcode getOpcode() const { return Op; }
307
308   /// getLHS - Get the left-hand side expression of the binary operator.
309   const MCExpr *getLHS() const { return LHS; }
310
311   /// getRHS - Get the right-hand side expression of the binary operator.
312   const MCExpr *getRHS() const { return RHS; }
313
314   /// @}
315
316   static bool classof(const MCExpr *E) {
317     return E->getKind() == MCExpr::Binary;
318   }
319   static bool classof(const MCBinaryExpr *) { return true; }
320 };
321
322 } // end namespace llvm
323
324 #endif