More const preparation: allow type casts to follow qualification.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of SourcePawn.
6 * SourcePawn is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
11 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * SourcePawn. If not, see http://www.gnu.org/licenses/.
18 #ifndef _include_sp2_hir_h_
19 #define _include_sp2_hir_h_
22 #include "../PoolAllocator.h"
23 #include "../Opcodes.h"
36 /* Special LValue types */ \
45 // Forward declarations.
46 #define _(name) class H##name;
55 class HIR : public PoolObject
59 #define _(name) k##name,
66 HIR(AstNode *node, Type *type)
75 AstNode *node() const {
79 virtual bool isLValue() const {
83 virtual HOp op() const = 0;
84 virtual void accept(HIRVisitor *visitor) = 0;
87 bool is##name() const { \
88 return op() == k##name; \
90 H##name *to##name() { \
92 return reinterpret_cast<H##name *>(this); \
99 return reinterpret_cast<HLValue *>(this);
104 ScopedRoot<Type> type_;
107 class BytecodeEmitter;
113 virtual void visit##name(H##name *hir) { \
120 typedef PoolList<HIR *> HIRList;
122 #define DEFINE_HIR(name) \
123 virtual HOp op() const { \
126 virtual void accept(HIRVisitor *visitor) { \
127 visitor->visit##name(this); \
130 class HInteger : public HIR
133 HInteger(AstNode *node, Type *type, int value)
148 class HString : public HIR
151 HString(AstNode *node, Type *type, String *string)
158 Handle<String> string() const {
163 ScopedRoot<String> string_;
166 class HArray : public HIR
169 HArray(AstNode *node, Type *type, Array *array, bool duplicate)
172 duplicate_(duplicate)
177 Handle<Array> array() const {
180 bool duplicate() const {
185 ScopedRoot<Array> array_;
189 class HConvert : public HIR
192 HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
200 Opcode opcode() const {
212 class HLValue : public HIR
215 HLValue(AstNode *node, Type *type)
220 // Pushes a reference to the LValue on the stack.
221 virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
223 // Duplicates a stack reference.
224 virtual void hold(BytecodeEmitter &emitter_) = 0;
226 // Reorders the stack for a post-increment operation:
227 // REF VAL -> VAL REF VAL
228 virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
230 // Given a stack layout of the form:
234 // Emits a store to the reference.
235 virtual void store(BytecodeEmitter &emitter_) = 0;
236 virtual void load(BytecodeEmitter &emitter_) = 0;
238 // Try to make a direct reference, if semantics allow it. False if the
239 // caller must allocate a reference to the stack.
240 virtual bool ref(BytecodeEmitter &emitter_) = 0;
242 bool isLValue() const {
247 class HLocal : public HLValue
250 HLocal(AstNode *node, VariableSymbol *sym);
254 // Pushes a reference to the LValue on the stack.
255 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
256 void hold(BytecodeEmitter &emitter_);
257 void swapAndPick(BytecodeEmitter &emitter_);
258 void store(BytecodeEmitter &emitter_);
259 void load(BytecodeEmitter &emitter_);
260 bool ref(BytecodeEmitter &emitter_);
262 VariableSymbol *sym() const {
267 VariableSymbol *sym_;
270 class HIndex : public HLValue
273 HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
274 : HLValue(node, type),
282 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
283 void hold(BytecodeEmitter &emitter_);
284 void swapAndPick(BytecodeEmitter &emitter_);
285 void store(BytecodeEmitter &emitter_);
286 void load(BytecodeEmitter &emitter_);
287 bool ref(BytecodeEmitter &emitter_);
294 class HGlobal : public HLValue
297 HGlobal(AstNode *node, Symbol *sym)
298 : HLValue(node, sym->type()),
305 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
306 void hold(BytecodeEmitter &emitter_);
307 void swapAndPick(BytecodeEmitter &emitter_);
308 void store(BytecodeEmitter &emitter_);
309 void load(BytecodeEmitter &emitter_);
310 bool ref(BytecodeEmitter &emitter_);
312 Symbol *sym() const {
320 class HBinary : public HIR
323 HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
332 TokenKind token() const {
348 class HFloat : public HIR
351 HFloat(AstNode *node, Type *type, float value)
358 float value() const {
366 class HStore : public HIR
369 HStore(AstNode *node, HLValue *lval, HIR *rval)
370 : HIR(node, lval->type()),
377 HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
378 : HIR(node, lval->type()),
387 HLValue *lval() const {
393 TokenKind kind() const {
403 class HPostIncDec : public HIR
406 HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
407 : HIR(node, lval->type()),
414 DEFINE_HIR(PostIncDec);
416 HLValue *lval() const {
422 TokenKind kind() const {
432 class HCall : public HIR
435 HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
444 HIR *callee() const {
447 HIRList *args() const {
456 class HToRef : public HIR
459 HToRef(AstNode *node, Type *type, HIR *in)
477 void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
481 #endif // _include_sp2_hir_h_