MC: Improve expression parsing and implement evaluation of absolute expressions
[oota-llvm.git] / tools / llvm-mc / AsmExpr.h
1 //===- AsmExpr.h - Assembly file 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 ASMEXPR_H
11 #define ASMEXPR_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
20 class AsmExpr {
21 public:
22   enum AsmExprKind {
23     Binary,    /// Binary expressions.
24     Constant,  /// Constant expressions.
25     SymbolRef, /// References to labels and assigned expressions.
26     Unary      /// Unary expressions.
27   };
28   
29 private:
30   AsmExprKind Kind;
31   
32 protected:
33   AsmExpr(AsmExprKind _Kind) : Kind(_Kind) {}
34   
35 public:
36   virtual ~AsmExpr();
37
38   AsmExprKind getKind() const { return Kind; }
39
40   /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
41   ///
42   /// @param Res - The absolute value if evaluation succeeds.
43   /// @result - True on success.
44   bool EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const;
45
46   static bool classof(const AsmExpr *) { return true; }
47 };
48
49 class AsmConstantExpr : public AsmExpr {
50   int64_t Value;
51
52 public:
53   AsmConstantExpr(int64_t _Value) 
54     : AsmExpr(AsmExpr::Constant), Value(_Value) {}
55   
56   int64_t getValue() const { return Value; }
57
58   static bool classof(const AsmExpr *E) { 
59     return E->getKind() == AsmExpr::Constant; 
60   }
61   static bool classof(const AsmConstantExpr *) { return true; }
62 };
63
64 class AsmSymbolRefExpr : public AsmExpr {
65   MCSymbol *Symbol;
66
67 public:
68   AsmSymbolRefExpr(MCSymbol *_Symbol) 
69     : AsmExpr(AsmExpr::SymbolRef), Symbol(_Symbol) {}
70   
71   MCSymbol *getSymbol() const { return Symbol; }
72
73   static bool classof(const AsmExpr *E) { 
74     return E->getKind() == AsmExpr::SymbolRef; 
75   }
76   static bool classof(const AsmSymbolRefExpr *) { return true; }
77 };
78
79 class AsmUnaryExpr : public AsmExpr {
80 public:
81   enum Opcode {
82     LNot,  /// Logical negation.
83     Minus, /// Unary minus.
84     Not,   /// Bit-wise negation.
85     Plus   /// Unary plus.
86   };
87
88 private:
89   Opcode Op;
90   AsmExpr *Expr;
91
92 public:
93   AsmUnaryExpr(Opcode _Op, AsmExpr *_Expr)
94     : AsmExpr(AsmExpr::Unary), Op(_Op), Expr(_Expr) {}
95   ~AsmUnaryExpr() {
96     delete Expr;
97   }
98
99   Opcode getOpcode() const { return Op; }
100
101   AsmExpr *getSubExpr() const { return Expr; }
102
103   static bool classof(const AsmExpr *E) { 
104     return E->getKind() == AsmExpr::Unary; 
105   }
106   static bool classof(const AsmUnaryExpr *) { return true; }
107 };
108
109 class AsmBinaryExpr : public AsmExpr {
110 public:
111   enum Opcode {
112     Add,  /// Addition.
113     And,  /// Bitwise and.
114     Div,  /// Division.
115     EQ,   /// Equality comparison.
116     GT,   /// Greater than comparison.
117     GTE,  /// Greater than or equal comparison.
118     LAnd, /// Logical and.
119     LOr,  /// Logical or.
120     LT,   /// Less than comparison.
121     LTE,  /// Less than or equal comparison.
122     Mod,  /// Modulus.
123     Mul,  /// Multiplication.
124     NE,   /// Inequality comparison.
125     Or,   /// Bitwise or.
126     Shl,  /// Bitwise shift left.
127     Shr,  /// Bitwise shift right.
128     Sub,  /// Subtraction.
129     Xor   /// Bitwise exclusive or.
130   };
131
132 private:
133   Opcode Op;
134   AsmExpr *LHS, *RHS;
135
136 public:
137   AsmBinaryExpr(Opcode _Op, AsmExpr *_LHS, AsmExpr *_RHS)
138     : AsmExpr(AsmExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
139   ~AsmBinaryExpr() {
140     delete LHS;
141     delete RHS;
142   }
143
144   Opcode getOpcode() const { return Op; }
145
146   AsmExpr *getLHS() const { return LHS; }
147   AsmExpr *getRHS() const { return RHS; }
148
149   static bool classof(const AsmExpr *E) { 
150     return E->getKind() == AsmExpr::Binary; 
151   }
152   static bool classof(const AsmBinaryExpr *) { return true; }
153 };
154
155 } // end namespace llvm
156
157 #endif