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