From 44e1dfa2df4de3e2de963f0505cdadade6fe8180 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 25 Mar 2010 23:30:28 -0700 Subject: [PATCH] Replace "mode" type tag with virtual as_foo() downcasting functions. These should work well even in a non-flat IR hierarchy. Signed-off-by: Ian Romanick --- ast_to_hir.cpp | 32 +++++++++++----------------- ir.cpp | 20 ++++++++--------- ir.h | 58 ++++++++++++++++++++++---------------------------- 3 files changed, 48 insertions(+), 62 deletions(-) diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index cdbf2c1e46b..5b577d1f56d 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -455,20 +455,16 @@ ast_expression::hir(exec_list *instructions, /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */ loc = this->subexpressions[0]->get_location(); - if (op[0]->mode != ir_op_dereference) { + const ir_dereference *const ref = op[0]->as_dereference(); + if (ref == NULL) { _mesa_glsl_error(& loc, state, "invalid lvalue in assignment"); error_emitted = true; type = glsl_error_type; } else { - const struct ir_dereference *const ref = - (struct ir_dereference *) op[0]; - const struct ir_variable *const var = - (struct ir_variable *) ref->var; - - if ((var != NULL) - && (var->mode == ir_op_var_decl) - && (var->read_only)) { + const ir_variable *const var = (ir_variable *) ref->var; + + if (var != NULL && var->read_only) { _mesa_glsl_error(& loc, state, "cannot assign to read-only " "variable `%s'", var->name); error_emitted = true; @@ -620,20 +616,16 @@ ast_expression::hir(exec_list *instructions, /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */ loc = this->subexpressions[0]->get_location(); - if (op[0]->mode != ir_op_dereference) { + const ir_dereference *const ref = op[0]->as_dereference(); + if (ref == NULL) { _mesa_glsl_error(& loc, state, "invalid lvalue in assignment"); error_emitted = true; type = glsl_error_type; } else { - const struct ir_dereference *const ref = - (struct ir_dereference *) op[0]; - const struct ir_variable *const var = - (struct ir_variable *) ref->var; - - if ((var != NULL) - && (var->mode == ir_op_var_decl) - && (var->read_only)) { + const ir_variable *const var = (ir_variable *) ref->var; + + if (var != NULL && var->read_only) { _mesa_glsl_error(& loc, state, "cannot assign to read-only " "variable `%s'", var->name); error_emitted = true; @@ -1126,7 +1118,7 @@ ast_function_definition::hir(exec_list *instructions, * either include invalid parameter names or may not have names at all. */ foreach_iter(exec_list_iterator, iter, signature->parameters) { - assert(((struct ir_instruction *)iter.get())->mode == ir_op_var_decl); + assert(((ir_instruction *) iter.get())->as_variable() != NULL); iter.remove(); delete iter.get(); @@ -1157,7 +1149,7 @@ ast_function_definition::hir(exec_list *instructions, foreach_iter(exec_list_iterator, iter, parameters) { ir_variable *const var = (ir_variable *) iter.get(); - assert(((ir_instruction *)var)->mode == ir_op_var_decl); + assert(((ir_instruction *) var)->as_variable() != NULL); iter.remove(); instructions->push_tail(var); diff --git a/ir.cpp b/ir.cpp index 1b5947a4704..0e98f0c8d99 100644 --- a/ir.cpp +++ b/ir.cpp @@ -28,7 +28,7 @@ ir_assignment::ir_assignment(ir_instruction *lhs, ir_instruction *rhs, ir_expression *condition) - : ir_instruction(ir_op_assign) + : ir_instruction() { this->lhs = (ir_dereference *) lhs; this->rhs = rhs; @@ -38,7 +38,7 @@ ir_assignment::ir_assignment(ir_instruction *lhs, ir_instruction *rhs, ir_expression::ir_expression(int op, const struct glsl_type *type, ir_instruction *op0, ir_instruction *op1) - : ir_instruction(ir_op_expression) + : ir_instruction() { this->type = type; this->operation = ir_expression_operation(op); @@ -48,14 +48,14 @@ ir_expression::ir_expression(int op, const struct glsl_type *type, ir_label::ir_label(const char *label) - : ir_instruction(ir_op_label), label(label) + : ir_instruction(), label(label) { /* empty */ } ir_constant::ir_constant(const struct glsl_type *type, const void *data) - : ir_instruction(ir_op_constant) + : ir_instruction() { const unsigned elements = ((type->vector_elements == 0) ? 1 : type->vector_elements) @@ -79,7 +79,7 @@ ir_constant::ir_constant(const struct glsl_type *type, const void *data) ir_dereference::ir_dereference(ir_instruction *var) - : ir_instruction(ir_op_dereference) + : ir_instruction() { this->mode = ir_reference_variable; this->var = var; @@ -89,7 +89,7 @@ ir_dereference::ir_dereference(ir_instruction *var) ir_dereference::ir_dereference(ir_instruction *var, ir_instruction *array_index) - : ir_instruction(ir_op_dereference), mode(ir_reference_array), + : ir_instruction(), mode(ir_reference_array), var(var) { this->type = (var != NULL) ? var->type : glsl_error_type; @@ -124,8 +124,8 @@ ir_dereference::set_swizzle(unsigned x, unsigned y, unsigned z, unsigned w, ir_variable::ir_variable(const struct glsl_type *type, const char *name) - : ir_instruction(ir_op_var_decl), read_only(false), centroid(false), - invariant(false), mode(ir_var_auto), interpolation(ir_var_smooth) + : ir_instruction(), read_only(false), centroid(false), invariant(false), + mode(ir_var_auto), interpolation(ir_var_smooth) { this->type = type; this->name = name; @@ -133,14 +133,14 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name) ir_function_signature::ir_function_signature(const glsl_type *return_type) - : ir_instruction(ir_op_func_sig), return_type(return_type), definition(NULL) + : ir_instruction(), return_type(return_type), definition(NULL) { /* empty */ } ir_function::ir_function(const char *name) - : ir_instruction(ir_op_func), name(name) + : ir_instruction(), name(name) { /* empty */ } diff --git a/ir.h b/ir.h index 22b46c971e8..c21b26a460e 100644 --- a/ir.h +++ b/ir.h @@ -33,46 +33,32 @@ struct ir_program { void *bong_hits; }; - -enum ir_opcodes { - ir_op_var_decl, - ir_op_assign, - ir_op_expression, - ir_op_dereference, - ir_op_jump, - ir_op_label, - ir_op_constant, - ir_op_func_sig, - ir_op_func, - ir_op_call, -}; - /** * Base class of all IR instructions */ class ir_instruction : public exec_node { public: - unsigned mode; const struct glsl_type *type; virtual void accept(ir_visitor *) = 0; + /** + * \name IR instruction downcast functions + * + * These functions either cast the object to a derived class or return + * \c NULL if the object's type does not match the specified derived class. + * Additional downcast functions will be added as needed. + */ + /*@{*/ + virtual class ir_variable * as_variable() { return NULL; } + virtual class ir_dereference * as_dereference() { return NULL; } + /*@}*/ + protected: - ir_instruction(int mode) - : mode(mode) + ir_instruction() { /* empty */ } - -private: - /** - * Dummy constructor to catch bad constructors in derived classes. - * - * Every derived must use the constructor that sets the instructions - * mode. Having the \c void constructor private prevents derived classes - * from accidentally doing the wrong thing. - */ - ir_instruction(void); }; @@ -94,6 +80,11 @@ class ir_variable : public ir_instruction { public: ir_variable(const struct glsl_type *, const char *); + virtual ir_variable *as_variable() + { + return this; + } + virtual void accept(ir_visitor *v) { v->visit(this); @@ -181,8 +172,6 @@ public: }; /*@}*/ -class ir_expression; -class ir_dereference; class ir_assignment : public ir_instruction { public: @@ -296,7 +285,7 @@ public: class ir_call : public ir_instruction { public: ir_call(const ir_function_signature *callee, exec_list *actual_parameters) - : ir_instruction(ir_op_call), callee(callee) + : ir_instruction(), callee(callee) { assert(callee->return_type != NULL); type = callee->return_type; @@ -315,7 +304,7 @@ public: private: ir_call() - : ir_instruction(ir_op_call), callee(NULL) + : ir_instruction(), callee(NULL) { /* empty */ } @@ -334,7 +323,7 @@ private: class ir_jump : public ir_instruction { protected: ir_jump() - : ir_instruction(ir_op_jump) + : ir_instruction() { /* empty */ } @@ -395,6 +384,11 @@ public: ir_dereference(ir_instruction *variable, ir_instruction *array_index); + virtual ir_dereference *as_dereference() + { + return this; + } + virtual void accept(ir_visitor *v) { v->visit(this); -- 2.30.2