summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2010-07-02 13:30:23 -0700
committerIan Romanick <[email protected]>2010-07-12 15:19:29 -0700
commitc67016de960c988c748ffdb11247072543a8f328 (patch)
tree40c039fdc244d0567f777946a42c38128d3d6fa7
parentdf05ad4e1aa5512ce1dfd2e6661641e012c8b279 (diff)
ir_validate: Additional function related invariant checks
Add two invariant checks related to functions and function signatures: 1. Ensure that function definitions (ir_function) are not nested. 2. Ensure that the ir_function pointed to by an ir_function_signature is the one that contains it in its signatures list.
-rw-r--r--src/glsl/ir_validate.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 7582d57e7c3..8c86748d26a 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -46,6 +46,8 @@ public:
this->ht = hash_table_ctor(0, hash_table_pointer_hash,
hash_table_pointer_compare);
+ this->current_function = NULL;
+
this->callback = ir_validate::validate_ir;
this->data = ht;
}
@@ -57,12 +59,70 @@ public:
virtual ir_visitor_status visit(ir_variable *v);
+ virtual ir_visitor_status visit_enter(ir_function *ir);
+ virtual ir_visitor_status visit_leave(ir_function *ir);
+ virtual ir_visitor_status visit_enter(ir_function_signature *ir);
+
static void validate_ir(ir_instruction *ir, void *data);
+ ir_function *current_function;
+
struct hash_table *ht;
};
ir_visitor_status
+ir_validate::visit_enter(ir_function *ir)
+{
+ /* Function definitions cannot be nested.
+ */
+ if (this->current_function != NULL) {
+ printf("Function definition nested inside another function "
+ "definition:\n");
+ printf("%s %p inside %s %p\n",
+ ir->name, ir,
+ this->current_function->name, this->current_function);
+ abort();
+ }
+
+ /* Store the current function hierarchy being traversed. This is used
+ * by the function signature visitor to ensure that the signatures are
+ * linked with the correct functions.
+ */
+ this->current_function = ir;
+
+ this->validate_ir(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_leave(ir_function *ir)
+{
+ (void) ir;
+
+ this->current_function = NULL;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_enter(ir_function_signature *ir)
+{
+ if (this->current_function != ir->function()) {
+ printf("Function signature nested inside wrong function "
+ "definition:\n");
+ printf("%p inside %s %p instead of %s %p\n",
+ ir,
+ this->current_function->name, this->current_function,
+ ir->function_name(), ir->function());
+ abort();
+ }
+
+ this->validate_ir(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
ir_validate::visit(ir_variable *ir)
{
/* An ir_variable is the one thing that can (and will) appear multiple times