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